s3db.js 9.2.0 → 9.2.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.
- package/PLUGINS.md +453 -102
- package/README.md +31 -2
- package/dist/s3db.cjs.js +1099 -507
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +1099 -507
- package/dist/s3db.es.js.map +1 -1
- package/package.json +5 -5
- package/src/concerns/async-event-emitter.js +46 -0
- package/src/database.class.js +23 -0
- package/src/plugins/backup/base-backup-driver.class.js +119 -0
- package/src/plugins/backup/filesystem-backup-driver.class.js +254 -0
- package/src/plugins/backup/index.js +85 -0
- package/src/plugins/backup/multi-backup-driver.class.js +304 -0
- package/src/plugins/backup/s3-backup-driver.class.js +313 -0
- package/src/plugins/backup.plugin.js +375 -729
- package/src/plugins/backup.plugin.js.backup +1026 -0
- package/src/plugins/scheduler.plugin.js +0 -1
- package/src/resource.class.js +9 -6
package/PLUGINS.md
CHANGED
|
@@ -29,22 +29,68 @@
|
|
|
29
29
|
|
|
30
30
|
## 🚀 Getting Started with Plugins
|
|
31
31
|
|
|
32
|
-
Plugins extend s3db.js with additional functionality
|
|
32
|
+
Plugins extend s3db.js with additional functionality using a **driver-based architecture**. They can be used individually or combined for powerful workflows.
|
|
33
|
+
|
|
34
|
+
### Plugin Architecture
|
|
35
|
+
|
|
36
|
+
Most s3db.js plugins follow a **driver pattern** where you specify:
|
|
37
|
+
- **`driver`**: The storage/connection type (`filesystem`, `s3`, `multi`, etc.)
|
|
38
|
+
- **`config`**: Driver-specific configuration options
|
|
39
|
+
- **Plugin options**: Global settings that apply across drivers
|
|
33
40
|
|
|
34
41
|
### Basic Plugin Usage
|
|
35
42
|
|
|
36
43
|
```javascript
|
|
37
|
-
import { S3db, CachePlugin, CostsPlugin } from 's3db.js';
|
|
44
|
+
import { S3db, CachePlugin, BackupPlugin, CostsPlugin } from 's3db.js';
|
|
38
45
|
|
|
39
46
|
const s3db = new S3db({
|
|
40
|
-
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
41
|
-
plugins: [
|
|
42
|
-
new CachePlugin(),
|
|
43
|
-
CostsPlugin // Some plugins are static objects
|
|
44
|
-
]
|
|
47
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
await s3db.connect();
|
|
51
|
+
|
|
52
|
+
// Driver-based plugins (most common)
|
|
53
|
+
await s3db.usePlugin(new CachePlugin({
|
|
54
|
+
driver: 'memory',
|
|
55
|
+
config: { maxSize: 1000 }
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
await s3db.usePlugin(new BackupPlugin({
|
|
59
|
+
driver: 'filesystem',
|
|
60
|
+
config: { path: './backups/{date}/' }
|
|
61
|
+
}));
|
|
62
|
+
|
|
63
|
+
// Static utility plugins
|
|
64
|
+
await s3db.usePlugin(CostsPlugin);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Driver-Based Configuration Pattern
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// Single driver example
|
|
71
|
+
new SomePlugin({
|
|
72
|
+
driver: 'driverType',
|
|
73
|
+
config: {
|
|
74
|
+
// Driver-specific options
|
|
75
|
+
option1: 'value1',
|
|
76
|
+
option2: 'value2'
|
|
77
|
+
},
|
|
78
|
+
// Global plugin options
|
|
79
|
+
verbose: true,
|
|
80
|
+
timeout: 30000
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Multi-driver example
|
|
84
|
+
new SomePlugin({
|
|
85
|
+
driver: 'multi',
|
|
86
|
+
config: {
|
|
87
|
+
strategy: 'all',
|
|
88
|
+
destinations: [
|
|
89
|
+
{ driver: 'driver1', config: {...} },
|
|
90
|
+
{ driver: 'driver2', config: {...} }
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
});
|
|
48
94
|
```
|
|
49
95
|
|
|
50
96
|
### Plugin Types
|
|
@@ -60,24 +106,72 @@ await s3db.connect();
|
|
|
60
106
|
|
|
61
107
|
## 💾 Cache Plugin
|
|
62
108
|
|
|
63
|
-
Intelligent caching
|
|
109
|
+
**Driver-Based Caching System** - Intelligent caching that reduces S3 API calls and improves performance using configurable storage drivers.
|
|
64
110
|
|
|
65
|
-
|
|
111
|
+
> 🏎️ **Performance**: Dramatically reduces S3 costs and latency by caching frequently accessed data.
|
|
66
112
|
|
|
113
|
+
### 🚀 Quick Start
|
|
114
|
+
|
|
115
|
+
#### Memory Driver (Fast & Temporary)
|
|
67
116
|
```javascript
|
|
68
117
|
import { S3db, CachePlugin } from 's3db.js';
|
|
69
118
|
|
|
70
119
|
const s3db = new S3db({
|
|
71
120
|
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
72
|
-
plugins: [
|
|
121
|
+
plugins: [
|
|
122
|
+
new CachePlugin({
|
|
123
|
+
driver: 'memory',
|
|
124
|
+
ttl: 300000, // 5 minutes
|
|
125
|
+
maxSize: 1000, // Max 1000 items
|
|
126
|
+
config: {
|
|
127
|
+
evictionPolicy: 'lru',
|
|
128
|
+
enableStats: true
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
]
|
|
73
132
|
});
|
|
74
133
|
|
|
75
134
|
await s3db.connect();
|
|
76
135
|
|
|
77
|
-
// Cache
|
|
136
|
+
// Cache automatically intercepts read operations
|
|
78
137
|
const users = s3db.resource('users');
|
|
79
|
-
await users.count(); // Cached for
|
|
80
|
-
await users.list(); // Cached result
|
|
138
|
+
await users.count(); // ⚡ Cached for 5 minutes
|
|
139
|
+
await users.list(); // ⚡ Cached result
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### S3 Driver (Persistent & Shared)
|
|
143
|
+
```javascript
|
|
144
|
+
const s3db = new S3db({
|
|
145
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
146
|
+
plugins: [
|
|
147
|
+
new CachePlugin({
|
|
148
|
+
driver: 's3',
|
|
149
|
+
ttl: 1800000, // 30 minutes
|
|
150
|
+
config: {
|
|
151
|
+
bucket: 'my-cache-bucket', // Optional: separate bucket
|
|
152
|
+
keyPrefix: 'cache/', // Cache key prefix
|
|
153
|
+
storageClass: 'STANDARD' // S3 storage class
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
]
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Filesystem Driver (Local & Fast)
|
|
161
|
+
```javascript
|
|
162
|
+
const s3db = new S3db({
|
|
163
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp",
|
|
164
|
+
plugins: [
|
|
165
|
+
new CachePlugin({
|
|
166
|
+
driver: 'filesystem',
|
|
167
|
+
config: {
|
|
168
|
+
path: './cache',
|
|
169
|
+
partitionAware: true,
|
|
170
|
+
partitionStrategy: 'hierarchical'
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
});
|
|
81
175
|
```
|
|
82
176
|
|
|
83
177
|
### ⚙️ Configuration Parameters
|
|
@@ -4286,149 +4380,406 @@ stateMachine.on('action_error', ({ actionName, error, machineId, entityId }) =>
|
|
|
4286
4380
|
|
|
4287
4381
|
## 💾 Backup Plugin
|
|
4288
4382
|
|
|
4289
|
-
Comprehensive database backup and restore capabilities with
|
|
4383
|
+
**Driver-Based Backup System** - Comprehensive database backup and restore capabilities with configurable drivers, compression, encryption, and retention policies.
|
|
4290
4384
|
|
|
4291
|
-
|
|
4385
|
+
> ⚡ **NEW**: Driver-based architecture supports filesystem, S3, and multi-destination backups with flexible strategies.
|
|
4292
4386
|
|
|
4387
|
+
### 🚀 Quick Start
|
|
4388
|
+
|
|
4389
|
+
#### Single Driver (Filesystem)
|
|
4293
4390
|
```javascript
|
|
4294
4391
|
import { S3db, BackupPlugin } from 's3db.js';
|
|
4295
4392
|
|
|
4296
4393
|
const s3db = new S3db({
|
|
4297
|
-
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
4298
|
-
plugins: [
|
|
4299
|
-
new BackupPlugin({
|
|
4300
|
-
destinations: [
|
|
4301
|
-
{
|
|
4302
|
-
type: 'filesystem',
|
|
4303
|
-
path: './backups/{date}/',
|
|
4304
|
-
compression: 'gzip'
|
|
4305
|
-
}
|
|
4306
|
-
],
|
|
4307
|
-
retention: {
|
|
4308
|
-
daily: 7,
|
|
4309
|
-
weekly: 4,
|
|
4310
|
-
monthly: 12
|
|
4311
|
-
},
|
|
4312
|
-
onBackupComplete: (type, stats) => {
|
|
4313
|
-
console.log(`${type} backup completed:`, {
|
|
4314
|
-
size: `${Math.round(stats.size / 1024)}KB`,
|
|
4315
|
-
duration: `${stats.duration}ms`
|
|
4316
|
-
});
|
|
4317
|
-
}
|
|
4318
|
-
})
|
|
4319
|
-
]
|
|
4394
|
+
connectionString: "s3://ACCESS_KEY:SECRET_KEY@BUCKET_NAME/databases/myapp"
|
|
4320
4395
|
});
|
|
4321
4396
|
|
|
4322
4397
|
await s3db.connect();
|
|
4323
4398
|
|
|
4324
|
-
//
|
|
4325
|
-
const
|
|
4399
|
+
// Install backup plugin with filesystem driver
|
|
4400
|
+
const backupPlugin = new BackupPlugin({
|
|
4401
|
+
driver: 'filesystem',
|
|
4402
|
+
config: {
|
|
4403
|
+
path: './backups/{date}/',
|
|
4404
|
+
compression: 'gzip'
|
|
4405
|
+
},
|
|
4406
|
+
retention: {
|
|
4407
|
+
daily: 7,
|
|
4408
|
+
weekly: 4,
|
|
4409
|
+
monthly: 12
|
|
4410
|
+
}
|
|
4411
|
+
});
|
|
4412
|
+
|
|
4413
|
+
await s3db.usePlugin(backupPlugin);
|
|
4414
|
+
|
|
4415
|
+
// Create backups
|
|
4416
|
+
const fullBackup = await backupPlugin.backup('full');
|
|
4326
4417
|
console.log('Backup ID:', fullBackup.id);
|
|
4327
4418
|
|
|
4328
|
-
|
|
4419
|
+
// List and restore
|
|
4420
|
+
const backups = await backupPlugin.listBackups();
|
|
4421
|
+
await backupPlugin.restore(fullBackup.id);
|
|
4422
|
+
```
|
|
4329
4423
|
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4424
|
+
#### Single Driver (S3)
|
|
4425
|
+
```javascript
|
|
4426
|
+
const backupPlugin = new BackupPlugin({
|
|
4427
|
+
driver: 's3',
|
|
4428
|
+
config: {
|
|
4429
|
+
bucket: 'my-backup-bucket',
|
|
4430
|
+
path: 'database/{date}/',
|
|
4431
|
+
storageClass: 'STANDARD_IA',
|
|
4432
|
+
serverSideEncryption: 'AES256'
|
|
4433
|
+
},
|
|
4434
|
+
compression: 'gzip',
|
|
4435
|
+
verification: true
|
|
4436
|
+
});
|
|
4437
|
+
```
|
|
4333
4438
|
|
|
4334
|
-
|
|
4335
|
-
|
|
4439
|
+
#### Multi-Driver (Multiple Destinations)
|
|
4440
|
+
```javascript
|
|
4441
|
+
const backupPlugin = new BackupPlugin({
|
|
4442
|
+
driver: 'multi',
|
|
4443
|
+
config: {
|
|
4444
|
+
strategy: 'all', // 'all', 'any', 'priority'
|
|
4445
|
+
destinations: [
|
|
4446
|
+
{
|
|
4447
|
+
driver: 'filesystem',
|
|
4448
|
+
config: { path: '/local/backups/{date}/' }
|
|
4449
|
+
},
|
|
4450
|
+
{
|
|
4451
|
+
driver: 's3',
|
|
4452
|
+
config: {
|
|
4453
|
+
bucket: 'remote-backups',
|
|
4454
|
+
storageClass: 'GLACIER'
|
|
4455
|
+
}
|
|
4456
|
+
}
|
|
4457
|
+
]
|
|
4458
|
+
}
|
|
4459
|
+
});
|
|
4336
4460
|
```
|
|
4337
4461
|
|
|
4338
|
-
###
|
|
4462
|
+
### 🎯 Driver Types
|
|
4339
4463
|
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4464
|
+
#### 📁 Filesystem Driver
|
|
4465
|
+
**Perfect for**: Local backups, network storage, development
|
|
4466
|
+
|
|
4467
|
+
```javascript
|
|
4468
|
+
{
|
|
4469
|
+
driver: 'filesystem',
|
|
4470
|
+
config: {
|
|
4471
|
+
path: '/backups/{date}/', // Template path with variables
|
|
4472
|
+
permissions: 0o644, // File permissions
|
|
4473
|
+
directoryPermissions: 0o755 // Directory permissions
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
```
|
|
4477
|
+
|
|
4478
|
+
**Path Templates:**
|
|
4479
|
+
- `{date}` → `2024-03-15`
|
|
4480
|
+
- `{time}` → `14-30-45`
|
|
4481
|
+
- `{year}` → `2024`
|
|
4482
|
+
- `{month}` → `03`
|
|
4483
|
+
- `{day}` → `15`
|
|
4484
|
+
- `{backupId}` → `full-2024-03-15T14-30-45-abc123`
|
|
4485
|
+
- `{type}` → `full` | `incremental`
|
|
4354
4486
|
|
|
4355
|
-
|
|
4487
|
+
#### ☁️ S3 Driver
|
|
4488
|
+
**Perfect for**: Cloud backups, long-term storage, disaster recovery
|
|
4356
4489
|
|
|
4357
|
-
#### Filesystem
|
|
4358
4490
|
```javascript
|
|
4359
4491
|
{
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4492
|
+
driver: 's3',
|
|
4493
|
+
config: {
|
|
4494
|
+
bucket: 'my-backup-bucket', // S3 bucket (optional, uses database bucket)
|
|
4495
|
+
path: 'backups/{date}/', // S3 key prefix with templates
|
|
4496
|
+
storageClass: 'STANDARD_IA', // S3 storage class
|
|
4497
|
+
serverSideEncryption: 'AES256', // Server-side encryption
|
|
4498
|
+
client: customS3Client // Custom S3 client (optional)
|
|
4499
|
+
}
|
|
4363
4500
|
}
|
|
4364
4501
|
```
|
|
4365
4502
|
|
|
4366
|
-
|
|
4503
|
+
**Storage Classes:** `STANDARD`, `STANDARD_IA`, `ONEZONE_IA`, `REDUCED_REDUNDANCY`, `GLACIER`, `DEEP_ARCHIVE`
|
|
4504
|
+
|
|
4505
|
+
#### 🔄 Multi Driver
|
|
4506
|
+
**Perfect for**: Redundancy, hybrid storage, complex backup strategies
|
|
4507
|
+
|
|
4367
4508
|
```javascript
|
|
4368
4509
|
{
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4510
|
+
driver: 'multi',
|
|
4511
|
+
config: {
|
|
4512
|
+
strategy: 'all', // Backup strategy
|
|
4513
|
+
concurrency: 3, // Max concurrent uploads
|
|
4514
|
+
destinations: [
|
|
4515
|
+
{ driver: 'filesystem', config: {...} },
|
|
4516
|
+
{ driver: 's3', config: {...} }
|
|
4517
|
+
]
|
|
4518
|
+
}
|
|
4374
4519
|
}
|
|
4375
4520
|
```
|
|
4376
4521
|
|
|
4377
|
-
|
|
4522
|
+
**Strategies:**
|
|
4523
|
+
- **`all`**: Upload to all destinations (fail if any fails)
|
|
4524
|
+
- **`any`**: Upload to all, succeed if at least one succeeds
|
|
4525
|
+
- **`priority`**: Try destinations in order, stop on first success
|
|
4526
|
+
|
|
4527
|
+
### 🔧 Configuration Parameters
|
|
4528
|
+
|
|
4529
|
+
| Parameter | Type | Default | Description |
|
|
4530
|
+
|-----------|------|---------|-------------|
|
|
4531
|
+
| **`driver`** | `string` | `'filesystem'` | Driver type: `filesystem`, `s3`, `multi` |
|
|
4532
|
+
| **`config`** | `object` | `{}` | Driver-specific configuration |
|
|
4533
|
+
| `retention` | `object` | `{}` | Retention policy (GFS rotation) |
|
|
4534
|
+
| `include` | `array` | `null` | Resources to include (null = all) |
|
|
4535
|
+
| `exclude` | `array` | `[]` | Resources to exclude |
|
|
4536
|
+
| `compression` | `string` | `'gzip'` | `'none'`, `'gzip'`, `'brotli'`, `'deflate'` |
|
|
4537
|
+
| `encryption` | `object` | `null` | Encryption configuration |
|
|
4538
|
+
| `verification` | `boolean` | `true` | Verify backup integrity |
|
|
4539
|
+
| `tempDir` | `string` | `'./tmp/backups'` | Temporary working directory |
|
|
4540
|
+
| `verbose` | `boolean` | `false` | Enable detailed logging |
|
|
4541
|
+
|
|
4542
|
+
### 🎛️ Backup Types & Operations
|
|
4543
|
+
|
|
4544
|
+
```javascript
|
|
4545
|
+
// Full backup - complete database snapshot
|
|
4546
|
+
const fullBackup = await backupPlugin.backup('full');
|
|
4547
|
+
console.log(`✓ Full backup: ${fullBackup.id} (${fullBackup.size} bytes)`);
|
|
4548
|
+
|
|
4549
|
+
// Incremental backup - changes since last backup
|
|
4550
|
+
const incrementalBackup = await backupPlugin.backup('incremental');
|
|
4551
|
+
|
|
4552
|
+
// Selective backup - specific resources only
|
|
4553
|
+
const selectiveBackup = await backupPlugin.backup('full', {
|
|
4554
|
+
resources: ['users', 'posts']
|
|
4555
|
+
});
|
|
4556
|
+
|
|
4557
|
+
// Custom backup type
|
|
4558
|
+
const customBackup = await backupPlugin.backup('weekly-snapshot');
|
|
4559
|
+
```
|
|
4560
|
+
|
|
4561
|
+
### 📋 Backup Management
|
|
4378
4562
|
|
|
4379
4563
|
```javascript
|
|
4380
|
-
//
|
|
4381
|
-
const
|
|
4564
|
+
// List all backups
|
|
4565
|
+
const allBackups = await backupPlugin.listBackups();
|
|
4566
|
+
|
|
4567
|
+
// List with filters
|
|
4568
|
+
const recentBackups = await backupPlugin.listBackups({
|
|
4569
|
+
limit: 10,
|
|
4570
|
+
prefix: 'full-2024'
|
|
4571
|
+
});
|
|
4382
4572
|
|
|
4383
|
-
//
|
|
4384
|
-
const
|
|
4573
|
+
// Get backup status
|
|
4574
|
+
const status = await backupPlugin.getBackupStatus(backupId);
|
|
4575
|
+
console.log(`Status: ${status.status}, Size: ${status.size}`);
|
|
4385
4576
|
|
|
4386
|
-
//
|
|
4387
|
-
|
|
4577
|
+
// Restore operations
|
|
4578
|
+
await backupPlugin.restore(backupId); // Full restore
|
|
4579
|
+
await backupPlugin.restore(backupId, { overwrite: true }); // Overwrite existing
|
|
4580
|
+
await backupPlugin.restore(backupId, {
|
|
4581
|
+
resources: ['users']
|
|
4582
|
+
}); // Selective restore
|
|
4388
4583
|
```
|
|
4389
4584
|
|
|
4390
|
-
###
|
|
4585
|
+
### 🔄 Legacy Format Support
|
|
4586
|
+
|
|
4587
|
+
The plugin automatically converts legacy `destinations` format:
|
|
4588
|
+
|
|
4589
|
+
```javascript
|
|
4590
|
+
// ❌ Old format (still works)
|
|
4591
|
+
new BackupPlugin({
|
|
4592
|
+
destinations: [
|
|
4593
|
+
{ type: 'filesystem', path: '/backups/' }
|
|
4594
|
+
]
|
|
4595
|
+
});
|
|
4596
|
+
|
|
4597
|
+
// ✅ Automatically converted to:
|
|
4598
|
+
// driver: 'multi'
|
|
4599
|
+
// config: { destinations: [{ driver: 'filesystem', config: { path: '/backups/' } }] }
|
|
4600
|
+
```
|
|
4601
|
+
|
|
4602
|
+
### 📊 Retention Policies (GFS)
|
|
4603
|
+
|
|
4604
|
+
Grandfather-Father-Son rotation keeps backups efficiently:
|
|
4391
4605
|
|
|
4392
4606
|
```javascript
|
|
4393
4607
|
retention: {
|
|
4394
|
-
daily: 7, // Keep daily backups
|
|
4395
|
-
weekly: 4, // Keep weekly backups
|
|
4396
|
-
monthly: 12, // Keep monthly backups
|
|
4397
|
-
yearly: 3 // Keep yearly backups
|
|
4608
|
+
daily: 7, // Keep 7 daily backups
|
|
4609
|
+
weekly: 4, // Keep 4 weekly backups
|
|
4610
|
+
monthly: 12, // Keep 12 monthly backups
|
|
4611
|
+
yearly: 3 // Keep 3 yearly backups
|
|
4398
4612
|
}
|
|
4399
4613
|
```
|
|
4400
4614
|
|
|
4401
|
-
###
|
|
4615
|
+
### 🎣 Hooks & Events
|
|
4402
4616
|
|
|
4403
4617
|
```javascript
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
await
|
|
4412
|
-
|
|
4413
|
-
|
|
4618
|
+
const backupPlugin = new BackupPlugin({
|
|
4619
|
+
driver: 'filesystem',
|
|
4620
|
+
config: { path: './backups/' },
|
|
4621
|
+
|
|
4622
|
+
// Lifecycle hooks
|
|
4623
|
+
onBackupStart: async (type, { backupId }) => {
|
|
4624
|
+
console.log(`🚀 Starting ${type} backup: ${backupId}`);
|
|
4625
|
+
await notifySlack(`Backup ${backupId} started`);
|
|
4626
|
+
},
|
|
4627
|
+
|
|
4628
|
+
onBackupComplete: async (type, stats) => {
|
|
4629
|
+
console.log(`✅ ${type} backup completed:`, {
|
|
4630
|
+
id: stats.backupId,
|
|
4631
|
+
size: `${Math.round(stats.size / 1024)}KB`,
|
|
4632
|
+
duration: `${stats.duration}ms`,
|
|
4633
|
+
destinations: stats.driverInfo
|
|
4634
|
+
});
|
|
4635
|
+
},
|
|
4636
|
+
|
|
4637
|
+
onBackupError: async (type, { backupId, error }) => {
|
|
4638
|
+
console.error(`❌ Backup ${backupId} failed:`, error.message);
|
|
4639
|
+
await alertOps(error);
|
|
4640
|
+
}
|
|
4641
|
+
});
|
|
4642
|
+
|
|
4643
|
+
// Event listeners
|
|
4644
|
+
backupPlugin.on('backup_start', ({ id, type }) => {
|
|
4645
|
+
updateDashboard(`Backup ${id} started`);
|
|
4646
|
+
});
|
|
4647
|
+
|
|
4648
|
+
backupPlugin.on('backup_complete', ({ id, type, size, duration }) => {
|
|
4649
|
+
metrics.record('backup.completed', { type, size, duration });
|
|
4650
|
+
});
|
|
4651
|
+
|
|
4652
|
+
backupPlugin.on('restore_complete', ({ id, restored }) => {
|
|
4653
|
+
console.log(`Restored ${restored.length} resources from ${id}`);
|
|
4654
|
+
});
|
|
4414
4655
|
```
|
|
4415
4656
|
|
|
4416
|
-
###
|
|
4657
|
+
### 🔒 Advanced Security
|
|
4417
4658
|
|
|
4418
4659
|
```javascript
|
|
4419
|
-
|
|
4420
|
-
|
|
4660
|
+
const secureBackupPlugin = new BackupPlugin({
|
|
4661
|
+
driver: 's3',
|
|
4662
|
+
config: {
|
|
4663
|
+
bucket: 'secure-backups',
|
|
4664
|
+
storageClass: 'STANDARD_IA',
|
|
4665
|
+
serverSideEncryption: 'aws:kms',
|
|
4666
|
+
kmsKeyId: 'arn:aws:kms:region:account:key/key-id'
|
|
4667
|
+
},
|
|
4668
|
+
|
|
4669
|
+
// Client-side encryption (before upload)
|
|
4670
|
+
encryption: {
|
|
4671
|
+
algorithm: 'AES-256-GCM',
|
|
4672
|
+
key: process.env.BACKUP_ENCRYPTION_KEY,
|
|
4673
|
+
keyDerivation: {
|
|
4674
|
+
algorithm: 'PBKDF2',
|
|
4675
|
+
iterations: 100000,
|
|
4676
|
+
salt: 'backup-salt-2024'
|
|
4677
|
+
}
|
|
4678
|
+
},
|
|
4679
|
+
|
|
4680
|
+
// Integrity verification
|
|
4681
|
+
verification: true,
|
|
4682
|
+
|
|
4683
|
+
// Compression for efficiency
|
|
4684
|
+
compression: 'gzip'
|
|
4421
4685
|
});
|
|
4686
|
+
```
|
|
4422
4687
|
|
|
4423
|
-
|
|
4424
|
-
|
|
4688
|
+
### 🚀 Production Examples
|
|
4689
|
+
|
|
4690
|
+
#### Enterprise Multi-Region Setup
|
|
4691
|
+
```javascript
|
|
4692
|
+
const enterpriseBackup = new BackupPlugin({
|
|
4693
|
+
driver: 'multi',
|
|
4694
|
+
config: {
|
|
4695
|
+
strategy: 'all',
|
|
4696
|
+
destinations: [
|
|
4697
|
+
{
|
|
4698
|
+
driver: 's3',
|
|
4699
|
+
config: {
|
|
4700
|
+
bucket: 'backups-us-east-1',
|
|
4701
|
+
path: 'production/{date}/',
|
|
4702
|
+
storageClass: 'STANDARD_IA'
|
|
4703
|
+
}
|
|
4704
|
+
},
|
|
4705
|
+
{
|
|
4706
|
+
driver: 's3',
|
|
4707
|
+
config: {
|
|
4708
|
+
bucket: 'backups-eu-west-1',
|
|
4709
|
+
path: 'production/{date}/',
|
|
4710
|
+
storageClass: 'STANDARD_IA'
|
|
4711
|
+
}
|
|
4712
|
+
},
|
|
4713
|
+
{
|
|
4714
|
+
driver: 'filesystem',
|
|
4715
|
+
config: {
|
|
4716
|
+
path: '/mnt/backup-nas/s3db/{date}/'
|
|
4717
|
+
}
|
|
4718
|
+
}
|
|
4719
|
+
]
|
|
4720
|
+
},
|
|
4721
|
+
retention: {
|
|
4722
|
+
daily: 30,
|
|
4723
|
+
weekly: 12,
|
|
4724
|
+
monthly: 24,
|
|
4725
|
+
yearly: 7
|
|
4726
|
+
},
|
|
4727
|
+
verification: true,
|
|
4728
|
+
compression: 'gzip'
|
|
4425
4729
|
});
|
|
4730
|
+
```
|
|
4426
4731
|
|
|
4427
|
-
|
|
4428
|
-
|
|
4732
|
+
#### Development Quick Backup
|
|
4733
|
+
```javascript
|
|
4734
|
+
const devBackup = new BackupPlugin({
|
|
4735
|
+
driver: 'filesystem',
|
|
4736
|
+
config: {
|
|
4737
|
+
path: './dev-backups/{date}/'
|
|
4738
|
+
},
|
|
4739
|
+
compression: 'none',
|
|
4740
|
+
verification: false,
|
|
4741
|
+
verbose: true,
|
|
4742
|
+
retention: { daily: 3 }
|
|
4429
4743
|
});
|
|
4430
4744
|
```
|
|
4431
4745
|
|
|
4746
|
+
### 🎯 CLI Integration
|
|
4747
|
+
|
|
4748
|
+
The BackupPlugin works with s3db CLI commands:
|
|
4749
|
+
|
|
4750
|
+
```bash
|
|
4751
|
+
# Create backups
|
|
4752
|
+
s3db backup full --connection "s3://key:secret@bucket"
|
|
4753
|
+
s3db backup incremental --connection "s3://key:secret@bucket"
|
|
4754
|
+
|
|
4755
|
+
# List and status
|
|
4756
|
+
s3db backup --list --connection "s3://key:secret@bucket"
|
|
4757
|
+
s3db backup --status backup-id --connection "s3://key:secret@bucket"
|
|
4758
|
+
|
|
4759
|
+
# Restore operations
|
|
4760
|
+
s3db restore backup-id --connection "s3://key:secret@bucket"
|
|
4761
|
+
s3db restore backup-id --overwrite --connection "s3://key:secret@bucket"
|
|
4762
|
+
```
|
|
4763
|
+
|
|
4764
|
+
> **Note**: CLI requires the BackupPlugin to be installed in the database instance.
|
|
4765
|
+
|
|
4766
|
+
### 🔍 Driver Information
|
|
4767
|
+
|
|
4768
|
+
```javascript
|
|
4769
|
+
// Get driver details
|
|
4770
|
+
const driverInfo = backupPlugin.driver.getStorageInfo();
|
|
4771
|
+
console.log('Driver type:', driverInfo.type);
|
|
4772
|
+
console.log('Configuration:', driverInfo.config);
|
|
4773
|
+
|
|
4774
|
+
// Multi-driver details
|
|
4775
|
+
if (driverInfo.type === 'multi') {
|
|
4776
|
+
console.log('Strategy:', driverInfo.strategy);
|
|
4777
|
+
driverInfo.destinations.forEach((dest, i) => {
|
|
4778
|
+
console.log(`Destination ${i}:`, dest.driver, dest.info);
|
|
4779
|
+
});
|
|
4780
|
+
}
|
|
4781
|
+
```
|
|
4782
|
+
|
|
4432
4783
|
---
|
|
4433
4784
|
|
|
4434
4785
|
## ⏰ Scheduler Plugin
|