react-native-update-cli 2.8.5 → 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 (106) 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/zh.d.ts +136 -0
  18. package/lib/module-manager.d.ts +20 -0
  19. package/lib/module-manager.js +3 -9
  20. package/lib/modules/app-module.d.ts +2 -0
  21. package/lib/modules/app-module.js +84 -44
  22. package/lib/modules/bundle-module.d.ts +2 -0
  23. package/lib/modules/bundle-module.js +7 -8
  24. package/lib/modules/index.d.ts +6 -0
  25. package/lib/modules/package-module.d.ts +2 -0
  26. package/lib/modules/user-module.d.ts +2 -0
  27. package/lib/modules/user-module.js +55 -44
  28. package/lib/modules/version-module.d.ts +2 -0
  29. package/lib/package.d.ts +58 -0
  30. package/lib/package.js +103 -139
  31. package/lib/provider.d.ts +26 -0
  32. package/lib/provider.js +115 -217
  33. package/lib/types.d.ts +120 -0
  34. package/lib/user.d.ts +8 -0
  35. package/lib/utils/add-gitignore.d.ts +1 -0
  36. package/lib/utils/app-info-parser/aab.d.ts +22 -0
  37. package/lib/utils/app-info-parser/aab.js +0 -4
  38. package/lib/utils/app-info-parser/apk.d.ts +14 -0
  39. package/lib/utils/app-info-parser/apk.js +6 -4
  40. package/lib/utils/app-info-parser/app.d.ts +4 -0
  41. package/lib/utils/app-info-parser/app.js +3 -0
  42. package/lib/utils/app-info-parser/index.d.ts +16 -0
  43. package/lib/utils/app-info-parser/index.js +2 -0
  44. package/lib/utils/app-info-parser/ipa.d.ts +14 -0
  45. package/lib/utils/app-info-parser/ipa.js +1 -1
  46. package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
  47. package/lib/utils/app-info-parser/utils.d.ts +31 -0
  48. package/lib/utils/app-info-parser/utils.js +1 -0
  49. package/lib/utils/app-info-parser/xml-parser/binary.d.ts +56 -0
  50. package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +10 -0
  51. package/lib/utils/app-info-parser/zip.d.ts +18 -0
  52. package/lib/utils/app-info-parser/zip.js +7 -9
  53. package/lib/utils/check-lockfile.d.ts +1 -0
  54. package/lib/utils/check-plugin.d.ts +7 -0
  55. package/lib/utils/command-result.d.ts +3 -0
  56. package/lib/utils/command-result.js +35 -0
  57. package/lib/utils/constants.d.ts +9 -0
  58. package/lib/utils/dep-versions.d.ts +1 -0
  59. package/lib/utils/git.d.ts +8 -0
  60. package/lib/utils/http-helper.d.ts +4 -0
  61. package/lib/utils/i18n.d.ts +12 -0
  62. package/lib/utils/index.d.ts +22 -0
  63. package/lib/utils/index.js +52 -22
  64. package/lib/utils/latest-version/cli.d.ts +1 -0
  65. package/lib/utils/latest-version/cli.js +24 -60
  66. package/lib/utils/latest-version/index.d.ts +146 -0
  67. package/lib/utils/latest-version/index.js +22 -22
  68. package/lib/utils/options.d.ts +4 -0
  69. package/lib/utils/options.js +63 -0
  70. package/lib/utils/plugin-config.d.ts +9 -0
  71. package/lib/utils/zip-entries.d.ts +3 -0
  72. package/lib/versions.d.ts +43 -0
  73. package/lib/workflow-runner.d.ts +2 -0
  74. package/lib/workflow-runner.js +25 -0
  75. package/package.json +20 -5
  76. package/src/api.ts +1 -1
  77. package/src/app.ts +20 -11
  78. package/src/bundle-pack.ts +51 -0
  79. package/src/bundle-runner.ts +463 -0
  80. package/src/bundle.ts +184 -571
  81. package/src/diff.ts +208 -174
  82. package/src/index.ts +15 -17
  83. package/src/module-manager.ts +15 -15
  84. package/src/modules/app-module.ts +120 -48
  85. package/src/modules/bundle-module.ts +21 -11
  86. package/src/modules/package-module.ts +0 -1
  87. package/src/modules/user-module.ts +117 -58
  88. package/src/package.ts +158 -138
  89. package/src/provider.ts +164 -240
  90. package/src/types.ts +13 -8
  91. package/src/utils/app-info-parser/aab.ts +0 -7
  92. package/src/utils/app-info-parser/apk.ts +9 -6
  93. package/src/utils/app-info-parser/app.ts +5 -1
  94. package/src/utils/app-info-parser/index.ts +11 -6
  95. package/src/utils/app-info-parser/ipa.ts +1 -1
  96. package/src/utils/app-info-parser/utils.ts +3 -0
  97. package/src/utils/app-info-parser/xml-parser/manifest.ts +3 -1
  98. package/src/utils/app-info-parser/zip.ts +12 -14
  99. package/src/utils/command-result.ts +24 -0
  100. package/src/utils/index.ts +138 -39
  101. package/src/utils/latest-version/cli.ts +22 -20
  102. package/src/utils/latest-version/index.ts +20 -20
  103. package/src/utils/options.ts +56 -0
  104. package/src/utils/zip-entries.ts +1 -1
  105. package/src/workflow-runner.ts +24 -0
  106. package/index.js +0 -1
package/src/provider.ts CHANGED
@@ -12,27 +12,73 @@ import type {
12
12
  UploadOptions,
13
13
  Version,
14
14
  } from './types';
15
+ import { runAsCommandResult } from './utils/command-result';
16
+ import { runWorkflow } from './workflow-runner';
15
17
 
16
18
  export class CLIProviderImpl implements CLIProvider {
17
19
  private workflows: Map<string, CustomWorkflow> = new Map();
18
20
  private session?: Session;
21
+ private sessionInitPromise?: Promise<void>;
19
22
 
20
- constructor() {
21
- this.init();
23
+ private createContext(
24
+ options: Record<string, unknown>,
25
+ args: string[] = [],
26
+ ): CommandContext {
27
+ return { args, options };
22
28
  }
23
29
 
24
- private async init() {
25
- try {
26
- await loadSession();
27
- this.session = getSession();
28
- } catch (error) {}
30
+ private async ensureInitialized(): Promise<void> {
31
+ if (this.session) {
32
+ return;
33
+ }
34
+
35
+ if (!this.sessionInitPromise) {
36
+ this.sessionInitPromise = (async () => {
37
+ await loadSession();
38
+ this.session = getSession();
39
+ })().finally(() => {
40
+ this.sessionInitPromise = undefined;
41
+ });
42
+ }
43
+
44
+ await this.sessionInitPromise;
45
+ }
46
+
47
+ private runMessageCommand(
48
+ task: () => Promise<void>,
49
+ fallbackError: string,
50
+ successMessage: string,
51
+ requireSession = true,
52
+ ): Promise<CommandResult> {
53
+ return runAsCommandResult(
54
+ async () => {
55
+ if (requireSession) {
56
+ await this.ensureInitialized();
57
+ }
58
+ await task();
59
+ },
60
+ fallbackError,
61
+ () => ({ message: successMessage }),
62
+ );
63
+ }
64
+
65
+ private runDataCommand<T>(
66
+ task: () => Promise<T>,
67
+ fallbackError: string,
68
+ requireSession = true,
69
+ ): Promise<CommandResult> {
70
+ return runAsCommandResult(async () => {
71
+ if (requireSession) {
72
+ await this.ensureInitialized();
73
+ }
74
+ return task();
75
+ }, fallbackError);
29
76
  }
30
77
 
31
78
  async bundle(options: BundleOptions): Promise<CommandResult> {
32
- try {
33
- const context: CommandContext = {
34
- args: [],
35
- options: {
79
+ return this.runMessageCommand(
80
+ async () => {
81
+ const context = this.createContext({
36
82
  dev: options.dev || false,
37
83
  platform: options.platform,
38
84
  bundleName: options.bundleName || 'index.bundlejs',
@@ -43,32 +89,21 @@ export class CLIProviderImpl implements CLIProvider {
43
89
  expo: options.expo || false,
44
90
  rncli: options.rncli || false,
45
91
  hermes: options.hermes || false,
46
- },
47
- };
48
-
49
- const { bundleCommands } = await import('./bundle');
50
- await bundleCommands.bundle(context);
51
-
52
- return {
53
- success: true,
54
- data: { message: 'Bundle created successfully' },
55
- };
56
- } catch (error) {
57
- return {
58
- success: false,
59
- error:
60
- error instanceof Error
61
- ? error.message
62
- : 'Unknown error during bundling',
63
- };
64
- }
92
+ });
93
+
94
+ const { bundleCommands } = await import('./bundle');
95
+ await bundleCommands.bundle(context);
96
+ },
97
+ 'Unknown error during bundling',
98
+ 'Bundle created successfully',
99
+ false,
100
+ );
65
101
  }
66
102
 
67
103
  async publish(options: PublishOptions): Promise<CommandResult> {
68
- try {
69
- const context: CommandContext = {
70
- args: [],
71
- options: {
104
+ return this.runMessageCommand(
105
+ async () => {
106
+ const context = this.createContext({
72
107
  name: options.name,
73
108
  description: options.description,
74
109
  metaInfo: options.metaInfo,
@@ -79,72 +114,50 @@ export class CLIProviderImpl implements CLIProvider {
79
114
  packageVersionRange: options.packageVersionRange,
80
115
  rollout: options.rollout,
81
116
  dryRun: options.dryRun || false,
82
- },
83
- };
84
-
85
- const { versionCommands } = await import('./versions');
86
- await versionCommands.publish(context);
87
-
88
- return {
89
- success: true,
90
- data: { message: 'Version published successfully' },
91
- };
92
- } catch (error) {
93
- return {
94
- success: false,
95
- error:
96
- error instanceof Error
97
- ? error.message
98
- : 'Unknown error during publishing',
99
- };
100
- }
117
+ });
118
+
119
+ const { versionCommands } = await import('./versions');
120
+ await versionCommands.publish(context);
121
+ },
122
+ 'Unknown error during publishing',
123
+ 'Version published successfully',
124
+ );
101
125
  }
102
126
 
103
127
  async upload(options: UploadOptions): Promise<CommandResult> {
104
- try {
105
- const platform = await this.getPlatform(options.platform);
106
- const { appId } = await this.getSelectedApp(platform);
107
-
108
- const filePath = options.filePath;
109
- const fileType = filePath.split('.').pop()?.toLowerCase();
110
-
111
- const context: CommandContext = {
112
- args: [filePath],
113
- options: { platform, appId, version: options.version },
114
- };
115
-
116
- const { packageCommands } = await import('./package');
117
-
118
- switch (fileType) {
119
- case 'ipa':
120
- await packageCommands.uploadIpa(context);
121
- break;
122
- case 'apk':
123
- await packageCommands.uploadApk(context);
124
- break;
125
- case 'aab':
126
- await packageCommands.uploadAab(context);
127
- break;
128
- case 'app':
129
- await packageCommands.uploadApp(context);
130
- break;
131
- default:
128
+ return this.runMessageCommand(
129
+ async () => {
130
+ const platform = await this.getPlatform(options.platform);
131
+ const { appId } = await this.getSelectedApp(platform);
132
+
133
+ const filePath = options.filePath;
134
+ const fileType = filePath.split('.').pop()?.toLowerCase();
135
+
136
+ const context = this.createContext(
137
+ { platform, appId, version: options.version },
138
+ [filePath],
139
+ );
140
+
141
+ const { packageCommands } = await import('./package');
142
+ const uploadHandlerMap = {
143
+ ipa: packageCommands.uploadIpa,
144
+ apk: packageCommands.uploadApk,
145
+ aab: packageCommands.uploadAab,
146
+ app: packageCommands.uploadApp,
147
+ } as const;
148
+ const uploadHandler =
149
+ fileType && fileType in uploadHandlerMap
150
+ ? uploadHandlerMap[fileType as keyof typeof uploadHandlerMap]
151
+ : undefined;
152
+
153
+ if (!uploadHandler) {
132
154
  throw new Error(`Unsupported file type: ${fileType}`);
133
- }
134
-
135
- return {
136
- success: true,
137
- data: { message: 'File uploaded successfully' },
138
- };
139
- } catch (error) {
140
- return {
141
- success: false,
142
- error:
143
- error instanceof Error
144
- ? error.message
145
- : 'Unknown error during upload',
146
- };
147
- }
155
+ }
156
+ await uploadHandler(context);
157
+ },
158
+ 'Unknown error during upload',
159
+ 'File uploaded successfully',
160
+ );
148
161
  }
149
162
 
150
163
  async getSelectedApp(
@@ -155,71 +168,45 @@ export class CLIProviderImpl implements CLIProvider {
155
168
  }
156
169
 
157
170
  async listApps(platform?: Platform): Promise<CommandResult> {
158
- try {
159
- const resolvedPlatform = await this.getPlatform(platform);
160
- const { appCommands } = await import('./app');
161
- await appCommands.apps({ options: { platform: resolvedPlatform } });
162
-
163
- return {
164
- success: true,
165
- data: { message: 'Apps listed successfully' },
166
- };
167
- } catch (error) {
168
- return {
169
- success: false,
170
- error:
171
- error instanceof Error ? error.message : 'Unknown error listing apps',
172
- };
173
- }
171
+ return this.runMessageCommand(
172
+ async () => {
173
+ const resolvedPlatform = await this.getPlatform(platform);
174
+ const { appCommands } = await import('./app');
175
+ await appCommands.apps({ options: { platform: resolvedPlatform } });
176
+ },
177
+ 'Unknown error listing apps',
178
+ 'Apps listed successfully',
179
+ );
174
180
  }
175
181
 
176
182
  async createApp(name: string, platform: Platform): Promise<CommandResult> {
177
- try {
178
- const { appCommands } = await import('./app');
179
- await appCommands.createApp({
180
- options: {
181
- name,
182
- platform,
183
- downloadUrl: '',
184
- },
185
- });
186
-
187
- return {
188
- success: true,
189
- data: { message: 'App created successfully' },
190
- };
191
- } catch (error) {
192
- return {
193
- success: false,
194
- error:
195
- error instanceof Error ? error.message : 'Unknown error creating app',
196
- };
197
- }
183
+ return this.runMessageCommand(
184
+ async () => {
185
+ const { appCommands } = await import('./app');
186
+ await appCommands.createApp({
187
+ options: {
188
+ name,
189
+ platform,
190
+ downloadUrl: '',
191
+ },
192
+ });
193
+ },
194
+ 'Unknown error creating app',
195
+ 'App created successfully',
196
+ );
198
197
  }
199
198
 
200
199
  async listVersions(appId: string): Promise<CommandResult> {
201
- try {
202
- const context: CommandContext = {
203
- args: [],
204
- options: { appId },
205
- };
206
-
207
- const { versionCommands } = await import('./versions');
208
- await versionCommands.versions(context);
209
-
210
- return {
211
- success: true,
212
- data: { message: 'Versions listed successfully' },
213
- };
214
- } catch (error) {
215
- return {
216
- success: false,
217
- error:
218
- error instanceof Error
219
- ? error.message
220
- : 'Unknown error listing versions',
221
- };
222
- }
200
+ return this.runMessageCommand(
201
+ async () => {
202
+ const context = this.createContext({ appId });
203
+
204
+ const { versionCommands } = await import('./versions');
205
+ await versionCommands.versions(context);
206
+ },
207
+ 'Unknown error listing versions',
208
+ 'Versions listed successfully',
209
+ );
223
210
  }
224
211
 
225
212
  async updateVersion(
@@ -227,31 +214,16 @@ export class CLIProviderImpl implements CLIProvider {
227
214
  versionId: string,
228
215
  updates: Partial<Version>,
229
216
  ): Promise<CommandResult> {
230
- try {
231
- const context: CommandContext = {
232
- args: [versionId],
233
- options: {
234
- appId,
235
- ...updates,
236
- },
237
- };
238
-
239
- const { versionCommands } = await import('./versions');
240
- await versionCommands.update(context);
241
-
242
- return {
243
- success: true,
244
- data: { message: 'Version updated successfully' },
245
- };
246
- } catch (error) {
247
- return {
248
- success: false,
249
- error:
250
- error instanceof Error
251
- ? error.message
252
- : 'Unknown error updating version',
253
- };
254
- }
217
+ return this.runMessageCommand(
218
+ async () => {
219
+ const context = this.createContext({ appId, ...updates }, [versionId]);
220
+
221
+ const { versionCommands } = await import('./versions');
222
+ await versionCommands.update(context);
223
+ },
224
+ 'Unknown error updating version',
225
+ 'Version updated successfully',
226
+ );
255
227
  }
256
228
 
257
229
  async getPlatform(platform?: Platform): Promise<Platform> {
@@ -259,8 +231,7 @@ export class CLIProviderImpl implements CLIProvider {
259
231
  }
260
232
 
261
233
  async loadSession(): Promise<Session> {
262
- await loadSession();
263
- this.session = getSession();
234
+ await this.ensureInitialized();
264
235
  if (!this.session) {
265
236
  throw new Error('Failed to load session');
266
237
  }
@@ -275,70 +246,23 @@ export class CLIProviderImpl implements CLIProvider {
275
246
  workflowName: string,
276
247
  context: CommandContext,
277
248
  ): Promise<CommandResult> {
278
- const workflow = this.workflows.get(workflowName);
279
- if (!workflow) {
280
- return {
281
- success: false,
282
- error: `Workflow '${workflowName}' not found`,
283
- };
284
- }
285
-
286
- try {
287
- let previousResult: any = null;
288
- for (const step of workflow.steps) {
289
- if (step.condition && !step.condition(context)) {
290
- console.log(`Skipping step '${step.name}' due to condition`);
291
- continue;
292
- }
293
-
294
- console.log(`Executing step '${step.name}'`);
295
- previousResult = await step.execute(context, previousResult);
249
+ return this.runDataCommand(async () => {
250
+ const workflow = this.workflows.get(workflowName);
251
+ if (!workflow) {
252
+ throw new Error(`Workflow '${workflowName}' not found`);
296
253
  }
297
-
298
- return {
299
- success: true,
300
- data: {
301
- message: `Workflow '${workflowName}' completed successfully`,
302
- result: previousResult,
303
- },
304
- };
305
- } catch (error) {
254
+ const result = await runWorkflow(workflowName, workflow, context);
306
255
  return {
307
- success: false,
308
- error:
309
- error instanceof Error
310
- ? error.message
311
- : `Workflow '${workflowName}' failed`,
256
+ message: `Workflow '${workflowName}' completed successfully`,
257
+ result,
312
258
  };
313
- }
314
- }
315
-
316
- getRegisteredWorkflows(): string[] {
317
- return Array.from(this.workflows.keys());
259
+ }, `Workflow '${workflowName}' failed`);
318
260
  }
319
261
 
320
262
  async listPackages(appId?: string): Promise<CommandResult> {
321
- try {
322
- const context: CommandContext = {
323
- args: [],
324
- options: appId ? { appId } : {},
325
- };
326
-
263
+ return this.runDataCommand(async () => {
327
264
  const { listPackage } = await import('./package');
328
- const result = await listPackage(appId || '');
329
-
330
- return {
331
- success: true,
332
- data: result,
333
- };
334
- } catch (error) {
335
- return {
336
- success: false,
337
- error:
338
- error instanceof Error
339
- ? error.message
340
- : 'Unknown error listing packages',
341
- };
342
- }
265
+ return listPackage(appId || '');
266
+ }, 'Unknown error listing packages');
343
267
  }
344
268
  }
package/src/types.ts CHANGED
@@ -16,8 +16,8 @@ export interface Package {
16
16
  status?: string;
17
17
  appId?: string;
18
18
  appKey?: string;
19
- versionName?: any;
20
- buildTime?: any;
19
+ versionName?: string | number | null;
20
+ buildTime?: string | number | null;
21
21
  deps?: Record<string, string> | string | null;
22
22
  }
23
23
 
@@ -29,9 +29,11 @@ export interface Version {
29
29
  deps?: Record<string, string> | string | null;
30
30
  }
31
31
 
32
- export interface CommandContext {
32
+ export interface CommandContext<
33
+ TOptions extends Record<string, unknown> = Record<string, unknown>,
34
+ > {
33
35
  args: string[];
34
- options: Record<string, any>;
36
+ options: TOptions;
35
37
  platform?: Platform;
36
38
  appId?: string;
37
39
  session?: Session;
@@ -39,7 +41,7 @@ export interface CommandContext {
39
41
 
40
42
  export interface CommandResult {
41
43
  success: boolean;
42
- data?: any;
44
+ data?: unknown;
43
45
  error?: string;
44
46
  }
45
47
 
@@ -51,7 +53,7 @@ export interface CommandDefinition {
51
53
  string,
52
54
  {
53
55
  hasValue?: boolean;
54
- default?: any;
56
+ default?: unknown;
55
57
  description?: string;
56
58
  }
57
59
  >;
@@ -93,7 +95,10 @@ export interface UploadOptions {
93
95
  export interface WorkflowStep {
94
96
  name: string;
95
97
  description?: string;
96
- execute: (context: CommandContext, previousResult?: any) => Promise<any>;
98
+ execute: (
99
+ context: CommandContext,
100
+ previousResult?: unknown,
101
+ ) => Promise<unknown>;
97
102
  condition?: (context: CommandContext) => boolean;
98
103
  }
99
104
 
@@ -106,7 +111,7 @@ export interface CustomWorkflow {
106
111
  string,
107
112
  {
108
113
  hasValue?: boolean;
109
- default?: any;
114
+ default?: unknown;
110
115
  description?: string;
111
116
  }
112
117
  >;
@@ -10,13 +10,6 @@ import { ManifestParser } from './xml-parser/manifest';
10
10
  import { Zip } from './zip';
11
11
 
12
12
  export class AabParser extends Zip {
13
- file: string | File;
14
-
15
- constructor(file: string | File) {
16
- super(file);
17
- this.file = file;
18
- }
19
-
20
13
  async extractApk(
21
14
  outputPath: string,
22
15
  {
@@ -8,10 +8,13 @@ const ResourceName = /^resources\.arsc$/;
8
8
 
9
9
  export class ApkParser extends Zip {
10
10
  parse(): Promise<any> {
11
+ const manifestKey = ManifestName.toString();
12
+ const resourceKey = ResourceName.toString();
13
+
11
14
  return new Promise((resolve, reject) => {
12
15
  this.getEntries([ManifestName, ResourceName])
13
- .then((buffers: any) => {
14
- const manifestBuffer = buffers[ManifestName];
16
+ .then((buffers: Record<string, Buffer | Blob | undefined>) => {
17
+ const manifestBuffer = buffers[manifestKey];
15
18
  if (!manifestBuffer) {
16
19
  throw new Error("AndroidManifest.xml can't be found.");
17
20
  }
@@ -20,19 +23,19 @@ export class ApkParser extends Zip {
20
23
 
21
24
  apkInfo = this._parseManifest(manifestBuffer as Buffer);
22
25
 
23
- if (!buffers[ResourceName]) {
26
+ if (!buffers[resourceKey]) {
24
27
  resolve(apkInfo);
25
28
  } else {
26
29
  resourceMap = this._parseResourceMap(
27
- buffers[ResourceName] as Buffer,
30
+ buffers[resourceKey] as Buffer,
28
31
  );
29
32
  apkInfo = mapInfoResource(apkInfo, resourceMap);
30
33
 
31
34
  const iconPath = findApkIconPath(apkInfo);
32
35
  if (iconPath) {
33
36
  this.getEntry(iconPath)
34
- .then((iconBuffer: Buffer | null) => {
35
- apkInfo.icon = iconBuffer
37
+ .then((iconBuffer: Buffer | Blob | undefined) => {
38
+ apkInfo.icon = Buffer.isBuffer(iconBuffer)
36
39
  ? getBase64FromBuffer(iconBuffer)
37
40
  : null;
38
41
  resolve(apkInfo);
@@ -1,3 +1,7 @@
1
1
  import { Zip } from './zip';
2
2
 
3
- export class AppParser extends Zip {}
3
+ export class AppParser extends Zip {
4
+ async parse(): Promise<Record<string, never>> {
5
+ return {};
6
+ }
7
+ }
@@ -2,11 +2,14 @@ import { AabParser } from './aab';
2
2
  import { ApkParser } from './apk';
3
3
  import { AppParser } from './app';
4
4
  import { IpaParser } from './ipa';
5
- const supportFileTypes = ['ipa', 'apk', 'app', 'aab'];
5
+
6
+ const supportFileTypes = ['ipa', 'apk', 'app', 'aab'] as const;
7
+ type SupportedFileType = (typeof supportFileTypes)[number];
8
+ type AppInfoInnerParser = AabParser | ApkParser | AppParser | IpaParser;
6
9
 
7
10
  class AppInfoParser {
8
11
  file: string | File;
9
- parser: any;
12
+ parser: AppInfoInnerParser;
10
13
  /**
11
14
  * parser for parsing .ipa or .apk file
12
15
  * @param {String | File} file // file's path in Node, instance of File in Browser
@@ -19,14 +22,14 @@ class AppInfoParser {
19
22
  }
20
23
  const splits = (typeof file === 'string' ? file : file.name).split('.');
21
24
  const fileType = splits[splits.length - 1].toLowerCase();
22
- if (!supportFileTypes.includes(fileType)) {
25
+ if (!supportFileTypes.includes(fileType as SupportedFileType)) {
23
26
  throw new Error(
24
27
  'Unsupported file type, only support .ipa, .apk, .app, or .aab file.',
25
28
  );
26
29
  }
27
30
  this.file = file;
28
31
 
29
- switch (fileType) {
32
+ switch (fileType as SupportedFileType) {
30
33
  case 'ipa':
31
34
  this.parser = new IpaParser(this.file);
32
35
  break;
@@ -39,10 +42,12 @@ class AppInfoParser {
39
42
  case 'aab':
40
43
  this.parser = new AabParser(this.file);
41
44
  break;
45
+ default:
46
+ throw new Error('Unsupported parser file type.');
42
47
  }
43
48
  }
44
- parse() {
45
- return this.parser.parse();
49
+ parse<T = unknown>(): Promise<T> {
50
+ return this.parser.parse() as Promise<T>;
46
51
  }
47
52
  }
48
53
 
@@ -61,7 +61,7 @@ export class IpaParser extends Zip {
61
61
  private _parsePlist(buffer: Buffer) {
62
62
  let result: any;
63
63
  const bufferType = buffer[0];
64
- if (bufferType === 60 || bufferType === '<' || bufferType === 239) {
64
+ if (bufferType === 60 || bufferType === 239) {
65
65
  result = parsePlist(buffer.toString());
66
66
  } else if (bufferType === 98) {
67
67
  result = parseBplist(buffer)[0];
@@ -11,6 +11,9 @@ const isPrimitive = (value: unknown): boolean =>
11
11
  value === null ||
12
12
  ['boolean', 'number', 'string', 'undefined'].includes(objectType(value));
13
13
 
14
+ const isBrowser = (): boolean =>
15
+ typeof window !== 'undefined' && typeof window.document !== 'undefined';
16
+
14
17
  /**
15
18
  * map file place with resourceMap
16
19
  * @param {Object} apkInfo // json info parsed from .apk file