├── .gitignore ├── .vscode └── settings.json ├── README.md ├── controllers └── tools.controller.js ├── index.js ├── middleware ├── errorHandler.js ├── limiter.js └── veiwCount.js ├── package.json ├── public ├── test.html └── wow.jpg ├── routes └── v1 │ └── tools.route.js ├── utils ├── dbConnect.js └── email.js └── views └── home.ejs /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | yarn.lock -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Abdify/express-mvc-acc/722ae0597cf7e7a70360ccf59733882889508efc/README.md -------------------------------------------------------------------------------- /controllers/tools.controller.js: -------------------------------------------------------------------------------- 1 | const { ObjectId } = require("mongodb"); 2 | const { getDb } = require("../utils/dbConnect"); 3 | 4 | let tools = [ 5 | { id: 1, name: "Hammer" }, 6 | { id: 2, name: "Hammer2" }, 7 | { id: 3, name: "Hammer3" }, 8 | ]; 9 | 10 | module.exports.getAllTools = async (req, res, next) => { 11 | try { 12 | const { limit, page } = req.query; 13 | const db = getDb(); 14 | 15 | // cursor => toArray(), forEach() 16 | const tool = await db 17 | .collection("tools") 18 | .find({}) 19 | // .project({ _id: 0 }) 20 | // .skip(+page * limit) 21 | // .limit(+limit) 22 | .toArray(); 23 | 24 | res.status(200).json({ success: true, data: tool }); 25 | } catch (error) { 26 | next(error); 27 | } 28 | }; 29 | 30 | module.exports.saveATool = async (req, res, next) => { 31 | try { 32 | const db = getDb(); 33 | const tool = req.body; 34 | 35 | const result = await db.collection("tools").insertOne(tool); 36 | console.log(result); 37 | 38 | if (!result.insertedId) { 39 | return res.status(400).send({ status: false, error: "Something went wrong!" }); 40 | } 41 | 42 | res.send({ success: true, message: `Tool added with id: ${result.insertedId}` }); 43 | } catch (error) { 44 | next(error); 45 | } 46 | }; 47 | 48 | module.exports.getToolDetail = async (req, res, next) => { 49 | try { 50 | const db = getDb(); 51 | const { id } = req.params; 52 | 53 | if(!ObjectId.isValid(id)){ 54 | return res.status(400).json({ success: false, error: "Not a valid tool id."}); 55 | } 56 | 57 | const tool = await db.collection("tools").findOne({_id: ObjectId(id)}); 58 | 59 | if(!tool){ 60 | return res.status(400).json({ success: false, error: "Couldn't find a tool with this id"}); 61 | } 62 | 63 | res.status(200).json({ success: true, data: tool }); 64 | 65 | } catch (error) { 66 | next(error); 67 | } 68 | }; 69 | 70 | module.exports.updateTool = async (req, res, next) => { 71 | try { 72 | const db = getDb(); 73 | const { id } = req.params; 74 | 75 | if (!ObjectId.isValid(id)) { 76 | return res.status(400).json({ success: false, error: "Not a valid tool id." }); 77 | } 78 | 79 | const tool = await db.collection("tools").updateOne({ _id: ObjectId(id) }, { $set: req.body }); 80 | 81 | if (!tool.modifiedCount) { 82 | return res.status(400).json({ success: false, error: "Couldn't update the tool" }); 83 | } 84 | 85 | res.status(200).json({ success: true, message: "Successfully updated the tool" }); 86 | } catch (error) { 87 | next(error); 88 | } 89 | }; 90 | 91 | module.exports.deleteTool = async (req, res, next) => { 92 | try { 93 | const db = getDb(); 94 | const { id } = req.params; 95 | 96 | if (!ObjectId.isValid(id)) { 97 | return res.status(400).json({ success: false, error: "Not a valid tool id." }); 98 | } 99 | 100 | const tool = await db.collection("tools").deleteOne({ _id: ObjectId(id) }); 101 | 102 | if (!tool.deletedCount) { 103 | return res.status(400).json({ success: false, error: "Couldn't delete the tool" }); 104 | } 105 | 106 | res.status(200).json({ success: true, message: "Successfully deleted the tool" }); 107 | } catch (error) { 108 | next(error); 109 | } 110 | }; 111 | 112 | module.exports.test = async(req, res, next) => { 113 | for (let i = 0; i < 100000; i++) { 114 | const db = getDb(); 115 | db.collection("test").insertOne({name: `test ${i}`, age: i }); 116 | } 117 | }; 118 | module.exports.testGet = async(req, res, next) => { 119 | const db = getDb(); 120 | 121 | const result = await db.collection("test").find({ name: "test 99999" }).toArray(); 122 | res.json(result); 123 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const cors = require("cors"); 3 | require("dotenv").config(); 4 | const app = express(); 5 | const port = process.env.PORT || 5000; 6 | const dbConnect = require("./utils/dbConnect"); 7 | const toolsRoutes = require("./routes/v1/tools.route.js"); 8 | const errorHandler = require("./middleware/errorHandler"); 9 | const { connectToServer } = require("./utils/dbConnect"); 10 | 11 | app.use(cors()); 12 | app.use(express.json()); 13 | app.use(express.static("public")); 14 | app.set("view engine", "ejs"); 15 | 16 | // app.use(viewCount); 17 | 18 | // Apply the rate limiting middleware to all requests 19 | // app.use(limiter); 20 | 21 | connectToServer((err) => { 22 | if (!err) { 23 | app.listen(port, () => { 24 | console.log(`Example app listening on port ${port}`); 25 | }); 26 | } else { 27 | console.log(err); 28 | } 29 | }); 30 | 31 | app.use("/api/v1/tools", toolsRoutes); 32 | 33 | app.get("/", (req, res) => { 34 | // res.send("Hello World"); 35 | // res.sendFile(__dirname + "/public/test.html"); 36 | res.render("home.ejs", { 37 | id: 5, 38 | user: { 39 | name: "test", 40 | }, 41 | }); 42 | }); 43 | 44 | app.all("*", (req, res) => { 45 | res.send("NO route found."); 46 | }); 47 | 48 | app.use(errorHandler); 49 | 50 | process.on("unhandledRejection", (error) => { 51 | console.log(error.name, error.message); 52 | app.close(() => { 53 | process.exit(1); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /middleware/errorHandler.js: -------------------------------------------------------------------------------- 1 | const errorHandler = (err, req, res, next) => { 2 | res.send(err.message); 3 | }; 4 | 5 | module.exports = errorHandler; -------------------------------------------------------------------------------- /middleware/limiter.js: -------------------------------------------------------------------------------- 1 | const { default: rateLimit } = require("express-rate-limit"); 2 | 3 | const limiter = rateLimit({ 4 | windowMs: 15 * 60 * 1000, // 15 minutes 5 | max: 100, // Limit each IP to 100 requests per `window` (here, per 15 minutes) 6 | standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers 7 | legacyHeaders: false, // Disable the `X-RateLimit-*` headers 8 | }); 9 | 10 | module.exports = limiter; -------------------------------------------------------------------------------- /middleware/veiwCount.js: -------------------------------------------------------------------------------- 1 | let count = 0; 2 | 3 | const viewCount = (req, res, next) => { 4 | count++; 5 | console.log(count); 6 | 7 | // res.send("tools found"); 8 | next(); 9 | }; 10 | 11 | module.exports = viewCount; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phero-final-project-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "start-dev": "nodemon index.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "cors": "^2.8.5", 16 | "dotenv": "^16.0.1", 17 | "ejs": "^3.1.8", 18 | "express": "^4.18.1", 19 | "express-rate-limit": "^6.5.2", 20 | "jsonwebtoken": "^8.5.1", 21 | "mongodb": "^4.6.0", 22 | "nodemailer": "^6.7.8", 23 | "nodemon": "^2.0.19", 24 | "stripe": "^10.3.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /public/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 |Hello, Sir
19 |Sincerely
23 |Total Car Care Ltd.
24 |Muradpur ,Ctg
26 |Bangladesh
27 | 28 |