jcc-express-mvc 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
File without changes
package/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("./src");
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "jcc-express-mvc",
3
+ "version": "1.0.0",
4
+ "description": "express mvc structure",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/jammehabdou64/express-mvc.git"
12
+ },
13
+ "keywords": [
14
+ "library"
15
+ ],
16
+ "author": "Abdou Jammeh",
17
+ "license": "ISC",
18
+ "bugs": {
19
+ "url": "https://github.com/jammehabdou64/express-mvc.git/issues"
20
+ },
21
+ "homepage": "https://github.com/jammehabdou64/express-mvc.git#readme"
22
+ }
@@ -0,0 +1,74 @@
1
+ const passport = require("passport");
2
+ const { getModel, verifyHash } = require("../helpers");
3
+ const User = getModel("User");
4
+
5
+ class Auth {
6
+ async login(data = {}, password = "") {
7
+ try {
8
+ const user = await User.findOne(data).select("+password");
9
+ if (!user) {
10
+ return false;
11
+ }
12
+
13
+ return (await verifyHash(password, user.password)) ? user : false;
14
+ } catch (error) {
15
+ return new Error(error.message);
16
+ }
17
+ }
18
+
19
+ async isAdmin(req, res, next) {
20
+ try {
21
+ const user = await User.findById(req.id);
22
+ if (!user) {
23
+ return res.json({ message: "Not authorize" }).status(403);
24
+ }
25
+
26
+ if (
27
+ user.role != "admin" ||
28
+ user.role != "Admin" ||
29
+ user.role != false ||
30
+ user.roleType != "admin" ||
31
+ user.roleType != "Admin" ||
32
+ user.roleType != false ||
33
+ user.isAdmin != "Admin" ||
34
+ user.isAdmin != "admin" ||
35
+ user.isAdmin != false
36
+ ) {
37
+ return res.json({ message: "Not authorize" }).status(403);
38
+ }
39
+
40
+ next();
41
+ } catch (error) {
42
+ next(error);
43
+ }
44
+ }
45
+
46
+ async verifyEmail(req, res, next) {
47
+ try {
48
+ const user = await User.findById(req.id);
49
+ if (!user) {
50
+ return res.json({ message: "Not authorize" }).status(403);
51
+ }
52
+ if (!user.verify_email || !user.verifyEmail) {
53
+ return res.json({ message: "please verify your email" }).status(403);
54
+ }
55
+ next();
56
+ } catch (err) {
57
+ next(err);
58
+ }
59
+ }
60
+
61
+ attempt(req, res, next) {
62
+ try {
63
+ let redirectBack = req.previsiousUrls[1];
64
+ return passport.authenticate("local", {
65
+ successRedirect: "/home",
66
+ failureRedirect: `${redirectBack ? redirectBack : "/login"}`,
67
+ failureFlash: true,
68
+ })(req, res, next);
69
+ } catch (error) {
70
+ next(error);
71
+ }
72
+ }
73
+ }
74
+ module.exports = new Auth();
@@ -0,0 +1,30 @@
1
+ exports.authenticated = (req, res, next) =>
2
+ req.isAuthenticated() ? next() : res.redirect("/login");
3
+
4
+ // exports.isLogIn = (req, res, next) =>
5
+ // req.isAuthenticated() ? res.redirect("/home") : next();
6
+
7
+ // exports.isLogIn
8
+
9
+ exports.protectedApi = (request, response, next) => {
10
+ let token;
11
+ if (
12
+ request.headers.authorization &&
13
+ request.headers.authorization.startsWith("Bearer")
14
+ ) {
15
+ token = request.headers.authorization.split(" ")[1];
16
+ } else if (request.cookies.token) {
17
+ token = request.cookies.token;
18
+ } else if (request.header("x-auth-token")) {
19
+ token = request.header("x-auth-token");
20
+ }
21
+ if (!token) {
22
+ return response.json({ message: "Not authorize" }).status(403);
23
+ }
24
+ try {
25
+ request.id = jwt.verify(token, process.env.JWT_SECRET);
26
+ next();
27
+ } catch (err) {
28
+ return response.json({ message: "Not authorize" }).status(403);
29
+ }
30
+ };
@@ -0,0 +1,42 @@
1
+ const Util = require("../utils");
2
+
3
+ class Router {
4
+ constructor(app, prefix, middlewares, classController) {
5
+ this.app = app;
6
+ this.prefixUrl = prefix;
7
+ this.middlewares = middlewares;
8
+ this.classController = classController;
9
+
10
+ this.util = new Util(app, prefix, middlewares, classController);
11
+ }
12
+
13
+ middleware(middlewares) {
14
+ this.middlewares = middlewares;
15
+ this.util.setGroupMiddleware(middlewares);
16
+ return this;
17
+ }
18
+
19
+ get(path, callback) {
20
+ this.util.routeHelper("get", path, callback);
21
+ return this;
22
+ }
23
+ post(path, callback) {
24
+ this.util.routeHelper("post", path, callback);
25
+ return this;
26
+ }
27
+ patch(path, callback) {
28
+ this.util.routeHelper("patch", path, callback);
29
+ return this;
30
+ }
31
+ put(path, callback) {
32
+ this.util.routeHelper("put", path, callback);
33
+ return this;
34
+ }
35
+ delete(path, callback) {
36
+ this.util.routeHelper("delete", path, callback);
37
+ return this;
38
+ }
39
+ all() {}
40
+ }
41
+
42
+ module.exports = Router;
@@ -0,0 +1,28 @@
1
+ const Router = require("./Router");
2
+ class Routes extends Router {
3
+ constructor(app) {
4
+ super(app);
5
+ }
6
+ prefix(url) {
7
+ this.prefixUrl = url;
8
+ return this;
9
+ }
10
+ controller(controller) {
11
+ this.classController = controller;
12
+ this.util.setGroupController(controller);
13
+ return this;
14
+ }
15
+ group(callback) {
16
+ callback(
17
+ new Router(
18
+ this.app,
19
+ this.prefixUrl,
20
+ this.middlewares,
21
+ this.classController
22
+ )
23
+ );
24
+ return this;
25
+ }
26
+ }
27
+
28
+ module.exports = Routes;
@@ -0,0 +1,62 @@
1
+ const http = require("http");
2
+ const express = require("express");
3
+ const dotenv = require("dotenv");
4
+ const Middleware = require("../middlware");
5
+ const Routes = require("../Router/Routes");
6
+ const { rootPath } = require("../helpers");
7
+ const dbConnection = require("../dbConnection");
8
+ const ErrorHandler = require("../error/ErrorHandler");
9
+ const SocketIo = require("../socket");
10
+ const getCommands = require("../command-line-interface/getCommands");
11
+
12
+ class App {
13
+ constructor() {
14
+ dotenv.config();
15
+ this.express = express;
16
+ this.app = express();
17
+ new Middleware(express, this.app);
18
+ }
19
+
20
+ commandLineArgv(argv) {
21
+ return getCommands(argv.slice(2));
22
+ }
23
+
24
+ webRoute() {
25
+ return new Routes(this.app);
26
+ }
27
+ apiRoute() {
28
+ return new Routes(this.app);
29
+ }
30
+ server() {
31
+ const app = this.app;
32
+ const PORT = process.env.PORT || process.env.NODE_ENV;
33
+ const server = http.Server(app);
34
+ const appError = new ErrorHandler(app);
35
+ new SocketIo(server);
36
+ return {
37
+ run() {
38
+ dbConnection();
39
+ rootPath("routes/index");
40
+ // rootPath("routes/api");
41
+
42
+ appError.errorRoutesHandler();
43
+ app.use(appError.handler);
44
+
45
+ app.listen(PORT, () => {
46
+ console.log(`Server running on port ${PORT}`);
47
+ if (process.send) {
48
+ process.send("online");
49
+ }
50
+ });
51
+
52
+ process.on("unhandledRejection", (err) => {
53
+ console.log({ unhandledRejection: err.message });
54
+ process.exit(1);
55
+ });
56
+ },
57
+ server,
58
+ };
59
+ }
60
+ }
61
+
62
+ module.exports = App;
@@ -0,0 +1,119 @@
1
+ const path = require("path");
2
+ const fs = require("fs");
3
+ const createController = require("../files/controller");
4
+ const createModel = require("../files/model");
5
+ const resourceController = require("../files/resoucesController");
6
+ const createRequest = require("../files/request");
7
+ const rootPath = require("app-root-path").path;
8
+ const colors = require("colors");
9
+ class Command {
10
+ addWeb(controllerName, modelName = false) {
11
+ try {
12
+ let webControllerPath = path.resolve(`${rootPath}/app/Controllers`);
13
+ if (fs.existsSync(`${webControllerPath}/${controllerName}.js`)) {
14
+ return console.log(`${controllerName} already exist`.yellow);
15
+ }
16
+ if (modelName) {
17
+ fs.writeFileSync(
18
+ `${webControllerPath}/${controllerName}.js`,
19
+ resourceController(controllerName, modelName)
20
+ );
21
+ return console.log(`${controllerName} added successfully`.green);
22
+ }
23
+ fs.writeFileSync(
24
+ `${webControllerPath}/${controllerName}.js`,
25
+ createController(controllerName)
26
+ );
27
+
28
+ return console.log(`${controllerName} added successfully`.green);
29
+ } catch (err) {
30
+ console.log(`${controllerName} admin controller not added`.red);
31
+ }
32
+ }
33
+
34
+ // addAdmin(controllerName, modelName = false) {
35
+ // try {
36
+ // let adminPath = path.resolve(`${rootPath}/app/Controllers/Admin`);
37
+ // if (fs.existsSync(`${adminPath}/${controllerName}.js`)) {
38
+ // return console.log(`${controllerName} already exist`.yellow);
39
+ // }
40
+ // if (modelName) {
41
+ // fs.writeFileSync(
42
+ // `${adminPath}/${controllerName}.js`,
43
+ // resourceController(controllerName, modelName)
44
+ // );
45
+ // return console.log(`${controllerName} added successfully`.green);
46
+ // }
47
+ // fs.writeFileSync(
48
+ // `${adminPath}/${controllerName}.js`,
49
+ // createController(controllerName)
50
+ // );
51
+
52
+ // return console.log(`${controllerName} added successfully`.green);
53
+ // } catch (err) {
54
+ // console.log(`${controllerName} admin controller not added`.red);
55
+ // }
56
+ // }
57
+
58
+ addApi(controllerName, modelName = false) {
59
+ try {
60
+ let apiPath = path.resolve(`${rootPath}/app/Controllers/Api`);
61
+ if (fs.existsSync(`${apiPath}/${controllerName}.js`)) {
62
+ return console.log(
63
+ `${controllerName} api controller already exist`.yellow
64
+ );
65
+ }
66
+ if (modelName) {
67
+ fs.writeFileSync(
68
+ `${apiPath}/${controllerName}.js`,
69
+ resourceController(controllerName, modelName)
70
+ );
71
+ return console.log(`${controllerName} added successfully`.green);
72
+ }
73
+ fs.writeFileSync(
74
+ `${apiPath}/${controllerName}.js`,
75
+ createController(controllerName)
76
+ );
77
+ return console.log(`${controllerName} added successfully`.green);
78
+ } catch (err) {
79
+ console.log(err.message);
80
+ console.log(`${controllerName} api controller not added`.red);
81
+ }
82
+ }
83
+
84
+ addModel(modelName) {
85
+ try {
86
+ let modelPath = path.resolve(`${rootPath}/app/Model`);
87
+ if (fs.existsSync(`${modelPath}/${modelName}.js`)) {
88
+ return console.log(`${modelName} model already exist`.yellow);
89
+ }
90
+ fs.writeFileSync(`${modelPath}/${modelName}.js`, createModel(modelName));
91
+ return console.log(`${modelName} model added successfully`.green);
92
+ } catch (err) {
93
+ return console.log(`${modelName} model not added`.red);
94
+ }
95
+ }
96
+
97
+ addRequest(requestName) {
98
+ try {
99
+ let requestPath = path.resolve(`${rootPath}/app/Request`);
100
+ if (fs.existsSync(`${requestPath}/${requestName}.js`)) {
101
+ return console.log(`${requestName} already exist`.yellow);
102
+ }
103
+
104
+ fs.writeFileSync(
105
+ `${requestPath}/${requestName}.js`,
106
+ createRequest(requestName)
107
+ );
108
+ return console.log(`${requestName} added successfully`.green);
109
+ } catch (err) {
110
+ return console.log(`${requestName} request not added`.red, { err });
111
+ }
112
+ }
113
+
114
+ notFound() {
115
+ return console.log(`Command not found`.bgRed);
116
+ }
117
+ }
118
+
119
+ module.exports = new Command();
@@ -0,0 +1,59 @@
1
+ const mongose = require("mongoose");
2
+ const dotenv = require("dotenv");
3
+ const { getModel, bcrypt } = require("../helpers");
4
+ class DbCli {
5
+ constructor(model) {
6
+ dotenv.config();
7
+ this.model = getModel(model);
8
+ this.connection();
9
+ }
10
+ async connection() {
11
+ try {
12
+ const connect = await mongose.connect(process.env.DB_HOST);
13
+ return connect
14
+ ? console.log("Database connected Successfuly")
15
+ : console.log("Database not connected ");
16
+ } catch (error) {
17
+ console.log("Database not connected ");
18
+ }
19
+ }
20
+
21
+ closeConnection() {
22
+ return mongose.connection.close();
23
+ }
24
+ async all() {
25
+ const data = await this.model.find({});
26
+ console.log(data);
27
+ return this.closeConnection();
28
+ }
29
+ async create(data) {
30
+ const obj = {};
31
+ const items = data.split(",");
32
+
33
+ for (let i = 0; i < items.length; i++) {
34
+ const objName = items[i].split(":")[0];
35
+ const objValue = items[i].split(":")[1];
36
+ if (objName === "password") {
37
+ obj[objName] = await bcrypt(objValue);
38
+ continue;
39
+ }
40
+ obj[objName] = objValue;
41
+ }
42
+ const result = await this.model.create(obj);
43
+ console.log(result);
44
+ return this.closeConnection();
45
+ }
46
+ async findById(id) {
47
+ const result = await this.model.findById(id);
48
+ console.log(result);
49
+ return this.closeConnection();
50
+ }
51
+ async delete(id) {
52
+ const result = await this.model.findByIdAndRemove(id);
53
+ console.log(result);
54
+ return this.closeConnection();
55
+ }
56
+ // update() {}
57
+ }
58
+
59
+ module.exports = DbCli;
@@ -0,0 +1,86 @@
1
+ const runCommand = require("./commands");
2
+
3
+ const getCommandLineArgv = (commandArg) => {
4
+ let command = commandArg[0].split(":")[1];
5
+
6
+ if (
7
+ commandArg.length === 4 &&
8
+ (command === "apiController" || command === "ApiController") &&
9
+ (commandArg[3] === "--resources" || commandArg[3] === "-r")
10
+ ) {
11
+ runCommand.addModel(commandArg[2]);
12
+ return runCommand.addApi(commandArg[1], commandArg[2]);
13
+ }
14
+ if (
15
+ commandArg.length === 4 &&
16
+ (command === "controller" || command === "Controller") &&
17
+ (commandArg[3] === "--resources" || commandArg[3] === "-r")
18
+ ) {
19
+ runCommand.addModel(commandArg[2]);
20
+ return runCommand.addWeb(commandArg[1], commandArg[2]);
21
+ }
22
+
23
+ if (
24
+ commandArg.length === 4 &&
25
+ (command === "adminController" || command === "AdminController") &&
26
+ (commandArg[3] === "--resources" || commandArg[3] === "-r")
27
+ ) {
28
+ runCommand.addModel(commandArg[2]);
29
+ return runCommand.addAdmin(commandArg[1], commandArg[2]);
30
+ }
31
+
32
+ if (
33
+ commandArg.length === 3 &&
34
+ (command === "controller" || command === "Controller")
35
+ ) {
36
+ return runCommand.addWeb(commandArg[1], commandArg[2]);
37
+ }
38
+ if (
39
+ commandArg.length === 3 &&
40
+ (command === "apiController" || command === "ApiController")
41
+ ) {
42
+ return runCommand.addApi(commandArg[1], commandArg[2]);
43
+ }
44
+
45
+ if (
46
+ commandArg.length === 3 &&
47
+ (command === "adminController" || command === "AdminController")
48
+ ) {
49
+ return runCommand.addAdmin(commandArg[1], commandArg[2]);
50
+ }
51
+
52
+ if (commandArg.length === 2 && (command === "model" || command === "Model")) {
53
+ return runCommand.addModel(commandArg[1]);
54
+ }
55
+
56
+ if (
57
+ commandArg.length === 2 &&
58
+ (command === "controller" || command === "Controller")
59
+ ) {
60
+ return runCommand.addWeb(commandArg[1], false);
61
+ }
62
+
63
+ if (
64
+ commandArg.length === 2 &&
65
+ (command === "apiController" || command === "ApiController")
66
+ ) {
67
+ return runCommand.addApi(commandArg[1], false);
68
+ }
69
+
70
+ // if (
71
+ // commandArg.length === 2 &&
72
+ // (command === "adminController" || command === "AdminController")
73
+ // ) {
74
+ // return runCommand.addAdmin(commandArg[1], false);
75
+ // }
76
+
77
+ if (
78
+ commandArg.length === 2 &&
79
+ (command === "Request" || command === "request")
80
+ ) {
81
+ return runCommand.addRequest(commandArg[1]);
82
+ // return console.log(commandArg[1]);
83
+ }
84
+ return runCommand.notFound();
85
+ };
86
+ module.exports = getCommandLineArgv;
@@ -0,0 +1,18 @@
1
+ const DbCli = require("./dbCli");
2
+
3
+ const getCommand = (command, index = 0) => {
4
+ let cmd = command.slice(2);
5
+ return `${cmd[0].split(".")[index]}`;
6
+ };
7
+
8
+ const getArg = (command) => command.slice(3)[0];
9
+
10
+ const getDbCLineArgv = (commandArg) => {
11
+ let model = getCommand(commandArg);
12
+ let method = getCommand(commandArg, 1);
13
+ let arg = getArg(commandArg);
14
+ const db = new DbCli(model);
15
+ return arg ? db[method](arg) : db[method]();
16
+ };
17
+
18
+ module.exports = getDbCLineArgv;
@@ -0,0 +1,14 @@
1
+ const mongose = require("mongoose");
2
+
3
+ const dbConnection = async () => {
4
+ try {
5
+ const connect = await mongose.connect(process.env.DB_HOST);
6
+ return connect
7
+ ? console.log("Database connected Successfuly")
8
+ : console.log("Database not connected ");
9
+ } catch (error) {
10
+ console.log("Database not connected ");
11
+ }
12
+ };
13
+
14
+ module.exports = dbConnection;
@@ -0,0 +1,8 @@
1
+ class AppError extends Error {
2
+ constructor(message, statusCode) {
3
+ super(message);
4
+ this.statusCode = statusCode;
5
+ }
6
+ }
7
+
8
+ module.exports = AppError;
@@ -0,0 +1,71 @@
1
+ class ErrorHandler {
2
+ constructor(app) {
3
+ this.app = app;
4
+ }
5
+ errorRoutesHandler() {
6
+ return this.app.all("*", (req, res, next) => {
7
+ return res.sendFile(__dirname + "/public/pageNotFound.html");
8
+ });
9
+ }
10
+ handler(err, req, res, next) {
11
+ let error = { ...err };
12
+ error.message = err.message;
13
+ //monogoose id not found
14
+ if (err.name === "CastError") {
15
+ const message = { [err.path]: ` ${err.kind} not found` };
16
+ error.message = message;
17
+ error.statusCode = 400;
18
+ }
19
+
20
+ //duplicate key
21
+ if (err.code === 11000) {
22
+ let field = Object.keys(err.keyValue)[0];
23
+ error.message = { [field]: `${field} already exist` };
24
+ error.statusCode = 400;
25
+ }
26
+
27
+ //validations error
28
+
29
+ if (err.name === "ValidationError") {
30
+ let message = {};
31
+
32
+ const errorMessages = Object.values(err.errors);
33
+ for (let i = 0; i < errorMessages.length; i++) {
34
+ let val = errorMessages[i];
35
+ message[val.path] = val.message
36
+ .replace(/[^\w ]/g, "")
37
+ .split(" ")
38
+ .slice(1)
39
+ .join(" ");
40
+ }
41
+
42
+ error.message = message;
43
+ error.statusCode = 400;
44
+ }
45
+
46
+ if (err.apiValidationErrors) {
47
+ error.message = err.apiValidationErrors;
48
+ error.statusCode = 400;
49
+ }
50
+
51
+ if (err.validationErrors) {
52
+ error.message = err.validationErrors;
53
+ error.statusCode = 400;
54
+ return res.redirectBack();
55
+ }
56
+
57
+ if (err.validationMethod) {
58
+ error.message = err.validationMethod;
59
+ error.statusCode = 400;
60
+ }
61
+
62
+ res.status(error.statusCode || 500).json({
63
+ status: err.status,
64
+ error: error.message,
65
+ message: "error",
66
+ stack: err.stack,
67
+ });
68
+ }
69
+ }
70
+
71
+ module.exports = ErrorHandler;
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Not Found</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+ body {
14
+ background: #eee;
15
+ height: 100vh;
16
+ display: flex;
17
+ justify-content: center;
18
+ align-items: center;
19
+ }
20
+ h1 {
21
+ color: rgba(0, 0, 0, 0.893);
22
+ }
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <h1>404 Page Not Found</h1>
27
+ </body>
28
+ </html>