react-native-update-cli 2.5.0 → 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 (45) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/cli.json +26 -0
  4. package/lib/api.js +1 -1
  5. package/lib/locales/en.js +13 -1
  6. package/lib/locales/zh.js +13 -1
  7. package/lib/package.js +53 -6
  8. package/lib/provider.js +3 -0
  9. package/lib/utils/app-info-parser/aab.js +165 -201
  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 +8 -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/package.json +1 -1
  21. package/src/api.ts +2 -6
  22. package/src/locales/en.ts +17 -0
  23. package/src/locales/zh.ts +15 -0
  24. package/src/modules/version-module.ts +1 -1
  25. package/src/package.ts +102 -11
  26. package/src/provider.ts +3 -0
  27. package/src/utils/app-info-parser/aab.ts +240 -0
  28. package/src/utils/app-info-parser/{apk.js → apk.ts} +30 -41
  29. package/src/utils/app-info-parser/app.ts +3 -0
  30. package/src/utils/app-info-parser/index.ts +4 -4
  31. package/src/utils/app-info-parser/{ipa.js → ipa.ts} +17 -31
  32. package/src/utils/app-info-parser/resource-finder.ts +508 -0
  33. package/src/utils/app-info-parser/utils.ts +162 -0
  34. package/src/utils/app-info-parser/xml-parser/{binary.js → binary.ts} +69 -61
  35. package/src/utils/app-info-parser/xml-parser/{manifest.js → manifest.ts} +50 -51
  36. package/src/utils/app-info-parser/zip.ts +86 -0
  37. package/src/utils/dep-versions.ts +7 -4
  38. package/src/utils/http-helper.ts +1 -1
  39. package/src/utils/latest-version/index.ts +2 -1
  40. package/src/versions.ts +1 -1
  41. package/src/utils/app-info-parser/aab.js +0 -326
  42. package/src/utils/app-info-parser/app.js +0 -16
  43. package/src/utils/app-info-parser/resource-finder.js +0 -495
  44. package/src/utils/app-info-parser/utils.js +0 -172
  45. package/src/utils/app-info-parser/zip.js +0 -66
package/README.md CHANGED
@@ -223,10 +223,12 @@ Each workflow step contains:
223
223
 
224
224
  - `uploadIpa`: Upload IPA files (supports `--version` to override extracted version)
225
225
  - `uploadApk`: Upload APK files (supports `--version` to override extracted version)
226
+ - `uploadAab`: Upload AAB files (converted to APK, supports `--version`, `--includeAllSplits`, `--splits`)
226
227
  - `uploadApp`: Upload APP files (supports `--version` to override extracted version)
227
228
  - `parseApp`: Parse APP file information
228
229
  - `parseIpa`: Parse IPA file information
229
230
  - `parseApk`: Parse APK file information
231
+ - `extractApk`: Extract a universal APK from an AAB (supports `--output`, `--includeAllSplits`, `--splits`)
230
232
  - `packages`: List packages
231
233
 
232
234
  ### User Module (`user`)
package/README.zh-CN.md CHANGED
@@ -221,10 +221,12 @@ const workflowResult = await moduleManager.executeWorkflow('my-workflow', {
221
221
 
222
222
  - `uploadIpa`: 上传 IPA 文件(支持 `--version` 参数覆盖提取的版本)
223
223
  - `uploadApk`: 上传 APK 文件(支持 `--version` 参数覆盖提取的版本)
224
+ - `uploadAab`: 上传 AAB 文件(转换为 APK,支持 `--version`、`--includeAllSplits`、`--splits`)
224
225
  - `uploadApp`: 上传 APP 文件(支持 `--version` 参数覆盖提取的版本)
225
226
  - `parseApp`: 解析 APP 文件信息
226
227
  - `parseIpa`: 解析 IPA 文件信息
227
228
  - `parseApk`: 解析 APK 文件信息
229
+ - `extractApk`: 从 AAB 提取通用 APK(支持 `--output`、`--includeAllSplits`、`--splits`)
228
230
  - `packages`: 列出包
229
231
 
230
232
  ### User 模块 (`user`)
package/cli.json CHANGED
@@ -45,6 +45,19 @@
45
45
  }
46
46
  }
47
47
  },
48
+ "uploadAab": {
49
+ "options": {
50
+ "version": {
51
+ "hasValue": true
52
+ },
53
+ "includeAllSplits": {
54
+ "default": false
55
+ },
56
+ "splits": {
57
+ "hasValue": true
58
+ }
59
+ }
60
+ },
48
61
  "uploadApp": {
49
62
  "options": {
50
63
  "version": {
@@ -56,6 +69,19 @@
56
69
  "parseIpa": {},
57
70
  "parseApk": {},
58
71
  "parseAab": {},
72
+ "extractApk": {
73
+ "options": {
74
+ "output": {
75
+ "hasValue": true
76
+ },
77
+ "includeAllSplits": {
78
+ "default": false
79
+ },
80
+ "splits": {
81
+ "hasValue": true
82
+ }
83
+ }
84
+ },
59
85
  "packages": {
60
86
  "options": {
61
87
  "platform": {
package/lib/api.js CHANGED
@@ -51,10 +51,10 @@ const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data"));
51
51
  const _nodefetch = /*#__PURE__*/ _interop_require_default(require("node-fetch"));
52
52
  const _progress = /*#__PURE__*/ _interop_require_default(require("progress"));
53
53
  const _tcpping = /*#__PURE__*/ _interop_require_default(require("tcp-ping"));
54
+ const _httphelper = require("./utils/http-helper");
54
55
  const _packagejson = /*#__PURE__*/ _interop_require_default(require("../package.json"));
55
56
  const _constants = require("./utils/constants");
56
57
  const _i18n = require("./utils/i18n");
57
- const _httphelper = require("./utils/http-helper");
58
58
  function _interop_require_default(obj) {
59
59
  return obj && obj.__esModule ? obj : {
60
60
  default: obj
package/lib/locales/en.js CHANGED
@@ -11,6 +11,15 @@ Object.defineProperty(exports, "default", {
11
11
  const _default = {
12
12
  addedToGitignore: 'Added {{line}} to .gitignore',
13
13
  androidCrunchPngsWarning: 'The crunchPngs option of android seems not disabled (Please ignore this warning if already disabled), which may cause abnormal consumption of mobile network traffic. Please refer to https://cresc.dev/docs/getting-started#disable-crunchpngs-on-android \n',
14
+ aabOpenApksFailed: 'Failed to open generated .apks file',
15
+ aabReadUniversalApkFailed: 'Failed to read universal.apk',
16
+ aabUniversalApkNotFound: 'universal.apk not found in generated .apks',
17
+ aabBundletoolDownloadHint: 'bundletool not found. Downloading node-bundletool via npx (first run may take a while).',
18
+ aabManifestNotFound: "AndroidManifest.xml can't be found in AAB base/manifest/",
19
+ aabParseResourcesWarning: '[Warning] Failed to parse resources.arsc: {{error}}',
20
+ aabParseFailed: 'Failed to parse AAB: {{error}}',
21
+ aabParseManifestError: 'Parse AndroidManifest.xml error: {{error}}',
22
+ aabParseResourcesError: 'Parser resources.arsc error: {{error}}',
14
23
  appId: 'App ID',
15
24
  appIdMismatchApk: 'App ID mismatch! Current APK: {{appIdInPkg}}, current update.json: {{appId}}',
16
25
  appIdMismatchApp: 'App ID mismatch! Current APP: {{appIdInPkg}}, current update.json: {{appId}}',
@@ -101,10 +110,12 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
101
110
  usageDiff: 'Usage: cresc {{command}} <origin> <next>',
102
111
  usageParseApk: 'Usage: cresc parseApk <apk file>',
103
112
  usageParseAab: 'Usage: cresc parseAab <aab file>',
113
+ usageExtractApk: 'Usage: cresc extractApk <aab file> [--output <apk file>] [--includeAllSplits] [--splits <split names>]',
104
114
  usageParseApp: 'Usage: cresc parseApp <app file>',
105
115
  usageParseIpa: 'Usage: cresc parseIpa <ipa file>',
106
116
  usageUnderDevelopment: 'Usage is under development now.',
107
117
  usageUploadApk: 'Usage: cresc uploadApk <apk file>',
118
+ usageUploadAab: 'Usage: cresc uploadAab <aab file> [--includeAllSplits] [--splits <split names>]',
108
119
  usageUploadApp: 'Usage: cresc uploadApp <app file>',
109
120
  usageUploadIpa: 'Usage: cresc uploadIpa <ipa file>',
110
121
  versionBind: 'Bound hot update {{version}} to native version {{nativeVersion}} (id: {{id}})',
@@ -125,5 +136,6 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
125
136
  bundleFileNotFound: 'Bundle file not found! Please use default bundle file name and path.',
126
137
  diffPackageGenerated: '{{- output}} generated.',
127
138
  nodeBsdiffRequired: 'This function needs "node-bsdiff". Please run "{{scriptName}} install node-bsdiff" to install',
128
- nodeHdiffpatchRequired: 'This function needs "node-hdiffpatch". Please run "{{scriptName}} install node-hdiffpatch" to install'
139
+ nodeHdiffpatchRequired: 'This function needs "node-hdiffpatch". Please run "{{scriptName}} install node-hdiffpatch" to install',
140
+ apkExtracted: 'APK extracted to {{output}}'
129
141
  };
package/lib/locales/zh.js CHANGED
@@ -11,6 +11,15 @@ Object.defineProperty(exports, "default", {
11
11
  const _default = {
12
12
  addedToGitignore: '已将 {{line}} 添加到 .gitignore',
13
13
  androidCrunchPngsWarning: 'android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n',
14
+ aabOpenApksFailed: '无法打开生成的 .apks 文件',
15
+ aabReadUniversalApkFailed: '无法读取 universal.apk',
16
+ aabUniversalApkNotFound: '在生成的 .apks 中未找到 universal.apk',
17
+ aabBundletoolDownloadHint: '未找到 bundletool,正在通过 npx 下载 node-bundletool(首次下载可能需要一些时间)。',
18
+ aabManifestNotFound: '在 AAB 的 base/manifest/ 中找不到 AndroidManifest.xml',
19
+ aabParseResourcesWarning: '[警告] 解析 resources.arsc 失败:{{error}}',
20
+ aabParseFailed: '解析 AAB 失败:{{error}}',
21
+ aabParseManifestError: '解析 AndroidManifest.xml 出错:{{error}}',
22
+ aabParseResourcesError: '解析 resources.arsc 出错:{{error}}',
14
23
  appId: '应用 id',
15
24
  appIdMismatchApk: 'appId不匹配!当前apk: {{appIdInPkg}}, 当前update.json: {{appId}}',
16
25
  appIdMismatchApp: 'appId不匹配!当前app: {{appIdInPkg}}, 当前update.json: {{appId}}',
@@ -101,9 +110,11 @@ const _default = {
101
110
  usageDiff: '用法:pushy {{command}} <origin> <next>',
102
111
  usageParseApk: '使用方法: pushy parseApk apk后缀文件',
103
112
  usageParseAab: '使用方法: pushy parseAab aab后缀文件',
113
+ usageExtractApk: '使用方法: pushy extractApk aab后缀文件 [--output apk文件] [--includeAllSplits] [--splits 分包名列表]',
104
114
  usageParseApp: '使用方法: pushy parseApp app后缀文件',
105
115
  usageParseIpa: '使用方法: pushy parseIpa ipa后缀文件',
106
116
  usageUploadApk: '使用方法: pushy uploadApk apk后缀文件',
117
+ usageUploadAab: '使用方法: pushy uploadAab aab后缀文件 [--includeAllSplits] [--splits 分包名列表]',
107
118
  usageUploadApp: '使用方法: pushy uploadApp app后缀文件',
108
119
  usageUploadIpa: '使用方法: pushy uploadIpa ipa后缀文件',
109
120
  versionBind: '已将热更包 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
@@ -124,5 +135,6 @@ const _default = {
124
135
  bundleFileNotFound: '未找到 bundle 文件!请使用默认的 bundle 文件名和路径。',
125
136
  diffPackageGenerated: '{{- output}} 已生成。',
126
137
  nodeBsdiffRequired: '此功能需要 "node-bsdiff"。请运行 "{{scriptName}} install node-bsdiff" 来安装',
127
- nodeHdiffpatchRequired: '此功能需要 "node-hdiffpatch"。请运行 "{{scriptName}} install node-hdiffpatch" 来安装'
138
+ nodeHdiffpatchRequired: '此功能需要 "node-hdiffpatch"。请运行 "{{scriptName}} install node-hdiffpatch" 来安装',
139
+ apkExtracted: 'APK 已提取到 {{output}}'
128
140
  };
package/lib/package.js CHANGED
@@ -19,20 +19,24 @@ _export(exports, {
19
19
  return packageCommands;
20
20
  }
21
21
  });
22
+ const _os = /*#__PURE__*/ _interop_require_default(require("os"));
23
+ const _path = /*#__PURE__*/ _interop_require_default(require("path"));
24
+ const _fsextra = /*#__PURE__*/ _interop_require_default(require("fs-extra"));
25
+ const _ttytable = /*#__PURE__*/ _interop_require_default(require("tty-table"));
22
26
  const _api = require("./api");
23
- const _utils = require("./utils");
24
- const _i18n = require("./utils/i18n");
25
27
  const _app = require("./app");
26
- const _ttytable = /*#__PURE__*/ _interop_require_default(require("tty-table"));
28
+ const _utils = require("./utils");
29
+ const _aab = require("./utils/app-info-parser/aab");
27
30
  const _depversions = require("./utils/dep-versions");
28
31
  const _git = require("./utils/git");
32
+ const _i18n = require("./utils/i18n");
29
33
  function _interop_require_default(obj) {
30
34
  return obj && obj.__esModule ? obj : {
31
35
  default: obj
32
36
  };
33
37
  }
34
38
  async function listPackage(appId) {
35
- const allPkgs = await (0, _api.getAllPackages)(appId);
39
+ const allPkgs = await (0, _api.getAllPackages)(appId) || [];
36
40
  const header = [
37
41
  {
38
42
  value: (0, _i18n.t)('nativePackageId')
@@ -75,7 +79,7 @@ async function choosePackage(appId) {
75
79
  const list = await listPackage(appId);
76
80
  while(true){
77
81
  const id = await (0, _utils.question)((0, _i18n.t)('enterNativePackageId'));
78
- const app = list.find((v)=>v.id.toString() === id);
82
+ const app = list == null ? void 0 : list.find((v)=>v.id.toString() === id);
79
83
  if (app) {
80
84
  return app;
81
85
  }
@@ -170,6 +174,32 @@ const packageCommands = {
170
174
  buildTime
171
175
  }));
172
176
  },
177
+ uploadAab: async ({ args, options })=>{
178
+ const source = args[0];
179
+ if (!source || !source.endsWith('.aab')) {
180
+ throw new Error((0, _i18n.t)('usageUploadAab'));
181
+ }
182
+ const output = _path.default.join(_os.default.tmpdir(), `${_path.default.basename(source, _path.default.extname(source))}-${Date.now()}.apk`);
183
+ const includeAllSplits = options.includeAllSplits === true || options.includeAllSplits === 'true';
184
+ const splits = options.splits ? String(options.splits).split(',').map((item)=>item.trim()).filter(Boolean) : null;
185
+ const parser = new _aab.AabParser(source);
186
+ try {
187
+ await parser.extractApk(output, {
188
+ includeAllSplits,
189
+ splits
190
+ });
191
+ await packageCommands.uploadApk({
192
+ args: [
193
+ output
194
+ ],
195
+ options
196
+ });
197
+ } finally{
198
+ if (await _fsextra.default.pathExists(output)) {
199
+ await _fsextra.default.remove(output);
200
+ }
201
+ }
202
+ },
173
203
  uploadApp: async ({ args, options })=>{
174
204
  const fn = args[0];
175
205
  if (!fn || !fn.endsWith('.app')) {
@@ -242,6 +272,23 @@ const packageCommands = {
242
272
  }
243
273
  console.log(await (0, _utils.getAabInfo)(fn));
244
274
  },
275
+ extractApk: async ({ args, options })=>{
276
+ const source = args[0];
277
+ if (!source || !source.endsWith('.aab')) {
278
+ throw new Error((0, _i18n.t)('usageExtractApk'));
279
+ }
280
+ const output = options.output || _path.default.join(_path.default.dirname(source), `${_path.default.basename(source, _path.default.extname(source))}.apk`);
281
+ const includeAllSplits = options.includeAllSplits === true || options.includeAllSplits === 'true';
282
+ const splits = options.splits ? String(options.splits).split(',').map((item)=>item.trim()).filter(Boolean) : null;
283
+ const parser = new _aab.AabParser(source);
284
+ await parser.extractApk(output, {
285
+ includeAllSplits,
286
+ splits
287
+ });
288
+ console.log((0, _i18n.t)('apkExtracted', {
289
+ output
290
+ }));
291
+ },
245
292
  packages: async ({ options })=>{
246
293
  const platform = await (0, _app.getPlatform)(options.platform);
247
294
  const { appId } = await (0, _app.getSelectedApp)(platform);
@@ -250,7 +297,7 @@ const packageCommands = {
250
297
  deletePackage: async ({ args, options })=>{
251
298
  let { appId, packageId, packageVersion } = options;
252
299
  if (!appId) {
253
- const platform = await (0, _app.getPlatform)();
300
+ const platform = await (0, _app.getPlatform)(options.platform);
254
301
  appId = (await (0, _app.getSelectedApp)(platform)).appId;
255
302
  }
256
303
  // If no packageId provided as argument, let user choose from list
package/lib/provider.js CHANGED
@@ -147,6 +147,9 @@ class CLIProviderImpl {
147
147
  case 'apk':
148
148
  await packageCommands.uploadApk(context);
149
149
  break;
150
+ case 'aab':
151
+ await packageCommands.uploadAab(context);
152
+ break;
150
153
  case 'app':
151
154
  await packageCommands.uploadApp(context);
152
155
  break;