mongodb-backup-service 1.0.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/.env.example ADDED
@@ -0,0 +1,25 @@
1
+ MONGO_URI=mongodb+srv://<user>:<password>@cluster.mongodb.net/<database>?retryWrites=true&w=majority
2
+
3
+ BACKUP_PROJECT_NAME=My Project
4
+
5
+ BACKUP_STORAGE_PATH=./backups
6
+
7
+ BACKUP_SCHEDULE_TYPE=daily
8
+ BACKUP_SCHEDULE_TIME=02:00
9
+ BACKUP_TIMEZONE=UTC
10
+
11
+ BACKUP_EXCEL_ENABLED=true
12
+ BACKUP_EXCLUDE_COLLECTIONS=sessions,temporaryLogs
13
+
14
+ BACKUP_RETENTION_ENABLED=true
15
+ BACKUP_RETENTION_DAYS=30
16
+
17
+ BACKUP_EMAIL_ENABLED=true
18
+ BACKUP_EMAIL_TO=admin@example.com
19
+
20
+ BACKUP_SMTP_HOST=smtp.gmail.com
21
+ BACKUP_SMTP_PORT=587
22
+ BACKUP_SMTP_SECURE=false
23
+ BACKUP_SMTP_USER=my-email@gmail.com
24
+ BACKUP_SMTP_PASSWORD=my-app-password
25
+ BACKUP_EMAIL_FROM=backup-service@myproject.com
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abishek K
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # mongodb-backup-service
2
+
3
+ Reusable Node.js service for automated MongoDB backups with scheduling, startup recovery, Excel export, retention, email notifications, and backup locking.
4
+
5
+ ## Key Features
6
+
7
+ - **MongoDB Atlas Backup**: Automated `mongodump` execution supporting local and Atlas clusters.
8
+ - **Gzip Archive**: Compresses database dumps natively via `mongodump --gzip`.
9
+ - **Excel Export**: Secondary human-readable `.xlsx` export, streaming large collections efficiently.
10
+ - **Collection Exclusion**: Skip unnecessary collections (e.g., sessions, temporary logs) from the Excel export.
11
+ - **Advanced Scheduling**: Supports `daily`, `weekly`, and `monthly` CRON scheduling.
12
+ - **Configurable Timezone**: Run backups according to your local timezone (e.g., `Asia/Kolkata`, `America/New_York`).
13
+ - **Startup Missed-Backup Recovery**: Automatically detects and recovers missed scheduled backups if the Node.js service was offline.
14
+ - **Backup Locking**: Ensures exactly-once execution and prevents concurrent backup collisions.
15
+ - **Retention Cleanup**: Automatically prunes old backups to save storage space (keeps the N most recent backups).
16
+ - **Email Notifications**: Detailed success/failure reports via SMTP, separating MongoDB and Excel statuses.
17
+ - **Local Storage Abstraction**: Clean, organized date-based directory structure for all artefacts.
18
+ - **CLI Tool**: Built-in `mongodb-backup` command for manual triggers and status checks.
19
+ - **Metadata Tracking**: Detailed `metadata.json` for every backup run.
20
+ - **Graceful Shutdown**: Safe `SIGINT`/`SIGTERM` handling to stop the scheduler cleanly.
21
+
22
+ ## Why this package exists
23
+
24
+ Managing automated database backups in Node.js applications often leads to scattered shell scripts and cron jobs that lack proper error handling, monitoring, and idempotency. `mongodb-backup-service` provides a robust, in-process solution that you can seamlessly integrate into your existing Express or Node.js backend. It treats backups as a first-class feature with strong guarantees against duplicate runs and missed schedules.
25
+
26
+ ## Architecture
27
+
28
+ ```mermaid
29
+ graph TD
30
+ A[Express / Node Backend] -->|backupService.start| B(DatabaseBackupService)
31
+ B --> C{Scheduler}
32
+ C -->|Trigger| D(BackupManager)
33
+ B -->|Startup Recovery| D
34
+
35
+ D -->|1. Acquire Lock| E[BackupLock]
36
+ D -->|2. Dump| F[MongoDump]
37
+ D -->|3. Export| G[ExcelExporter]
38
+ D -->|4. Clean| H[RetentionManager]
39
+ D -->|5. Notify| I[EmailNotifier]
40
+
41
+ F --> J[(Storage: .gz)]
42
+ G --> K[(Storage: .xlsx)]
43
+
44
+ subgraph Storage Directory
45
+ J
46
+ K
47
+ L[metadata.json]
48
+ end
49
+
50
+ D -->|Writes| L
51
+ ```
52
+
53
+ ## Requirements
54
+
55
+ - **Node.js**: `>=18.0.0`
56
+ - **MongoDB Database Tools**: `mongodump` must be installed on the host system and available in the system `PATH`.
57
+ - **MongoDB Connection**: A valid MongoDB URI (supports MongoDB Atlas).
58
+ - **SMTP Server**: Required only if email notifications are enabled.
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ npm install mongodb-backup-service
64
+ ```
65
+
66
+ ## Configuration
67
+
68
+ The service is configured using a JavaScript object, typically populated via environment variables (`.env`). Copy `.env.example` to `.env` in your project root.
69
+
70
+ | Variable | Required | Description | Example Safe Value |
71
+ |---|---|---|---|
72
+ | `MONGO_URI` | Yes | MongoDB connection string. | `mongodb+srv://<user>:<pwd>@cluster...` |
73
+ | `BACKUP_PROJECT_NAME` | No | Identifier for logs and emails. | `My Project` |
74
+ | `BACKUP_STORAGE_PATH` | No | Local directory to save backups. | `./backups` |
75
+ | `BACKUP_SCHEDULE_TYPE` | No | `daily`, `weekly`, or `monthly`. | `daily` |
76
+ | `BACKUP_SCHEDULE_TIME` | No | Time to run backup (HH:MM). | `02:00` |
77
+ | `BACKUP_TIMEZONE` | No | Valid IANA Timezone. | `UTC` |
78
+ | `BACKUP_EXCEL_ENABLED` | No | Enable/disable Excel export. | `true` |
79
+ | `BACKUP_EXCLUDE_COLLECTIONS` | No | Comma-separated collections to skip in Excel. | `sessions,temporaryLogs` |
80
+ | `BACKUP_RETENTION_ENABLED` | No | Enable/disable cleanup of old backups. | `true` |
81
+ | `BACKUP_RETENTION_DAYS` | No | Number of most recent backups to keep. | `30` |
82
+ | `BACKUP_EMAIL_ENABLED` | No | Enable/disable SMTP notifications. | `true` |
83
+ | `BACKUP_EMAIL_TO` | No | Alert recipient address. | `admin@example.com` |
84
+ | `BACKUP_SMTP_HOST` | No | SMTP server hostname. | `smtp.gmail.com` |
85
+ | `BACKUP_SMTP_PORT` | No | SMTP port (e.g., 587, 465). | `587` |
86
+ | `BACKUP_SMTP_SECURE` | No | Use TLS (true for 465, false for 587). | `false` |
87
+ | `BACKUP_SMTP_USER` | No | SMTP username. | `user@gmail.com` |
88
+ | `BACKUP_SMTP_PASSWORD` | No | SMTP password/App Password. | `xxxx-xxxx-xxxx-xxxx` |
89
+ | `BACKUP_EMAIL_FROM` | No | Sender address for alerts. | `backup@myproject.com` |
90
+
91
+ > **Security Note:** Never commit your real `.env` file containing database credentials or SMTP passwords to version control.
92
+
93
+ ## Express Backend Integration
94
+
95
+ Integrate the backup service into your existing Node.js or Express application lifecycle:
96
+
97
+ ```javascript
98
+ require('dotenv').config();
99
+ const express = require('express');
100
+ const backupService = require('mongodb-backup-service');
101
+
102
+ const app = express();
103
+
104
+ // 1. Configure and start the backup service
105
+ backupService.start({
106
+ mongoUri: process.env.MONGO_URI,
107
+ projectName: process.env.BACKUP_PROJECT_NAME || 'My App',
108
+ storage: { path: process.env.BACKUP_STORAGE_PATH || './backups' },
109
+ schedule: {
110
+ type: process.env.BACKUP_SCHEDULE_TYPE || 'daily',
111
+ time: process.env.BACKUP_SCHEDULE_TIME || '02:00',
112
+ timezone: process.env.BACKUP_TIMEZONE || 'UTC'
113
+ },
114
+ // ... include excel, retention, and email configs ...
115
+ });
116
+
117
+ const server = app.listen(3000, () => {
118
+ console.log('Server running on port 3000');
119
+ });
120
+
121
+ // 2. Ensure graceful shutdown
122
+ const shutdown = () => {
123
+ console.log('Shutting down server...');
124
+ backupService.stop(); // Stops the scheduler cleanly
125
+ server.close(() => {
126
+ process.exit(0);
127
+ });
128
+ };
129
+
130
+ process.on('SIGINT', shutdown);
131
+ process.on('SIGTERM', shutdown);
132
+ ```
133
+
134
+ ## Scheduling
135
+
136
+ The internal scheduler uses standard cron expressions based on your configuration:
137
+ - `daily`: Runs every day at the specified `time`.
138
+ - `weekly`: Requires a `day` (e.g., `sunday`) and `time`.
139
+ - `monthly`: Requires a `day` (e.g., `1` for the 1st of the month) and `time`.
140
+
141
+ The `timezone` parameter ensures that Daylight Saving Time and regional offsets are respected.
142
+
143
+ ## Startup Missed-Backup Recovery
144
+
145
+ If your Node.js application is stopped or crashes during the scheduled backup window, the backup will not run while the process is offline.
146
+
147
+ To prevent data gaps, `mongodb-backup-service` performs a **Startup Recovery Check** when you call `backupService.start()`. It calculates the date of the most recently expected scheduled backup. If the backup directory for that date is missing, or its metadata indicates it did not complete successfully, the service will immediately trigger a recovery backup in the background.
148
+
149
+ ## Backup Locking / Duplicate Protection
150
+
151
+ To prevent overlapping backups (e.g., a manual trigger coinciding with a scheduled run, or a recovery run overlapping with a cron tick), the service utilizes a file-based lock (`.backup.lock`).
152
+
153
+ This ensures **exactly-once execution**. If a backup is already in progress, any subsequent trigger (cron, recovery, or manual) will be safely rejected, logging a warning rather than corrupting the archive.
154
+
155
+ ## Backup Directory Structure
156
+
157
+ Backups are neatly organized by date (in the configured timezone) within the storage path.
158
+
159
+ ```text
160
+ backups/
161
+ └── 2026-09-10/
162
+ ├── mongodb.archive.gz # Compressed mongodump output
163
+ ├── database.xlsx # Human-readable export
164
+ └── metadata.json # Execution report
165
+ ```
166
+
167
+ ### Metadata
168
+
169
+ The `metadata.json` file tracks the execution status without exposing any sensitive credentials. It contains:
170
+ - `projectName` and `backupDate`
171
+ - `startedAt`, `completedAt`, and `durationMs`
172
+ - `status`: Overall backup status (`success` or `failed`)
173
+ - `mongoDump`: Specific status, filename, and error (if any)
174
+ - `excel`: Specific status, filename, and error (if any)
175
+
176
+ ## Excel Export
177
+
178
+ When `excel.enabled` is `true`, the service exports your database to `database.xlsx`:
179
+ - **One Sheet per Collection**: Each MongoDB collection becomes a separate worksheet.
180
+ - **Dynamic Columns**: Columns are discovered dynamically as documents are streamed.
181
+ - **Data Types**: Dates are preserved. `ObjectId`s are converted to strings. Nested objects and arrays are flattened into JSON strings to fit in Excel cells.
182
+ - **Exclusions**: Use `excludeCollections` to skip large or irrelevant collections (like sessions).
183
+
184
+ ## Retention
185
+
186
+ When `retention.enabled` is `true`, the `RetentionManager` runs at the end of every successful backup. It scans the storage directory and keeps the `N` most recent backup directories (where `N` is `retention.days`), deleting older directories to prevent disk exhaustion.
187
+
188
+ ## Email Notifications
189
+
190
+ When `email.enabled` is `true`, an SMTP email is dispatched upon backup completion. The email clearly delineates the overall status, the MongoDB dump status, and the Excel export status.
191
+
192
+ If the email notification itself fails to send (e.g., invalid SMTP credentials), the error is logged, but it **does not** mark the backup as failed in `metadata.json`, ensuring the actual data archiving process remains resilient.
193
+
194
+ ## CLI
195
+
196
+ The package includes a command-line interface for manual administration. Ensure your `.env` is present in the directory where you run the commands.
197
+
198
+ ```bash
199
+ # Manually trigger a backup right now
200
+ npx mongodb-backup backup
201
+
202
+ # Check the status of today's backup
203
+ npx mongodb-backup status
204
+
205
+ # List all available backup dates on disk
206
+ npx mongodb-backup list
207
+
208
+ # Manually trigger retention cleanup
209
+ npx mongodb-backup cleanup
210
+
211
+ # View help
212
+ npx mongodb-backup help
213
+ ```
214
+
215
+ ## Security
216
+
217
+ - **`.env`**: Always add `.env` and `backups/` to your `.gitignore`.
218
+ - **Metadata**: No MongoDB URIs, passwords, or SMTP credentials are ever written to `metadata.json` or log files.
219
+ - **Storage**: Ensure the host environment has appropriate file permissions for the `backups/` directory.
220
+
221
+ ## Testing
222
+
223
+ The package includes a comprehensive suite of unit and integration tests covering scheduling, locking, database operations, and failure scenarios.
224
+
225
+ ```bash
226
+ npm test
227
+ ```
228
+ *(Currently 60/60 tests passing)*
229
+
230
+ ## V1 Scope
231
+
232
+ Version 1 is designed specifically for single-node or replica-set MongoDB deployments (including Atlas) backing Node.js applications, utilizing local disk storage for artefacts and standard SMTP for notifications.
233
+
234
+ ## Limitations
235
+
236
+ - **System Dependency**: Requires `mongodump` binary to be installed on the host machine.
237
+ - **Storage**: Currently only supports local filesystem storage.
238
+ - **Restore**: Does not currently include automated `mongorestore` functionality; archives must be restored manually.
239
+
240
+ ## Roadmap
241
+
242
+ *Future considerations (Not yet implemented):*
243
+ - Support for Cloud Storage (AWS S3, Google Drive, Azure Blob).
244
+ - Automated restore workflows.
245
+ - Webhook integrations (Slack/Discord alerts).
246
+
247
+ ## License
248
+
249
+ [MIT](LICENSE)
package/bin/cli.js ADDED
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('dotenv').config();
4
+ const backup = require('../src/index');
5
+
6
+ const args = process.argv.slice(2);
7
+ const command = args[0] || 'help';
8
+
9
+ // Load config from environment for CLI usage
10
+ const config = {
11
+ mongoUri: process.env.MONGO_URI,
12
+ projectName: process.env.BACKUP_PROJECT_NAME || 'CLI Backup',
13
+
14
+ storage: {
15
+ path: process.env.BACKUP_STORAGE_PATH || './backups'
16
+ },
17
+
18
+ schedule: {
19
+ type: process.env.BACKUP_SCHEDULE_TYPE || 'daily',
20
+ time: process.env.BACKUP_SCHEDULE_TIME || '02:00',
21
+ timezone: process.env.BACKUP_TIMEZONE || Intl.DateTimeFormat().resolvedOptions().timeZone
22
+ },
23
+
24
+ excel: {
25
+ enabled: process.env.BACKUP_EXCEL_ENABLED === 'true',
26
+ excludeCollections: (process.env.BACKUP_EXCLUDE_COLLECTIONS || '').split(',').filter(c => c.trim() !== '')
27
+ },
28
+
29
+ retention: {
30
+ enabled: process.env.BACKUP_RETENTION_ENABLED === 'true',
31
+ days: parseInt(process.env.BACKUP_RETENTION_DAYS || '30', 10)
32
+ },
33
+
34
+ // ── Email — was missing entirely; caused email.enabled to always be false ──
35
+ email: {
36
+ enabled: process.env.BACKUP_EMAIL_ENABLED === 'true',
37
+ to: process.env.BACKUP_EMAIL_TO || '',
38
+ from: process.env.BACKUP_EMAIL_FROM || '',
39
+ host: process.env.BACKUP_SMTP_HOST || '',
40
+ port: parseInt(process.env.BACKUP_SMTP_PORT || '587', 10),
41
+ secure: process.env.BACKUP_SMTP_SECURE === 'true',
42
+ user: process.env.BACKUP_SMTP_USER || '',
43
+ password: process.env.BACKUP_SMTP_PASSWORD || ''
44
+ }
45
+ };
46
+
47
+ async function run() {
48
+ try {
49
+ // Only commands that actually touch MongoDB need a full config load with mongoUri
50
+ const requiresMongoUri = ['backup'];
51
+
52
+ if (requiresMongoUri.includes(command)) {
53
+ if (!config.mongoUri) {
54
+ console.error("Error: MONGO_URI environment variable is required for this command.");
55
+ process.exit(1);
56
+ }
57
+ const configManager = require('../src/config/config');
58
+ configManager.load(config);
59
+ } else if (command !== 'help') {
60
+ // For list/status/cleanup, load a minimal config without requiring mongoUri
61
+ // We only need storage.path; set a dummy uri to pass validation
62
+ const configManager = require('../src/config/config');
63
+ try {
64
+ configManager.load({ ...config, mongoUri: config.mongoUri || 'mongodb://localhost:27017/__cli_readonly' });
65
+ } catch (e) {
66
+ // ignore email validation errors for read-only commands
67
+ }
68
+ }
69
+
70
+ switch (command) {
71
+ case 'backup':
72
+ console.log("Starting manual backup...");
73
+ const success = await backup.createBackup();
74
+ if (success) {
75
+ console.log("Backup completed successfully.");
76
+ } else {
77
+ console.error("Backup failed.");
78
+ process.exit(1);
79
+ }
80
+ break;
81
+
82
+ case 'status':
83
+ const status = backup.getStatus();
84
+ if (status) {
85
+ console.log(JSON.stringify(status, null, 2));
86
+ } else {
87
+ console.log("No backup found for today.");
88
+ }
89
+ break;
90
+
91
+ case 'list':
92
+ const backups = backup.listBackups();
93
+ if (backups.length > 0) {
94
+ console.log("Available backups:");
95
+ backups.forEach(b => console.log(`- ${b}`));
96
+ } else {
97
+ console.log("No backups found.");
98
+ }
99
+ break;
100
+
101
+ case 'cleanup':
102
+ console.log("Running retention cleanup...");
103
+ await backup.cleanup();
104
+ console.log("Cleanup completed.");
105
+ break;
106
+
107
+ case 'help':
108
+ default:
109
+ console.log(`
110
+ Usage: mongodb-backup <command>
111
+
112
+ Commands:
113
+ backup - Manually trigger a backup
114
+ status - Show status of today's backup
115
+ list - List available backups
116
+ cleanup - Run retention cleanup
117
+ help - Show this help message
118
+ `);
119
+ break;
120
+ }
121
+ } catch (error) {
122
+ console.error("CLI error:", error);
123
+ process.exit(1);
124
+ }
125
+ }
126
+
127
+ run();
@@ -0,0 +1,51 @@
1
+ require('dotenv').config();
2
+ const backup = require('../src/index');
3
+
4
+ // Setup process signal handlers for graceful shutdown
5
+ process.on('SIGINT', () => {
6
+ console.log("Shutting down backup service...");
7
+ backup.stop();
8
+ process.exit(0);
9
+ });
10
+
11
+ // Configure and start the backup service
12
+ backup.start({
13
+ // Using environment variables or fallback to defaults
14
+ mongoUri: process.env.MONGO_URI,
15
+
16
+ projectName: process.env.BACKUP_PROJECT_NAME || 'Example Backend',
17
+
18
+ storage: {
19
+ path: process.env.BACKUP_STORAGE_PATH || './backups'
20
+ },
21
+
22
+ schedule: {
23
+ type: process.env.BACKUP_SCHEDULE_TYPE || 'daily',
24
+ time: process.env.BACKUP_SCHEDULE_TIME || '02:00',
25
+ timezone: process.env.BACKUP_TIMEZONE || Intl.DateTimeFormat().resolvedOptions().timeZone
26
+ },
27
+
28
+ excel: {
29
+ enabled: process.env.BACKUP_EXCEL_ENABLED === 'true',
30
+ excludeCollections: (process.env.BACKUP_EXCLUDE_COLLECTIONS || '').split(',').filter(c => c.trim() !== '')
31
+ },
32
+
33
+ retention: {
34
+ enabled: process.env.BACKUP_RETENTION_ENABLED === 'true',
35
+ days: parseInt(process.env.BACKUP_RETENTION_DAYS || '30', 10)
36
+ },
37
+
38
+ email: {
39
+ enabled: process.env.BACKUP_EMAIL_ENABLED === 'true',
40
+ to: process.env.BACKUP_EMAIL_TO,
41
+ host: process.env.BACKUP_SMTP_HOST,
42
+ port: parseInt(process.env.BACKUP_SMTP_PORT || '587', 10),
43
+ secure: process.env.BACKUP_SMTP_SECURE === 'true',
44
+ user: process.env.BACKUP_SMTP_USER,
45
+ password: process.env.BACKUP_SMTP_PASSWORD,
46
+ from: process.env.BACKUP_EMAIL_FROM
47
+ }
48
+ });
49
+
50
+ console.log("Backup service started. It is running in the background and will trigger based on the schedule.");
51
+ console.log("You can also trigger a manual backup using the CLI: npx database-backup backup");
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "mongodb-backup-service",
3
+ "version": "1.0.0",
4
+ "description": "Reusable Node.js service for automated MongoDB backups with scheduling, startup recovery, Excel export, retention, email notifications, and backup locking.",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "mongodb-backup": "bin/cli.js"
8
+ },
9
+ "files": [
10
+ "src/",
11
+ "bin/",
12
+ "examples/",
13
+ ".env.example",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "test": "jest",
19
+ "start": "node examples/basic-usage.js"
20
+ },
21
+ "keywords": [
22
+ "mongodb",
23
+ "mongodb-backup",
24
+ "mongodb-atlas",
25
+ "backup",
26
+ "database-backup",
27
+ "nodejs",
28
+ "automated-backup",
29
+ "mongodump",
30
+ "scheduler",
31
+ "disaster-recovery",
32
+ "excel",
33
+ "export"
34
+ ],
35
+ "author": "Abishek K",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/Abishek6702/Automated_DB_Backup.git"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/Abishek6702/Automated_DB_Backup/issues"
43
+ },
44
+ "homepage": "https://github.com/Abishek6702/Automated_DB_Backup#readme",
45
+ "engines": {
46
+ "node": ">=18.0.0"
47
+ },
48
+ "dependencies": {
49
+ "exceljs": "^4.4.0",
50
+ "mongodb": "^7.6.0",
51
+ "node-cron": "^4.0.0",
52
+ "nodemailer": "^10.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "dotenv": "^17.4.2",
56
+ "jest": "^30.5.1"
57
+ }
58
+ }
@@ -0,0 +1,49 @@
1
+ const defaults = require('./defaults');
2
+
3
+ class ConfigManager {
4
+ constructor() {
5
+ this.config = { ...defaults };
6
+ }
7
+
8
+ load(userConfig = {}) {
9
+ if (!userConfig.mongoUri) {
10
+ throw new Error("mongoUri is required for database-backup-package");
11
+ }
12
+
13
+ this.config = {
14
+ ...defaults,
15
+ ...userConfig,
16
+ storage: {
17
+ ...defaults.storage,
18
+ ...(userConfig.storage || {})
19
+ },
20
+ schedule: {
21
+ ...defaults.schedule,
22
+ ...(userConfig.schedule || {})
23
+ },
24
+ excel: {
25
+ ...defaults.excel,
26
+ ...(userConfig.excel || {})
27
+ },
28
+ email: {
29
+ ...defaults.email,
30
+ ...(userConfig.email || {})
31
+ },
32
+ retention: {
33
+ ...defaults.retention,
34
+ ...(userConfig.retention || {})
35
+ }
36
+ };
37
+
38
+ // If email is enabled, 'to' is required
39
+ if (this.config.email.enabled && !this.config.email.to) {
40
+ throw new Error("email.to is required when email notifications are enabled");
41
+ }
42
+ }
43
+
44
+ get() {
45
+ return this.config;
46
+ }
47
+ }
48
+
49
+ module.exports = new ConfigManager();
@@ -0,0 +1,29 @@
1
+ module.exports = {
2
+ projectName: "Unknown Project",
3
+ storage: {
4
+ path: "./backups"
5
+ },
6
+ schedule: {
7
+ type: "daily",
8
+ time: "02:00",
9
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
10
+ },
11
+ excel: {
12
+ enabled: true,
13
+ excludeCollections: []
14
+ },
15
+ email: {
16
+ enabled: false,
17
+ host: "localhost",
18
+ port: 25,
19
+ secure: false,
20
+ user: "",
21
+ password: "",
22
+ to: "",
23
+ from: "backup@localhost"
24
+ },
25
+ retention: {
26
+ enabled: true,
27
+ days: 30
28
+ }
29
+ };
@@ -0,0 +1,50 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const logger = require('../utils/logger');
4
+ const DateUtils = require('../utils/dateUtils');
5
+
6
+ class BackupLock {
7
+ constructor(storageBasePath) {
8
+ this.lockFile = path.join(storageBasePath, 'backup.lock');
9
+ // Lock expiration in ms (e.g., 2 hours). If a lock is older than this, it's considered stale.
10
+ this.staleMs = 2 * 60 * 60 * 1000;
11
+ }
12
+
13
+ acquire() {
14
+ if (fs.existsSync(this.lockFile)) {
15
+ const stats = fs.statSync(this.lockFile);
16
+ const age = Date.now() - stats.mtimeMs;
17
+
18
+ if (age > this.staleMs) {
19
+ logger.warn("Found stale backup lock. Removing it and continuing.");
20
+ this.release();
21
+ } else {
22
+ logger.error("Another backup is currently in progress. Lock found.");
23
+ return false;
24
+ }
25
+ }
26
+
27
+ try {
28
+ fs.writeFileSync(this.lockFile, JSON.stringify({
29
+ lockedAt: DateUtils.getIsoString(),
30
+ pid: process.pid
31
+ }), { flag: 'wx' });
32
+ return true;
33
+ } catch (error) {
34
+ logger.error("Failed to acquire backup lock.");
35
+ return false;
36
+ }
37
+ }
38
+
39
+ release() {
40
+ if (fs.existsSync(this.lockFile)) {
41
+ try {
42
+ fs.unlinkSync(this.lockFile);
43
+ } catch (error) {
44
+ logger.error("Failed to release backup lock.");
45
+ }
46
+ }
47
+ }
48
+ }
49
+
50
+ module.exports = BackupLock;