native-update 1.0.9 → 1.1.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.
package/cli/index.js ADDED
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Native Update CLI
5
+ *
6
+ * Provides command-line tools for managing Capacitor Native Update plugin
7
+ * Can be used with npx, global install, or local install
8
+ */
9
+
10
+ import { Command } from 'commander';
11
+ import chalk from 'chalk';
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname, join } from 'path';
14
+ import fs from 'fs/promises';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ const packagePath = join(__dirname, '..', 'package.json');
19
+ const packageJson = JSON.parse(await fs.readFile(packagePath, 'utf-8'));
20
+
21
+ const program = new Command();
22
+
23
+ program
24
+ .name('native-update')
25
+ .description(`CLI tools for Capacitor Native Update plugin
26
+
27
+ ${chalk.bold('Quick Start:')}
28
+ ${chalk.gray('npx native-update init --example')} # Initialize with examples
29
+ ${chalk.gray('npx native-update backend create express')} # Create backend server
30
+ ${chalk.gray('npx native-update bundle create ./www')} # Create update bundle
31
+
32
+ ${chalk.bold('Documentation:')}
33
+ ${chalk.blue('https://github.com/aoneahsan/native-update/blob/main/docs/cli-reference.md')}`)
34
+ .version(packageJson.version)
35
+ .configureHelp({
36
+ sortSubcommands: true,
37
+ subcommandTerm: (cmd) => cmd.name() + ' ' + cmd.aliases().join(', ')
38
+ });
39
+
40
+ // Bundle Management Commands
41
+ program
42
+ .command('bundle')
43
+ .description('Bundle management commands')
44
+ .command('create <webDir>')
45
+ .alias('create-bundle')
46
+ .description(`Create an update bundle from your web directory
47
+
48
+ ${chalk.bold('Examples:')}
49
+ ${chalk.gray('# Create bundle from default build directory')}
50
+ ${chalk.green('npx native-update bundle create ./www')}
51
+
52
+ ${chalk.gray('# Create with specific version and channel')}
53
+ ${chalk.green('npx native-update bundle create ./dist --version 1.2.0 --channel staging')}
54
+
55
+ ${chalk.gray('# Add metadata like release notes')}
56
+ ${chalk.green(`npx native-update bundle create ./www --metadata '{"releaseNotes":"Bug fixes"}'`)}`)
57
+ .option('-o, --output <path>', 'Output directory for the bundle', './update-bundles')
58
+ .option('-v, --version <version>', 'Bundle version (defaults to package.json version)')
59
+ .option('-c, --channel <channel>', 'Release channel', 'production')
60
+ .option('-m, --metadata <json>', 'Additional metadata as JSON string')
61
+ .action(async (webDir, options) => {
62
+ const { createBundle } = await import('./commands/bundle-create.js');
63
+ await createBundle(webDir, options);
64
+ });
65
+
66
+ program
67
+ .command('bundle')
68
+ .command('sign <bundlePath>')
69
+ .alias('sign-bundle')
70
+ .description(`Sign an update bundle with your private key
71
+
72
+ ${chalk.bold('Examples:')}
73
+ ${chalk.gray('# Sign a bundle with your private key')}
74
+ ${chalk.green('npx native-update bundle sign ./bundle.zip --key ./keys/private.pem')}
75
+
76
+ ${chalk.gray('# Specify output path for signed bundle')}
77
+ ${chalk.green('npx native-update bundle sign ./bundle.zip --key private.pem --output ./signed-bundle.zip')}`)
78
+ .requiredOption('-k, --key <path>', 'Path to private key file')
79
+ .option('-o, --output <path>', 'Output path for signed bundle')
80
+ .action(async (bundlePath, options) => {
81
+ const { signBundle } = await import('./commands/bundle-sign.js');
82
+ await signBundle(bundlePath, options);
83
+ });
84
+
85
+ program
86
+ .command('bundle')
87
+ .command('verify <bundlePath>')
88
+ .alias('verify-bundle')
89
+ .description(`Verify a signed bundle with public key
90
+
91
+ ${chalk.bold('Example:')}
92
+ ${chalk.green('npx native-update bundle verify ./signed-bundle.zip --key ./keys/public.pem')}`)
93
+ .requiredOption('-k, --key <path>', 'Path to public key file')
94
+ .action(async (bundlePath, options) => {
95
+ const { verifyBundle } = await import('./commands/bundle-verify.js');
96
+ await verifyBundle(bundlePath, options);
97
+ });
98
+
99
+ // Key Management Commands
100
+ program
101
+ .command('keys')
102
+ .description('Key management commands')
103
+ .command('generate')
104
+ .alias('generate-keys')
105
+ .description(`Generate a new key pair for bundle signing
106
+
107
+ ${chalk.bold('Examples:')}
108
+ ${chalk.gray('# Generate default RSA 2048-bit keys')}
109
+ ${chalk.green('npx native-update keys generate')}
110
+
111
+ ${chalk.gray('# Generate strong RSA 4096-bit keys for production')}
112
+ ${chalk.green('npx native-update keys generate --type rsa --size 4096')}
113
+
114
+ ${chalk.gray('# Generate EC keys for smaller signatures')}
115
+ ${chalk.green('npx native-update keys generate --type ec --size 256 --output ./my-keys')}`)
116
+ .option('-o, --output <dir>', 'Output directory for keys', './keys')
117
+ .option('-t, --type <type>', 'Key type (rsa or ec)', 'rsa')
118
+ .option('-s, --size <size>', 'Key size (RSA: 2048/4096, EC: 256/384)', '2048')
119
+ .action(async (options) => {
120
+ const { generateKeys } = await import('./commands/keys-generate.js');
121
+ await generateKeys(options);
122
+ });
123
+
124
+ // Server Commands
125
+ program
126
+ .command('server')
127
+ .description('Development server commands')
128
+ .command('start')
129
+ .alias('start-server')
130
+ .description('Start a local update server for testing')
131
+ .option('-p, --port <port>', 'Server port', '3000')
132
+ .option('-d, --dir <dir>', 'Directory containing update bundles', './update-bundles')
133
+ .option('--cors', 'Enable CORS for testing', true)
134
+ .action(async (options) => {
135
+ const { startServer } = await import('./commands/server-start.js');
136
+ await startServer(options);
137
+ });
138
+
139
+ // Init Commands
140
+ program
141
+ .command('init')
142
+ .description(`Initialize native-update in your project
143
+
144
+ ${chalk.bold('Examples:')}
145
+ ${chalk.gray('# Basic initialization')}
146
+ ${chalk.green('npx native-update init')}
147
+
148
+ ${chalk.gray('# Initialize with example code and configuration')}
149
+ ${chalk.green('npx native-update init --example')}
150
+
151
+ ${chalk.gray('# Initialize for Firebase backend')}
152
+ ${chalk.green('npx native-update init --backend firebase --example')}`)
153
+ .option('--example', 'Include example configuration')
154
+ .option('--backend <type>', 'Backend type (firebase, express, custom)', 'custom')
155
+ .action(async (options) => {
156
+ const { init } = await import('./commands/init.js');
157
+ await init(options);
158
+ });
159
+
160
+ // Backend Commands
161
+ program
162
+ .command('backend')
163
+ .description('Backend template commands')
164
+ .command('create <type>')
165
+ .alias('create-backend')
166
+ .description(`Create a backend template (express, firebase, vercel)
167
+
168
+ ${chalk.bold('Examples:')}
169
+ ${chalk.gray('# Create Express.js backend with admin dashboard')}
170
+ ${chalk.green('npx native-update backend create express --with-admin')}
171
+
172
+ ${chalk.gray('# Create Firebase Functions backend with monitoring')}
173
+ ${chalk.green('npx native-update backend create firebase --with-monitoring')}
174
+
175
+ ${chalk.gray('# Create Vercel serverless backend')}
176
+ ${chalk.green('npx native-update backend create vercel --output my-backend')}`)
177
+ .option('-o, --output <dir>', 'Output directory', './native-update-backend')
178
+ .option('--with-monitoring', 'Include monitoring setup', false)
179
+ .option('--with-admin', 'Include admin dashboard', false)
180
+ .action(async (type, options) => {
181
+ const { createBackend } = await import('./commands/backend-create.js');
182
+ await createBackend(type, options);
183
+ });
184
+
185
+ // Config Commands
186
+ program
187
+ .command('config')
188
+ .description('Configuration commands')
189
+ .command('check')
190
+ .description('Validate your native-update configuration')
191
+ .action(async () => {
192
+ const { checkConfig } = await import('./commands/config-check.js');
193
+ await checkConfig();
194
+ });
195
+
196
+ // Migration Commands
197
+ program
198
+ .command('migrate')
199
+ .description('Migrate from other OTA solutions')
200
+ .option('--from <solution>', 'Source solution (codepush, appflow)', 'codepush')
201
+ .action(async (options) => {
202
+ const { migrate } = await import('./commands/migrate.js');
203
+ await migrate(options);
204
+ });
205
+
206
+ // Monitoring Commands
207
+ program
208
+ .command('monitor')
209
+ .description('Monitor update deployments')
210
+ .option('-s, --server <url>', 'Backend server URL')
211
+ .option('-k, --key <key>', 'API key for authentication')
212
+ .action(async (options) => {
213
+ const { monitor } = await import('./commands/monitor.js');
214
+ await monitor(options);
215
+ });
216
+
217
+ // Add helpful examples
218
+ program.on('--help', () => {
219
+ console.log('');
220
+ console.log('Examples:');
221
+ console.log('');
222
+ console.log(' Quick Start:');
223
+ console.log(' $ npx native-update init --example');
224
+ console.log(' $ npx native-update backend create express --with-admin');
225
+ console.log('');
226
+ console.log(' Bundle Management:');
227
+ console.log(' $ npx native-update bundle create ./www');
228
+ console.log(' $ npx native-update bundle sign ./bundle.zip --key ./keys/private.pem');
229
+ console.log(' $ npx native-update bundle verify ./bundle.zip --key ./keys/public.pem');
230
+ console.log('');
231
+ console.log(' Key Management:');
232
+ console.log(' $ npx native-update keys generate --type rsa --size 4096');
233
+ console.log('');
234
+ console.log(' Development:');
235
+ console.log(' $ npx native-update server start --port 3000');
236
+ console.log(' $ npx native-update monitor --server http://localhost:3000');
237
+ console.log('');
238
+ console.log(' Backend Templates:');
239
+ console.log(' $ npx native-update backend create express');
240
+ console.log(' $ npx native-update backend create firebase --with-monitoring');
241
+ console.log(' $ npx native-update backend create vercel --with-admin');
242
+ console.log('');
243
+ console.log(chalk.bold('Resources:'));
244
+ console.log(' Documentation: ' + chalk.blue('https://github.com/aoneahsan/native-update/blob/main/docs/'));
245
+ console.log(' CLI Reference: ' + chalk.blue('https://github.com/aoneahsan/native-update/blob/main/docs/cli-reference.md'));
246
+ console.log(' Quick Start: ' + chalk.blue('https://github.com/aoneahsan/native-update/blob/main/docs/getting-started/quick-start.md'));
247
+ console.log('');
248
+ console.log(chalk.bold('Support:'));
249
+ console.log(' Issues: ' + chalk.blue('https://github.com/aoneahsan/native-update/issues'));
250
+ console.log(' Author: Ahsan Mahmood (' + chalk.blue('https://aoneahsan.com') + ')');
251
+ console.log(' Email: ' + chalk.blue('aoneahsan@gmail.com'));
252
+ });
253
+
254
+ // Error handling
255
+ program.exitOverride();
256
+
257
+ try {
258
+ await program.parseAsync(process.argv);
259
+ } catch (error) {
260
+ if (error.code === 'commander.missingArgument') {
261
+ console.error(chalk.red(`Error: ${error.message}`));
262
+ } else if (error.code === 'commander.unknownCommand') {
263
+ console.error(chalk.red(`Error: Unknown command`));
264
+ program.outputHelp();
265
+ } else {
266
+ console.error(chalk.red(`Error: ${error.message}`));
267
+ }
268
+ process.exit(1);
269
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "native-update-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI for Native Update",
5
+ "type": "module",
6
+ "bin": {
7
+ "cap-update": "./cap-update.js"
8
+ },
9
+ "dependencies": {
10
+ "commander": "^11.0.0"
11
+ }
12
+ }
@@ -14,16 +14,23 @@ Bundle signing uses RSA-2048 with SHA-256 to create digital signatures that veri
14
14
 
15
15
  ### 1. Generate RSA Key Pair
16
16
 
17
+ The easiest way is using our CLI tool:
18
+
17
19
  ```bash
18
- cd server-example
19
- node bundle-signer.js generate-keys
20
+ # Generate strong RSA keys for production
21
+ npx native-update keys generate --type rsa --size 4096
22
+
23
+ # Or generate EC keys for smaller signatures
24
+ npx native-update keys generate --type ec --size 256
20
25
  ```
21
26
 
22
27
  This creates:
23
28
 
24
- - `private.key` - Keep secure on your server
25
- - `public.key` - Include in your app
26
- - `public.key.b64` - Base64 version for app config
29
+ - `private-{timestamp}.pem` - Keep secure on your server (NEVER commit to git!)
30
+ - `public-{timestamp}.pem` - Include in your app
31
+ - Proper file permissions (600) are set automatically
32
+
33
+ For detailed key management instructions, see the [Key Management Guide](./guides/key-management.md).
27
34
 
28
35
  ### 2. Secure Private Key
29
36
 
@@ -55,7 +62,7 @@ const signature = signBundle(fileBuffer, privateKey);
55
62
  Sign bundles manually:
56
63
 
57
64
  ```bash
58
- node bundle-signer.js sign bundle-1.0.0.zip /secure/keys/private.key
65
+ npx native-update bundle sign bundle-1.0.0.zip --key /secure/keys/private.key
59
66
  ```
60
67
 
61
68
  This creates `bundle-1.0.0.zip.sig` containing the base64 signature.
@@ -161,7 +168,7 @@ async function verifyBundle(
161
168
  PRIVATE_KEY: ${{ secrets.BUNDLE_SIGNING_KEY }}
162
169
  run: |
163
170
  echo "$PRIVATE_KEY" > private.key
164
- node bundle-signer.js sign dist/bundle.zip
171
+ npx native-update bundle sign dist/bundle.zip --key private.key
165
172
  rm private.key
166
173
  ```
167
174
 
@@ -169,7 +176,7 @@ async function verifyBundle(
169
176
 
170
177
  ```groovy
171
178
  withCredentials([file(credentialsId: 'bundle-signing-key', variable: 'KEY_FILE')]) {
172
- sh 'node bundle-signer.js sign dist/bundle.zip $KEY_FILE'
179
+ sh 'npx native-update bundle sign dist/bundle.zip --key $KEY_FILE'
173
180
  }
174
181
  ```
175
182
 
@@ -198,7 +205,7 @@ Test signature verification:
198
205
 
199
206
  ```bash
200
207
  # Verify manually
201
- node bundle-signer.js verify bundle.zip bundle.zip.sig public.key
208
+ npx native-update bundle verify bundle.zip --key public.key
202
209
 
203
210
  # Check signature format
204
211
  cat bundle.zip.sig | base64 -d | xxd | head
@@ -397,7 +397,7 @@ zip -r ../bundle-1.0.1.zip www/
397
397
 
398
398
  # 3. Sign the bundle (optional but recommended)
399
399
  cd ..
400
- node server-example/bundle-signer.js sign bundle-1.0.1.zip
400
+ npx native-update bundle sign bundle-1.0.1.zip --key private.key
401
401
 
402
402
  # 4. Upload to server
403
403
  curl -X POST https://updates.example.com/api/v1/bundles \
package/docs/README.md CHANGED
@@ -33,6 +33,7 @@ Created by **Ahsan Mahmood** and open-sourced for the developer community, this
33
33
  ### Guides
34
34
 
35
35
  - [**Security Best Practices**](./guides/security-best-practices.md) - Implement secure updates
36
+ - [**Key Management**](./guides/key-management.md) - Generate and manage signing keys
36
37
  - [**Migration from CodePush**](./guides/migration-from-codepush.md) - Migrate from CodePush
37
38
  - [**Testing Guide**](./guides/testing-guide.md) - Testing your update implementation
38
39
  - [**Deployment Guide**](./guides/deployment-guide.md) - Deploy to production
@@ -0,0 +1,321 @@
1
+ # CLI Reference
2
+
3
+ The Native Update CLI provides comprehensive tools for managing your update workflow.
4
+
5
+ ## Installation
6
+
7
+ The CLI is included with the native-update package. You can use it via npx without any additional installation:
8
+
9
+ ```bash
10
+ # Use directly with npx (recommended)
11
+ npx native-update <command>
12
+
13
+ # Or install globally
14
+ npm install -g native-update
15
+
16
+ # Or use locally in your project
17
+ npm install native-update
18
+ npx native-update <command>
19
+ ```
20
+
21
+ ## Commands
22
+
23
+ ### Bundle Management
24
+
25
+ #### `bundle create <webDir>`
26
+
27
+ Creates an update bundle from your web build directory.
28
+
29
+ ```bash
30
+ npx native-update bundle create ./www
31
+
32
+ # Options:
33
+ # -o, --output <path> Output directory (default: ./update-bundles)
34
+ # -v, --version <version> Bundle version (default: from package.json)
35
+ # -c, --channel <channel> Release channel (default: production)
36
+ # -m, --metadata <json> Additional metadata as JSON string
37
+ ```
38
+
39
+ **Example:**
40
+ ```bash
41
+ npx native-update bundle create ./dist \
42
+ --version 1.2.0 \
43
+ --channel staging \
44
+ --metadata '{"releaseNotes":"Bug fixes"}'
45
+ ```
46
+
47
+ #### `bundle sign <bundlePath>`
48
+
49
+ Signs a bundle with your private key for security verification.
50
+
51
+ ```bash
52
+ npx native-update bundle sign ./bundle.zip --key ./keys/private.pem
53
+
54
+ # Options:
55
+ # -k, --key <path> Path to private key file (required)
56
+ # -o, --output <path> Output path for signed bundle
57
+ ```
58
+
59
+ #### `bundle verify <bundlePath>`
60
+
61
+ Verifies a signed bundle with the public key.
62
+
63
+ ```bash
64
+ npx native-update bundle verify ./bundle.zip --key ./keys/public.pem
65
+
66
+ # Options:
67
+ # -k, --key <path> Path to public key file (required)
68
+ ```
69
+
70
+ ### Key Management
71
+
72
+ #### `keys generate`
73
+
74
+ Generates a new cryptographic key pair for bundle signing. This is the recommended way to create keys for the Native Update plugin.
75
+
76
+ ```bash
77
+ npx native-update keys generate
78
+
79
+ # Options:
80
+ # -o, --output <dir> Output directory (default: ./keys)
81
+ # -t, --type <type> Key type: rsa or ec (default: rsa)
82
+ # -s, --size <size> Key size - RSA: 2048/4096, EC: 256/384 (default: 2048)
83
+ ```
84
+
85
+ **What it creates:**
86
+ - `private-{timestamp}.pem` - Private key for signing (keep SECRET on server)
87
+ - `public-{timestamp}.pem` - Public key for verification (include in app)
88
+ - Sets proper file permissions (600) on private key
89
+ - Timestamps prevent accidental overwriting
90
+
91
+ **Example:**
92
+ ```bash
93
+ # Generate strong RSA keys for production (recommended)
94
+ npx native-update keys generate --type rsa --size 4096
95
+
96
+ # Generate EC keys for smaller signature size
97
+ npx native-update keys generate --type ec --size 256
98
+
99
+ # Generate in custom directory
100
+ npx native-update keys generate --output ./my-keys --type rsa --size 4096
101
+ ```
102
+
103
+ **Security Notes:**
104
+ - NEVER commit private keys to version control
105
+ - Store private keys in secure locations with restricted access
106
+ - Use environment variables or key management services in production
107
+ - See [Key Management Guide](./guides/key-management.md) for best practices
108
+
109
+ ### Backend Templates
110
+
111
+ #### `backend create <type>`
112
+
113
+ Creates a backend server template for hosting updates.
114
+
115
+ ```bash
116
+ npx native-update backend create express
117
+
118
+ # Types available:
119
+ # express - Node.js Express server
120
+ # firebase - Firebase Functions
121
+ # vercel - Vercel serverless functions
122
+
123
+ # Options:
124
+ # -o, --output <dir> Output directory (default: ./native-update-backend)
125
+ # --with-monitoring Include monitoring setup
126
+ # --with-admin Include admin dashboard
127
+ ```
128
+
129
+ **Examples:**
130
+ ```bash
131
+ # Express server with admin dashboard
132
+ npx native-update backend create express --with-admin
133
+
134
+ # Firebase Functions with monitoring
135
+ npx native-update backend create firebase --with-monitoring
136
+
137
+ # Vercel deployment ready backend
138
+ npx native-update backend create vercel
139
+ ```
140
+
141
+ ### Development Tools
142
+
143
+ #### `server start`
144
+
145
+ Starts a local update server for development and testing.
146
+
147
+ ```bash
148
+ npx native-update server start
149
+
150
+ # Options:
151
+ # -p, --port <port> Server port (default: 3000)
152
+ # -d, --dir <dir> Directory containing bundles (default: ./update-bundles)
153
+ # --cors Enable CORS (default: true)
154
+ ```
155
+
156
+ #### `init`
157
+
158
+ Initializes Native Update configuration in your project.
159
+
160
+ ```bash
161
+ npx native-update init
162
+
163
+ # Options:
164
+ # --example Include example code
165
+ # --backend <type> Backend type: firebase, express, custom (default: custom)
166
+ ```
167
+
168
+ ### Monitoring
169
+
170
+ #### `monitor`
171
+
172
+ Monitors update deployment statistics in real-time.
173
+
174
+ ```bash
175
+ npx native-update monitor --server https://your-update-server.com
176
+
177
+ # Options:
178
+ # -s, --server <url> Backend server URL (required)
179
+ # -k, --key <key> API key for authentication
180
+ ```
181
+
182
+ ### Configuration
183
+
184
+ #### `config check`
185
+
186
+ Validates your Native Update configuration.
187
+
188
+ ```bash
189
+ npx native-update config check
190
+ ```
191
+
192
+ ### Migration
193
+
194
+ #### `migrate`
195
+
196
+ Helps migrate from other OTA solutions.
197
+
198
+ ```bash
199
+ npx native-update migrate --from codepush
200
+
201
+ # Options:
202
+ # --from <solution> Source solution: codepush, appflow (default: codepush)
203
+ ```
204
+
205
+ ## Complete Workflow Example
206
+
207
+ Here's a typical workflow using the CLI:
208
+
209
+ ```bash
210
+ # 1. Initialize in your project
211
+ npx native-update init --example
212
+
213
+ # 2. Generate signing keys
214
+ npx native-update keys generate --type rsa --size 4096
215
+
216
+ # 3. Create a backend
217
+ npx native-update backend create express --with-admin
218
+
219
+ # 4. Start the backend (in another terminal)
220
+ cd native-update-backend
221
+ npm install
222
+ npm run dev
223
+
224
+ # 5. Build your app
225
+ npm run build
226
+
227
+ # 6. Create and sign a bundle
228
+ npx native-update bundle create ./www --version 1.0.1
229
+ npx native-update bundle sign ./update-bundles/bundle-*.zip --key ./keys/private-*.pem
230
+
231
+ # 7. Upload to your server (use the admin dashboard or API)
232
+
233
+ # 8. Monitor deployments
234
+ npx native-update monitor --server http://localhost:3000
235
+ ```
236
+
237
+ ## CI/CD Integration
238
+
239
+ ### GitHub Actions
240
+
241
+ ```yaml
242
+ - name: Create Update Bundle
243
+ run: |
244
+ npx native-update bundle create ./dist \
245
+ --version ${{ github.event.release.tag_name }}
246
+ --channel production
247
+
248
+ - name: Sign Bundle
249
+ run: |
250
+ npx native-update bundle sign ./update-bundles/*.zip \
251
+ --key ${{ secrets.PRIVATE_KEY }}
252
+ ```
253
+
254
+ ### Jenkins
255
+
256
+ ```groovy
257
+ stage('Create Update') {
258
+ steps {
259
+ sh 'npx native-update bundle create ./www --version ${BUILD_NUMBER}'
260
+ sh 'npx native-update bundle sign ./update-bundles/*.zip --key ${PRIVATE_KEY_PATH}'
261
+ }
262
+ }
263
+ ```
264
+
265
+ ## Environment Variables
266
+
267
+ The CLI respects these environment variables:
268
+
269
+ - `NATIVE_UPDATE_SERVER` - Default server URL for commands
270
+ - `NATIVE_UPDATE_API_KEY` - Default API key for authentication
271
+ - `NATIVE_UPDATE_CHANNEL` - Default release channel
272
+ - `NO_COLOR` - Disable colored output
273
+
274
+ ## Troubleshooting
275
+
276
+ ### "Command not found"
277
+
278
+ Make sure you're using `npx` or have installed the package:
279
+ ```bash
280
+ npx native-update <command>
281
+ ```
282
+
283
+ ### "EACCES: permission denied"
284
+
285
+ Key files need proper permissions:
286
+ ```bash
287
+ chmod 600 ./keys/private-*.pem
288
+ ```
289
+
290
+ ### Bundle creation fails
291
+
292
+ Ensure your web directory contains built files:
293
+ ```bash
294
+ # Build first
295
+ npm run build
296
+
297
+ # Then create bundle
298
+ npx native-update bundle create ./www
299
+ ```
300
+
301
+ ## Best Practices
302
+
303
+ 1. **Security**
304
+ - Keep private keys secure and never commit them
305
+ - Use strong RSA 4096 keys for production
306
+ - Always sign bundles before deployment
307
+
308
+ 2. **Versioning**
309
+ - Use semantic versioning (1.0.0, 1.0.1, etc.)
310
+ - Increment versions for each update
311
+ - Use channels for staged rollouts
312
+
313
+ 3. **Testing**
314
+ - Test updates locally first using `server start`
315
+ - Verify bundles before deployment
316
+ - Use staging channel before production
317
+
318
+ 4. **Monitoring**
319
+ - Always monitor deployments
320
+ - Set up alerts for failed updates
321
+ - Track adoption rates
@@ -66,8 +66,9 @@ liveUpdate: {
66
66
  serverUrl: 'https://updates.yourserver.com',
67
67
  channel: 'production',
68
68
 
69
- // Security
70
- publicKey: 'YOUR_RSA_PUBLIC_KEY',
69
+ // Security (see Key Management Guide for generating keys)
70
+ // Generate keys: npx native-update keys generate --type rsa --size 4096
71
+ publicKey: 'YOUR_RSA_PUBLIC_KEY', // Base64 encoded public key
71
72
  requireSignature: true,
72
73
  checksumAlgorithm: 'SHA-256', // or 'SHA-512'
73
74