@liorandb/db 1.0.0 → 1.0.2
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/dist/cli/index.js +222 -0
- package/dist/server.js +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const readline_1 = __importDefault(require("readline"));
|
|
8
|
+
const util_1 = __importDefault(require("util"));
|
|
9
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
10
|
+
const database_1 = require("../config/database");
|
|
11
|
+
/* -------------------------------- INTERACTIVE MODE -------------------------------- */
|
|
12
|
+
console.log("🚀 LioranDB Interactive Shell");
|
|
13
|
+
console.log("Type: help to see commands\n");
|
|
14
|
+
const rl = readline_1.default.createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout,
|
|
17
|
+
prompt: "liorandb> ",
|
|
18
|
+
historySize: 1000,
|
|
19
|
+
});
|
|
20
|
+
let currentDB = "default";
|
|
21
|
+
/* -------------------------------- HELP -------------------------------- */
|
|
22
|
+
async function printHelp() {
|
|
23
|
+
console.log(`
|
|
24
|
+
Database:
|
|
25
|
+
show dbs
|
|
26
|
+
use <dbname>
|
|
27
|
+
show collections
|
|
28
|
+
db.createCollection("<name>")
|
|
29
|
+
db.dropCollection("<name>")
|
|
30
|
+
db.renameCollection("<old>", "<new>")
|
|
31
|
+
|
|
32
|
+
CRUD:
|
|
33
|
+
db.<collection>.insert({...})
|
|
34
|
+
db.<collection>.insertMany([...])
|
|
35
|
+
db.<collection>.find({...})
|
|
36
|
+
db.<collection>.findOne({...})
|
|
37
|
+
db.<collection>.update({...filter}, {...update})
|
|
38
|
+
db.<collection>.updateMany({...filter}, {...update})
|
|
39
|
+
db.<collection>.delete({...filter})
|
|
40
|
+
db.<collection>.deleteMany({...filter})
|
|
41
|
+
db.<collection>.count({...})
|
|
42
|
+
|
|
43
|
+
User Management:
|
|
44
|
+
user.create("username","password")
|
|
45
|
+
user.delete("username")
|
|
46
|
+
user.list()
|
|
47
|
+
|
|
48
|
+
System:
|
|
49
|
+
clear
|
|
50
|
+
exit
|
|
51
|
+
`);
|
|
52
|
+
}
|
|
53
|
+
/* -------------------------------- HELPERS -------------------------------- */
|
|
54
|
+
function safeParse(obj) {
|
|
55
|
+
try {
|
|
56
|
+
return eval(`(${obj})`);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/* -------------------------------- USER COMMAND HANDLER -------------------------------- */
|
|
63
|
+
async function handleUserCommand(cmd) {
|
|
64
|
+
const users = await (0, database_1.getAuthCollection)();
|
|
65
|
+
if (cmd.startsWith("user.create")) {
|
|
66
|
+
const args = cmd.match(/\("(.+?)","(.+?)"\)/);
|
|
67
|
+
if (!args)
|
|
68
|
+
return console.error("Invalid syntax");
|
|
69
|
+
const [, username, password] = args;
|
|
70
|
+
const existing = await users.findOne({ username });
|
|
71
|
+
if (existing)
|
|
72
|
+
return console.error("User already exists");
|
|
73
|
+
const hashed = await bcryptjs_1.default.hash(password, 10);
|
|
74
|
+
await users.insertOne({
|
|
75
|
+
username,
|
|
76
|
+
password: hashed,
|
|
77
|
+
createdAt: new Date().toISOString(),
|
|
78
|
+
});
|
|
79
|
+
return console.log(`✔ User '${username}' created`);
|
|
80
|
+
}
|
|
81
|
+
if (cmd.startsWith("user.delete")) {
|
|
82
|
+
const args = cmd.match(/\("(.+?)"\)/);
|
|
83
|
+
if (!args)
|
|
84
|
+
return console.error("Invalid syntax");
|
|
85
|
+
const [, username] = args;
|
|
86
|
+
const r = await users.deleteOne({ username });
|
|
87
|
+
return console.log(`Deleted: ${r}`);
|
|
88
|
+
}
|
|
89
|
+
if (cmd === "user.list()") {
|
|
90
|
+
const list = await users.find({});
|
|
91
|
+
return console.table(list.map((u) => ({
|
|
92
|
+
username: u.username,
|
|
93
|
+
createdAt: u.createdAt
|
|
94
|
+
})));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/* -------------------------------- MAIN COMMAND HANDLER -------------------------------- */
|
|
98
|
+
async function handleCommand(input) {
|
|
99
|
+
const cmd = input.trim();
|
|
100
|
+
if (!cmd)
|
|
101
|
+
return;
|
|
102
|
+
if (cmd === "exit")
|
|
103
|
+
process.exit(0);
|
|
104
|
+
if (cmd === "clear")
|
|
105
|
+
return console.clear();
|
|
106
|
+
if (cmd === "help")
|
|
107
|
+
return printHelp();
|
|
108
|
+
if (cmd === "show dbs") {
|
|
109
|
+
const list = await database_1.manager.listDatabases();
|
|
110
|
+
return console.table(list);
|
|
111
|
+
}
|
|
112
|
+
if (cmd.startsWith("use ")) {
|
|
113
|
+
currentDB = cmd.split(" ")[1];
|
|
114
|
+
await database_1.manager.db(currentDB);
|
|
115
|
+
return console.log(`✔ Switched to database: ${currentDB}`);
|
|
116
|
+
}
|
|
117
|
+
if (cmd === "show collections") {
|
|
118
|
+
const db = await database_1.manager.db(currentDB);
|
|
119
|
+
const cols = await db.listCollections();
|
|
120
|
+
return console.table(cols);
|
|
121
|
+
}
|
|
122
|
+
if (cmd.startsWith("db.createCollection")) {
|
|
123
|
+
const name = cmd.match(/\("(.+)"\)/)?.[1];
|
|
124
|
+
if (!name)
|
|
125
|
+
return console.error("Invalid syntax");
|
|
126
|
+
const db = await database_1.manager.db(currentDB);
|
|
127
|
+
await db.createCollection(name);
|
|
128
|
+
return console.log("✔ Collection created");
|
|
129
|
+
}
|
|
130
|
+
if (cmd.startsWith("db.dropCollection")) {
|
|
131
|
+
const name = cmd.match(/\("(.+)"\)/)?.[1];
|
|
132
|
+
if (!name)
|
|
133
|
+
return console.error("Invalid syntax");
|
|
134
|
+
const db = await database_1.manager.db(currentDB);
|
|
135
|
+
await db.deleteCollection(name);
|
|
136
|
+
return console.log("✔ Collection deleted");
|
|
137
|
+
}
|
|
138
|
+
if (cmd.startsWith("db.renameCollection")) {
|
|
139
|
+
const args = cmd.match(/\("(.+)",\s*"(.+)"\)/);
|
|
140
|
+
if (!args)
|
|
141
|
+
return console.error("Invalid syntax");
|
|
142
|
+
const db = await database_1.manager.db(currentDB);
|
|
143
|
+
await db.renameCollection(args[1], args[2]);
|
|
144
|
+
return console.log("✔ Collection renamed");
|
|
145
|
+
}
|
|
146
|
+
/* -------- USER COMMANDS -------- */
|
|
147
|
+
if (cmd.startsWith("user.")) {
|
|
148
|
+
return handleUserCommand(cmd);
|
|
149
|
+
}
|
|
150
|
+
/* -------- DATABASE CRUD -------- */
|
|
151
|
+
if (cmd.startsWith("db.")) {
|
|
152
|
+
const match = cmd.match(/^db\.([^.]+)\.(.+)$/);
|
|
153
|
+
if (!match)
|
|
154
|
+
return console.error("Invalid syntax");
|
|
155
|
+
const [, colName, action] = match;
|
|
156
|
+
const db = await database_1.manager.db(currentDB);
|
|
157
|
+
const col = db.collection(colName);
|
|
158
|
+
if (action.startsWith("insertMany")) {
|
|
159
|
+
const match = action.match(/^insertMany\((.*)\)$/);
|
|
160
|
+
const data = JSON.parse(match[1]);
|
|
161
|
+
const r = await col.insertMany(data);
|
|
162
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
163
|
+
}
|
|
164
|
+
if (action.startsWith("insert")) {
|
|
165
|
+
const match = action.match(/^insert\((.*)\)$/);
|
|
166
|
+
const data = JSON.parse(match[1]);
|
|
167
|
+
const r = await col.insertOne(data);
|
|
168
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
169
|
+
}
|
|
170
|
+
if (action.startsWith("findOne")) {
|
|
171
|
+
const q = safeParse(action.slice(8));
|
|
172
|
+
const r = await col.findOne(q || {});
|
|
173
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
174
|
+
}
|
|
175
|
+
if (action.startsWith("find")) {
|
|
176
|
+
const q = safeParse(action.slice(4));
|
|
177
|
+
const r = await col.find(q || {});
|
|
178
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
179
|
+
}
|
|
180
|
+
if (action.startsWith("updateMany")) {
|
|
181
|
+
const match = action.match(/^updateMany\((.*)\)$/);
|
|
182
|
+
const args = safeParse(`[${match[1]}]`);
|
|
183
|
+
const r = await col.updateMany(args[0], args[1]);
|
|
184
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
185
|
+
}
|
|
186
|
+
if (action.startsWith("update")) {
|
|
187
|
+
const args = safeParse(`[${action.slice(6)}]`);
|
|
188
|
+
const r = await col.updateOne(args[0], args[1]);
|
|
189
|
+
return console.log(util_1.default.inspect(r, false, 10, true));
|
|
190
|
+
}
|
|
191
|
+
if (action.startsWith("deleteMany")) {
|
|
192
|
+
const q = safeParse(action.slice(10));
|
|
193
|
+
const r = await col.deleteMany(q);
|
|
194
|
+
return console.log(`Deleted: ${r}`);
|
|
195
|
+
}
|
|
196
|
+
if (action.startsWith("delete")) {
|
|
197
|
+
const q = safeParse(action.slice(6));
|
|
198
|
+
const r = await col.deleteOne(q);
|
|
199
|
+
return console.log(`Deleted: ${r}`);
|
|
200
|
+
}
|
|
201
|
+
if (action.startsWith("count")) {
|
|
202
|
+
const q = safeParse(action.slice(5));
|
|
203
|
+
const r = await col.countDocuments(q);
|
|
204
|
+
return console.log(`Count: ${r}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
console.log("Unknown command. Type: help");
|
|
208
|
+
}
|
|
209
|
+
/* -------------------------------- START REPL -------------------------------- */
|
|
210
|
+
rl.prompt();
|
|
211
|
+
rl.on("line", async (line) => {
|
|
212
|
+
try {
|
|
213
|
+
await handleCommand(line);
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
console.error("Error:", err);
|
|
217
|
+
}
|
|
218
|
+
rl.prompt();
|
|
219
|
+
});
|
|
220
|
+
rl.on("close", () => {
|
|
221
|
+
process.exit(0);
|
|
222
|
+
});
|
package/dist/server.js
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liorandb/db",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "LioranDB server and CLI",
|
|
5
5
|
"main": "dist/server.js",
|
|
6
6
|
"types": "dist/server.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
-
"dbi": "dist/cli.js",
|
|
8
|
+
"dbi": "dist/cli/cli.js",
|
|
9
9
|
"serve": "dist/server.js"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"dev": "ts-node-dev --respawn --transpile-only src/server.ts",
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"start": "node dist/server.js",
|
|
15
|
-
"cli": "ts-node cli/index.ts"
|
|
15
|
+
"cli": "ts-node src/cli/index.ts"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"dist"
|