@liorandb/db 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 ADDED
@@ -0,0 +1,172 @@
1
+ # LioranDB Server
2
+
3
+ LioranDB Server is a Node.js + TypeScript REST API server built on top of **LioranDB Core**, designed to manage databases, collections, and documents, while providing user authentication. It is intended as the backend for applications using the LioranDB database engine.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ * [Features](#features)
10
+ * [Tech Stack](#tech-stack)
11
+ * [Setup](#setup)
12
+ * [Environment Variables](#environment-variables)
13
+ * [Scripts](#scripts)
14
+ * [API Endpoints](#api-endpoints)
15
+ * [Project Structure](#project-structure)
16
+ * [License](#license)
17
+
18
+ ---
19
+
20
+ ## Features
21
+
22
+ * User authentication (register/login) with JWT tokens
23
+ * CRUD operations for databases, collections, and documents
24
+ * Health check endpoint
25
+ * TypeScript support with strict typing
26
+ * Middleware for authentication
27
+
28
+ ---
29
+
30
+ ## Tech Stack
31
+
32
+ * Node.js
33
+ * TypeScript
34
+ * Express.js
35
+ * LioranDB Core
36
+ * bcryptjs
37
+ * jsonwebtoken
38
+ * dotenv
39
+
40
+ ---
41
+
42
+ ## Setup
43
+
44
+ 1. Clone the repository
45
+
46
+ ```bash
47
+ git clone <repo_url>
48
+ cd server
49
+ ```
50
+
51
+ 2. Install dependencies
52
+
53
+ ```bash
54
+ npm install
55
+ ```
56
+
57
+ 3. Create a `.env` file at the root:
58
+
59
+ ```env
60
+ PORT=4000
61
+ JWT_SECRET=<your_jwt_secret>
62
+ JWT_EXPIRES_IN=7d
63
+ ```
64
+
65
+ 4. Run the development server
66
+
67
+ ```bash
68
+ npm run dev
69
+ ```
70
+
71
+ The server will start on `http://localhost:4000` (or your configured PORT).
72
+
73
+ ---
74
+
75
+ ## Environment Variables
76
+
77
+ * `PORT` – Port number for the server (default: 4000)
78
+ * `JWT_SECRET` – Secret key used for signing JWT tokens **(required)**
79
+ * `JWT_EXPIRES_IN` – JWT expiration time (default: `7d`)
80
+
81
+ ---
82
+
83
+ ## Scripts
84
+
85
+ * `npm run dev` – Start the development server with hot reload
86
+ * `npm run build` – Compile TypeScript to JavaScript (`dist/` folder)
87
+ * `npm start` – Run the compiled server
88
+
89
+ ---
90
+
91
+ ## API Endpoints
92
+
93
+ ### Health Check
94
+
95
+ * `GET /health` – Returns server status
96
+
97
+ ### Authentication
98
+
99
+ * `POST /auth/register` – Register a new user
100
+ * `POST /auth/login` – Login and receive JWT token
101
+
102
+ ### Databases
103
+
104
+ * `GET /databases` – List all databases
105
+ * `POST /databases` – Create a new database
106
+ * `DELETE /databases/:db` – Delete a database
107
+
108
+ ### Collections
109
+
110
+ * `GET /db/:db/collections` – List all collections in a database
111
+ * `POST /db/:db/collections` – Create a new collection
112
+
113
+ ### Documents
114
+
115
+ * `POST /db/:db/collections/:col` – Insert a document
116
+ * `POST /db/:db/collections/:col/find` – Find documents by query
117
+ * `GET /db/:db/collections/:col/:id` – Get a single document by ID
118
+ * `PATCH /db/:db/collections/:col/:id` – Update a document by ID
119
+ * `DELETE /db/:db/collections/:col/:id` – Delete a document by ID
120
+
121
+ > All database, collection, and document endpoints require **Bearer JWT authentication**
122
+
123
+ ---
124
+
125
+ ## Project Structure
126
+
127
+ ```
128
+ server/
129
+ ├─ src/
130
+ │ ├─ config/
131
+ │ │ └─ database.ts # LioranDB manager and auth collection
132
+ │ ├─ controllers/
133
+ │ │ ├─ auth.controller.ts
134
+ │ │ ├─ collection.controller.ts
135
+ │ │ ├─ database.controller.ts
136
+ │ │ └─ document.controller.ts
137
+ │ ├─ middleware/
138
+ │ │ └─ auth.middleware.ts
139
+ │ ├─ routes/
140
+ │ │ ├─ auth.routes.ts
141
+ │ │ ├─ collection.routes.ts
142
+ │ │ ├─ database.routes.ts
143
+ │ │ └─ document.routes.ts
144
+ │ ├─ types/
145
+ │ │ ├─ auth-user.ts
146
+ │ │ └─ express.d.ts
147
+ │ ├─ utils/
148
+ │ │ └─ token.ts
149
+ │ ├─ app.ts
150
+ │ └─ server.ts
151
+ ├─ package.json
152
+ ├─ tsconfig.json
153
+ └─ .env
154
+ ```
155
+
156
+ ---
157
+
158
+ ## License
159
+
160
+ This project is licensed under the **ISC License**.
161
+
162
+ ---
163
+
164
+ ## Notes
165
+
166
+ * Make sure to set a strong `JWT_SECRET` in `.env`
167
+ * The server is designed to work with **LioranDB Core**, which is a peer-to-peer database engine.
168
+ * TypeScript strict mode is enabled for safer coding.
169
+
170
+ ---
171
+
172
+ For further documentation on **LioranDB Core**, refer to its repository: [LioranDB Core](https://www.npmjs.com/package/@liorandb/core)
package/dist/app.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const cors_1 = __importDefault(require("cors"));
7
+ const express_1 = __importDefault(require("express"));
8
+ const auth_routes_1 = __importDefault(require("./routes/auth.routes"));
9
+ const database_routes_1 = __importDefault(require("./routes/database.routes"));
10
+ const collection_routes_1 = __importDefault(require("./routes/collection.routes"));
11
+ const document_routes_1 = __importDefault(require("./routes/document.routes"));
12
+ const requestLogger_middleware_1 = require("./middleware/requestLogger.middleware");
13
+ const app = (0, express_1.default)();
14
+ app.use(express_1.default.json());
15
+ app.use((0, cors_1.default)());
16
+ app.use(requestLogger_middleware_1.requestLogger);
17
+ // health check
18
+ app.get("/health", (req, res) => res.json({ ok: true, time: new Date().toISOString() }));
19
+ app.get("/", (_, res) => {
20
+ res.json({
21
+ name: "LioranDB",
22
+ role: "Database Host",
23
+ status: "online"
24
+ });
25
+ });
26
+ // routes
27
+ app.use("/auth", auth_routes_1.default);
28
+ app.use("/databases", database_routes_1.default);
29
+ app.use("/db/:db/collections", collection_routes_1.default);
30
+ app.use("/db/:db/collections/:col", document_routes_1.default);
31
+ exports.default = app;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.manager = void 0;
4
+ exports.getAuthCollection = getAuthCollection;
5
+ // src/config/database.ts
6
+ const core_1 = require("@liorandb/core");
7
+ exports.manager = new core_1.LioranManager();
8
+ async function getAuthCollection() {
9
+ const db = await exports.manager.db("_auth");
10
+ await db.createCollection("users").catch(() => { });
11
+ // explicitly type this collection as AuthUser so TS knows the fields
12
+ return db.collection("users");
13
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.login = exports.register = void 0;
7
+ const bcryptjs_1 = __importDefault(require("bcryptjs"));
8
+ const database_1 = require("../config/database");
9
+ const token_1 = require("../utils/token");
10
+ const register = async (req, res) => {
11
+ try {
12
+ const { username, password } = req.body;
13
+ if (!username || !password)
14
+ return res.status(400).json({ error: "username and password required" });
15
+ if (typeof username !== "string" || typeof password !== "string")
16
+ return res.status(400).json({ error: "invalid types" });
17
+ if (password.length < 6)
18
+ return res.status(400).json({ error: "password must be at least 6 characters" });
19
+ const users = await (0, database_1.getAuthCollection)(); // typed as AuthUser collection
20
+ const existing = await users.findOne({ username });
21
+ if (existing)
22
+ return res.status(409).json({ error: "username already exists" });
23
+ const hashed = await bcryptjs_1.default.hash(password, 10);
24
+ const created = await users.insertOne({
25
+ username,
26
+ password: hashed,
27
+ createdAt: new Date().toISOString(),
28
+ });
29
+ const token = (0, token_1.signToken)({ id: created._id, username });
30
+ res.json({ user: { id: created._id, username }, token });
31
+ }
32
+ catch (err) {
33
+ console.error(err);
34
+ res.status(500).json({ error: "server error" });
35
+ }
36
+ };
37
+ exports.register = register;
38
+ const login = async (req, res) => {
39
+ try {
40
+ const { username, password } = req.body;
41
+ if (!username || !password)
42
+ return res.status(400).json({ error: "username and password required" });
43
+ const users = await (0, database_1.getAuthCollection)();
44
+ const user = await users.findOne({ username });
45
+ if (!user)
46
+ return res.status(401).json({ error: "invalid credentials" });
47
+ // user is typed as AuthUser so .password exists
48
+ const ok = await bcryptjs_1.default.compare(password, user.password);
49
+ if (!ok)
50
+ return res.status(401).json({ error: "invalid credentials" });
51
+ const token = (0, token_1.signToken)({ id: user._id, username });
52
+ res.json({ user: { id: user._id, username }, token });
53
+ }
54
+ catch (err) {
55
+ console.error(err);
56
+ res.status(500).json({ error: "server error" });
57
+ }
58
+ };
59
+ exports.login = login;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectionStats = exports.renameCollection = exports.deleteCollection = exports.createCollection = exports.listCollections = void 0;
4
+ const database_1 = require("../config/database");
5
+ const listCollections = async (req, res) => {
6
+ try {
7
+ const database = await database_1.manager.db(req.params.db);
8
+ const collections = await database.listCollections();
9
+ res.json({ collections });
10
+ }
11
+ catch {
12
+ res.status(500).json({ error: "server error" });
13
+ }
14
+ };
15
+ exports.listCollections = listCollections;
16
+ const createCollection = async (req, res) => {
17
+ try {
18
+ const database = await database_1.manager.db(req.params.db);
19
+ await database.createCollection(req.body.name);
20
+ res.json({ ok: true });
21
+ }
22
+ catch {
23
+ res.status(500).json({ error: "server error" });
24
+ }
25
+ };
26
+ exports.createCollection = createCollection;
27
+ const deleteCollection = async (req, res) => {
28
+ try {
29
+ const database = await database_1.manager.db(req.params.db);
30
+ await database.deleteCollection(req.params.col);
31
+ res.json({ ok: true });
32
+ }
33
+ catch {
34
+ res.status(500).json({ error: "server error" });
35
+ }
36
+ };
37
+ exports.deleteCollection = deleteCollection;
38
+ const renameCollection = async (req, res) => {
39
+ try {
40
+ const { db, col } = req.params;
41
+ const { newName } = req.body;
42
+ const database = await database_1.manager.db(db);
43
+ await database.renameCollection(col, newName);
44
+ res.json({ ok: true, old: col, new: newName });
45
+ }
46
+ catch {
47
+ res.status(500).json({ error: "server error" });
48
+ }
49
+ };
50
+ exports.renameCollection = renameCollection;
51
+ const collectionStats = async (req, res) => {
52
+ try {
53
+ const { db, col } = req.params;
54
+ const database = await database_1.manager.db(db);
55
+ const collection = database.collection(col);
56
+ const count = await collection.countDocuments();
57
+ res.json({
58
+ name: col,
59
+ documents: count,
60
+ });
61
+ }
62
+ catch {
63
+ res.status(500).json({ error: "server error" });
64
+ }
65
+ };
66
+ exports.collectionStats = collectionStats;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseStats = exports.renameDatabase = exports.deleteDatabase = exports.createDatabase = exports.listDatabases = void 0;
4
+ const database_1 = require("../config/database");
5
+ const listDatabases = async (_, res) => {
6
+ try {
7
+ const list = await database_1.manager.listDatabases();
8
+ res.json({ databases: list });
9
+ }
10
+ catch {
11
+ res.status(500).json({ error: "server error" });
12
+ }
13
+ };
14
+ exports.listDatabases = listDatabases;
15
+ const createDatabase = async (req, res) => {
16
+ try {
17
+ const { name } = req.body;
18
+ if (!name)
19
+ return res.status(400).json({ error: "database name required" });
20
+ await database_1.manager.createDatabase(name);
21
+ res.json({ ok: true, db: name });
22
+ }
23
+ catch {
24
+ res.status(500).json({ error: "server error" });
25
+ }
26
+ };
27
+ exports.createDatabase = createDatabase;
28
+ const deleteDatabase = async (req, res) => {
29
+ try {
30
+ const { db } = req.params;
31
+ const ok = await database_1.manager.deleteDatabase(db);
32
+ res.json({ ok: !!ok });
33
+ }
34
+ catch {
35
+ res.status(500).json({ error: "server error" });
36
+ }
37
+ };
38
+ exports.deleteDatabase = deleteDatabase;
39
+ const renameDatabase = async (req, res) => {
40
+ try {
41
+ const { db } = req.params;
42
+ const { newName } = req.body;
43
+ if (!newName)
44
+ return res.status(400).json({ error: "newName required" });
45
+ await database_1.manager.renameDatabase(db, newName);
46
+ res.json({ ok: true, old: db, new: newName });
47
+ }
48
+ catch {
49
+ res.status(500).json({ error: "server error" });
50
+ }
51
+ };
52
+ exports.renameDatabase = renameDatabase;
53
+ const databaseStats = async (req, res) => {
54
+ try {
55
+ const { db } = req.params;
56
+ const database = await database_1.manager.db(db);
57
+ const cols = await database.listCollections();
58
+ let totalDocs = 0;
59
+ for (const colName of cols) {
60
+ const col = database.collection(colName);
61
+ totalDocs += await col.countDocuments();
62
+ }
63
+ res.json({
64
+ name: db,
65
+ collections: cols.length,
66
+ documents: totalDocs,
67
+ });
68
+ }
69
+ catch {
70
+ res.status(500).json({ error: "server error" });
71
+ }
72
+ };
73
+ exports.databaseStats = databaseStats;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.countDocuments = exports.deleteMany = exports.updateMany = exports.findDocuments = exports.insertMany = exports.insertDocument = void 0;
4
+ const database_1 = require("../config/database");
5
+ const insertDocument = async (req, res) => {
6
+ const collection = (await database_1.manager.db(req.params.db))
7
+ .collection(req.params.col);
8
+ const doc = await collection.insertOne(req.body);
9
+ res.json({ ok: true, doc });
10
+ };
11
+ exports.insertDocument = insertDocument;
12
+ const insertMany = async (req, res) => {
13
+ const collection = (await database_1.manager.db(req.params.db))
14
+ .collection(req.params.col);
15
+ const docs = await collection.insertMany(req.body.docs || []);
16
+ res.json({ ok: true, docs });
17
+ };
18
+ exports.insertMany = insertMany;
19
+ const findDocuments = async (req, res) => {
20
+ const collection = (await database_1.manager.db(req.params.db))
21
+ .collection(req.params.col);
22
+ const results = await collection.find(req.body.query || {});
23
+ res.json({ results });
24
+ };
25
+ exports.findDocuments = findDocuments;
26
+ const updateMany = async (req, res) => {
27
+ const collection = (await database_1.manager.db(req.params.db))
28
+ .collection(req.params.col);
29
+ const docs = await collection.updateMany(req.body.filter, req.body.update);
30
+ res.json({ updated: docs });
31
+ };
32
+ exports.updateMany = updateMany;
33
+ const deleteMany = async (req, res) => {
34
+ const collection = (await database_1.manager.db(req.params.db))
35
+ .collection(req.params.col);
36
+ const count = await collection.deleteMany(req.body.filter || {});
37
+ res.json({ deleted: count });
38
+ };
39
+ exports.deleteMany = deleteMany;
40
+ const countDocuments = async (req, res) => {
41
+ const collection = (await database_1.manager.db(req.params.db))
42
+ .collection(req.params.col);
43
+ const count = await collection.countDocuments(req.body.filter || {});
44
+ res.json({ count });
45
+ };
46
+ exports.countDocuments = countDocuments;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.authMiddleware = authMiddleware;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ const token_1 = require("../utils/token");
9
+ function authMiddleware(req, res, next) {
10
+ const auth = req.headers.authorization;
11
+ if (!auth || !auth.startsWith("Bearer ")) {
12
+ return res.status(401).json({ error: "Missing token" });
13
+ }
14
+ try {
15
+ const token = auth.split(" ")[1];
16
+ const decoded = jsonwebtoken_1.default.verify(token, token_1.JWT_SECRET);
17
+ req.user = decoded;
18
+ next();
19
+ }
20
+ catch {
21
+ return res.status(401).json({ error: "Invalid token" });
22
+ }
23
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestLogger = requestLogger;
4
+ const hostLogger_1 = require("../utils/hostLogger");
5
+ function formatResponse(body) {
6
+ if (!body)
7
+ return "null";
8
+ // If already an object
9
+ if (typeof body === "object") {
10
+ return JSON.stringify(body, null, 2);
11
+ }
12
+ // If string, try parsing JSON
13
+ if (typeof body === "string") {
14
+ try {
15
+ const parsed = JSON.parse(body);
16
+ return JSON.stringify(parsed, null, 2);
17
+ }
18
+ catch {
19
+ return body; // normal string (HTML, text, etc.)
20
+ }
21
+ }
22
+ return String(body);
23
+ }
24
+ function requestLogger(req, res, next) {
25
+ const start = Date.now();
26
+ const oldSend = res.send.bind(res);
27
+ let responseBody;
28
+ res.send = (body) => {
29
+ responseBody = body;
30
+ return oldSend(body);
31
+ };
32
+ res.on("finish", () => {
33
+ const duration = Date.now() - start;
34
+ const logData = `
35
+ ──────────────────────────────────────
36
+ INCOMING REQUEST
37
+ Method : ${req.method}
38
+ URL : ${req.originalUrl}
39
+ IP : ${req.ip}
40
+ Auth : ${req.headers.authorization ? "Yes" : "No"}
41
+ RequestBody :
42
+ ${JSON.stringify(req.body || {}, null, 2)}
43
+
44
+ RESPONSE
45
+ Status : ${res.statusCode}
46
+ Duration : ${duration}ms
47
+ Response :
48
+ ${formatResponse(responseBody)}
49
+ ──────────────────────────────────────
50
+ `;
51
+ (0, hostLogger_1.hostLog)(logData.trim());
52
+ });
53
+ next();
54
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const express_1 = require("express");
4
+ const auth_controller_1 = require("../controllers/auth.controller");
5
+ const router = (0, express_1.Router)();
6
+ router.post("/register", auth_controller_1.register);
7
+ router.post("/login", auth_controller_1.login);
8
+ exports.default = router;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const express_1 = require("express");
4
+ const collection_controller_1 = require("../controllers/collection.controller");
5
+ const auth_middleware_1 = require("../middleware/auth.middleware");
6
+ const router = (0, express_1.Router)({ mergeParams: true });
7
+ router.get("/", auth_middleware_1.authMiddleware, collection_controller_1.listCollections);
8
+ router.post("/", auth_middleware_1.authMiddleware, collection_controller_1.createCollection);
9
+ router.delete("/:col", auth_middleware_1.authMiddleware, collection_controller_1.deleteCollection);
10
+ router.patch("/:col/rename", auth_middleware_1.authMiddleware, collection_controller_1.renameCollection);
11
+ router.get("/:col/stats", auth_middleware_1.authMiddleware, collection_controller_1.collectionStats);
12
+ exports.default = router;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const express_1 = require("express");
4
+ const database_controller_1 = require("../controllers/database.controller");
5
+ const auth_middleware_1 = require("../middleware/auth.middleware");
6
+ const router = (0, express_1.Router)();
7
+ router.get("/", auth_middleware_1.authMiddleware, database_controller_1.listDatabases);
8
+ router.post("/", auth_middleware_1.authMiddleware, database_controller_1.createDatabase);
9
+ router.delete("/:db", auth_middleware_1.authMiddleware, database_controller_1.deleteDatabase);
10
+ router.patch("/:db/rename", auth_middleware_1.authMiddleware, database_controller_1.renameDatabase);
11
+ router.get("/:db/stats", auth_middleware_1.authMiddleware, database_controller_1.databaseStats);
12
+ exports.default = router;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const express_1 = require("express");
4
+ const document_controller_1 = require("../controllers/document.controller");
5
+ const auth_middleware_1 = require("../middleware/auth.middleware");
6
+ const router = (0, express_1.Router)({ mergeParams: true });
7
+ router.post("/", auth_middleware_1.authMiddleware, document_controller_1.insertDocument);
8
+ router.post("/bulk", auth_middleware_1.authMiddleware, document_controller_1.insertMany);
9
+ router.post("/find", auth_middleware_1.authMiddleware, document_controller_1.findDocuments);
10
+ router.patch("/updateMany", auth_middleware_1.authMiddleware, document_controller_1.updateMany);
11
+ router.post("/deleteMany", auth_middleware_1.authMiddleware, document_controller_1.deleteMany);
12
+ router.post("/count", auth_middleware_1.authMiddleware, document_controller_1.countDocuments);
13
+ exports.default = router;
package/dist/server.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // src/server.ts
7
+ const app_1 = __importDefault(require("./app"));
8
+ const PORT = 4000;
9
+ app_1.default.listen(PORT, "0.0.0.0", () => {
10
+ console.log("======================================");
11
+ console.log("🚀 LioranDB Host is LIVE");
12
+ console.log(`📡 Listening on port: ${PORT}`);
13
+ // print all running host IPs
14
+ console.log(`🌐 Host Address: localhost:4000`);
15
+ const os = require("os");
16
+ const networkInterfaces = os.networkInterfaces();
17
+ for (const interfaceName in networkInterfaces) {
18
+ const interfaceInfo = networkInterfaces[interfaceName];
19
+ for (const addressInfo of interfaceInfo) {
20
+ if (addressInfo.family === "IPv4" && !addressInfo.internal) {
21
+ console.log(`🌐 Host Address: ${addressInfo.address}:4000`);
22
+ }
23
+ }
24
+ }
25
+ // console.log(`🧠 Mode: ${process.env.NODE_ENV || "development"}`);
26
+ console.log("======================================");
27
+ });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hostLog = hostLog;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const LOG_DIR = path_1.default.join(process.cwd(), "logs");
10
+ if (!fs_1.default.existsSync(LOG_DIR)) {
11
+ fs_1.default.mkdirSync(LOG_DIR, { recursive: true });
12
+ }
13
+ function getLogFilePath() {
14
+ const now = new Date();
15
+ const date = now.toISOString().split("T")[0]; // YYYY-MM-DD
16
+ const hour = String(now.getHours()).padStart(2, "0"); // HH
17
+ return path_1.default.join(LOG_DIR, `${date}_${hour}.log`);
18
+ }
19
+ function hostLog(message) {
20
+ const timestamp = new Date().toISOString();
21
+ const logLine = `[${timestamp}] ${message}\n`;
22
+ // Write to file
23
+ fs_1.default.appendFileSync(getLogFilePath(), logLine, "utf8");
24
+ // Print to console
25
+ console.log(logLine.trim());
26
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.JWT_EXPIRES_IN = exports.JWT_SECRET = void 0;
7
+ exports.signToken = signToken;
8
+ exports.verifyToken = verifyToken;
9
+ // src/utils/token.ts
10
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ const os_1 = __importDefault(require("os"));
13
+ /**
14
+ * Derive a stable, machine-bound secret
15
+ */
16
+ function getHardwareSecret() {
17
+ const fingerprint = [
18
+ os_1.default.hostname(),
19
+ os_1.default.platform(),
20
+ os_1.default.arch(),
21
+ os_1.default.cpus()?.[0]?.model || "unknown-cpu",
22
+ os_1.default.cpus()?.length.toString() || "0",
23
+ os_1.default.totalmem().toString()
24
+ ].join("|");
25
+ return crypto_1.default
26
+ .createHash("sha256")
27
+ .update(fingerprint)
28
+ .digest("hex"); // JWT expects string | Buffer
29
+ }
30
+ exports.JWT_SECRET = getHardwareSecret();
31
+ // Safe default, still configurable if needed
32
+ exports.JWT_EXPIRES_IN = "7d";
33
+ function signToken(payload) {
34
+ return jsonwebtoken_1.default.sign(payload, exports.JWT_SECRET, {
35
+ expiresIn: exports.JWT_EXPIRES_IN,
36
+ });
37
+ }
38
+ function verifyToken(token) {
39
+ return jsonwebtoken_1.default.verify(token, exports.JWT_SECRET);
40
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@liorandb/db",
3
+ "version": "1.0.0",
4
+ "description": "LioranDB server and CLI",
5
+ "main": "dist/server.js",
6
+ "types": "dist/server.d.ts",
7
+ "bin": {
8
+ "dbi": "dist/cli.js",
9
+ "serve": "dist/server.js"
10
+ },
11
+ "scripts": {
12
+ "dev": "ts-node-dev --respawn --transpile-only src/server.ts",
13
+ "build": "tsc",
14
+ "start": "node dist/server.js",
15
+ "cli": "ts-node cli/index.ts"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "database",
22
+ "liorandb",
23
+ "server",
24
+ "cli"
25
+ ],
26
+ "author": "Your Name",
27
+ "license": "ISC",
28
+ "devDependencies": {
29
+ "@types/bcryptjs": "^2.4.6",
30
+ "@types/commander": "^2.12.0",
31
+ "@types/cors": "^2.8.19",
32
+ "@types/express": "^5.0.6",
33
+ "@types/jsonwebtoken": "^9.0.10",
34
+ "@types/node": "^25.0.1",
35
+ "commander": "^14.0.2",
36
+ "nodemon": "^3.1.11",
37
+ "ts-node": "^10.9.2",
38
+ "ts-node-dev": "^2.0.0",
39
+ "typescript": "^5.9.3"
40
+ },
41
+ "dependencies": {
42
+ "@liorandb/core": "^1.0.9",
43
+ "bcryptjs": "^3.0.3",
44
+ "cors": "^2.8.6",
45
+ "express": "^5.2.1",
46
+ "jsonwebtoken": "^9.0.3"
47
+ }
48
+ }