@neevjs/server 0.0.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.
Files changed (49) hide show
  1. package/README.md +34 -0
  2. package/dist/controllers/authController.d.ts +6 -0
  3. package/dist/controllers/authController.d.ts.map +1 -0
  4. package/dist/controllers/authController.js +52 -0
  5. package/dist/controllers/authController.js.map +1 -0
  6. package/dist/controllers/modelController.d.ts +9 -0
  7. package/dist/controllers/modelController.d.ts.map +1 -0
  8. package/dist/controllers/modelController.js +47 -0
  9. package/dist/controllers/modelController.js.map +1 -0
  10. package/dist/db/index.d.ts +16 -0
  11. package/dist/db/index.d.ts.map +1 -0
  12. package/dist/db/index.js +72 -0
  13. package/dist/db/index.js.map +1 -0
  14. package/dist/middleware/auth.d.ts +4 -0
  15. package/dist/middleware/auth.d.ts.map +1 -0
  16. package/dist/middleware/auth.js +35 -0
  17. package/dist/middleware/auth.js.map +1 -0
  18. package/dist/middleware/jwt.d.ts +9 -0
  19. package/dist/middleware/jwt.d.ts.map +1 -0
  20. package/dist/middleware/jwt.js +22 -0
  21. package/dist/middleware/jwt.js.map +1 -0
  22. package/dist/middleware/response.d.ts +8 -0
  23. package/dist/middleware/response.d.ts.map +1 -0
  24. package/dist/middleware/response.js +24 -0
  25. package/dist/middleware/response.js.map +1 -0
  26. package/dist/routes/auth.d.ts +4 -0
  27. package/dist/routes/auth.d.ts.map +1 -0
  28. package/dist/routes/auth.js +12 -0
  29. package/dist/routes/auth.js.map +1 -0
  30. package/dist/routes/modelRouter.d.ts +3 -0
  31. package/dist/routes/modelRouter.d.ts.map +1 -0
  32. package/dist/routes/modelRouter.js +22 -0
  33. package/dist/routes/modelRouter.js.map +1 -0
  34. package/dist/server.d.ts +4 -0
  35. package/dist/server.d.ts.map +1 -0
  36. package/dist/server.js +37 -0
  37. package/dist/server.js.map +1 -0
  38. package/package.json +36 -0
  39. package/src/controllers/authController.ts +71 -0
  40. package/src/controllers/modelController.ts +50 -0
  41. package/src/db/index.ts +77 -0
  42. package/src/middleware/auth.ts +34 -0
  43. package/src/middleware/jwt.ts +24 -0
  44. package/src/middleware/response.ts +28 -0
  45. package/src/routes/auth.ts +12 -0
  46. package/src/routes/modelRouter.ts +23 -0
  47. package/src/server.ts +40 -0
  48. package/src/types/express.d.ts +11 -0
  49. package/tsconfig.json +12 -0
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ <div align="center">
2
+ <img src="https://raw.githubusercontent.com/Rahul7raj/neevjs/main/docs/logo-inline.png" alt="NeevJS" height="80" />
3
+ <br />
4
+ <br />
5
+ <a href="https://github.com/Rahul7raj/neevjs"><strong>GitHub Repository</strong></a> &nbsp;|&nbsp; <a href="https://Rahul7raj.github.io/neevjs"><strong>Documentation</strong></a>
6
+ </div>
7
+
8
+ <br />
9
+
10
+ # @neevjs/server
11
+
12
+ > The optional Node.js + Express backend that works out-of-the-box with NeevJS.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @neevjs/server
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```typescript
23
+ import express from 'express'
24
+ // Note: In a real project, you would import the router/controllers from your compiled server code.
25
+ // The @neevjs/server package provides standard backend routes and middleware.
26
+ ```
27
+
28
+ ## Docs
29
+
30
+ Full documentation at [Rahul7raj.github.io/neevjs](https://Rahul7raj.github.io/neevjs)
31
+
32
+ ## License
33
+
34
+ MIT — Rahul Raj Kushwaha
@@ -0,0 +1,6 @@
1
+ import type { Request, Response } from 'express';
2
+ export declare function login(req: Request, res: Response): void;
3
+ export declare function register(req: Request, res: Response): void;
4
+ export declare function me(req: Request, res: Response): void;
5
+ export declare function logout(_req: Request, res: Response): void;
6
+ //# sourceMappingURL=authController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authController.d.ts","sourceRoot":"","sources":["../../src/controllers/authController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAahD,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAmBvD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAuB1D;AAED,wBAAgB,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAMpD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAGzD"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.login = login;
4
+ exports.register = register;
5
+ exports.me = me;
6
+ exports.logout = logout;
7
+ const db_1 = require("../db");
8
+ const jwt_1 = require("../middleware/jwt");
9
+ const response_1 = require("../middleware/response");
10
+ function login(req, res) {
11
+ const { email, password } = req.body;
12
+ if (!email || !password) {
13
+ (0, response_1.sendError)(res, 'Email and password are required');
14
+ return;
15
+ }
16
+ const user = db_1.db.findBy('auth_users', 'email', email);
17
+ if (!user || user.password !== password) {
18
+ (0, response_1.sendError)(res, 'Invalid credentials', 401);
19
+ return;
20
+ }
21
+ const { password: _pw, ...safeUser } = user;
22
+ const token = (0, jwt_1.generateToken)(safeUser);
23
+ (0, response_1.sendSuccess)(res, { user: safeUser, token });
24
+ }
25
+ function register(req, res) {
26
+ const { email, password, name } = req.body;
27
+ if (!email || !password) {
28
+ (0, response_1.sendError)(res, 'Email and password are required');
29
+ return;
30
+ }
31
+ const existing = db_1.db.findBy('auth_users', 'email', email);
32
+ if (existing) {
33
+ (0, response_1.sendError)(res, 'Email already registered', 409);
34
+ return;
35
+ }
36
+ const created = db_1.db.insert('auth_users', { email, password, name, role: 'user' });
37
+ const { password: _pw, ...safeUser } = created;
38
+ const token = (0, jwt_1.generateToken)(safeUser);
39
+ (0, response_1.sendSuccess)(res, { user: safeUser, token }, {}, 201);
40
+ }
41
+ function me(req, res) {
42
+ if (!req.user) {
43
+ (0, response_1.sendError)(res, 'Unauthorized', 401);
44
+ return;
45
+ }
46
+ (0, response_1.sendSuccess)(res, req.user);
47
+ }
48
+ function logout(_req, res) {
49
+ // JWT is stateless — client just drops the token
50
+ (0, response_1.sendSuccess)(res, { message: 'Logged out successfully' });
51
+ }
52
+ //# sourceMappingURL=authController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authController.js","sourceRoot":"","sources":["../../src/controllers/authController.ts"],"names":[],"mappings":";;AAaA,sBAmBC;AAED,4BAuBC;AAED,gBAMC;AAED,wBAGC;AArED,8BAA0B;AAC1B,2CAAiD;AACjD,qDAA+D;AAU/D,SAAgB,KAAK,CAAC,GAAY,EAAE,GAAa;IAC/C,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAA6C,CAAA;IAE7E,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAA,oBAAS,EAAC,GAAG,EAAE,iCAAiC,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,OAAE,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAA+B,CAAA;IAElF,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACxC,IAAA,oBAAS,EAAC,GAAG,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAA;QAC1C,OAAM;IACR,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAA;IAC3C,MAAM,KAAK,GAAG,IAAA,mBAAa,EAAC,QAAoB,CAAC,CAAA;IAEjD,IAAA,sBAAW,EAAC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAC7C,CAAC;AAED,SAAgB,QAAQ,CAAC,GAAY,EAAE,GAAa;IAClD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,IAIrC,CAAA;IAED,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,IAAA,oBAAS,EAAC,GAAG,EAAE,iCAAiC,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,OAAE,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IACxD,IAAI,QAAQ,EAAE,CAAC;QACb,IAAA,oBAAS,EAAC,GAAG,EAAE,0BAA0B,EAAE,GAAG,CAAC,CAAA;QAC/C,OAAM;IACR,CAAC;IAED,MAAM,OAAO,GAAG,OAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAmB,CAAA;IAClG,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC9C,MAAM,KAAK,GAAG,IAAA,mBAAa,EAAC,QAAoB,CAAC,CAAA;IAEjD,IAAA,sBAAW,EAAC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;AACtD,CAAC;AAED,SAAgB,EAAE,CAAC,GAAY,EAAE,GAAa;IAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,IAAA,oBAAS,EAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,CAAA;QACnC,OAAM;IACR,CAAC;IACD,IAAA,sBAAW,EAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC;AAED,SAAgB,MAAM,CAAC,IAAa,EAAE,GAAa;IACjD,iDAAiD;IACjD,IAAA,sBAAW,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAA;AAC1D,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Request, Response } from 'express';
2
+ export declare function createModelController(tableName: string): {
3
+ index(req: Request, res: Response): void;
4
+ show(req: Request, res: Response): void;
5
+ store(req: Request, res: Response): void;
6
+ update(req: Request, res: Response): void;
7
+ destroy(req: Request, res: Response): void;
8
+ };
9
+ //# sourceMappingURL=modelController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelController.d.ts","sourceRoot":"","sources":["../../src/controllers/modelController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAKhD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM;eAExC,OAAO,OAAO,QAAQ,GAAG,IAAI;cAS9B,OAAO,OAAO,QAAQ,GAAG,IAAI;eAS5B,OAAO,OAAO,QAAQ,GAAG,IAAI;gBAM5B,OAAO,OAAO,QAAQ,GAAG,IAAI;iBAS5B,OAAO,OAAO,QAAQ,GAAG,IAAI;EAS7C"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModelController = createModelController;
4
+ const db_1 = require("../db");
5
+ const response_1 = require("../middleware/response");
6
+ function createModelController(tableName) {
7
+ return {
8
+ index(req, res) {
9
+ const all = db_1.db.findAll(tableName);
10
+ const page = parseInt(String(req.query['page'] ?? '1'), 10);
11
+ const perPage = parseInt(String(req.query['perPage'] ?? '20'), 10);
12
+ const start = (page - 1) * perPage;
13
+ const paginated = all.slice(start, start + perPage);
14
+ (0, response_1.sendSuccess)(res, paginated, (0, response_1.paginateMeta)(all.length, page, perPage));
15
+ },
16
+ show(req, res) {
17
+ const record = db_1.db.findById(tableName, req.params['id'] ?? '');
18
+ if (!record) {
19
+ (0, response_1.sendError)(res, `${tableName} not found`, 404);
20
+ return;
21
+ }
22
+ (0, response_1.sendSuccess)(res, record);
23
+ },
24
+ store(req, res) {
25
+ const body = req.body;
26
+ const record = db_1.db.insert(tableName, body);
27
+ (0, response_1.sendSuccess)(res, record, {}, 201);
28
+ },
29
+ update(req, res) {
30
+ const record = db_1.db.update(tableName, req.params['id'] ?? '', req.body);
31
+ if (!record) {
32
+ (0, response_1.sendError)(res, `${tableName} not found`, 404);
33
+ return;
34
+ }
35
+ (0, response_1.sendSuccess)(res, record);
36
+ },
37
+ destroy(req, res) {
38
+ const deleted = db_1.db.delete(tableName, req.params['id'] ?? '');
39
+ if (!deleted) {
40
+ (0, response_1.sendError)(res, `${tableName} not found`, 404);
41
+ return;
42
+ }
43
+ (0, response_1.sendSuccess)(res, { message: `${tableName} deleted` });
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=modelController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelController.js","sourceRoot":"","sources":["../../src/controllers/modelController.ts"],"names":[],"mappings":";;AAKA,sDA4CC;AAhDD,8BAA0B;AAC1B,qDAA6E;AAG7E,SAAgB,qBAAqB,CAAC,SAAiB;IACrD,OAAO;QACL,KAAK,CAAC,GAAY,EAAE,GAAa;YAC/B,MAAM,GAAG,GAAG,OAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;YAC3D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;YAClE,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAA;YAClC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;YACnD,IAAA,sBAAW,EAAC,GAAG,EAAE,SAAS,EAAE,IAAA,uBAAY,EAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;QACtE,CAAC;QAED,IAAI,CAAC,GAAY,EAAE,GAAa;YAC9B,MAAM,MAAM,GAAG,OAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YAC7D,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAA,oBAAS,EAAC,GAAG,EAAE,GAAG,SAAS,YAAY,EAAE,GAAG,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YACD,IAAA,sBAAW,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAC1B,CAAC;QAED,KAAK,CAAC,GAAY,EAAE,GAAa;YAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,IAA+B,CAAA;YAChD,MAAM,MAAM,GAAG,OAAE,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YACzC,IAAA,sBAAW,EAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;QACnC,CAAC;QAED,MAAM,CAAC,GAAY,EAAE,GAAa;YAChC,MAAM,MAAM,GAAG,OAAE,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,IAA4B,CAAC,CAAA;YAC7F,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAA,oBAAS,EAAC,GAAG,EAAE,GAAG,SAAS,YAAY,EAAE,GAAG,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YACD,IAAA,sBAAW,EAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,CAAC,GAAY,EAAE,GAAa;YACjC,MAAM,OAAO,GAAG,OAAE,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;YAC5D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAA,oBAAS,EAAC,GAAG,EAAE,GAAG,SAAS,YAAY,EAAE,GAAG,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YACD,IAAA,sBAAW,EAAC,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,SAAS,UAAU,EAAE,CAAC,CAAA;QACvD,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { ModelRecord } from '@neevjs/shared';
2
+ declare class InMemoryDB {
3
+ private store;
4
+ private counters;
5
+ private nextId;
6
+ seed(table: string, rows: ModelRecord[]): void;
7
+ findAll(table: string): ModelRecord[];
8
+ findById(table: string, id: number | string): ModelRecord | undefined;
9
+ findBy(table: string, key: string, value: unknown): ModelRecord | undefined;
10
+ insert(table: string, data: Omit<ModelRecord, 'id'>): ModelRecord;
11
+ update(table: string, id: number | string, data: Partial<ModelRecord>): ModelRecord | null;
12
+ delete(table: string, id: number | string): boolean;
13
+ }
14
+ export declare const db: InMemoryDB;
15
+ export {};
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAGjD,cAAM,UAAU;IACd,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,QAAQ,CAA4B;IAE5C,OAAO,CAAC,MAAM;IAOd,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,IAAI;IAM9C,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE;IAIrC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS;IAIrE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS;IAI3E,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,WAAW;IAQjE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,GAAG,IAAI;IAS1F,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;CAQpD;AAED,eAAO,MAAM,EAAE,YAAmB,CAAA"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.db = void 0;
4
+ // Simple in-memory store — replace with PostgreSQL/SQLite in production
5
+ class InMemoryDB {
6
+ constructor() {
7
+ this.store = new Map();
8
+ this.counters = new Map();
9
+ }
10
+ nextId(table) {
11
+ const current = this.counters.get(table) ?? 0;
12
+ const next = current + 1;
13
+ this.counters.set(table, next);
14
+ return next;
15
+ }
16
+ seed(table, rows) {
17
+ this.store.set(table, rows);
18
+ const maxId = rows.reduce((m, r) => Math.max(m, Number(r.id ?? 0)), 0);
19
+ this.counters.set(table, maxId);
20
+ }
21
+ findAll(table) {
22
+ return this.store.get(table) ?? [];
23
+ }
24
+ findById(table, id) {
25
+ return (this.store.get(table) ?? []).find((r) => String(r.id) === String(id));
26
+ }
27
+ findBy(table, key, value) {
28
+ return (this.store.get(table) ?? []).find((r) => r[key] === value);
29
+ }
30
+ insert(table, data) {
31
+ const rows = this.store.get(table) ?? [];
32
+ const record = { id: this.nextId(table), ...data };
33
+ rows.push(record);
34
+ this.store.set(table, rows);
35
+ return record;
36
+ }
37
+ update(table, id, data) {
38
+ const rows = this.store.get(table) ?? [];
39
+ const index = rows.findIndex((r) => String(r.id) === String(id));
40
+ if (index === -1)
41
+ return null;
42
+ rows[index] = { ...rows[index], ...data };
43
+ this.store.set(table, rows);
44
+ return rows[index];
45
+ }
46
+ delete(table, id) {
47
+ const rows = this.store.get(table) ?? [];
48
+ const index = rows.findIndex((r) => String(r.id) === String(id));
49
+ if (index === -1)
50
+ return false;
51
+ rows.splice(index, 1);
52
+ this.store.set(table, rows);
53
+ return true;
54
+ }
55
+ }
56
+ exports.db = new InMemoryDB();
57
+ // Seed default tables
58
+ exports.db.seed('users', [
59
+ { id: 1, name: 'Rahul Kushwaha', email: 'rahul@example.com', role: 'admin' },
60
+ { id: 2, name: 'Priya Sharma', email: 'priya@example.com', role: 'user' },
61
+ ]);
62
+ exports.db.seed('auth_users', [
63
+ {
64
+ id: 1,
65
+ name: 'Admin',
66
+ email: 'admin@neevjs.dev',
67
+ // In production use bcrypt — for demo plain text
68
+ password: 'admin123',
69
+ role: 'admin',
70
+ },
71
+ ]);
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { NextFunction, Request, Response } from 'express';
2
+ export declare function authMiddleware(req: Request, res: Response, next: NextFunction): void;
3
+ export declare function requireRole(role: string): (req: Request, res: Response, next: NextFunction) => void;
4
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAG9D,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAoBpF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,IAC9B,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,KAAG,IAAI,CAO/D"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authMiddleware = authMiddleware;
4
+ exports.requireRole = requireRole;
5
+ const jwt_1 = require("./jwt");
6
+ function authMiddleware(req, res, next) {
7
+ const authHeader = req.headers.authorization;
8
+ const token = authHeader?.split(' ')[1];
9
+ if (!token) {
10
+ res.status(401).json({ data: null, meta: {}, error: 'Unauthorized — no token provided' });
11
+ return;
12
+ }
13
+ try {
14
+ const decoded = (0, jwt_1.verifyToken)(token);
15
+ req.user = {
16
+ id: decoded.id,
17
+ email: decoded.email,
18
+ role: decoded.role,
19
+ };
20
+ next();
21
+ }
22
+ catch {
23
+ res.status(401).json({ data: null, meta: {}, error: 'Unauthorized — invalid or expired token' });
24
+ }
25
+ }
26
+ function requireRole(role) {
27
+ return (req, res, next) => {
28
+ if (req.user?.role !== role) {
29
+ res.status(403).json({ data: null, meta: {}, error: 'Forbidden — insufficient permissions' });
30
+ return;
31
+ }
32
+ next();
33
+ };
34
+ }
35
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":";;AAGA,wCAoBC;AAED,kCAQC;AAhCD,+BAAmC;AAEnC,SAAgB,cAAc,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAA;IAC5C,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAA;QACzF,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,iBAAW,EAAC,KAAK,CAAC,CAAA;QAClC,GAAG,CAAC,IAAI,GAAG;YACT,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAA;QACD,IAAI,EAAE,CAAA;IACR,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC,CAAA;IAClG,CAAC;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAC/D,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC,CAAA;YAC7F,OAAM;QACR,CAAC;QACD,IAAI,EAAE,CAAA;IACR,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { AuthUser } from '@neevjs/shared';
2
+ export interface JwtPayload {
3
+ id: number | string;
4
+ email: string;
5
+ role?: string;
6
+ }
7
+ export declare function generateToken(user: AuthUser): string;
8
+ export declare function verifyToken(token: string): JwtPayload;
9
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/middleware/jwt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAK9C,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAOpD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAErD"}
@@ -0,0 +1,22 @@
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.generateToken = generateToken;
7
+ exports.verifyToken = verifyToken;
8
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
+ const SECRET = process.env['JWT_SECRET'] ?? 'neevjs-secret-change-in-production';
10
+ const EXPIRES_IN = '7d';
11
+ function generateToken(user) {
12
+ const payload = {
13
+ id: user.id,
14
+ email: user.email,
15
+ role: typeof user.role === 'string' ? user.role : undefined,
16
+ };
17
+ return jsonwebtoken_1.default.sign(payload, SECRET, { expiresIn: EXPIRES_IN });
18
+ }
19
+ function verifyToken(token) {
20
+ return jsonwebtoken_1.default.verify(token, SECRET);
21
+ }
22
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/middleware/jwt.ts"],"names":[],"mappings":";;;;;AAYA,sCAOC;AAED,kCAEC;AAvBD,gEAA8B;AAG9B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,oCAAoC,CAAA;AAChF,MAAM,UAAU,GAAG,IAAI,CAAA;AAQvB,SAAgB,aAAa,CAAC,IAAc;IAC1C,MAAM,OAAO,GAAe;QAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KAC5D,CAAA;IACD,OAAO,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAA;AAC7D,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAe,CAAA;AAChD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Response } from 'express';
2
+ import type { Pagination } from '@neevjs/shared';
3
+ export declare function sendSuccess<T>(res: Response, data: T, meta?: Record<string, unknown>, status?: number): void;
4
+ export declare function sendError(res: Response, message: string, status?: number): void;
5
+ export declare function paginateMeta(total: number, page: number, perPage: number): {
6
+ pagination: Pagination;
7
+ };
8
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/middleware/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE7D,wBAAgB,WAAW,CAAC,CAAC,EAC3B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,CAAC,EACP,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,MAAM,SAAM,GACX,IAAI,CAGN;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,CASrG"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendSuccess = sendSuccess;
4
+ exports.sendError = sendError;
5
+ exports.paginateMeta = paginateMeta;
6
+ function sendSuccess(res, data, meta = {}, status = 200) {
7
+ const body = { data, meta, error: null };
8
+ res.status(status).json(body);
9
+ }
10
+ function sendError(res, message, status = 400) {
11
+ const body = { data: null, meta: {}, error: message };
12
+ res.status(status).json(body);
13
+ }
14
+ function paginateMeta(total, page, perPage) {
15
+ return {
16
+ pagination: {
17
+ page,
18
+ perPage,
19
+ total,
20
+ lastPage: Math.ceil(total / perPage),
21
+ },
22
+ };
23
+ }
24
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/middleware/response.ts"],"names":[],"mappings":";;AAGA,kCAQC;AAED,8BAGC;AAED,oCASC;AAxBD,SAAgB,WAAW,CACzB,GAAa,EACb,IAAO,EACP,OAAgC,EAAE,EAClC,MAAM,GAAG,GAAG;IAEZ,MAAM,IAAI,GAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACxD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAED,SAAgB,SAAS,CAAC,GAAa,EAAE,OAAe,EAAE,MAAM,GAAG,GAAG;IACpE,MAAM,IAAI,GAAsB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IACxE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAED,SAAgB,YAAY,CAAC,KAAa,EAAE,IAAY,EAAE,OAAe;IACvE,OAAO;QACL,UAAU,EAAE;YACV,IAAI;YACJ,OAAO;YACP,KAAK;YACL,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC;SACrC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Router } from 'express';
2
+ declare const router: Router;
3
+ export default router;
4
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIhC,QAAA,MAAM,MAAM,EAAE,MAAiB,CAAA;AAO/B,eAAe,MAAM,CAAA"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const express_1 = require("express");
4
+ const authController_1 = require("../controllers/authController");
5
+ const auth_1 = require("../middleware/auth");
6
+ const router = (0, express_1.Router)();
7
+ router.post('/login', authController_1.login);
8
+ router.post('/register', authController_1.register);
9
+ router.get('/me', auth_1.authMiddleware, authController_1.me);
10
+ router.post('/logout', auth_1.authMiddleware, authController_1.logout);
11
+ exports.default = router;
12
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":";;AAAA,qCAAgC;AAChC,kEAA2E;AAC3E,6CAAmD;AAEnD,MAAM,MAAM,GAAW,IAAA,gBAAM,GAAE,CAAA;AAE/B,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAK,CAAC,CAAA;AAC5B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,yBAAQ,CAAC,CAAA;AAClC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,qBAAc,EAAE,mBAAE,CAAC,CAAA;AACrC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAc,EAAE,uBAAM,CAAC,CAAA;AAE9C,kBAAe,MAAM,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ export declare function createModelRouter(tableName: string, protected_?: boolean): Router;
3
+ //# sourceMappingURL=modelRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelRouter.d.ts","sourceRoot":"","sources":["../../src/routes/modelRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGhC,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,MAAM,CAmB/E"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModelRouter = createModelRouter;
4
+ const express_1 = require("express");
5
+ const modelController_1 = require("../controllers/modelController");
6
+ function createModelRouter(tableName, protected_ = false) {
7
+ const router = (0, express_1.Router)();
8
+ const ctrl = (0, modelController_1.createModelController)(tableName);
9
+ // Lazy import to avoid circular dep — only import when protected routes needed
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const { authMiddleware } = protected_
12
+ ? require('../middleware/auth')
13
+ : { authMiddleware: null };
14
+ const guard = protected_ && authMiddleware ? [authMiddleware] : [];
15
+ router.get('/', ...guard, ctrl.index);
16
+ router.get('/:id', ...guard, ctrl.show);
17
+ router.post('/', ...guard, ctrl.store);
18
+ router.put('/:id', ...guard, ctrl.update);
19
+ router.delete('/:id', ...guard, ctrl.destroy);
20
+ return router;
21
+ }
22
+ //# sourceMappingURL=modelRouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelRouter.js","sourceRoot":"","sources":["../../src/routes/modelRouter.ts"],"names":[],"mappings":";;AAGA,8CAmBC;AAtBD,qCAAgC;AAChC,oEAAsE;AAEtE,SAAgB,iBAAiB,CAAC,SAAiB,EAAE,UAAU,GAAG,KAAK;IACrE,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAA;IACvB,MAAM,IAAI,GAAG,IAAA,uCAAqB,EAAC,SAAS,CAAC,CAAA;IAE7C,+EAA+E;IAC/E,8DAA8D;IAC9D,MAAM,EAAE,cAAc,EAAE,GAAG,UAAU;QACnC,CAAC,CAAE,OAAO,CAAC,oBAAoB,CAAyI;QACxK,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAA;IAE5B,MAAM,KAAK,GAAG,UAAU,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAElE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACrC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACzC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAE7C,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Application } from 'express';
2
+ declare const app: Application;
3
+ export default app;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAK9C,QAAA,MAAM,GAAG,EAAE,WAAuB,CAAA;AAkClC,eAAe,GAAG,CAAA"}
package/dist/server.js ADDED
@@ -0,0 +1,37 @@
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 express_1 = __importDefault(require("express"));
7
+ const cors_1 = __importDefault(require("cors"));
8
+ const auth_1 = __importDefault(require("./routes/auth"));
9
+ const modelRouter_1 = require("./routes/modelRouter");
10
+ const app = (0, express_1.default)();
11
+ const PORT = process.env['PORT'] ?? 3001;
12
+ // ─── Middleware ───────────────────────────────────────────────────────────────
13
+ app.use((0, cors_1.default)({ origin: '*' }));
14
+ app.use(express_1.default.json());
15
+ // ─── Health check ─────────────────────────────────────────────────────────────
16
+ app.get('/api/health', (_req, res) => {
17
+ res.json({ data: { status: 'ok', framework: 'NeevJS Server v0.0.1' }, meta: {}, error: null });
18
+ });
19
+ // ─── Auth routes ──────────────────────────────────────────────────────────────
20
+ app.use('/api/auth', auth_1.default);
21
+ // ─── Auto-registered model routes ─────────────────────────────────────────────
22
+ // Add your models here. Set second arg to true to require authentication.
23
+ app.use('/api/users', (0, modelRouter_1.createModelRouter)('users', false));
24
+ // Example of a protected route:
25
+ // app.use('/api/orders', createModelRouter('orders', true))
26
+ // ─── 404 handler ──────────────────────────────────────────────────────────────
27
+ app.use((_req, res) => {
28
+ res.status(404).json({ data: null, meta: {}, error: 'Route not found' });
29
+ });
30
+ // ─── Start ────────────────────────────────────────────────────────────────────
31
+ app.listen(PORT, () => {
32
+ console.log(`\n🚀 NeevJS Server running at http://localhost:${PORT}`);
33
+ console.log(` API: http://localhost:${PORT}/api`);
34
+ console.log(` Health: http://localhost:${PORT}/api/health\n`);
35
+ });
36
+ exports.default = app;
37
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8C;AAC9C,gDAAuB;AACvB,yDAAsC;AACtC,sDAAwD;AAExD,MAAM,GAAG,GAAgB,IAAA,iBAAO,GAAE,CAAA;AAClC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAA;AAExC,iFAAiF;AACjF,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;AAC9B,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAA;AAEvB,iFAAiF;AACjF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACnC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,sBAAsB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AAChG,CAAC,CAAC,CAAA;AAEF,iFAAiF;AACjF,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,cAAU,CAAC,CAAA;AAEhC,iFAAiF;AACjF,0EAA0E;AAC1E,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,IAAA,+BAAiB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;AAExD,gCAAgC;AAChC,4DAA4D;AAE5D,iFAAiF;AACjF,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;AAC1E,CAAC,CAAC,CAAA;AAEF,iFAAiF;AACjF,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,OAAO,CAAC,GAAG,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAA;IACrE,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,MAAM,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,eAAe,CAAC,CAAA;AACjE,CAAC,CAAC,CAAA;AAEF,kBAAe,GAAG,CAAA"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@neevjs/server",
3
+ "version": "0.0.1",
4
+ "description": "NeevJS optional Node.js backend starter — REST API with auth, middleware, and JSON contract",
5
+ "keywords": [
6
+ "neevjs",
7
+ "node",
8
+ "express",
9
+ "api",
10
+ "backend"
11
+ ],
12
+ "author": "Rahul Raj Kushwaha <rahulkraj.dev@gmail.com>",
13
+ "license": "MIT",
14
+ "main": "dist/server.js",
15
+ "types": "dist/server.d.ts",
16
+ "dependencies": {
17
+ "cors": "^2.8.5",
18
+ "express": "^4.18.2",
19
+ "jsonwebtoken": "^9.0.2",
20
+ "@neevjs/shared": "0.0.1"
21
+ },
22
+ "devDependencies": {
23
+ "@types/cors": "^2.8.17",
24
+ "@types/express": "^4.17.21",
25
+ "@types/jsonwebtoken": "^9.0.5",
26
+ "@types/node": "^20.10.0",
27
+ "ts-node-dev": "^2.0.0",
28
+ "typescript": "^5.3.3"
29
+ },
30
+ "scripts": {
31
+ "dev": "ts-node-dev --respawn --transpile-only src/server.ts",
32
+ "build": "tsc -p tsconfig.json",
33
+ "start": "node dist/server.js",
34
+ "clean": "rm -rf dist"
35
+ }
36
+ }
@@ -0,0 +1,71 @@
1
+ import type { Request, Response } from 'express'
2
+ import { db } from '../db'
3
+ import { generateToken } from '../middleware/jwt'
4
+ import { sendError, sendSuccess } from '../middleware/response'
5
+ import type { AuthUser, ModelRecord } from '@neevjs/shared'
6
+
7
+ interface AuthUserRecord extends ModelRecord {
8
+ email: string
9
+ password: string
10
+ name?: string
11
+ role?: string
12
+ }
13
+
14
+ export function login(req: Request, res: Response): void {
15
+ const { email, password } = req.body as { email?: string; password?: string }
16
+
17
+ if (!email || !password) {
18
+ sendError(res, 'Email and password are required')
19
+ return
20
+ }
21
+
22
+ const user = db.findBy('auth_users', 'email', email) as AuthUserRecord | undefined
23
+
24
+ if (!user || user.password !== password) {
25
+ sendError(res, 'Invalid credentials', 401)
26
+ return
27
+ }
28
+
29
+ const { password: _pw, ...safeUser } = user
30
+ const token = generateToken(safeUser as AuthUser)
31
+
32
+ sendSuccess(res, { user: safeUser, token })
33
+ }
34
+
35
+ export function register(req: Request, res: Response): void {
36
+ const { email, password, name } = req.body as {
37
+ email?: string
38
+ password?: string
39
+ name?: string
40
+ }
41
+
42
+ if (!email || !password) {
43
+ sendError(res, 'Email and password are required')
44
+ return
45
+ }
46
+
47
+ const existing = db.findBy('auth_users', 'email', email)
48
+ if (existing) {
49
+ sendError(res, 'Email already registered', 409)
50
+ return
51
+ }
52
+
53
+ const created = db.insert('auth_users', { email, password, name, role: 'user' }) as AuthUserRecord
54
+ const { password: _pw, ...safeUser } = created
55
+ const token = generateToken(safeUser as AuthUser)
56
+
57
+ sendSuccess(res, { user: safeUser, token }, {}, 201)
58
+ }
59
+
60
+ export function me(req: Request, res: Response): void {
61
+ if (!req.user) {
62
+ sendError(res, 'Unauthorized', 401)
63
+ return
64
+ }
65
+ sendSuccess(res, req.user)
66
+ }
67
+
68
+ export function logout(_req: Request, res: Response): void {
69
+ // JWT is stateless — client just drops the token
70
+ sendSuccess(res, { message: 'Logged out successfully' })
71
+ }
@@ -0,0 +1,50 @@
1
+ import type { Request, Response } from 'express'
2
+ import { db } from '../db'
3
+ import { sendError, sendSuccess, paginateMeta } from '../middleware/response'
4
+ import type { ModelRecord } from '@neevjs/shared'
5
+
6
+ export function createModelController(tableName: string) {
7
+ return {
8
+ index(req: Request, res: Response): void {
9
+ const all = db.findAll(tableName)
10
+ const page = parseInt(String(req.query['page'] ?? '1'), 10)
11
+ const perPage = parseInt(String(req.query['perPage'] ?? '20'), 10)
12
+ const start = (page - 1) * perPage
13
+ const paginated = all.slice(start, start + perPage)
14
+ sendSuccess(res, paginated, paginateMeta(all.length, page, perPage))
15
+ },
16
+
17
+ show(req: Request, res: Response): void {
18
+ const record = db.findById(tableName, req.params['id'] ?? '')
19
+ if (!record) {
20
+ sendError(res, `${tableName} not found`, 404)
21
+ return
22
+ }
23
+ sendSuccess(res, record)
24
+ },
25
+
26
+ store(req: Request, res: Response): void {
27
+ const body = req.body as Omit<ModelRecord, 'id'>
28
+ const record = db.insert(tableName, body)
29
+ sendSuccess(res, record, {}, 201)
30
+ },
31
+
32
+ update(req: Request, res: Response): void {
33
+ const record = db.update(tableName, req.params['id'] ?? '', req.body as Partial<ModelRecord>)
34
+ if (!record) {
35
+ sendError(res, `${tableName} not found`, 404)
36
+ return
37
+ }
38
+ sendSuccess(res, record)
39
+ },
40
+
41
+ destroy(req: Request, res: Response): void {
42
+ const deleted = db.delete(tableName, req.params['id'] ?? '')
43
+ if (!deleted) {
44
+ sendError(res, `${tableName} not found`, 404)
45
+ return
46
+ }
47
+ sendSuccess(res, { message: `${tableName} deleted` })
48
+ },
49
+ }
50
+ }
@@ -0,0 +1,77 @@
1
+ import type { ModelRecord } from '@neevjs/shared'
2
+
3
+ // Simple in-memory store — replace with PostgreSQL/SQLite in production
4
+ class InMemoryDB {
5
+ private store = new Map<string, ModelRecord[]>()
6
+ private counters = new Map<string, number>()
7
+
8
+ private nextId(table: string): number {
9
+ const current = this.counters.get(table) ?? 0
10
+ const next = current + 1
11
+ this.counters.set(table, next)
12
+ return next
13
+ }
14
+
15
+ seed(table: string, rows: ModelRecord[]): void {
16
+ this.store.set(table, rows)
17
+ const maxId = rows.reduce((m, r) => Math.max(m, Number(r.id ?? 0)), 0)
18
+ this.counters.set(table, maxId)
19
+ }
20
+
21
+ findAll(table: string): ModelRecord[] {
22
+ return this.store.get(table) ?? []
23
+ }
24
+
25
+ findById(table: string, id: number | string): ModelRecord | undefined {
26
+ return (this.store.get(table) ?? []).find((r) => String(r.id) === String(id))
27
+ }
28
+
29
+ findBy(table: string, key: string, value: unknown): ModelRecord | undefined {
30
+ return (this.store.get(table) ?? []).find((r) => r[key] === value)
31
+ }
32
+
33
+ insert(table: string, data: Omit<ModelRecord, 'id'>): ModelRecord {
34
+ const rows = this.store.get(table) ?? []
35
+ const record: ModelRecord = { id: this.nextId(table), ...data }
36
+ rows.push(record)
37
+ this.store.set(table, rows)
38
+ return record
39
+ }
40
+
41
+ update(table: string, id: number | string, data: Partial<ModelRecord>): ModelRecord | null {
42
+ const rows = this.store.get(table) ?? []
43
+ const index = rows.findIndex((r) => String(r.id) === String(id))
44
+ if (index === -1) return null
45
+ rows[index] = { ...rows[index], ...data }
46
+ this.store.set(table, rows)
47
+ return rows[index]
48
+ }
49
+
50
+ delete(table: string, id: number | string): boolean {
51
+ const rows = this.store.get(table) ?? []
52
+ const index = rows.findIndex((r) => String(r.id) === String(id))
53
+ if (index === -1) return false
54
+ rows.splice(index, 1)
55
+ this.store.set(table, rows)
56
+ return true
57
+ }
58
+ }
59
+
60
+ export const db = new InMemoryDB()
61
+
62
+ // Seed default tables
63
+ db.seed('users', [
64
+ { id: 1, name: 'Rahul Kushwaha', email: 'rahul@example.com', role: 'admin' },
65
+ { id: 2, name: 'Priya Sharma', email: 'priya@example.com', role: 'user' },
66
+ ])
67
+
68
+ db.seed('auth_users', [
69
+ {
70
+ id: 1,
71
+ name: 'Admin',
72
+ email: 'admin@neevjs.dev',
73
+ // In production use bcrypt — for demo plain text
74
+ password: 'admin123',
75
+ role: 'admin',
76
+ },
77
+ ])
@@ -0,0 +1,34 @@
1
+ import type { NextFunction, Request, Response } from 'express'
2
+ import { verifyToken } from './jwt'
3
+
4
+ export function authMiddleware(req: Request, res: Response, next: NextFunction): void {
5
+ const authHeader = req.headers.authorization
6
+ const token = authHeader?.split(' ')[1]
7
+
8
+ if (!token) {
9
+ res.status(401).json({ data: null, meta: {}, error: 'Unauthorized — no token provided' })
10
+ return
11
+ }
12
+
13
+ try {
14
+ const decoded = verifyToken(token)
15
+ req.user = {
16
+ id: decoded.id,
17
+ email: decoded.email,
18
+ role: decoded.role,
19
+ }
20
+ next()
21
+ } catch {
22
+ res.status(401).json({ data: null, meta: {}, error: 'Unauthorized — invalid or expired token' })
23
+ }
24
+ }
25
+
26
+ export function requireRole(role: string) {
27
+ return (req: Request, res: Response, next: NextFunction): void => {
28
+ if (req.user?.role !== role) {
29
+ res.status(403).json({ data: null, meta: {}, error: 'Forbidden — insufficient permissions' })
30
+ return
31
+ }
32
+ next()
33
+ }
34
+ }
@@ -0,0 +1,24 @@
1
+ import jwt from 'jsonwebtoken'
2
+ import type { AuthUser } from '@neevjs/shared'
3
+
4
+ const SECRET = process.env['JWT_SECRET'] ?? 'neevjs-secret-change-in-production'
5
+ const EXPIRES_IN = '7d'
6
+
7
+ export interface JwtPayload {
8
+ id: number | string
9
+ email: string
10
+ role?: string
11
+ }
12
+
13
+ export function generateToken(user: AuthUser): string {
14
+ const payload: JwtPayload = {
15
+ id: user.id,
16
+ email: user.email,
17
+ role: typeof user.role === 'string' ? user.role : undefined,
18
+ }
19
+ return jwt.sign(payload, SECRET, { expiresIn: EXPIRES_IN })
20
+ }
21
+
22
+ export function verifyToken(token: string): JwtPayload {
23
+ return jwt.verify(token, SECRET) as JwtPayload
24
+ }
@@ -0,0 +1,28 @@
1
+ import type { Response } from 'express'
2
+ import type { ApiResponse, Pagination } from '@neevjs/shared'
3
+
4
+ export function sendSuccess<T>(
5
+ res: Response,
6
+ data: T,
7
+ meta: Record<string, unknown> = {},
8
+ status = 200
9
+ ): void {
10
+ const body: ApiResponse<T> = { data, meta, error: null }
11
+ res.status(status).json(body)
12
+ }
13
+
14
+ export function sendError(res: Response, message: string, status = 400): void {
15
+ const body: ApiResponse<null> = { data: null, meta: {}, error: message }
16
+ res.status(status).json(body)
17
+ }
18
+
19
+ export function paginateMeta(total: number, page: number, perPage: number): { pagination: Pagination } {
20
+ return {
21
+ pagination: {
22
+ page,
23
+ perPage,
24
+ total,
25
+ lastPage: Math.ceil(total / perPage),
26
+ },
27
+ }
28
+ }
@@ -0,0 +1,12 @@
1
+ import { Router } from 'express'
2
+ import { login, register, me, logout } from '../controllers/authController'
3
+ import { authMiddleware } from '../middleware/auth'
4
+
5
+ const router: Router = Router()
6
+
7
+ router.post('/login', login)
8
+ router.post('/register', register)
9
+ router.get('/me', authMiddleware, me)
10
+ router.post('/logout', authMiddleware, logout)
11
+
12
+ export default router
@@ -0,0 +1,23 @@
1
+ import { Router } from 'express'
2
+ import { createModelController } from '../controllers/modelController'
3
+
4
+ export function createModelRouter(tableName: string, protected_ = false): Router {
5
+ const router = Router()
6
+ const ctrl = createModelController(tableName)
7
+
8
+ // Lazy import to avoid circular dep — only import when protected routes needed
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ const { authMiddleware } = protected_
11
+ ? (require('../middleware/auth') as { authMiddleware: (req: import('express').Request, res: import('express').Response, next: import('express').NextFunction) => void })
12
+ : { authMiddleware: null }
13
+
14
+ const guard = protected_ && authMiddleware ? [authMiddleware] : []
15
+
16
+ router.get('/', ...guard, ctrl.index)
17
+ router.get('/:id', ...guard, ctrl.show)
18
+ router.post('/', ...guard, ctrl.store)
19
+ router.put('/:id', ...guard, ctrl.update)
20
+ router.delete('/:id', ...guard, ctrl.destroy)
21
+
22
+ return router
23
+ }
package/src/server.ts ADDED
@@ -0,0 +1,40 @@
1
+ import express, { Application } from 'express'
2
+ import cors from 'cors'
3
+ import authRoutes from './routes/auth'
4
+ import { createModelRouter } from './routes/modelRouter'
5
+
6
+ const app: Application = express()
7
+ const PORT = process.env['PORT'] ?? 3001
8
+
9
+ // ─── Middleware ───────────────────────────────────────────────────────────────
10
+ app.use(cors({ origin: '*' }))
11
+ app.use(express.json())
12
+
13
+ // ─── Health check ─────────────────────────────────────────────────────────────
14
+ app.get('/api/health', (_req, res) => {
15
+ res.json({ data: { status: 'ok', framework: 'NeevJS Server v0.0.1' }, meta: {}, error: null })
16
+ })
17
+
18
+ // ─── Auth routes ──────────────────────────────────────────────────────────────
19
+ app.use('/api/auth', authRoutes)
20
+
21
+ // ─── Auto-registered model routes ─────────────────────────────────────────────
22
+ // Add your models here. Set second arg to true to require authentication.
23
+ app.use('/api/users', createModelRouter('users', false))
24
+
25
+ // Example of a protected route:
26
+ // app.use('/api/orders', createModelRouter('orders', true))
27
+
28
+ // ─── 404 handler ──────────────────────────────────────────────────────────────
29
+ app.use((_req, res) => {
30
+ res.status(404).json({ data: null, meta: {}, error: 'Route not found' })
31
+ })
32
+
33
+ // ─── Start ────────────────────────────────────────────────────────────────────
34
+ app.listen(PORT, () => {
35
+ console.log(`\n🚀 NeevJS Server running at http://localhost:${PORT}`)
36
+ console.log(` API: http://localhost:${PORT}/api`)
37
+ console.log(` Health: http://localhost:${PORT}/api/health\n`)
38
+ })
39
+
40
+ export default app
@@ -0,0 +1,11 @@
1
+ import type { AuthUser } from '@neevjs/shared'
2
+
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ user?: AuthUser
7
+ }
8
+ }
9
+ }
10
+
11
+ export {}
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "target": "ES2020",
5
+ "module": "CommonJS",
6
+ "moduleResolution": "node",
7
+ "outDir": "dist",
8
+ "rootDir": "src",
9
+ "jsx": "preserve"
10
+ },
11
+ "include": ["src"]
12
+ }