From 3acd7ac8bc93ebbf6b67c64f6e6f6a8f463a064f Mon Sep 17 00:00:00 2001 From: JDC-horizons Date: Wed, 31 Jul 2024 17:43:20 +0100 Subject: [PATCH 1/3] core complete --- data/index.js | 32 ++++++++++----------- package-lock.json | 35 ++++++++++++----------- package.json | 12 ++++++-- src/index.js | 4 +-- src/routers/books.js | 67 ++++++++++++++++++++++++++++++++++++++++++-- src/routers/films.js | 65 ++++++++++++++++++++++++++++++++++++++++++ src/routers/users.js | 65 ++++++++++++++++++++++++++++++++++++++++++ src/server.js | 8 ++++-- 8 files changed, 246 insertions(+), 42 deletions(-) diff --git a/data/index.js b/data/index.js index 7a216ce..3d55a03 100644 --- a/data/index.js +++ b/data/index.js @@ -4,71 +4,71 @@ const books = [ title: "1984", type: "fiction", author: "George Orwell", - pages: 5 + pages: 5, }, { id: 2, title: "Life of Pi", type: "fiction", author: "Yann Martel", - pages: 4 + pages: 4, }, { id: 3, title: "How to Win Friends and Influence People", type: "non-fiction", author: "Dale Carnegie", - pages: 3 + pages: 3, }, { id: 4, title: "The Lean Startup", type: "non-fiction", author: "Eric Reis", - pages: 2 - } + pages: 2, + }, ]; const films = [ { id: 1, title: "Bonnie and Clyde", - director: "Arthur Penn" + director: "Arthur Penn", }, { id: 2, title: "Reservoir Dogs", - director: "Quentin Tarantino" + director: "Quentin Tarantino", }, { id: 3, title: "Inception", - director: "Christopher Nolan" + director: "Christopher Nolan", }, { id: 4, title: "Django Unchained", - director: "Quentin Tarantino" - } + director: "Quentin Tarantino", + }, ]; const users = [ { id: 1, - email: "edward@mail.com" + email: "edward@mail.com", }, { id: 2, - email: "nathan@mail.com" + email: "nathan@mail.com", }, { id: 3, - email: "mike@mail.com" - } + email: "mike@mail.com", + }, ]; module.exports = { books: books, films: films, - users: users -} + users: users, +}; diff --git a/package-lock.json b/package-lock.json index fc9d54a..d0349b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,9 +7,10 @@ "": { "name": "express-router-with-in-memory-data-store", "version": "1.0.0", + "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "morgan": "^1.10.0" }, "devDependencies": { @@ -1395,12 +1396,12 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -1408,7 +1409,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1719,9 +1720,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -1992,16 +1993,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -3914,9 +3915,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", diff --git a/package.json b/package.json index c63bc01..8821e43 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "express-router-with-in-memory-data-store", "version": "1.0.0", - "description": "", + "description": "In this exercise, you are going to extend the REST APIs you have been building to handle DELETE and PUT requests. You will also learn how to make your route handling more modular in express using express.Router.", "main": "index.js", "scripts": { "start": "npx nodemon src/index.js", @@ -10,7 +10,7 @@ }, "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", + "express": "^4.19.2", "morgan": "^1.10.0" }, "devDependencies": { @@ -18,5 +18,11 @@ "nodemon": "^2.0.22", "supertest": "^6.3.3" }, - "keywords": [] + "keywords": [], + "directories": { + "doc": "docs", + "test": "test" + }, + "author": "", + "license": "ISC" } diff --git a/src/index.js b/src/index.js index c16707f..6b312ef 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ /* REQUIRE APP */ -const app = require('./server.js') -const port = 3030; +const app = require("./server.js"); +const port = 3031; /* START SERVER */ app.listen(port, () => { diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..1ae990a 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,67 @@ -// Import data here... +const express = require("express"); +const router = express.Router(); +let { books } = require("../../data/index.js"); -// Write routes here... +router.get("/", (req, res) => { + res.status(200).json({ books: books }); +}); + +router.post("/", function (req, res) { + const { title, type, author, pages } = req.body; + if (!title || !type || !author || !pages) { + return res.status(400); + } + const currentHighId = books.reduce((max, obj) => { + return obj.id > max ? obj.id : max; + }, 0); + req.body.id = currentHighId + 1; + books.push(req.body); + res.status(201).json({ book: req.body }); +}); + +router.get("/:id", function (req, res) { + const toFind = parseInt(req.params.id, 10); + const index = books.findIndex((obj) => obj.id === toFind); + const foundBook = books[index]; + if (foundBook) { + res.status(200).json({ book: foundBook }); + } else { + res.sendStatus(404); + } +}); + +router.delete("/:id", function (req, res) { + const toRemove = parseInt(req.params.id, 10); + const bookIndex = books.findIndex((obj) => obj.id === toRemove); + if (bookIndex === -1) { + return res.status(404).json({ error: "Book not found" }); + } + + const deletedBook = books[bookIndex]; + books = books.filter((obj) => obj.id !== toRemove); + + res.status(200).json({ book: deletedBook }); +}); + +router.put("/:id", function (req, res) { + const id = parseInt(req.params.id, 10); + const bookIndex = books.findIndex((book) => book.id === id); + if (bookIndex === -1) { + return res.status(404).json({ error: "Book not found" }); + } + + const { title, type, author, pages } = req.body; + const updatedBook = { + ...books[bookIndex], + title, + type, + author, + pages, + }; + books[bookIndex] = updatedBook; + + res.status(200).json({ book: updatedBook }); +}); + +module.exports = router; diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..4b37323 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,65 @@ +const express = require("express"); +const router = express.Router(); + +let { films } = require("../../data/index.js"); + +router.get("/", (req, res) => { + res.status(200).json({ films: films }); +}); + +router.post("/", function (req, res) { + const { title, director } = req.body; + if (!title || !director) { + return res.status(400); + } + const currentHighId = films.reduce((max, obj) => { + return obj.id > max ? obj.id : max; + }, 0); + req.body.id = currentHighId + 1; + films.push(req.body); + res.status(201).json({ film: req.body }); +}); + +router.get("/:id", function (req, res) { + const toFind = parseInt(req.params.id, 10); + const index = films.findIndex((obj) => obj.id === toFind); + const foundFilm = films[index]; + if (foundFilm) { + res.send({ film: foundFilm }); + } else { + res.sendStatus(404); + } +}); + +router.delete("/:id", function (req, res) { + const toRemove = parseInt(req.params.id, 10); + const filmIndex = films.findIndex((obj) => obj.id === toRemove); + if (filmIndex === -1) { + return res.status(404).json({ error: "Film not found" }); + } + + const deletedFilm = films[filmIndex]; + films = films.filter((obj) => obj.id !== toRemove); + + res.status(200).json({ film: deletedFilm }); +}); + +router.put("/:id", function (req, res) { + const id = parseInt(req.params.id, 10); + const filmIndex = films.findIndex((film) => film.id === id); + if (filmIndex === -1) { + return res.status(404).json({ error: "Film not found" }); + } + + const { title, director } = req.body; + const updatedFilm = { + ...films[filmIndex], + title, + director, + }; + films[filmIndex] = updatedFilm; + + res.status(200).json({ film: updatedFilm }); +}); + +module.exports = router; diff --git a/src/routers/users.js b/src/routers/users.js index e69de29..39bfdaa 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -0,0 +1,65 @@ +const express = require("express"); +const router = express.Router(); + +let { users } = require("../../data/index.js"); + +router.get("/", (req, res) => { + res.status(200).json({ users: users }); +}); + +router.post("/", function (req, res) { + const { email } = req.body; + if (!email) { + return res.status(400); + } + const currentHighId = users.reduce((max, obj) => { + return obj.id > max ? obj.id : max; + }, 0); + req.body.id = currentHighId + 1; + users.push(req.body); + res.status(201).json({ user: req.body }); +}); + +router.get("/:id", function (req, res) { + const toFind = parseInt(req.params.id, 10); + const index = users.findIndex((obj) => obj.id === toFind); + const foundUser = users[index]; + if (foundUser) { + res.status(200).json({ user: foundUser }); + } else { + res.sendStatus(404); + } +}); + +router.delete("/:id", function (req, res) { + const toRemove = parseInt(req.params.id, 10); + const userIndex = users.findIndex((obj) => obj.id === toRemove); + if (userIndex === -1) { + return res.status(404).json({ error: "User not found" }); + } + + const deletedUser = users[userIndex]; + users = users.filter((obj) => obj.id !== toRemove); + + res.status(200).json({ user: deletedUser }); +}); + +router.put("/:id", function (req, res) { + const id = parseInt(req.params.id, 10); + const userIndex = users.findIndex((user) => user.id === id); + if (userIndex === -1) { + return res.status(404).json({ error: "User not found" }); + } + + const { firstName, lastName, street, city, type, email, linkedin, twitter } = + req.body; + const updatedUser = { + ...users[userIndex], + email, + }; + users[userIndex] = updatedUser; + + res.status(200).json({ user: updatedUser }); +}); + +module.exports = router; diff --git a/src/server.js b/src/server.js index 715321f..03be555 100644 --- a/src/server.js +++ b/src/server.js @@ -11,8 +11,12 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); +const booksRouter = require("./routers/books"); +const filmsRouter = require("./routers/films"); // ADD ROUTERS TO APP +app.use("/users", usersRouter); +app.use("/books", booksRouter); +app.use("/films", filmsRouter); - -module.exports = app +module.exports = app; From 73e7cc3f5fc1409be4101de985efcd6e8304b681 Mon Sep 17 00:00:00 2001 From: JDC-horizons Date: Fri, 2 Aug 2024 16:01:24 +0100 Subject: [PATCH 2/3] minor change --- src/routers/books.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/routers/books.js b/src/routers/books.js index 1ae990a..f0579f0 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -8,16 +8,23 @@ router.get("/", (req, res) => { }); router.post("/", function (req, res) { - const { title, type, author, pages } = req.body; - if (!title || !type || !author || !pages) { - return res.status(400); + const { title, type, author } = req.body; + if (!title || !type || !author) { + return res.status(400).json({ error: "error" }); } const currentHighId = books.reduce((max, obj) => { return obj.id > max ? obj.id : max; }, 0); - req.body.id = currentHighId + 1; - books.push(req.body); - res.status(201).json({ book: req.body }); + const newBook = { + id: currentHighId + 1, + title, + type, + author, + pages, + }; + console.log(req.body); + books.push(newBook); + res.status(201).json({ book: newBook }); }); router.get("/:id", function (req, res) { From 664ea2ad65f7779a8c787f31e036418e4e4d3fa8 Mon Sep 17 00:00:00 2001 From: JDC-horizons Date: Fri, 2 Aug 2024 16:03:27 +0100 Subject: [PATCH 3/3] minor change to the minor change --- src/routers/books.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routers/books.js b/src/routers/books.js index f0579f0..24c66b5 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -20,7 +20,6 @@ router.post("/", function (req, res) { title, type, author, - pages, }; console.log(req.body); books.push(newBook);