diff --git a/package-lock.json b/package-lock.json index fc9d54a..2f9ad09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1395,12 +1395,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 +1408,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" }, @@ -1428,12 +1428,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1719,9 +1719,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 +1992,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", @@ -2054,9 +2054,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3914,9 +3914,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/src/contollers/books.js b/src/contollers/books.js new file mode 100644 index 0000000..88a83c2 --- /dev/null +++ b/src/contollers/books.js @@ -0,0 +1,93 @@ +const { books } = require("../../data/index.js"); +const { + MissingFieldError, + DataError, + NotFoundError, +} = require("../errors/index.js"); + +let bookID = books.length + 1; + +const all = (req, res) => { + res.status(200).json({ books: books }); +}; + +const get = (req, res) => { + const id = Number(req.params.id); + const found = books.find((book) => book.id === id); + + if (!found) { + res.status(404).send({ error: "A book the provided ID does not exist" }); + throw new NotFoundError("A book the provided ID does not exist"); + } + + res.status(200).json({ book: found }); +}; + +const create = (req, res) => { + const newBook = req.body; + if (!newBook.title || !newBook.author || !newBook.type) { + res.status(400).send({ error: `Missing fields in request body` }); + throw new MissingFieldError(`Missing fields in request body`); + } + + if (books.find((book) => book.title === newBook.title)) { + res + .status(409) + .send({ error: `A book with the provided title already exists` }); + throw new MissingFieldError( + `A book with the provided title already exists` + ); + } + newBook.id = bookID; + books.push(newBook); + bookID++; + res.status(201).json({ book: newBook }); +}; + +const update = (req, res) => { + const id = Number(req.params.id); + const updates = req.body; + + if (!updates.title || !updates.author || !updates.type) { + res.status(400).send({ error: `Missing fields in request body` }); + throw new MissingFieldError(`Missing fields in the request body`); + } + + const found = books.find((book) => book.id === id); + if (!found) { + res.status(404).send({ error: `A book the provided ID does not exist` }); + throw new NotFoundError(`A book with the provided ID does not exist`); + } + + if (books.find((book) => book.title === updates.title)) { + res.status(409).send({ error: `A book with the provided title already exists` }); + throw new MissingFieldError( + `A book with the provided title already exists` + ); + } + + const index = books.indexOf(found); + const updated = { ...found, ...updates }; + res.status(200).json({ book: updated }); +}; + +const remove = (req, res) => { + const id = Number(req.params.id); + const found = books.find((book) => book.id === id); + if (!found) { + res.status(404).send({ error: `A book the provided ID does not exist` }); + throw new NotFoundError(`Book with the provided ID does not exist`); + } + + const index = books.indexOf(found); + books.splice(index, 1); + res.status(200).json({ book: found }); +}; + +module.exports = { + all, + get, + create, + update, + remove, +}; diff --git a/src/contollers/films.js b/src/contollers/films.js new file mode 100644 index 0000000..6ca8767 --- /dev/null +++ b/src/contollers/films.js @@ -0,0 +1,117 @@ +const { films } = require("../../data/index.js"); + +let filmID = films.length + 1; + +const all = (req, res) => { + const { director } = req.query; + if (!director) { + res.status(200).json({ films: films }); + } + const found = films.filter((film) => film.director === director); + res.status(200).json({ films: found }); +}; + +const get = (req, res) => { + const id = Number(req.params.id); + const found = films.find((film) => film.id === id); + if (!found) { + res.status(404).send({ error: "A film with provided ID does not exist" }); + throw new NotFoundError("A film with provided ID does not exist"); + } + res.status(200).json({ film: found }); +}; + +const create = (req, res) => { + const newfilm = req.body; + if (!newfilm.title || !newfilm.director) { + res.status(400).send({ error: `Missing fields in request body` }); + throw new MissingFieldError(`Missing fields in request body`); + } + if (films.find((film) => film.title === newfilm.title)) { + res + .status(409) + .send({ error: `A film with the provided title already exists` }); + throw new MissingFieldError( + `A film with the provided title already exists` + ); + } + newfilm.id = filmID; + films.push(newfilm); + filmID++; + res.status(201).json({ film: newfilm }); +}; + +const update = (req, res) => { + const id = Number(req.params.id); + const updates = req.body; + const found = films.find((film) => film.id === id); + if (!found) { + res.status(404).send({ error: `A film with provided ID does not exist` }); + throw new NotFoundError(`A film with provided ID does not exist`); + } + + if (!updates.title || !updates.director) { + res.status(400).send({ error: `Missing fields in the request body` }); + throw new MissingFieldError(`Missing fields in the request body`); + } + + if (films.find((film) => film.title === updates.title)) { + res + .status(409) + .send({ error: `A film with the provided title already exists` }); + throw new MissingFieldError(`A film with the provided title already exists`); + } + const index = films.indexOf(found); + const updated = { ...found, ...updates }; + res.status(200).json({ film: updated }); +}; + +const remove = (req, res) => { + const id = Number(req.params.id); + const found = films.find((film) => film.id === id); + if (!found) { + res.status(404).send({ error: `A film with provided ID does not exist` }); + throw new NotFoundError(`A film with provided ID does not exist`); + } + const index = films.indexOf(found); + films.splice(index, 1); + res.status(200).json({ film: found }); +}; + +const patch = (req, res) => { + const id = Number(req.params.id); + const updates = req.body; + + if (!updates.title && !updates.director) { + res.status(400).send({ error: `Missing fields in the request body` }); + throw new MissingFieldError(`Missing fields in the request body`); + } + + if (films.find((film) => film.title === updates.title)) { + res + .status(409) + .send({ error: `A film with the provided title already exists` }); + throw new MissingFieldError( + `A film with the provided title already exists` + ); + } + + const found = films.find((film) => film.id === id); + if (!found) { + res.status(404).send({ error: `A film with provided ID does not exist` }); + throw new NotFoundError(`A film with provided ID does not exist`); + } + + const index = films.indexOf(found); + const updated = { ...found, ...updates }; + res.status(200).json({ film: updated }); +}; + +module.exports = { + all, + get, + create, + update, + remove, + patch +}; diff --git a/src/contollers/users.js b/src/contollers/users.js new file mode 100644 index 0000000..5453cb9 --- /dev/null +++ b/src/contollers/users.js @@ -0,0 +1,80 @@ +const { users } = require("../../data/index.js"); + +let userID = users.length + 1; + +const all = (req, res) => { + res.status(200).json({ users: users }); +}; + +const get = (req, res) => { + const id = Number(req.params.id); + const found = users.find((user) => user.id === id); + if (!found) { + res.status(404).send({ error: "A user with the provided ID does not exist" }); + throw new NotFoundError("A user with provided ID does not exist"); + } + res.status(200).json({ user: found }); +}; + +const create = (req, res) => { + const newUser = req.body; + if (!newUser.email) { + res.status(400).send({ error: `Missing fields in request body` }); + throw new MissingFieldError(`Missing fields in request body`); + } + if (users.find((user) => user.email === newUser.email)) { + res + .status(409) + .send({ error: `A user with the provided email already exists` }); + throw new MissingFieldError(`A user the with provided title already exists`); + } + newUser.id = userID; + users.push(newUser); + userID++; + res.status(201).json({ user: newUser }); +}; + +const update = (req, res) => { + const id = Number(req.params.id); + const updates = req.body; + const found = users.find((user) => user.id === id); + if (!found) { + res.status(404).send({ error: `A user with the provided ID does not exist` }); + throw new NotFoundError(`A user with the provided ID does not exist`); + } + + if (!updates.email) { + res.status(400).send({ error: `Missing fields in the request body` }); + throw new MissingFieldError(`Missing fields in the request body`); + } + + if (users.find((user) => user.email === updates.email)) { + res + .status(409) + .send({ error: `A user with the provided email already exists` }); + throw new MissingFieldError(`A user with the provided email already exists`); + } + const index = users.indexOf(found); + const updated = { ...found, ...updates }; + res.status(200).json({ user: updated }); +}; + +const remove = (req, res) => { + const id = Number(req.params.id); + const found = users.find((user) => user.id === id); + if (!found) { + res.status(404).send({ error: `A user with the provided ID does not exist` }); + throw new NotFoundError(`A user with the provided ID does not exist`); + } + const index = users.indexOf(found); + users.splice(index, 1); + res.status(200).json({ user: found }); +}; + +module.exports = { + all, + get, + create, + update, + remove, +}; diff --git a/src/errors/index.js b/src/errors/index.js new file mode 100644 index 0000000..3354add --- /dev/null +++ b/src/errors/index.js @@ -0,0 +1,12 @@ +class MissingFieldError extends Error {} + +class DataError extends Error {} + +class NotFoundError extends Error { +} + +module.exports = { + MissingFieldError, + DataError, + NotFoundError, +}; diff --git a/src/routers/books.js b/src/routers/books.js index 18b9a7c..d54d3bd 100644 --- a/src/routers/books.js +++ b/src/routers/books.js @@ -1,4 +1,19 @@ -// Import data here... +const { all, get, create, update, remove } = require("../contollers/books"); +const express = require("express"); +const router = express.Router(); -// Write routes here... +router.get("/", all); + +router.post("/", create); + +router.get("/:id", get); + +router.put("/:id", update); + +router.delete("/:id", remove); + +router.patch("/:id", update); + + +module.exports = router; diff --git a/src/routers/films.js b/src/routers/films.js index e69de29..3a5a830 100644 --- a/src/routers/films.js +++ b/src/routers/films.js @@ -0,0 +1,18 @@ +const { all, get, create, update, remove, patch } = require("../contollers/films"); + +const express = require("express"); +const router = express.Router(); + +router.get("/", all); + +router.post("/", create); + +router.get("/:id", get); + +router.put("/:id", update); + +router.delete("/:id", remove); + +router.patch("/:id", patch); + +module.exports = router; diff --git a/src/routers/users.js b/src/routers/users.js index e69de29..3630fbe 100644 --- a/src/routers/users.js +++ b/src/routers/users.js @@ -0,0 +1,16 @@ +const { all, get, create, update, remove } = require("../contollers/users"); + +const express = require("express"); +const router = express.Router(); + +router.get("/", all); + +router.post("/", create); + +router.get("/:id", get); + +router.put("/:id", update); + +router.delete("/:id", remove); + +module.exports = router; diff --git a/src/server.js b/src/server.js index 715321f..7ce2a66 100644 --- a/src/server.js +++ b/src/server.js @@ -11,8 +11,15 @@ app.use(morgan("dev")); // REQUIRE ROUTERS const usersRouter = require("./routers/users"); +app.use('/users', usersRouter) // ADD ROUTERS TO APP +const booksRouter = require("./routers/books") +app.use('/books', booksRouter) + +const filmsRouter = require("./routers/films") +app.use('/films', filmsRouter) + module.exports = app