milodb 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/README.md +141 -0
- package/package.json +20 -0
- package/src/cli.js +39 -0
- package/src/encrypt.js +24 -0
- package/src/milodb.js +102 -0
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Here’s a sample `README.md` file that explains how to use the database manager NPM package you've created.
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# JSON Database Manager with Encryption
|
|
6
|
+
|
|
7
|
+
This is a simple database manager that allows you to store and manage your data in encrypted JSON files. It provides an easy-to-use CLI interface to perform CRUD operations (Create, Read, Update, Delete) on tables stored as JSON files.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
- **Encrypted Data**: Store your data securely using AES encryption.
|
|
11
|
+
- **CRUD Operations**: Create, read, update, and delete records in JSON tables.
|
|
12
|
+
- **Command-Line Interface (CLI)**: Interact with the database using simple CLI commands.
|
|
13
|
+
|
|
14
|
+
### Table of Contents
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Usage](#usage)
|
|
17
|
+
- [Create a Table](#create-a-table)
|
|
18
|
+
- [Add a Record](#add-a-record)
|
|
19
|
+
- [Edit a Record](#edit-a-record)
|
|
20
|
+
- [Delete a Record](#delete-a-record)
|
|
21
|
+
- [Get All Records](#get-all-records)
|
|
22
|
+
- [License](#license)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
1. Clone the repository or download the package.
|
|
29
|
+
|
|
30
|
+
2. Install the dependencies:
|
|
31
|
+
```bash
|
|
32
|
+
npm install
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
3. Link the package globally to use the CLI commands:
|
|
36
|
+
```bash
|
|
37
|
+
npm link
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
4. The commands will now be available globally through the terminal.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
Once installed, you can use the following commands to manage your encrypted JSON database.
|
|
47
|
+
|
|
48
|
+
### Create a Table
|
|
49
|
+
|
|
50
|
+
To create a new table, run the following command:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
db-manager createTable <tableName>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This will create a new table (a JSON file) in the `./db` directory. The table will be initialized as an empty array.
|
|
57
|
+
|
|
58
|
+
**Example**:
|
|
59
|
+
```bash
|
|
60
|
+
db-manager createTable users
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This will create a table named `users.json` inside the `./db` folder.
|
|
64
|
+
|
|
65
|
+
### Add a Record
|
|
66
|
+
|
|
67
|
+
To add a new record to a table, use the `addRecord` command. The record must be a valid JSON object.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
db-manager addRecord <tableName> <record>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Example**:
|
|
74
|
+
```bash
|
|
75
|
+
db-manager addRecord users '{"id": 1, "name": "John Doe", "email": "john@example.com"}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This will add the record to the `users` table. The data will be encrypted before being stored.
|
|
79
|
+
|
|
80
|
+
### Edit a Record
|
|
81
|
+
|
|
82
|
+
To edit an existing record, use the `editRecord` command. You need to specify the table name, the `recordId` (the ID of the record to be updated), and the new updated record in JSON format.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
db-manager editRecord <tableName> <recordId> <updatedRecord>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Example**:
|
|
89
|
+
```bash
|
|
90
|
+
db-manager editRecord users 1 '{"id": 1, "name": "John Doe", "email": "john.doe@example.com"}'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This will update the record with ID `1` in the `users` table.
|
|
94
|
+
|
|
95
|
+
### Delete a Record
|
|
96
|
+
|
|
97
|
+
To delete a record from a table, use the `deleteRecord` command. Provide the table name and the `recordId` of the record you want to delete.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
db-manager deleteRecord <tableName> <recordId>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Example**:
|
|
104
|
+
```bash
|
|
105
|
+
db-manager deleteRecord users 1
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This will delete the record with ID `1` from the `users` table.
|
|
109
|
+
|
|
110
|
+
### Get All Records
|
|
111
|
+
|
|
112
|
+
To retrieve all records from a table, use the `getRecords` command. This will output all the records in the specified table.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
db-manager getRecords <tableName>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Example**:
|
|
119
|
+
```bash
|
|
120
|
+
db-manager getRecords users
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This will display all the records from the `users` table. The data will be decrypted before being shown.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### Notes
|
|
134
|
+
|
|
135
|
+
- All the data is stored encrypted for security. When retrieving data, it will be automatically decrypted before being displayed.
|
|
136
|
+
- Make sure you use a strong `secretKey` in the `encrypt.js` file for enhanced security.
|
|
137
|
+
- This package uses the `fs-extra` module to interact with the file system and store data as JSON files.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
This README will help users get started with the database manager and use it for simple operations on encrypted JSON data files.
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "milodb",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "src/milodb.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [],
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"description": "",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"commander": "^12.1.0",
|
|
14
|
+
"crypto": "^1.0.1",
|
|
15
|
+
"fs-extra": "^11.2.0"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"milodb": "./src/cli.js"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const MiloDB = require('./src/milodb');
|
|
6
|
+
|
|
7
|
+
// Function to initialize the database
|
|
8
|
+
async function initDatabase() {
|
|
9
|
+
const dbPath = path.join(process.cwd(), 'src/db'); // Set the path where the database will be stored
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// Create a new instance of MiloDB
|
|
13
|
+
const db = new MiloDB(dbPath, false); // Default to no encryption
|
|
14
|
+
|
|
15
|
+
// Ensure the database folder exists
|
|
16
|
+
fs.ensureDirSync(dbPath);
|
|
17
|
+
|
|
18
|
+
console.log(`Database initialized at: ${dbPath}`);
|
|
19
|
+
|
|
20
|
+
// Optionally, you could create a default table
|
|
21
|
+
// await db.createTable('users');
|
|
22
|
+
// console.log('Default "users" table created.');
|
|
23
|
+
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('Error initializing database:', error.message);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Parse command line arguments
|
|
31
|
+
const args = process.argv.slice(2);
|
|
32
|
+
|
|
33
|
+
// Handle the `init` command
|
|
34
|
+
if (args[0] === 'init') {
|
|
35
|
+
initDatabase();
|
|
36
|
+
} else {
|
|
37
|
+
console.log('Unknown command. Please use "milodb init" to initialize the database.');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
package/src/encrypt.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/encrypt.js
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
const secretKey = 'your-secret-key'; // Use a strong key for real-world applications
|
|
4
|
+
const algorithm = 'aes-256-cbc';
|
|
5
|
+
|
|
6
|
+
// Encrypt data
|
|
7
|
+
function encrypt(data) {
|
|
8
|
+
const iv = crypto.randomBytes(16);
|
|
9
|
+
const cipher = crypto.createCipheriv(algorithm, Buffer.from(secretKey), iv);
|
|
10
|
+
let encryptedData = cipher.update(data, 'utf8', 'hex');
|
|
11
|
+
encryptedData += cipher.final('hex');
|
|
12
|
+
return `${iv.toString('hex')}:${encryptedData}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Decrypt data
|
|
16
|
+
function decrypt(encryptedData) {
|
|
17
|
+
const [iv, data] = encryptedData.split(':');
|
|
18
|
+
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(secretKey), Buffer.from(iv, 'hex'));
|
|
19
|
+
let decryptedData = decipher.update(data, 'hex', 'utf8');
|
|
20
|
+
decryptedData += decipher.final('utf8');
|
|
21
|
+
return decryptedData;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { encrypt, decrypt };
|
package/src/milodb.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { encrypt, decrypt } = require('./encrypt');
|
|
4
|
+
|
|
5
|
+
class MiloDB {
|
|
6
|
+
constructor(dbPath = path.join(__dirname, 'db'), encryptData = false) {
|
|
7
|
+
// Use the root folder for dbPath if not provided
|
|
8
|
+
this.dbPath = dbPath;
|
|
9
|
+
this.encryptData = encryptData;
|
|
10
|
+
fs.ensureDirSync(this.dbPath); // Ensure that the DB path exists
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Create a new table (i.e., a new JSON file)
|
|
14
|
+
async createTable(tableName) {
|
|
15
|
+
const tablePath = path.join(this.dbPath, `${tableName}.json`);
|
|
16
|
+
if (fs.existsSync(tablePath)) {
|
|
17
|
+
throw new Error(`Table ${tableName} already exists.`);
|
|
18
|
+
}
|
|
19
|
+
await fs.writeJson(tablePath, [], { spaces: 2 });
|
|
20
|
+
console.log(`Table ${tableName} created successfully.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Add a record to a table
|
|
24
|
+
async addRecord(tableName, record) {
|
|
25
|
+
const tablePath = path.join(this.dbPath, `${tableName}.json`);
|
|
26
|
+
if (!fs.existsSync(tablePath)) {
|
|
27
|
+
throw new Error(`Table ${tableName} does not exist.`);
|
|
28
|
+
}
|
|
29
|
+
const table = await fs.readJson(tablePath);
|
|
30
|
+
|
|
31
|
+
// Apply encryption if needed
|
|
32
|
+
if (this.encryptData) {
|
|
33
|
+
record = encrypt(JSON.stringify(record));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
table.push(record);
|
|
37
|
+
await fs.writeJson(tablePath, table, { spaces: 2 });
|
|
38
|
+
console.log('Record added successfully.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Edit a record in a table
|
|
42
|
+
async editRecord(tableName, recordId, updatedRecord) {
|
|
43
|
+
const tablePath = path.join(this.dbPath, `${tableName}.json`);
|
|
44
|
+
if (!fs.existsSync(tablePath)) {
|
|
45
|
+
throw new Error(`Table ${tableName} does not exist.`);
|
|
46
|
+
}
|
|
47
|
+
const table = await fs.readJson(tablePath);
|
|
48
|
+
const index = table.findIndex((rec) => this.decryptIfNeeded(rec).id === recordId);
|
|
49
|
+
if (index === -1) {
|
|
50
|
+
throw new Error(`Record with ID ${recordId} not found.`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Apply encryption if needed
|
|
54
|
+
table[index] = this.encryptIfNeeded(updatedRecord);
|
|
55
|
+
await fs.writeJson(tablePath, table, { spaces: 2 });
|
|
56
|
+
console.log('Record updated successfully.');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Delete a record from a table
|
|
60
|
+
async deleteRecord(tableName, recordId) {
|
|
61
|
+
const tablePath = path.join(this.dbPath, `${tableName}.json`);
|
|
62
|
+
if (!fs.existsSync(tablePath)) {
|
|
63
|
+
throw new Error(`Table ${tableName} does not exist.`);
|
|
64
|
+
}
|
|
65
|
+
const table = await fs.readJson(tablePath);
|
|
66
|
+
const index = table.findIndex((rec) => this.decryptIfNeeded(rec).id === recordId);
|
|
67
|
+
if (index === -1) {
|
|
68
|
+
throw new Error(`Record with ID ${recordId} not found.`);
|
|
69
|
+
}
|
|
70
|
+
table.splice(index, 1);
|
|
71
|
+
await fs.writeJson(tablePath, table, { spaces: 2 });
|
|
72
|
+
console.log('Record deleted successfully.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Get all records from a table
|
|
76
|
+
async getRecords(tableName) {
|
|
77
|
+
const tablePath = path.join(this.dbPath, `${tableName}.json`);
|
|
78
|
+
if (!fs.existsSync(tablePath)) {
|
|
79
|
+
throw new Error(`Table ${tableName} does not exist.`);
|
|
80
|
+
}
|
|
81
|
+
const table = await fs.readJson(tablePath);
|
|
82
|
+
return table.map((record) => this.decryptIfNeeded(record));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Helper function to decrypt a record if encryption is enabled
|
|
86
|
+
decryptIfNeeded(record) {
|
|
87
|
+
if (this.encryptData) {
|
|
88
|
+
return JSON.parse(decrypt(record));
|
|
89
|
+
}
|
|
90
|
+
return JSON.parse(record);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Helper function to encrypt a record if encryption is enabled
|
|
94
|
+
encryptIfNeeded(record) {
|
|
95
|
+
if (this.encryptData) {
|
|
96
|
+
return encrypt(JSON.stringify(record));
|
|
97
|
+
}
|
|
98
|
+
return JSON.stringify(record);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = MiloDB;
|