island-bridge 1.1.0 → 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 (57) hide show
  1. package/README.md +120 -1
  2. package/dist/bin/cli.d.ts +2 -0
  3. package/dist/bin/cli.js +327 -0
  4. package/dist/bin/cli.js.map +1 -0
  5. package/dist/lib/args.d.ts +6 -0
  6. package/dist/lib/args.js +128 -0
  7. package/dist/lib/args.js.map +1 -0
  8. package/dist/lib/backup.d.ts +26 -0
  9. package/dist/lib/backup.js +96 -0
  10. package/dist/lib/backup.js.map +1 -0
  11. package/dist/lib/config.d.ts +25 -0
  12. package/dist/lib/config.js +216 -0
  13. package/dist/lib/config.js.map +1 -0
  14. package/dist/lib/history.d.ts +9 -0
  15. package/dist/lib/history.js +84 -0
  16. package/dist/lib/history.js.map +1 -0
  17. package/dist/lib/hooks.d.ts +11 -0
  18. package/dist/lib/hooks.js +36 -0
  19. package/dist/lib/hooks.js.map +1 -0
  20. package/dist/lib/init.d.ts +28 -0
  21. package/dist/lib/init.js +90 -0
  22. package/dist/lib/init.js.map +1 -0
  23. package/dist/lib/interactive.d.ts +9 -0
  24. package/dist/lib/interactive.js +41 -0
  25. package/dist/lib/interactive.js.map +1 -0
  26. package/dist/lib/progress.d.ts +18 -0
  27. package/dist/lib/progress.js +65 -0
  28. package/dist/lib/progress.js.map +1 -0
  29. package/dist/lib/reporter.d.ts +59 -0
  30. package/dist/lib/reporter.js +189 -0
  31. package/dist/lib/reporter.js.map +1 -0
  32. package/dist/lib/status.d.ts +41 -0
  33. package/dist/lib/status.js +123 -0
  34. package/dist/lib/status.js.map +1 -0
  35. package/dist/lib/summary.d.ts +19 -0
  36. package/dist/lib/summary.js +56 -0
  37. package/dist/lib/summary.js.map +1 -0
  38. package/dist/lib/sync.d.ts +32 -0
  39. package/dist/lib/sync.js +237 -0
  40. package/dist/lib/sync.js.map +1 -0
  41. package/dist/lib/types.d.ts +91 -0
  42. package/dist/lib/types.js +2 -0
  43. package/dist/lib/types.js.map +1 -0
  44. package/dist/lib/watch.d.ts +10 -0
  45. package/dist/lib/watch.js +73 -0
  46. package/dist/lib/watch.js.map +1 -0
  47. package/package.json +11 -5
  48. package/bin/cli.js +0 -200
  49. package/lib/args.js +0 -75
  50. package/lib/config.js +0 -193
  51. package/lib/history.js +0 -94
  52. package/lib/hooks.js +0 -26
  53. package/lib/interactive.js +0 -46
  54. package/lib/progress.js +0 -56
  55. package/lib/summary.js +0 -35
  56. package/lib/sync.js +0 -235
  57. package/lib/watch.js +0 -64
package/README.md CHANGED
@@ -21,9 +21,28 @@ npx island-bridge push
21
21
  - `rsync` installed on both local and remote machines
22
22
  - SSH access to remote server (uses system `~/.ssh/config`)
23
23
 
24
+ ## Quick Start
25
+
26
+ ```bash
27
+ # Create config interactively
28
+ island-bridge init
29
+
30
+ # Or create config via flags (AI/script friendly)
31
+ island-bridge init --host 192.168.1.100 --user deploy --paths "/var/www/app,/etc/nginx/conf.d"
32
+
33
+ # Check environment is ready
34
+ island-bridge status
35
+
36
+ # Pull remote folders to local
37
+ island-bridge pull
38
+
39
+ # Push local changes back
40
+ island-bridge push
41
+ ```
42
+
24
43
  ## Usage
25
44
 
26
- 1. Create `island-bridge.json` in your working directory:
45
+ 1. Create `island-bridge.json` in your working directory (or run `island-bridge init`):
27
46
 
28
47
  ```json
29
48
  {
@@ -68,6 +87,9 @@ island-bridge push
68
87
  | `watch` | Watch local folders and auto-push on changes |
69
88
  | `diff` | Preview changes without syncing |
70
89
  | `history` | Show sync history |
90
+ | `init` | Create config file interactively or via flags |
91
+ | `status` | Show config, SSH, rsync, and paths status |
92
+ | `backup` | Manage sync backups (list, restore, clean) |
71
93
 
72
94
  ## Options
73
95
 
@@ -80,9 +102,80 @@ island-bridge push
80
102
  | `--env <name>` | Use named profile from config |
81
103
  | `--bwlimit <KB/s>` | Limit transfer bandwidth |
82
104
  | `-s, --select` | Interactively select folders to sync |
105
+ | `--path <name>` | Sync specific folder by name (repeatable) |
106
+ | `--json` | Output in JSON format (for scripts/AI) |
107
+ | `--no-backup` | Skip backup for this sync |
83
108
  | `-V, --version` | Show version |
84
109
  | `-h, --help` | Show help |
85
110
 
111
+ ## Backup & Restore
112
+
113
+ Backups are **enabled by default**. Before each sync, files that will be overwritten are automatically saved to a timestamped backup directory.
114
+
115
+ ```bash
116
+ # List available backups
117
+ island-bridge backup list
118
+
119
+ # Restore a specific backup
120
+ island-bridge backup restore 2026-04-07T14-30-00
121
+
122
+ # Clean old backups, keep 5 most recent
123
+ island-bridge backup clean --keep 5
124
+ ```
125
+
126
+ ### Backup Config
127
+
128
+ ```json
129
+ {
130
+ "backup": {
131
+ "enabled": true,
132
+ "maxCount": 10,
133
+ "localDir": ".island-bridge-backups",
134
+ "remoteDir": "~/.island-bridge-backups"
135
+ }
136
+ }
137
+ ```
138
+
139
+ Use `--no-backup` to skip backup for a single sync operation.
140
+
141
+ ## JSON Output (AI/Script Friendly)
142
+
143
+ Add `--json` to any command for structured JSON output — no colors, no progress bars, no interactive prompts:
144
+
145
+ ```bash
146
+ # Check environment before syncing
147
+ island-bridge status --json
148
+
149
+ # Sync and parse results programmatically
150
+ island-bridge pull --json
151
+
152
+ # Create config non-interactively
153
+ island-bridge init --json --host example.com --user deploy --paths "/var/www/app"
154
+ ```
155
+
156
+ Example JSON output:
157
+
158
+ ```json
159
+ {
160
+ "version": "2.0.0",
161
+ "command": "pull",
162
+ "success": true,
163
+ "results": [
164
+ {
165
+ "folder": "app",
166
+ "remotePath": "/var/www/app",
167
+ "success": true,
168
+ "changes": [
169
+ { "type": "add", "file": "index.js" },
170
+ { "type": "delete", "file": "old.css" }
171
+ ]
172
+ }
173
+ ],
174
+ "messages": [],
175
+ "errors": []
176
+ }
177
+ ```
178
+
86
179
  ## Advanced Config
87
180
 
88
181
  ```json
@@ -94,6 +187,10 @@ island-bridge push
94
187
  },
95
188
  "exclude": ["node_modules", ".DS_Store", "*.log"],
96
189
  "bwlimit": 1000,
190
+ "backup": {
191
+ "enabled": true,
192
+ "maxCount": 10
193
+ },
97
194
  "hooks": {
98
195
  "beforeSync": "echo 'Starting sync...'",
99
196
  "afterSync": "pm2 restart app"
@@ -162,6 +259,12 @@ island-bridge pull --config /path/to/my-config.json
162
259
  ## Examples
163
260
 
164
261
  ```bash
262
+ # Create config interactively
263
+ island-bridge init
264
+
265
+ # Check everything is working
266
+ island-bridge status
267
+
165
268
  # Preview what would change
166
269
  island-bridge pull --dry-run
167
270
 
@@ -171,6 +274,9 @@ island-bridge diff
171
274
  # Sync with bandwidth limit
172
275
  island-bridge pull --bwlimit 500
173
276
 
277
+ # Sync only specific folder
278
+ island-bridge pull --path app
279
+
174
280
  # Auto-push on file changes
175
281
  island-bridge watch
176
282
 
@@ -183,8 +289,15 @@ island-bridge pull --env staging
183
289
  # Quiet mode for CI/scripts
184
290
  island-bridge push --quiet
185
291
 
292
+ # JSON output for AI/scripts
293
+ island-bridge pull --json
294
+
186
295
  # View sync history
187
296
  island-bridge history
297
+
298
+ # List and restore backups
299
+ island-bridge backup list
300
+ island-bridge backup restore 2026-04-07T14-30-00
188
301
  ```
189
302
 
190
303
  ## Features
@@ -207,6 +320,12 @@ island-bridge history
207
320
  - **Config search** — finds config in parent directories
208
321
  - **Fault tolerant** — skips failed transfers, reports summary at end
209
322
  - **Zero dependencies** — pure Node.js, no npm dependencies
323
+ - **Auto backup** — files backed up before overwrite, with restore support
324
+ - **JSON output** — structured output for AI agents and scripts
325
+ - **Init command** — interactive or flag-based config setup
326
+ - **Status check** — diagnose SSH, rsync, and path issues
327
+ - **Path filter** — sync specific folders with `--path`
328
+ - **Error hints** — actionable suggestions on every error
210
329
 
211
330
  ## License
212
331
 
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from '../lib/args.js';
3
+ import { loadConfig, extractFolderName } from '../lib/config.js';
4
+ import { checkRsync, syncAll, diffPreview } from '../lib/sync.js';
5
+ import { Reporter } from '../lib/reporter.js';
6
+ import { startWatch } from '../lib/watch.js';
7
+ import { recordSync, showHistory } from '../lib/history.js';
8
+ import { runHook } from '../lib/hooks.js';
9
+ import { selectPaths } from '../lib/interactive.js';
10
+ import { runInit } from '../lib/init.js';
11
+ import { runStatus } from '../lib/status.js';
12
+ import { listBackups, restoreBackup, cleanBackups } from '../lib/backup.js';
13
+ import { getErrorHint } from '../lib/summary.js';
14
+ import { readFileSync } from 'node:fs';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { dirname, join } from 'node:path';
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
19
+ const USAGE = `
20
+ island-bridge v${pkg.version} - Sync remote folders via rsync over SSH
21
+
22
+ Usage:
23
+ island-bridge <command> [options]
24
+
25
+ Commands:
26
+ pull Pull remote folders to local directory
27
+ push Push local folders to remote server
28
+ watch Watch local folders and auto-push on changes
29
+ diff Preview changes without syncing
30
+ history Show sync history
31
+ init Create island-bridge.json config interactively
32
+ status Show config, SSH, rsync, and paths status
33
+ backup Manage sync backups (list, restore, clean)
34
+
35
+ Options:
36
+ -n, --dry-run Preview sync without making changes
37
+ -v, --verbose Show detailed output
38
+ -q, --quiet Suppress output (exit code only)
39
+ -c, --config <path> Use specific config file
40
+ --env <name> Use named profile from config
41
+ --bwlimit <KB/s> Limit transfer bandwidth
42
+ -s, --select Interactively select folders to sync
43
+ --path <name> Sync specific folder by name (repeatable)
44
+ --json Output in JSON format (for scripts/AI)
45
+ --no-backup Skip backup for this sync
46
+ -V, --version Show version
47
+ -h, --help Show this help message
48
+
49
+ Backup subcommands:
50
+ backup list List available backups
51
+ backup restore <timestamp> Restore files from a backup
52
+ backup clean --keep <N> Remove old backups, keep N most recent
53
+ `.trim();
54
+ async function main() {
55
+ let args;
56
+ try {
57
+ args = parseArgs();
58
+ }
59
+ catch (err) {
60
+ console.error(`\x1b[31mError: ${err.message}\x1b[0m`);
61
+ process.exit(1);
62
+ }
63
+ const reporter = new Reporter(args.json ? 'json' : 'human');
64
+ if (args.help || (!args.command && !args.version)) {
65
+ console.log(USAGE);
66
+ process.exit(0);
67
+ }
68
+ if (args.version) {
69
+ if (args.json) {
70
+ reporter.setCommand('version');
71
+ reporter.info(pkg.version);
72
+ reporter.flush();
73
+ }
74
+ else {
75
+ console.log(`island-bridge v${pkg.version}`);
76
+ }
77
+ process.exit(0);
78
+ }
79
+ const validCommands = ['pull', 'push', 'watch', 'diff', 'history', 'init', 'status', 'backup'];
80
+ if (!validCommands.includes(args.command)) {
81
+ reporter.error(`Unknown command: ${args.command}`, `Valid commands: ${validCommands.join(', ')}`);
82
+ if (args.json)
83
+ reporter.flush();
84
+ process.exit(1);
85
+ }
86
+ reporter.setCommand(args.command);
87
+ // === Init ===
88
+ if (args.command === 'init') {
89
+ const ok = await runInit(args, reporter);
90
+ if (args.json)
91
+ reporter.flush();
92
+ process.exit(ok ? 0 : 1);
93
+ }
94
+ // === History (doesn't need rsync) ===
95
+ if (args.command === 'history') {
96
+ let config;
97
+ try {
98
+ config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
99
+ }
100
+ catch {
101
+ // Show history from cwd if no config found
102
+ }
103
+ if (args.json) {
104
+ const { readFileSync: rfs, existsSync: efs } = await import('node:fs');
105
+ const { dirname: dn, join: jn } = await import('node:path');
106
+ const historyFile = config?._filePath
107
+ ? jn(dn(config._filePath), '.island-bridge-history.json')
108
+ : '.island-bridge-history.json';
109
+ let entries = [];
110
+ if (efs(historyFile)) {
111
+ try {
112
+ const parsed = JSON.parse(rfs(historyFile, 'utf-8'));
113
+ entries = Array.isArray(parsed) ? parsed : [];
114
+ }
115
+ catch { /* ignore */ }
116
+ }
117
+ reporter.historyReport(entries);
118
+ reporter.flush();
119
+ }
120
+ else {
121
+ showHistory(config?._filePath);
122
+ }
123
+ process.exit(0);
124
+ }
125
+ // === Backup ===
126
+ if (args.command === 'backup') {
127
+ let config;
128
+ try {
129
+ config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
130
+ }
131
+ catch {
132
+ config = { backup: { enabled: true, localDir: '.island-bridge-backups', remoteDir: '~/.island-bridge-backups', maxCount: 10 } };
133
+ }
134
+ const backupConfig = config.backup;
135
+ if (args.subcommand === 'list') {
136
+ const backups = listBackups(backupConfig.localDir);
137
+ if (args.json) {
138
+ reporter.historyReport(backups.map((b) => ({ timestamp: b.name, date: b.date.toISOString() })));
139
+ reporter.flush();
140
+ }
141
+ else {
142
+ if (backups.length === 0) {
143
+ console.log('No backups found.');
144
+ }
145
+ else {
146
+ console.log('\n--- Backups ---\n');
147
+ for (const b of backups) {
148
+ console.log(` ${b.name} (${b.date.toLocaleString()})`);
149
+ }
150
+ console.log(`\n${backups.length} backup(s) found.`);
151
+ }
152
+ }
153
+ process.exit(0);
154
+ }
155
+ if (args.subcommand === 'restore') {
156
+ if (!args.backupTimestamp) {
157
+ reporter.error('backup restore requires a timestamp', 'Run "island-bridge backup list" to see available backups');
158
+ if (args.json)
159
+ reporter.flush();
160
+ process.exit(1);
161
+ }
162
+ try {
163
+ const results = restoreBackup(backupConfig.localDir, args.backupTimestamp);
164
+ if (args.json) {
165
+ for (const r of results) {
166
+ reporter.syncEnd(r.folder, r);
167
+ }
168
+ reporter.flush();
169
+ }
170
+ else {
171
+ for (const r of results) {
172
+ if (r.success) {
173
+ console.log(` \x1b[32m\u2713\x1b[0m ${r.folder} restored`);
174
+ }
175
+ else {
176
+ console.log(` \x1b[31m\u2717\x1b[0m ${r.folder} \u2014 ${r.error}`);
177
+ }
178
+ }
179
+ }
180
+ }
181
+ catch (err) {
182
+ reporter.error(err.message, 'Run "island-bridge backup list" to see available backups');
183
+ if (args.json)
184
+ reporter.flush();
185
+ process.exit(1);
186
+ }
187
+ process.exit(0);
188
+ }
189
+ if (args.subcommand === 'clean') {
190
+ const keep = args.keep || backupConfig.maxCount || 10;
191
+ const removed = cleanBackups(backupConfig.localDir, keep);
192
+ if (args.json) {
193
+ reporter.info(`Removed ${removed.length} backup(s), keeping ${keep}`);
194
+ reporter.flush();
195
+ }
196
+ else {
197
+ if (removed.length === 0) {
198
+ console.log(`No backups to remove (keeping ${keep}).`);
199
+ }
200
+ else {
201
+ for (const name of removed) {
202
+ console.log(` Removed: ${name}`);
203
+ }
204
+ console.log(`\nRemoved ${removed.length} backup(s), keeping ${keep}.`);
205
+ }
206
+ }
207
+ process.exit(0);
208
+ }
209
+ reporter.error('Unknown backup subcommand', 'Usage: island-bridge backup <list|restore|clean>');
210
+ if (args.json)
211
+ reporter.flush();
212
+ process.exit(1);
213
+ }
214
+ // === Pre-flight: check rsync ===
215
+ const rsyncOk = await checkRsync();
216
+ if (!rsyncOk) {
217
+ reporter.error('rsync is required but not found in PATH', getErrorHint('rsync-not-found'));
218
+ if (args.json)
219
+ reporter.flush();
220
+ process.exit(1);
221
+ }
222
+ // === Load config ===
223
+ let config;
224
+ try {
225
+ config = loadConfig({ configPath: args.config ?? undefined, env: args.env ?? undefined });
226
+ }
227
+ catch (err) {
228
+ const hint = err.message.includes('Cannot find')
229
+ ? getErrorHint('config-not-found')
230
+ : null;
231
+ reporter.error(err.message, hint);
232
+ if (args.json)
233
+ reporter.flush();
234
+ process.exit(1);
235
+ }
236
+ if (args.env) {
237
+ reporter.info(`Using profile: ${args.env}`);
238
+ }
239
+ if (config._filePath) {
240
+ reporter.info(`Config: ${config._filePath}`);
241
+ }
242
+ // === Status ===
243
+ if (args.command === 'status') {
244
+ await runStatus(config, reporter);
245
+ if (args.json)
246
+ reporter.flush();
247
+ process.exit(0);
248
+ }
249
+ // === --path filter ===
250
+ if (args.path.length > 0) {
251
+ const allNames = config.remote.paths.map((p) => extractFolderName(p));
252
+ const invalid = args.path.filter((name) => !allNames.includes(name));
253
+ if (invalid.length > 0) {
254
+ reporter.error(`Unknown folder name(s): ${invalid.join(', ')}`, `Available folders: ${allNames.join(', ')}`);
255
+ if (args.json)
256
+ reporter.flush();
257
+ process.exit(1);
258
+ }
259
+ config.remote.paths = config.remote.paths.filter((p) => args.path.includes(extractFolderName(p)));
260
+ }
261
+ // === Interactive selection ===
262
+ if (args.select && !args.json && ['pull', 'push', 'diff'].includes(args.command)) {
263
+ config.remote.paths = await selectPaths(config.remote.paths, reporter);
264
+ }
265
+ // === Watch mode ===
266
+ if (args.command === 'watch') {
267
+ startWatch(config, {
268
+ dryRun: args.dryRun,
269
+ verbose: args.verbose,
270
+ quiet: args.quiet,
271
+ bwlimit: args.bwlimit,
272
+ noBackup: args.noBackup,
273
+ }, reporter);
274
+ return;
275
+ }
276
+ // === Diff preview ===
277
+ if (args.command === 'diff') {
278
+ const diffs = await diffPreview(config, 'pull', {
279
+ bwlimit: args.bwlimit,
280
+ exclude: config.exclude,
281
+ });
282
+ reporter.diffReport(diffs);
283
+ if (args.json)
284
+ reporter.flush();
285
+ process.exit(0);
286
+ }
287
+ // === Pull or Push ===
288
+ const options = {
289
+ dryRun: args.dryRun,
290
+ verbose: args.verbose,
291
+ quiet: args.quiet,
292
+ bwlimit: args.bwlimit,
293
+ noBackup: args.noBackup,
294
+ };
295
+ // Disable hooks from configs found via upward search
296
+ if (!config._explicitConfig && config._filePath !== join(process.cwd(), 'island-bridge.json')) {
297
+ if (config.hooks.beforeSync || config.hooks.afterSync) {
298
+ reporter.warn(`hooks ignored from inherited config ${config._filePath}`);
299
+ reporter.warn(`Use --config ${config._filePath} to explicitly enable hooks.`);
300
+ config.hooks = {};
301
+ }
302
+ }
303
+ // Run beforeSync hook
304
+ if (config.hooks.beforeSync) {
305
+ runHook('beforeSync', config.hooks.beforeSync, args.quiet, reporter);
306
+ }
307
+ const results = await syncAll(config, args.command, options, reporter);
308
+ // Run afterSync hook
309
+ if (config.hooks.afterSync) {
310
+ runHook('afterSync', config.hooks.afterSync, args.quiet, reporter);
311
+ }
312
+ // Record history
313
+ recordSync(config._filePath, args.command, results);
314
+ // Print summary
315
+ if (!args.quiet || args.json) {
316
+ reporter.summary(results);
317
+ if (!args.json && args.dryRun) {
318
+ reporter.info('(dry-run mode \u2014 no changes were made)');
319
+ }
320
+ }
321
+ if (args.json)
322
+ reporter.flush();
323
+ const hasFailed = results.some((r) => !r.success);
324
+ process.exit(hasFailed ? 1 : 0);
325
+ }
326
+ main();
327
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Lightweight CLI argument parser for island-bridge.
3
+ * Zero dependencies.
4
+ */
5
+ import type { ParsedArgs } from './types.js';
6
+ export declare function parseArgs(argv?: string[]): ParsedArgs;
@@ -0,0 +1,128 @@
1
+ export function parseArgs(argv = process.argv.slice(2)) {
2
+ const args = {
3
+ command: null,
4
+ subcommand: null,
5
+ dryRun: false,
6
+ verbose: false,
7
+ quiet: false,
8
+ json: false,
9
+ config: null,
10
+ env: null,
11
+ bwlimit: null,
12
+ select: false,
13
+ noBackup: false,
14
+ path: [],
15
+ help: false,
16
+ version: false,
17
+ // init-specific
18
+ host: null,
19
+ user: null,
20
+ paths: null,
21
+ // backup-specific
22
+ backupTimestamp: null,
23
+ keep: null,
24
+ };
25
+ for (let i = 0; i < argv.length; i++) {
26
+ const arg = argv[i];
27
+ switch (arg) {
28
+ case '--dry-run':
29
+ case '-n':
30
+ args.dryRun = true;
31
+ break;
32
+ case '--verbose':
33
+ case '-v':
34
+ args.verbose = true;
35
+ break;
36
+ case '--quiet':
37
+ case '-q':
38
+ args.quiet = true;
39
+ break;
40
+ case '--json':
41
+ args.json = true;
42
+ break;
43
+ case '--config':
44
+ case '-c':
45
+ args.config = argv[++i];
46
+ if (!args.config || args.config.startsWith('-'))
47
+ throw new Error('--config requires a file path');
48
+ break;
49
+ case '--env':
50
+ args.env = argv[++i];
51
+ if (!args.env || args.env.startsWith('-'))
52
+ throw new Error('--env requires a profile name');
53
+ break;
54
+ case '--bwlimit': {
55
+ const bwRaw = argv[++i];
56
+ if (!bwRaw || isNaN(Number(bwRaw))) {
57
+ throw new Error('--bwlimit requires a numeric value (KB/s)');
58
+ }
59
+ args.bwlimit = Number(bwRaw);
60
+ break;
61
+ }
62
+ case '--select':
63
+ case '-s':
64
+ args.select = true;
65
+ break;
66
+ case '--no-backup':
67
+ args.noBackup = true;
68
+ break;
69
+ case '--path':
70
+ {
71
+ const val = argv[++i];
72
+ if (!val || val.startsWith('-'))
73
+ throw new Error('--path requires a folder name');
74
+ args.path.push(val);
75
+ }
76
+ break;
77
+ case '--host':
78
+ args.host = argv[++i];
79
+ if (!args.host)
80
+ throw new Error('--host requires a value');
81
+ break;
82
+ case '--user':
83
+ args.user = argv[++i];
84
+ if (!args.user)
85
+ throw new Error('--user requires a value');
86
+ break;
87
+ case '--paths':
88
+ args.paths = argv[++i];
89
+ if (!args.paths)
90
+ throw new Error('--paths requires a value');
91
+ break;
92
+ case '--keep': {
93
+ const keepRaw = argv[++i];
94
+ if (!keepRaw || isNaN(Number(keepRaw))) {
95
+ throw new Error('--keep requires a numeric value');
96
+ }
97
+ args.keep = Number(keepRaw);
98
+ break;
99
+ }
100
+ case '--help':
101
+ case '-h':
102
+ args.help = true;
103
+ break;
104
+ case '--version':
105
+ case '-V':
106
+ args.version = true;
107
+ break;
108
+ default:
109
+ if (!arg.startsWith('-')) {
110
+ if (!args.command) {
111
+ args.command = arg;
112
+ }
113
+ else if (args.command === 'backup' && !args.subcommand) {
114
+ args.subcommand = arg;
115
+ }
116
+ else if (args.command === 'backup' && args.subcommand === 'restore' && !args.backupTimestamp) {
117
+ args.backupTimestamp = arg;
118
+ }
119
+ }
120
+ break;
121
+ }
122
+ }
123
+ if (args.verbose && args.quiet) {
124
+ throw new Error('Cannot use --verbose and --quiet together');
125
+ }
126
+ return args;
127
+ }
128
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/lib/args.ts"],"names":[],"mappings":"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"}