react-native-codepush-sdk 1.0.0 โ†’ 1.0.2

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.
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -1,44 +1,46 @@
1
1
  # React Native CodePush SDK
2
2
 
3
- A comprehensive SDK for integrating CodePush-style over-the-air updates into your React Native apps, with support for custom servers and advanced update workflows.
3
+ A React Native SDK for over-the-air (OTA) updates with support for your own backend. Use it to ship JS and asset updates without going through the app stores.
4
4
 
5
- > **Looking for a working demo app?**
6
- > See the `example/` folder for a full React Native project that consumes this SDK.
5
+ - **Custom server**: Works with any server that implements the CodePush-style API.
6
+ - **Unified API**: Same API on iOS and Android (provider, hook, or class-based).
7
+ - **Optional demo**: See the `example/` app and `example/mock-server/` for a full setup.
7
8
 
8
9
  ## Features
9
10
 
10
- ### ๐Ÿš€ Core Functionality
11
- - **Custom Server Integration**: Connect to your own CodePush server
12
- - **Over-the-Air Updates**: Download and install app updates without app store releases
13
- - **Rollback Support**: Automatically rollback failed updates
14
- - **Progress Tracking**: Real-time download and installation progress
15
- - **Mandatory Updates**: Support for required updates that users cannot skip
16
-
17
- ### ๐Ÿ“ฑ Platform Support
18
- - **iOS**: Full native integration
19
- - **Android**: Complete Android support
20
- - **Cross-Platform**: Unified API for both platforms
21
-
22
- ### ๐Ÿ”ง Advanced Features
23
- - **Gradual Rollouts**: Support for percentage-based rollouts
24
- - **Update Validation**: Verify update integrity before installation
25
- - **Offline Support**: Handle updates when network is unavailable
26
- - **Background Downloads**: Download updates in the background
27
- - **Custom Install Modes**: Immediate, on restart, or on resume installation
11
+ - **Custom server** โ€“ Point to your own update server (see [Server API](#server-api)).
12
+ - **OTA updates** โ€“ Download and install JS bundles and assets without a store release.
13
+ - **Rollback** โ€“ Revert to the previous bundle on failed install.
14
+ - **Progress** โ€“ Download and install progress callbacks.
15
+ - **Mandatory updates** โ€“ Optional forced updates.
16
+ - **Install modes** โ€“ Immediate, on next restart, or on next resume.
17
+ - **Gradual rollouts** โ€“ Server-side rollout percentage support.
18
+
19
+ ## Requirements
20
+
21
+ - React Native >= 0.60, React >= 16.8
22
+ - Node >= 18 (for tooling)
28
23
 
29
24
  ## Installation
30
25
 
31
- ### 1. Install Dependencies
26
+ ### 1. Install the package
27
+
28
+ ```bash
29
+ npm install react-native-codepush-sdk
30
+ ```
31
+
32
+ Peer dependencies (install if not already present):
32
33
 
33
34
  ```bash
34
35
  npm install react-native-fs react-native-zip-archive react-native-device-info @react-native-async-storage/async-storage
35
36
  ```
36
37
 
37
- ### 2. Platform Setup
38
+ ### 2. Platform setup
39
+
40
+ #### iOS
38
41
 
39
- #### iOS Setup
40
- 1. Run `cd ios && pod install`
41
- 2. Add the following to your `Info.plist`:
42
+ 1. Run `cd ios && pod install`.
43
+ 2. If your server uses HTTP (e.g. local dev), add to `Info.plist`:
42
44
  ```xml
43
45
  <key>NSAppTransportSecurity</key>
44
46
  <dict>
@@ -47,8 +49,9 @@ npm install react-native-fs react-native-zip-archive react-native-device-info @r
47
49
  </dict>
48
50
  ```
49
51
 
50
- #### Android Setup
51
- 1. Add permissions to `android/app/src/main/AndroidManifest.xml`:
52
+ #### Android
53
+
54
+ Add to `android/app/src/main/AndroidManifest.xml`:
52
55
  ```xml
53
56
  <uses-permission android:name="android.permission.INTERNET" />
54
57
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -57,46 +60,48 @@ npm install react-native-fs react-native-zip-archive react-native-device-info @r
57
60
 
58
61
  ## Usage
59
62
 
60
- ### Basic Setup
63
+ App version is read from the device via `react-native-device-info`; you only configure `serverUrl`, `deploymentKey`, and `appName`.
64
+
65
+ ### Provider + component (recommended)
61
66
 
62
67
  ```tsx
63
68
  import React from 'react';
64
69
  import { SafeAreaView } from 'react-native';
65
- import { CodePushProvider } from './src/sdk/CodePushProvider';
66
- import UpdateChecker from './src/components/UpdateChecker';
67
-
68
- const App: React.FC = () => {
69
- const codePushConfig = {
70
- serverUrl: 'https://your-custom-codepush-server.com',
71
- deploymentKey: 'your-deployment-key-here',
72
- appVersion: '1.0.0',
73
- checkFrequency: 'ON_APP_START',
74
- installMode: 'ON_NEXT_RESTART',
75
- };
70
+ import { CodePushProvider, UpdateChecker } from 'react-native-codepush-sdk';
71
+
72
+ const config = {
73
+ serverUrl: 'https://your-codepush-server.com',
74
+ deploymentKey: 'your-deployment-key',
75
+ appName: 'YourApp',
76
+ checkFrequency: 'ON_APP_START',
77
+ installMode: 'ON_NEXT_RESTART',
78
+ minimumBackgroundDuration: 0,
79
+ };
76
80
 
81
+ export default function App() {
77
82
  return (
78
- <CodePushProvider config={codePushConfig} autoCheck={true}>
83
+ <CodePushProvider config={config} autoCheck checkOnResume>
79
84
  <SafeAreaView style={{ flex: 1 }}>
80
85
  <UpdateChecker />
81
86
  </SafeAreaView>
82
87
  </CodePushProvider>
83
88
  );
84
- };
85
-
86
- export default App;
89
+ }
87
90
  ```
88
91
 
89
- ### Using the Hook
92
+ ### useCodePush hook
90
93
 
91
94
  ```tsx
92
- import { useCodePush } from './src/sdk/CodePushProvider';
95
+ import { View, Button } from 'react-native';
96
+ import { useCodePush } from 'react-native-codepush-sdk';
93
97
 
94
- const MyComponent = () => {
98
+ function MyScreen() {
95
99
  const {
96
100
  availableUpdate,
97
101
  isChecking,
98
102
  checkForUpdate,
99
103
  syncUpdate,
104
+ getBundleUrl,
100
105
  } = useCodePush();
101
106
 
102
107
  return (
@@ -104,175 +109,170 @@ const MyComponent = () => {
104
109
  {availableUpdate && (
105
110
  <Button title="Install Update" onPress={syncUpdate} />
106
111
  )}
107
- <Button
108
- title="Check for Updates"
112
+ <Button
113
+ title="Check for Updates"
109
114
  onPress={checkForUpdate}
110
115
  disabled={isChecking}
111
116
  />
112
117
  </View>
113
118
  );
114
- };
119
+ }
115
120
  ```
116
121
 
117
- ### Manual Integration
122
+ ### Class-based (CustomCodePush)
118
123
 
119
124
  ```tsx
120
- import CustomCodePush from './src/sdk/CustomCodePush';
125
+ import { CustomCodePush } from 'react-native-codepush-sdk';
121
126
 
122
127
  const codePush = new CustomCodePush({
123
128
  serverUrl: 'https://your-server.com',
124
129
  deploymentKey: 'your-key',
125
- appVersion: '1.0.0',
130
+ appName: 'YourApp',
126
131
  });
127
132
 
128
- // Check for updates
129
- const update = await codePush.checkForUpdate();
133
+ await codePush.initialize();
130
134
 
131
- // Download and install
135
+ const update = await codePush.checkForUpdate();
132
136
  if (update) {
133
137
  const localPackage = await codePush.downloadUpdate(update, (progress) => {
134
- console.log(`Download progress: ${progress.receivedBytes}/${progress.totalBytes}`);
138
+ console.log(`${progress.receivedBytes}/${progress.totalBytes}`);
135
139
  });
136
-
137
140
  await codePush.installUpdate(localPackage);
138
141
  }
139
142
  ```
140
143
 
141
- ## Server Implementation
144
+ ## Server API
142
145
 
143
- Your custom CodePush server needs to implement these endpoints:
146
+ The SDK calls these paths on your `serverUrl` (no trailing slash). In a typical dashboard setup (e.g. on Vercel), you would expose these as API routes:
144
147
 
145
- ### Check for Updates
146
- ```
147
- POST /api/v1/updates/check
148
- ```
148
+ | Method | Path | Purpose |
149
+ |--------|------|---------|
150
+ | POST | `/api/v1/update_check` | Check for an available update |
151
+ | POST | `/api/v1/report_status/deploy` | Report install/deploy/rollback status |
152
+ | POST | `/api/v1/report_status/download` | Report download status |
149
153
 
150
- ### Report Installation
151
- ```
152
- POST /api/v1/updates/report
153
- ```
154
+ **update_check** request body (example):
154
155
 
155
- ### Report Rollback
156
+ ```json
157
+ {
158
+ "deploymentKey": "your-deployment-key",
159
+ "appVersion": "1.0.0",
160
+ "packageHash": null,
161
+ "clientUniqueId": "device-id",
162
+ "label": null
163
+ }
156
164
  ```
157
- POST /api/v1/updates/rollback
165
+
166
+ **update_check** response when an update is available:
167
+
168
+ ```json
169
+ {
170
+ "updateInfo": {
171
+ "packageHash": "abc123",
172
+ "label": "v1.0.1",
173
+ "appVersion": "1.0.0",
174
+ "description": "Bug fixes",
175
+ "isMandatory": false,
176
+ "size": 1048576,
177
+ "downloadUrl": "https://your-server.com/packages/abc123.zip",
178
+ "rollout": 100,
179
+ "isDisabled": false
180
+ }
181
+ }
158
182
  ```
159
183
 
160
- See `src/api/server-example.md` for detailed API documentation.
184
+ When no update is available, return `updateInfo.isAvailable: false` or omit `updateInfo`.
185
+
186
+ A full server example and request/response shapes are in `src/api/server-example.md`. Implement those routes in your dashboard/backend (for example, as Vercel/Next.js API routes).
161
187
 
162
- ## Configuration Options
188
+ ## Configuration
163
189
 
164
190
  ```typescript
165
191
  interface CodePushConfiguration {
166
- serverUrl: string; // Your server URL
167
- deploymentKey: string; // Deployment key for authentication
168
- appVersion: string; // Current app version
169
- checkFrequency?: 'ON_APP_START' | // When to check for updates
170
- 'ON_APP_RESUME' |
171
- 'MANUAL';
172
- installMode?: 'IMMEDIATE' | // When to install updates
173
- 'ON_NEXT_RESTART' |
174
- 'ON_NEXT_RESUME';
175
- minimumBackgroundDuration?: number; // Minimum background time before checking
192
+ serverUrl: string; // Base URL of your update server (no trailing slash)
193
+ deploymentKey: string; // Deployment key for this app/deployment
194
+ appName: string; // App name (e.g. for server-side routing)
195
+ checkFrequency?: 'ON_APP_START' | 'ON_APP_RESUME' | 'MANUAL'; // default: 'ON_APP_START'
196
+ installMode?: 'IMMEDIATE' | 'ON_NEXT_RESTART' | 'ON_NEXT_RESUME'; // default: 'ON_NEXT_RESTART'
197
+ minimumBackgroundDuration?: number; // default: 0 (seconds in background before resume check)
176
198
  }
177
199
  ```
178
200
 
179
201
  ## API Reference
180
202
 
181
- ### CustomCodePush Class
203
+ ### Exports
182
204
 
183
- #### Methods
205
+ - `CodePushProvider` โ€“ React context provider; wrap your app (or root screen) with it.
206
+ - `useCodePush` โ€“ Hook to access update state and actions (must be used inside `CodePushProvider`).
207
+ - `CustomCodePush` โ€“ Class for non-React or manual integration.
208
+ - `UpdateChecker` โ€“ Optional UI component that shows update prompts.
209
+ - `BundleManager` โ€“ Utility for bundle path and loading.
210
+ - `codePushService` โ€“ Optional service layer (e.g. for deployment/history UIs).
211
+ - `useFrameworkReady` โ€“ Hook to wait for framework/engine ready before loading bundles.
212
+ - Types: `CodePushUpdate`, `CodePushDeployment`, `CodePushSyncStatus`, `CodePushConfiguration`, `UpdateHistory`, etc. (see `types/codepush.ts`).
184
213
 
185
- - `checkForUpdate()`: Check if an update is available
186
- - `downloadUpdate(update, progressCallback)`: Download an update package
187
- - `installUpdate(localPackage)`: Install a downloaded update
188
- - `sync(options, statusCallback, progressCallback)`: Complete sync process
189
- - `getCurrentPackage()`: Get current installed package info
190
- - `rollback()`: Rollback to previous version
191
- - `clearUpdates()`: Clear all downloaded updates
214
+ ### CustomCodePush
192
215
 
193
- ### CodePushProvider Component
216
+ - `initialize()`: Promise that resolves when SDK is ready (directories + stored package loaded).
217
+ - `checkForUpdate()`: Returns `UpdatePackage | null`.
218
+ - `downloadUpdate(update, progressCallback?)`: Returns `Promise<LocalPackage>`.
219
+ - `installUpdate(localPackage)`: Install a downloaded update.
220
+ - `sync(statusCallback?, progressCallback?)`: Check, download, and install in one flow.
221
+ - `getCurrentPackage()`: Current installed package or null.
222
+ - `getBundleUrl()`: URL/path to load the current bundle (e.g. for custom loaders).
223
+ - `rollback()`: Rollback to the previous version.
224
+ - `clearUpdates()`: Clear all downloaded updates.
194
225
 
195
- #### Props
226
+ ### CodePushProvider
196
227
 
197
- - `config`: CodePush configuration object
198
- - `autoCheck`: Automatically check for updates on app start
199
- - `checkOnResume`: Check for updates when app resumes
228
+ - **config** (`CodePushConfiguration`): Required.
229
+ - **autoCheck** (boolean, default `true`): Run a check on mount.
230
+ - **checkOnResume** (boolean, default `true`): Run a check when app comes to foreground.
200
231
 
201
- ### useCodePush Hook
232
+ ### useCodePush()
202
233
 
203
- #### Returns
234
+ Returns: `codePush`, `currentUpdate`, `availableUpdate`, `syncStatus`, `isChecking`, `isDownloading`, `isInstalling`, `checkForUpdate`, `syncUpdate`, `rollback`, `clearUpdates`, `getBundleUrl`.
204
235
 
205
- - `codePush`: CustomCodePush instance
206
- - `currentUpdate`: Currently installed update info
207
- - `availableUpdate`: Available update info
208
- - `syncStatus`: Current sync status
209
- - `isChecking`: Whether checking for updates
210
- - `isDownloading`: Whether downloading an update
211
- - `isInstalling`: Whether installing an update
212
- - `checkForUpdate()`: Function to check for updates
213
- - `syncUpdate()`: Function to sync and install updates
214
- - `rollback()`: Function to rollback updates
215
- - `clearUpdates()`: Function to clear all updates
236
+ ## Update package format
216
237
 
217
- ## Update Package Format
238
+ The server should serve either:
218
239
 
219
- Update packages should be ZIP files with this structure:
240
+ - **ZIP** โ€“ Standard CodePush-style package:
241
+ - `index.bundle` (main JS bundle), optional `index.bundle.map`, `assets/`, and `metadata.json`.
242
+ - **Single JS file** โ€“ For simple/demo setups the SDK can also use a direct `.js` URL (e.g. mock server demo bundles).
220
243
 
221
- ```
222
- package.zip
223
- โ”œโ”€โ”€ index.bundle # Main JavaScript bundle
224
- โ”œโ”€โ”€ index.bundle.map # Source map (optional)
225
- โ”œโ”€โ”€ assets/ # Static assets
226
- โ”‚ โ”œโ”€โ”€ images/
227
- โ”‚ โ”œโ”€โ”€ fonts/
228
- โ”‚ โ””โ”€โ”€ ...
229
- โ””โ”€โ”€ metadata.json # Package metadata
230
- ```
244
+ See `src/api/server-example.md` and `example/mock-server/` for package layout and metadata.
231
245
 
232
- ## Security Considerations
246
+ ## Development and example app
233
247
 
234
- 1. **HTTPS Only**: Always use HTTPS for your server
235
- 2. **Authentication**: Validate deployment keys on server
236
- 3. **Package Signing**: Consider signing update packages
237
- 4. **Rate Limiting**: Implement rate limiting on your server
238
- 5. **Rollback Protection**: Implement automatic rollback for failed updates
248
+ - **Example app**: `example/` is a React Native app that uses this SDK; run it with `cd example && npm start` (and start the mock server for updates).
249
+ - **Mock server**: `example/mock-server/` implements the `/v1/public/codepush/*` endpoints (Supabase-backed). Use it to test update flow locally.
250
+ - **Test script**: From the repo root, run `node test-update-check.js` (with the mock server on port 3080) to hit the update-check endpoint.
239
251
 
240
- ## Troubleshooting
241
-
242
- ### Common Issues
252
+ ```bash
253
+ # Terminal 1 โ€“ mock server
254
+ cd example/mock-server && npm start
243
255
 
244
- 1. **Network Errors**: Check server URL and network connectivity
245
- 2. **Permission Errors**: Ensure file system permissions are granted
246
- 3. **Bundle Errors**: Verify update package format and integrity
247
- 4. **Installation Failures**: Check available storage space
256
+ # Terminal 2 โ€“ test update check
257
+ node test-update-check.js
258
+ ```
248
259
 
249
- ### Debug Mode
260
+ ## Security
250
261
 
251
- Enable debug logging by setting:
262
+ - Prefer **HTTPS** for the update server.
263
+ - Validate **deployment keys** and apply **rate limiting** on the server.
264
+ - Consider **signed packages** and automatic **rollback** on failed installs.
252
265
 
253
- ```typescript
254
- // Add to your configuration
255
- const config = {
256
- // ... other config
257
- debug: true,
258
- };
259
- ```
260
-
261
- ## Contributing
266
+ ## Troubleshooting
262
267
 
263
- 1. Fork the repository
264
- 2. Create a feature branch
265
- 3. Make your changes
266
- 4. Add tests if applicable
267
- 5. Submit a pull request
268
+ - **Network errors**: Confirm `serverUrl` and device connectivity (and ATS/cleartext if using HTTP).
269
+ - **Permission errors**: Ensure storage permissions (e.g. Android manifest) are set.
270
+ - **Bundle/install failures**: Check package format, integrity, and free space.
268
271
 
269
272
  ## License
270
273
 
271
- MIT License - see LICENSE file for details.
274
+ MIT โ€“ see [LICENSE](LICENSE).
272
275
 
273
- ## Support
276
+ ## Links
274
277
 
275
- For issues and questions:
276
- - Check the troubleshooting section
277
- - Review the server API documentation
278
- - Create an issue in the repository
278
+ - [Repository](https://github.com/picassio/RN-CodePush) ยท [Issues](https://github.com/picassio/RN-CodePush/issues)
File without changes
package/dist/index.js CHANGED
File without changes
File without changes
File without changes
File without changes
@@ -78,7 +78,7 @@ class CustomCodePush {
78
78
  this.isCheckingForUpdate = true;
79
79
  try {
80
80
  const deviceInfo = await this.getDeviceInfo();
81
- const response = await fetch(`${this.config.serverUrl}/v0.1/public/codepush/update_check`, {
81
+ const response = await fetch(`${this.config.serverUrl}/api/v1/update_check`, {
82
82
  method: 'POST',
83
83
  headers: {
84
84
  'Content-Type': 'application/json',
@@ -228,7 +228,7 @@ class CustomCodePush {
228
228
  async logUpdateInstallation(localPackage, success) {
229
229
  try {
230
230
  const deviceInfo = await this.getDeviceInfo();
231
- await fetch(`${this.config.serverUrl}/v0.1/public/codepush/report_status/deploy`, {
231
+ await fetch(`${this.config.serverUrl}/api/v1/report_status/deploy`, {
232
232
  method: 'POST',
233
233
  headers: {
234
234
  'Content-Type': 'application/json',
@@ -346,7 +346,7 @@ class CustomCodePush {
346
346
  var _a;
347
347
  try {
348
348
  const deviceInfo = await this.getDeviceInfo();
349
- await fetch(`${this.config.serverUrl}/v0.1/public/codepush/report_status/deploy`, {
349
+ await fetch(`${this.config.serverUrl}/api/v1/report_status/deploy`, {
350
350
  method: 'POST',
351
351
  headers: {
352
352
  'Content-Type': 'application/json',
File without changes
File without changes
File without changes
package/index.ts CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-codepush-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A React Native CodePush SDK for over-the-air updates",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,8 @@
9
9
  "dev": "cd example && npm run start",
10
10
  "test": "jest",
11
11
  "lint": "eslint .",
12
- "prepare": "npm run build"
12
+ "prepare": "npm run build",
13
+ "publish": "npm publish --access public"
13
14
  },
14
15
  "keywords": [
15
16
  "react-native",
@@ -23,11 +24,11 @@
23
24
  "license": "MIT",
24
25
  "repository": {
25
26
  "type": "git",
26
- "url": "git+https://github.com/picassio/react-native-codepush-sdk.git"
27
+ "url": "git+https://github.com/picassio/RN-CodePush.git"
27
28
  },
28
- "homepage": "https://github.com/picassio/react-native-codepush-sdk#readme",
29
+ "homepage": "https://github.com/picassio/RN-CodePush#readme",
29
30
  "bugs": {
30
- "url": "https://github.com/picassio/react-native-codepush-sdk/issues"
31
+ "url": "https://github.com/picassio/RN-CodePush/issues"
31
32
  },
32
33
  "publishConfig": {
33
34
  "access": "public"
File without changes
File without changes
File without changes