react-native-update-cli 1.46.2 → 2.0.1

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 (68) hide show
  1. package/README.md +603 -1
  2. package/README.zh-CN.md +601 -0
  3. package/cli.json +39 -3
  4. package/lib/api.js +5 -5
  5. package/lib/app.js +1 -1
  6. package/lib/bundle.js +30 -28
  7. package/lib/exports.js +65 -0
  8. package/lib/index.js +100 -9
  9. package/lib/locales/en.js +2 -1
  10. package/lib/locales/zh.js +2 -1
  11. package/lib/module-manager.js +125 -0
  12. package/lib/modules/app-module.js +223 -0
  13. package/lib/modules/bundle-module.js +188 -0
  14. package/lib/modules/index.js +42 -0
  15. package/lib/modules/package-module.js +16 -0
  16. package/lib/modules/user-module.js +402 -0
  17. package/lib/modules/version-module.js +16 -0
  18. package/lib/package.js +40 -9
  19. package/lib/provider.js +341 -0
  20. package/lib/user.js +3 -3
  21. package/lib/utils/app-info-parser/apk.js +1 -1
  22. package/lib/utils/app-info-parser/ipa.js +2 -2
  23. package/lib/utils/app-info-parser/resource-finder.js +35 -35
  24. package/lib/utils/app-info-parser/xml-parser/manifest.js +2 -2
  25. package/lib/utils/app-info-parser/zip.js +3 -6
  26. package/lib/utils/check-plugin.js +1 -1
  27. package/lib/utils/git.js +1 -1
  28. package/lib/utils/i18n.js +3 -1
  29. package/lib/utils/index.js +4 -4
  30. package/lib/utils/latest-version/cli.js +3 -3
  31. package/lib/utils/latest-version/index.js +4 -4
  32. package/lib/versions.js +2 -2
  33. package/package.json +4 -4
  34. package/src/api.ts +7 -7
  35. package/src/app.ts +2 -2
  36. package/src/bundle.ts +44 -32
  37. package/src/exports.ts +30 -0
  38. package/src/index.ts +118 -16
  39. package/src/locales/en.ts +1 -0
  40. package/src/locales/zh.ts +1 -0
  41. package/src/module-manager.ts +149 -0
  42. package/src/modules/app-module.ts +205 -0
  43. package/src/modules/bundle-module.ts +202 -0
  44. package/src/modules/index.ts +19 -0
  45. package/src/modules/package-module.ts +11 -0
  46. package/src/modules/user-module.ts +406 -0
  47. package/src/modules/version-module.ts +8 -0
  48. package/src/package.ts +59 -25
  49. package/src/provider.ts +341 -0
  50. package/src/types.ts +126 -0
  51. package/src/user.ts +4 -3
  52. package/src/utils/app-info-parser/apk.js +62 -52
  53. package/src/utils/app-info-parser/app.js +5 -5
  54. package/src/utils/app-info-parser/ipa.js +69 -57
  55. package/src/utils/app-info-parser/resource-finder.js +50 -54
  56. package/src/utils/app-info-parser/utils.js +59 -54
  57. package/src/utils/app-info-parser/xml-parser/binary.js +366 -354
  58. package/src/utils/app-info-parser/xml-parser/manifest.js +145 -137
  59. package/src/utils/app-info-parser/zip.js +1 -1
  60. package/src/utils/check-plugin.ts +4 -2
  61. package/src/utils/dep-versions.ts +13 -6
  62. package/src/utils/git.ts +1 -1
  63. package/src/utils/i18n.ts +3 -1
  64. package/src/utils/index.ts +8 -10
  65. package/src/utils/latest-version/cli.ts +4 -4
  66. package/src/utils/latest-version/index.ts +17 -17
  67. package/src/utils/plugin-config.ts +3 -3
  68. package/src/versions.ts +3 -3
package/README.md CHANGED
@@ -1 +1,603 @@
1
- # react-native-update-cli
1
+ # React Native Update CLI
2
+
3
+ [中文文档](./README.zh-CN.md) | [Chinese Documentation](./README.zh-CN.md)
4
+
5
+ A unified React Native Update CLI that supports both traditional commands and modular architecture with custom publishing workflows.
6
+
7
+ ## 🚀 Features
8
+
9
+ - **Unified CLI**: Single `pushy` command for all functionality
10
+ - **Backward Compatibility**: All existing commands work as before
11
+ - **Modular Architecture**: Split CLI functionality into independent modules
12
+ - **Custom Workflows**: Support for creating custom publishing workflows
13
+ - **Extensibility**: Users can import and register custom modules
14
+ - **Type Safety**: Complete TypeScript type support
15
+
16
+ ## 📦 Installation
17
+
18
+ ```bash
19
+ npm install react-native-update-cli
20
+ ```
21
+
22
+ ## 🎯 Quick Start
23
+
24
+ ### Basic Usage
25
+
26
+ ```bash
27
+ # Use unified CLI
28
+ npx pushy help
29
+
30
+ # List all available commands and workflows
31
+ npx pushy list
32
+
33
+ # Execute built-in workflow
34
+ npx pushy workflow setup-app
35
+
36
+ # Execute custom workflow
37
+ npx pushy workflow custom-publish
38
+ ```
39
+
40
+ ### Programmatic Usage
41
+
42
+ ```typescript
43
+ import { moduleManager, CLIProviderImpl } from 'react-native-update-cli';
44
+
45
+ // Get CLI provider
46
+ const provider = moduleManager.getProvider();
47
+
48
+ // Execute bundling
49
+ const bundleResult = await provider.bundle({
50
+ platform: 'ios',
51
+ dev: false,
52
+ sourcemap: true,
53
+ });
54
+
55
+ // Publish version
56
+ const publishResult = await provider.publish({
57
+ name: 'v1.2.3',
58
+ description: 'Bug fixes and improvements',
59
+ rollout: 100,
60
+ });
61
+ ```
62
+
63
+ ## 🔧 Creating Custom Modules
64
+
65
+ ### 1. Define Module
66
+
67
+ ```typescript
68
+ import type {
69
+ CLIModule,
70
+ CommandDefinition,
71
+ CustomWorkflow,
72
+ } from 'react-native-update-cli';
73
+
74
+ export const myCustomModule: CLIModule = {
75
+ name: 'my-custom',
76
+ version: '1.0.0',
77
+
78
+ commands: [
79
+ {
80
+ name: 'custom-command',
81
+ description: 'My custom command',
82
+ handler: async (context) => {
83
+ console.log('Executing custom command...');
84
+ return {
85
+ success: true,
86
+ data: { message: 'Custom command executed' },
87
+ };
88
+ },
89
+ options: {
90
+ param: { hasValue: true, description: 'Custom parameter' },
91
+ },
92
+ },
93
+ ],
94
+
95
+ workflows: [
96
+ {
97
+ name: 'my-workflow',
98
+ description: 'My custom workflow',
99
+ steps: [
100
+ {
101
+ name: 'step1',
102
+ description: 'First step',
103
+ execute: async (context, previousResult) => {
104
+ console.log('Executing step 1...');
105
+ return { step1Completed: true };
106
+ },
107
+ },
108
+ {
109
+ name: 'step2',
110
+ description: 'Second step',
111
+ execute: async (context, previousResult) => {
112
+ console.log('Executing step 2...');
113
+ return { ...previousResult, step2Completed: true };
114
+ },
115
+ },
116
+ ],
117
+ },
118
+ ],
119
+
120
+ init: (provider) => {
121
+ console.log('Custom module initialized');
122
+ },
123
+
124
+ cleanup: () => {
125
+ console.log('Custom module cleanup');
126
+ },
127
+ };
128
+ ```
129
+
130
+ ### 2. Register Module
131
+
132
+ ```typescript
133
+ import { moduleManager } from 'react-native-update-cli';
134
+ import { myCustomModule } from './my-custom-module';
135
+
136
+ // Register custom module
137
+ moduleManager.registerModule(myCustomModule);
138
+
139
+ // Execute custom command
140
+ const result = await moduleManager.executeCommand('custom-command', {
141
+ args: [],
142
+ options: { param: 'value' },
143
+ });
144
+
145
+ // Execute custom workflow
146
+ const workflowResult = await moduleManager.executeWorkflow('my-workflow', {
147
+ args: [],
148
+ options: {},
149
+ });
150
+ ```
151
+
152
+ ## 🔄 Workflow System
153
+
154
+ ### Workflow Steps
155
+
156
+ Each workflow step contains:
157
+
158
+ - `name`: Step name
159
+ - `description`: Step description
160
+ - `execute`: Execution function
161
+ - `condition`: Optional condition function
162
+
163
+ ### Conditional Execution
164
+
165
+ ```typescript
166
+ {
167
+ name: 'conditional-step',
168
+ description: 'Only execute in production',
169
+ execute: async (context, previousResult) => {
170
+ // Execution logic
171
+ },
172
+ condition: (context) => {
173
+ return context.options.environment === 'production';
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### Workflow Validation
179
+
180
+ ```typescript
181
+ {
182
+ name: 'validated-workflow',
183
+ description: 'Workflow with validation',
184
+ steps: [...],
185
+ validate: (context) => {
186
+ if (!context.options.requiredParam) {
187
+ console.error('Required parameter missing');
188
+ return false;
189
+ }
190
+ return true;
191
+ }
192
+ }
193
+ ```
194
+
195
+ ## 📋 Built-in Modules
196
+
197
+ ### Bundle Module (`bundle`)
198
+
199
+ - `bundle`: Bundle JavaScript code and optionally publish
200
+ - `diff`: Generate differences between two PPK files
201
+ - `hdiff`: Generate hdiff between two PPK files
202
+ - `diffFromApk`: Generate differences from APK files
203
+ - `hdiffFromApk`: Generate hdiff from APK files
204
+ - `hdiffFromApp`: Generate hdiff from APP files
205
+ - `diffFromIpa`: Generate differences from IPA files
206
+ - `hdiffFromIpa`: Generate hdiff from IPA files
207
+
208
+ ### Version Module (`version`)
209
+
210
+ - `publish`: Publish new version
211
+ - `versions`: List all versions
212
+ - `update`: Update version information
213
+ - `updateVersionInfo`: Update version metadata
214
+
215
+ ### App Module (`app`)
216
+
217
+ - `createApp`: Create new application
218
+ - `apps`: List all applications
219
+ - `selectApp`: Select application
220
+ - `deleteApp`: Delete application
221
+
222
+ ### Package Module (`package`)
223
+
224
+ - `uploadIpa`: Upload IPA files (supports `--version` to override extracted version)
225
+ - `uploadApk`: Upload APK files (supports `--version` to override extracted version)
226
+ - `uploadApp`: Upload APP files (supports `--version` to override extracted version)
227
+ - `parseApp`: Parse APP file information
228
+ - `parseIpa`: Parse IPA file information
229
+ - `parseApk`: Parse APK file information
230
+ - `packages`: List packages
231
+
232
+ ### User Module (`user`)
233
+
234
+ - `login`: Login
235
+ - `logout`: Logout
236
+ - `me`: Show user information
237
+
238
+ ## 🛠️ CLI Provider API
239
+
240
+ ### Core Functionality
241
+
242
+ ```typescript
243
+ interface CLIProvider {
244
+ // Bundle
245
+ bundle(options: BundleOptions): Promise<CommandResult>;
246
+
247
+ // Publish
248
+ publish(options: PublishOptions): Promise<CommandResult>;
249
+
250
+ // Upload
251
+ upload(options: UploadOptions): Promise<CommandResult>;
252
+
253
+ // Application management
254
+ getSelectedApp(
255
+ platform?: Platform,
256
+ ): Promise<{ appId: string; platform: Platform }>;
257
+ listApps(platform?: Platform): Promise<CommandResult>;
258
+ createApp(name: string, platform: Platform): Promise<CommandResult>;
259
+
260
+ // Version management
261
+ listVersions(appId: string): Promise<CommandResult>;
262
+ getVersion(appId: string, versionId: string): Promise<CommandResult>;
263
+ updateVersion(
264
+ appId: string,
265
+ versionId: string,
266
+ updates: Partial<Version>,
267
+ ): Promise<CommandResult>;
268
+
269
+ // Package management
270
+ listPackages(appId: string, platform?: Platform): Promise<CommandResult>;
271
+ getPackage(appId: string, packageId: string): Promise<CommandResult>;
272
+
273
+ // Utility functions
274
+ getPlatform(platform?: Platform): Promise<Platform>;
275
+ loadSession(): Promise<Session>;
276
+ saveToLocal(key: string, value: string): void;
277
+ question(prompt: string): Promise<string>;
278
+
279
+ // Workflows
280
+ registerWorkflow(workflow: CustomWorkflow): void;
281
+ executeWorkflow(
282
+ workflowName: string,
283
+ context: CommandContext,
284
+ ): Promise<CommandResult>;
285
+ }
286
+ ```
287
+
288
+ ### Custom Commands
289
+
290
+ ```typescript
291
+ // Execute custom bundle command
292
+ const bundleResult = await moduleManager.executeCommand('custom-bundle', {
293
+ args: [],
294
+ options: {
295
+ platform: 'android',
296
+ validate: true,
297
+ optimize: true,
298
+ },
299
+ });
300
+
301
+ // Generate diff file
302
+ const diffResult = await moduleManager.executeCommand('diff', {
303
+ args: [],
304
+ options: {
305
+ origin: './build/v1.0.0.ppk',
306
+ next: './build/v1.1.0.ppk',
307
+ output: './build/diff.patch',
308
+ },
309
+ });
310
+
311
+ // Generate diff from APK files
312
+ const apkDiffResult = await moduleManager.executeCommand('diffFromApk', {
313
+ args: [],
314
+ options: {
315
+ origin: './build/app-v1.0.0.apk',
316
+ next: './build/app-v1.1.0.apk',
317
+ output: './build/apk-diff.patch',
318
+ },
319
+ });
320
+ ```
321
+
322
+ ## 🔧 Configuration
323
+
324
+ ### Environment Variables
325
+
326
+ ```bash
327
+ # Set API endpoint
328
+ export PUSHY_REGISTRY=https://your-api-endpoint.com
329
+
330
+ # Set non-interactive mode
331
+ export NO_INTERACTIVE=true
332
+ ```
333
+
334
+ ### Configuration File
335
+
336
+ Create `update.json` file:
337
+
338
+ ```json
339
+ {
340
+ "ios": {
341
+ "appId": "your-ios-app-id",
342
+ "appKey": "your-ios-app-key"
343
+ },
344
+ "android": {
345
+ "appId": "your-android-app-id",
346
+ "appKey": "your-android-app-key"
347
+ }
348
+ }
349
+ ```
350
+
351
+ ## 🚨 Important Notes
352
+
353
+ 1. **Backward Compatibility**: The new modular CLI maintains compatibility with existing CLI
354
+ 2. **Type Safety**: All APIs have complete TypeScript type definitions
355
+ 3. **Error Handling**: All operations return standardized result formats
356
+ 4. **Resource Cleanup**: Modules support cleanup functions to release resources
357
+ 5. **Module Separation**: Functionality is logically separated into different modules for easy maintenance and extension
358
+
359
+ ## 🤝 Contributing
360
+
361
+ Welcome to submit Issues and Pull Requests to improve this project!
362
+
363
+ ## 🚀 Provider API Usage Guide
364
+
365
+ Provider provides a concise programming interface suitable for integrating React Native Update CLI functionality in applications.
366
+
367
+ ### 📋 Core API Methods
368
+
369
+ #### Core Business Functions
370
+
371
+ ```typescript
372
+ // Bundle application
373
+ await provider.bundle({
374
+ platform: 'ios',
375
+ dev: false,
376
+ sourcemap: true,
377
+ });
378
+
379
+ // Publish version
380
+ await provider.publish({
381
+ name: 'v1.0.0',
382
+ description: 'Bug fixes',
383
+ rollout: 100,
384
+ });
385
+
386
+ // Upload file
387
+ await provider.upload({
388
+ filePath: 'app.ipa',
389
+ platform: 'ios',
390
+ });
391
+ ```
392
+
393
+ #### Application Management
394
+
395
+ ```typescript
396
+ // Create application
397
+ await provider.createApp('MyApp', 'ios');
398
+
399
+ // List applications
400
+ await provider.listApps('ios');
401
+
402
+ // Get current application
403
+ const { appId, platform } = await provider.getSelectedApp('ios');
404
+ ```
405
+
406
+ #### Version Management
407
+
408
+ ```typescript
409
+ // List versions
410
+ await provider.listVersions('app123');
411
+
412
+ // Update version
413
+ await provider.updateVersion('app123', 'version456', {
414
+ name: 'v1.1.0',
415
+ description: 'New features',
416
+ });
417
+ ```
418
+
419
+ #### Utility Functions
420
+
421
+ ```typescript
422
+ // Get platform
423
+ const platform = await provider.getPlatform('ios');
424
+
425
+ // Load session
426
+ const session = await provider.loadSession();
427
+ ```
428
+
429
+ ### 🎯 Use Cases
430
+
431
+ #### 1. Automated Build Scripts
432
+
433
+ ```typescript
434
+ import { moduleManager } from 'react-native-update-cli';
435
+
436
+ async function buildAndPublish() {
437
+ const provider = moduleManager.getProvider();
438
+
439
+ // 1. Bundle
440
+ const bundleResult = await provider.bundle({
441
+ platform: 'ios',
442
+ dev: false,
443
+ sourcemap: true,
444
+ });
445
+
446
+ if (!bundleResult.success) {
447
+ throw new Error(`Bundle failed: ${bundleResult.error}`);
448
+ }
449
+
450
+ // 2. Publish
451
+ const publishResult = await provider.publish({
452
+ name: 'v1.2.3',
453
+ description: 'Bug fixes and performance improvements',
454
+ rollout: 100,
455
+ });
456
+
457
+ if (!publishResult.success) {
458
+ throw new Error(`Publish failed: ${publishResult.error}`);
459
+ }
460
+
461
+ console.log('Build and publish completed!');
462
+ }
463
+ ```
464
+
465
+ #### 2. CI/CD Integration
466
+
467
+ ```typescript
468
+ async function ciBuild() {
469
+ const provider = moduleManager.getProvider();
470
+
471
+ const result = await provider.bundle({
472
+ platform: process.env.PLATFORM as 'ios' | 'android',
473
+ dev: process.env.NODE_ENV !== 'production',
474
+ sourcemap: process.env.NODE_ENV === 'production',
475
+ });
476
+
477
+ return result;
478
+ }
479
+ ```
480
+
481
+ #### 3. Application Management Service
482
+
483
+ ```typescript
484
+ class AppManagementService {
485
+ private provider = moduleManager.getProvider();
486
+
487
+ async setupNewApp(name: string, platform: Platform) {
488
+ // Create application
489
+ const createResult = await this.provider.createApp(name, platform);
490
+
491
+ if (createResult.success) {
492
+ // Get application information
493
+ const { appId } = await this.provider.getSelectedApp(platform);
494
+
495
+ // List versions
496
+ await this.provider.listVersions(appId);
497
+
498
+ return { appId, success: true };
499
+ }
500
+
501
+ return { success: false, error: createResult.error };
502
+ }
503
+ }
504
+ ```
505
+
506
+ ### ⚠️ Important Notes
507
+
508
+ 1. **Error Handling**: All Provider methods return `CommandResult`, need to check the `success` field
509
+ 2. **Type Safety**: Provider provides complete TypeScript type support
510
+ 3. **Session Management**: Ensure login before use, can check via `loadSession()`
511
+ 4. **Platform Support**: Supports `'ios' | 'android' | 'harmony'` three platforms
512
+
513
+ ### 🔧 Advanced Features
514
+
515
+ #### Custom Workflows
516
+
517
+ ```typescript
518
+ // Register custom workflow
519
+ provider.registerWorkflow({
520
+ name: 'quick-release',
521
+ description: 'Quick release process',
522
+ steps: [
523
+ {
524
+ name: 'bundle',
525
+ execute: async () => {
526
+ return await provider.bundle({ platform: 'ios', dev: false });
527
+ },
528
+ },
529
+ {
530
+ name: 'publish',
531
+ execute: async (context, bundleResult) => {
532
+ if (!bundleResult.success) {
533
+ throw new Error('Bundle failed, cannot publish');
534
+ }
535
+ return await provider.publish({ name: 'auto-release', rollout: 50 });
536
+ },
537
+ },
538
+ ],
539
+ });
540
+
541
+ // Execute workflow
542
+ await provider.executeWorkflow('quick-release', { args: [], options: {} });
543
+ ```
544
+
545
+ ### 📚 Complete Example
546
+
547
+ ```typescript
548
+ import { moduleManager } from 'react-native-update-cli';
549
+
550
+ class ReactNativeUpdateService {
551
+ private provider = moduleManager.getProvider();
552
+
553
+ async initialize() {
554
+ // Load session
555
+ await this.provider.loadSession();
556
+ }
557
+
558
+ async buildAndDeploy(platform: Platform, version: string) {
559
+ try {
560
+ // 1. Bundle
561
+ const bundleResult = await this.provider.bundle({
562
+ platform,
563
+ dev: false,
564
+ sourcemap: true,
565
+ });
566
+
567
+ if (!bundleResult.success) {
568
+ throw new Error(`Bundle failed: ${bundleResult.error}`);
569
+ }
570
+
571
+ // 2. Publish
572
+ const publishResult = await this.provider.publish({
573
+ name: version,
574
+ description: `Release ${version}`,
575
+ rollout: 100,
576
+ });
577
+
578
+ if (!publishResult.success) {
579
+ throw new Error(`Publish failed: ${publishResult.error}`);
580
+ }
581
+
582
+ return { success: true, data: publishResult.data };
583
+ } catch (error) {
584
+ return {
585
+ success: false,
586
+ error: error instanceof Error ? error.message : 'Unknown error',
587
+ };
588
+ }
589
+ }
590
+
591
+ async getAppInfo(platform: Platform) {
592
+ const { appId } = await this.provider.getSelectedApp(platform);
593
+ const versions = await this.provider.listVersions(appId);
594
+
595
+ return { appId, versions };
596
+ }
597
+ }
598
+
599
+ // Usage example
600
+ const service = new ReactNativeUpdateService();
601
+ await service.initialize();
602
+ await service.buildAndDeploy('ios', 'v1.0.0');
603
+ ```