diff --git a/src/controllers/books/booksControllers.js b/src/controllers/books/booksControllers.js new file mode 100644 index 0000000..18db6ec --- /dev/null +++ b/src/controllers/books/booksControllers.js @@ -0,0 +1,111 @@ +const { books } = require("../../../data/index.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") +const { + verifyBookBody, + verifyBookTitle, + addBookToDb, + findBookId, + removeBookFromDb, + replaceBookInDb, + verifyPatchOfBookBody, + verifyBookBodyRequest, +} = require("../../domain/books/booksRepository.js") + +const getBooks = (req, res) => { + res.json({ + books: books, + }) +} + +const postBook = (req, res) => { + verifyBookBody(req) + + verifyBookTitle(req) + + const book = { id: books.length + 1, ...req.body } + + addBookToDb(book) + + res.status(201).json({ + book: book, + }) +} + +const getBookById = (req, res) => { + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + res.json({ + book: book, + }) +} + +const deleteBook = (req, res) => { + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + removeBookFromDb(book) + + res.json({ + book: book, + }) +} + +const updateBook = (req, res) => { + verifyBookBody(req) + + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + const updatedBook = { id: book.id, ...req.body } + + verifyBookTitle(req) + + replaceBookInDb(book, updatedBook) + + res.json({ + book: updatedBook, + }) +} + +const patchBook = (req, res) => { + verifyPatchOfBookBody(req) + + const id = Number(req.params.id) + const book = findBookId(id) + + if (!book) { + throw new DataNotFoundError("A book the provided ID does not exist") + } + + verifyBookTitle(req) + + let updatedBook = {} + + verifyBookBodyRequest(req, updatedBook, book) + + res.json({ + book: updatedBook, + }) +} + +module.exports = { + getBooks, + postBook, + getBookById, + deleteBook, + updateBook, + patchBook, +} diff --git a/src/controllers/films/filmsControllers.js b/src/controllers/films/filmsControllers.js new file mode 100644 index 0000000..fa18e57 --- /dev/null +++ b/src/controllers/films/filmsControllers.js @@ -0,0 +1,116 @@ +const { films } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") +const { + verifyFilmReqQuery, + verifyFilmBody, + verifyFilmTitle, + addFilmToDb, + findFilmById, + removeFilmFromDb, + replaceFilmInDb, + verifyFilmReqBody, + verifyMssingFields, +} = require("../../domain/films/filmsRepository.js") + +const getFilms = (req, res) => { + verifyFilmReqQuery(req, res) + + res.json({ + films: films, + }) +} + +const postFilm = (req, res) => { + verifyFilmBody(req) + + verifyFilmTitle(req) + + const film = { id: films.length + 1, ...req.body } + + addFilmToDb(film) + + res.status(201).json({ + film: film, + }) +} + +const getFilmById = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + res.json({ + film: film, + }) +} + +const deleteFilm = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + removeFilmFromDb(film) + + res.json({ + film: film, + }) +} + +const updateFilm = (req, res) => { + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + verifyFilmTitle(req) + + const updatedFilm = { id: film.id, ...req.body } + + replaceFilmInDb(film, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +const patchFilm = (req, res) => { + verifyMssingFields(req) + + const id = Number(req.params.id) + const film = findFilmById(id) + + if (!film) { + throw new DataNotFoundError("A film with provided ID does not exist") + } + + verifyFilmTitle(req) + + let updatedFilm = {} + + verifyFilmReqBody(req, updatedFilm, film) + + replaceFilmInDb(film, updatedFilm) + + res.json({ + film: updatedFilm, + }) +} + +module.exports = { + getFilms, + postFilm, + getFilmById, + deleteFilm, + updateFilm, + patchFilm, +} diff --git a/src/controllers/users/usersControllers.js b/src/controllers/users/usersControllers.js new file mode 100644 index 0000000..d7c37f2 --- /dev/null +++ b/src/controllers/users/usersControllers.js @@ -0,0 +1,87 @@ +const { users } = require("../../../data/index.js") +const { + verifyUserBody, + verifyUserEmail, + addUserToDb, + findUserId, + deleteUserFromDb, + replaceUserInDb, +} = require("../../domain/users/usersRepository.js") +const DataNotFoundError = require("../../errors/DataNotFoundError.js") + +const getUsers = (req, res) => { + res.json({ + users: users, + }) +} + +const postUser = (req, res) => { + verifyUserBody(req) + + verifyUserEmail(req) + + const user = { id: users.length + 1, ...req.body } + + addUserToDb(user) + + res.status(201).json({ + user: user, + }) +} + +const getUserById = (req, res) => { + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + res.json({ + user: user, + }) +} + +const deleteUser = (req, res) => { + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + deleteUserFromDb(user) + + res.json({ + user: user, + }) +} + +const updateUser = (req, res) => { + verifyUserBody(req) + + const id = Number(req.params.id) + const user = findUserId(id) + + if (!user) { + throw new DataNotFoundError("A user with the provided ID does not exist") + } + + verifyUserEmail(req) + + const updatedUser = { id: user.id, ...req.body } + + replaceUserInDb(user, updatedUser) + + res.json({ + user: updatedUser, + }) +} + +module.exports = { + getUsers, + postUser, + getUserById, + deleteUser, + updateUser, +} diff --git a/src/domain/books/booksRepository.js b/src/domain/books/booksRepository.js new file mode 100644 index 0000000..02484e1 --- /dev/null +++ b/src/domain/books/booksRepository.js @@ -0,0 +1,102 @@ +const { books } = require("../../../data/index.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") +const MissingDataError = require("../../errors/MissingDataError.js") + +const verifyBookBody = (req) => { + if (!req.body.title || !req.body.type || !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyBookTitle = (req) => { + const existingBook = books.find((b) => b.title === req.body.title) + + if (existingBook) { + throw new ExistingDataError( + "A book with the provided title already exists" + ) + } +} + +const addBookToDb = (book) => { + books.push(book) +} + +const findBookId = (id) => { + return books.find((b) => b.id === id) +} + +const removeBookFromDb = (book) => { + books.splice(books.indexOf(book), 1) +} + +const replaceBookInDb = (book, updatedBook) => { + books.splice(books.indexOf(book), 1, updatedBook) +} + +const verifyPatchOfBookBody = (req) => { + if (!req.body.title && !req.body.type && !req.body.author) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyBookBodyRequest = (req, updatedBook, book) => { + if (req.body.title && !req.body.type && !req.body.author) { + return (updatedBook = { + id: book.id, + ...req.body, + type: book.type, + author: book.author, + }) + } + + if (req.body.title && req.body.type && !req.body.author) { + return (updatedBook = { id: book.id, ...req.body, author: book.author }) + } + + if (req.body.title && !req.body.type && req.body.author) { + return (updatedBook = { + id: book.id, + title: req.body.title, + type: book.type, + author: req.body.author, + }) + } + + if (!req.body.title && req.body.type && !req.body.author) { + return (updatedBook = { + id: book.id, + title: book.title, + ...req.body, + author: book.author, + }) + } + + if (!req.body.title && req.body.type && req.body.author) { + return (updatedBook = { id: book.id, title: book.title, ...req.body }) + } + + if (!req.body.title && !req.body.type && req.body.author) { + return (updatedBook = { + id: book.id, + title: book.title, + type: book.type, + ...req.body, + }) + } + + if (req.body.title && req.body.type && req.body.author) { + return (updatedBook = { id: book.id, ...req.body }) + } +} + +module.exports = { + verifyBookBody, + verifyBookTitle, + addBookToDb, + findBookId, + removeBookFromDb, + replaceBookInDb, + verifyPatchOfBookBody, + verifyBookBodyRequest, +} diff --git a/src/domain/films/filmsRepository.js b/src/domain/films/filmsRepository.js new file mode 100644 index 0000000..a2f85aa --- /dev/null +++ b/src/domain/films/filmsRepository.js @@ -0,0 +1,80 @@ +const { films } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") + +const verifyFilmReqQuery = (req, res) => { + if (req.query.director) { + const directorName = req.query.director.split(" ").join("").toLowerCase() + const directorFilms = films.filter( + (f) => f.director.split(" ").join("").toLowerCase() === directorName + ) + + return res.json({ + films: directorFilms, + }) + } +} + +const verifyFilmBody = (req) => { + if (!req.body.title || !req.body.director) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyFilmTitle = (req) => { + const existingFilm = films.find((f) => f.title === req.body.title) + + if (existingFilm) { + throw new ExistingDataError( + "A film with the provided title already exists" + ) + } +} + +const addFilmToDb = (film) => { + films.push(film) +} + +const findFilmById = (id) => { + return films.find((f) => f.id === id) +} + +const removeFilmFromDb = (film) => { + films.splice(films.indexOf(film), 1) +} + +const replaceFilmInDb = (film, updatedFilm) => { + films.splice(films.indexOf(film), 1, updatedFilm) +} + +const verifyFilmReqBody = (req, updatedFilm, film) => { + if (!req.body.title && req.body.director) { + return (updatedFilm = { id: film.id, title: film.title, ...req.body }) + } + + if (req.body.title && !req.body.director) { + return (updatedFilm = { + id: film.id, + ...req.body, + director: film.director, + }) + } +} + +const verifyMssingFields = (req) => { + if (!req.body.title && !req.body.director) { + throw new MissingDataError("Missing fields in request body") + } +} + +module.exports = { + verifyFilmReqQuery, + verifyFilmBody, + verifyFilmTitle, + addFilmToDb, + findFilmById, + removeFilmFromDb, + replaceFilmInDb, + verifyFilmReqBody, + verifyMssingFields, +} diff --git a/src/domain/users/usersRepository.js b/src/domain/users/usersRepository.js new file mode 100644 index 0000000..216cce6 --- /dev/null +++ b/src/domain/users/usersRepository.js @@ -0,0 +1,44 @@ +const { users } = require("../../../data/index.js") +const MissingDataError = require("../../errors/MissingDataError.js") +const ExistingDataError = require("../../errors/ExistingDataError.js") + +const verifyUserBody = (req) => { + if (!req.body.email) { + throw new MissingDataError("Missing fields in request body") + } +} + +const verifyUserEmail = (req) => { + const existingUser = users.find((u) => u.email === req.body.email) + + if (existingUser) { + throw new ExistingDataError( + "A user with the provided email already exists" + ) + } +} + +const addUserToDb = (user) => { + users.push(user) +} + +const findUserId = (id) => { + return users.find((u) => u.id === id) +} + +const deleteUserFromDb = (user) => { + users.splice(users.indexOf(user), 1) +} + +const replaceUserInDb = (user, updatedUser) => { + users.splice(users.indexOf(user), 1, updatedUser) +} + +module.exports = { + verifyUserBody, + verifyUserEmail, + addUserToDb, + findUserId, + deleteUserFromDb, + replaceUserInDb, +} diff --git a/src/errors/DataNotFoundError.js b/src/errors/DataNotFoundError.js new file mode 100644 index 0000000..a4a42d7 --- /dev/null +++ b/src/errors/DataNotFoundError.js @@ -0,0 +1,3 @@ +class DataNotFoundError extends Error {} + +module.exports = DataNotFoundError diff --git a/src/errors/ExistingDataError.js b/src/errors/ExistingDataError.js new file mode 100644 index 0000000..9001278 --- /dev/null +++ b/src/errors/ExistingDataError.js @@ -0,0 +1,3 @@ +class ExistingDataError extends Error {} + +module.exports = ExistingDataError diff --git a/src/errors/MissingDataError.js b/src/errors/MissingDataError.js new file mode 100644 index 0000000..14ddd5e --- /dev/null +++ b/src/errors/MissingDataError.js @@ -0,0 +1,3 @@ +class MissingDataError extends Error {} + +module.exports = MissingDataError \ No newline at end of file diff --git a/src/index.js b/src/index.js index c16707f..8c97d0b 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,8 @@ /* REQUIRE APP */ -const app = require('./server.js') -const port = 3030; +const app = require("./server.js") +const port = 3030 /* START SERVER */ app.listen(port, () => { - console.log(`Server is running on http://localhost:${port}/`); -}); + console.log(`Server is running on http://localhost:${port}/`) +}) diff --git a/src/routers/books.js b/src/routers/books.js deleted file mode 100644 index 18b9a7c..0000000 --- a/src/routers/books.js +++ /dev/null @@ -1,4 +0,0 @@ -// Import data here... - - -// Write routes here... diff --git a/src/routers/books/books.js b/src/routers/books/books.js new file mode 100644 index 0000000..05f7ef3 --- /dev/null +++ b/src/routers/books/books.js @@ -0,0 +1,24 @@ +const express = require("express") +const { + postBook, + getBookById, + deleteBook, + updateBook, + patchBook, + getBooks, +} = require("../../controllers/books/booksControllers.js") +const router = express.Router() + +router.get("/", getBooks) + +router.post("/", postBook) + +router.get("/:id", getBookById) + +router.delete("/:id", deleteBook) + +router.put("/:id", updateBook) + +router.patch("/:id", patchBook) + +module.exports = router diff --git a/src/routers/films.js b/src/routers/films.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/routers/films/films.js b/src/routers/films/films.js new file mode 100644 index 0000000..74f100e --- /dev/null +++ b/src/routers/films/films.js @@ -0,0 +1,24 @@ +const express = require("express") +const { + getFilms, + postFilm, + getFilmById, + deleteFilm, + updateFilm, + patchFilm, +} = require("../../controllers/films/filmsControllers.js") +const router = express.Router() + +router.get("/", getFilms) + +router.post("/", postFilm) + +router.get("/:id", getFilmById) + +router.delete("/:id", deleteFilm) + +router.put("/:id", updateFilm) + +router.patch("/:id", patchFilm) + +module.exports = router diff --git a/src/routers/users.js b/src/routers/users.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/routers/users/users.js b/src/routers/users/users.js new file mode 100644 index 0000000..9f8050e --- /dev/null +++ b/src/routers/users/users.js @@ -0,0 +1,21 @@ +const express = require("express") +const { + getUsers, + postUser, + getUserById, + deleteUser, + updateUser, +} = require("../../controllers/users/usersControllers.js") +const router = express.Router() + +router.get("/", getUsers) + +router.post("/", postUser) + +router.get("/:id", getUserById) + +router.delete("/:id", deleteUser) + +router.put("/:id", updateUser) + +module.exports = router diff --git a/src/server.js b/src/server.js index 715321f..97f3946 100644 --- a/src/server.js +++ b/src/server.js @@ -1,18 +1,47 @@ -const express = require("express"); -const app = express(); +const express = require("express") +const app = express() -const cors = require("cors"); -const morgan = require("morgan"); +const cors = require("cors") +const morgan = require("morgan") // SETUP MIDDLEWARE -app.use(cors()); -app.use(express.json()); -app.use(morgan("dev")); +app.use(cors()) +app.use(express.json()) +app.use(morgan("dev")) // REQUIRE ROUTERS -const usersRouter = require("./routers/users"); +const usersRouter = require("./routers/users/users.js") +const filmsRouter = require("./routers/films/films.js") +const booksRouter = require("./routers/books/books.js") // ADD ROUTERS TO APP +app.use("/users", usersRouter) +app.use("/films", filmsRouter) +app.use("/books", booksRouter) +// ADD ERRORS CLASSES +const MissingDataError = require("./errors/MissingDataError.js") +const ExistingDataError = require("./errors/ExistingDataError.js") +const DataNotFoundError = require("./errors/DataNotFoundError.js") + +app.use((error, req, res, next) => { + if (error instanceof MissingDataError) { + return res.status(400).json({ + error: error.message, + }) + } + + if (error instanceof ExistingDataError) { + return res.status(409).json({ + error: error.message, + }) + } + + if (error instanceof DataNotFoundError) { + return res.status(404).json({ + error: error.message, + }) + } +}) module.exports = app