From 1f68495edb7e0c77dfed5f5759040c415cd28894 Mon Sep 17 00:00:00 2001 From: Szyszeekk Date: Sat, 2 Nov 2024 12:18:50 +0100 Subject: [PATCH 1/2] hw2 --- package-lock.json | 87 ++++++++++++++++++++++++++++++++ package.json | 1 + routes/api/contacts.js | 112 ++++++++++++++++++++++++++++++++++------- 3 files changed, 182 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6d047044e5..b3aa40a93ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "cors": "2.8.5", "cross-env": "7.0.3", "express": "4.17.1", + "joi": "^17.13.3", "morgan": "1.10.0" }, "devDependencies": { @@ -141,6 +142,37 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -2166,6 +2198,18 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3757,6 +3801,37 @@ "strip-json-comments": "^3.1.1" } }, + "@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -5269,6 +5344,18 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "requires": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 5045e827160..3c7b3ab3e2a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "cors": "2.8.5", "cross-env": "7.0.3", "express": "4.17.1", + "joi": "^17.13.3", "morgan": "1.10.0" }, "devDependencies": { diff --git a/routes/api/contacts.js b/routes/api/contacts.js index a60ebd69231..415a87e886b 100644 --- a/routes/api/contacts.js +++ b/routes/api/contacts.js @@ -1,25 +1,101 @@ -const express = require('express') +const express = require("express"); +const joi = require("joi"); -const router = express.Router() +const router = express.Router(); -router.get('/', async (req, res, next) => { - res.json({ message: 'template message' }) -}) +const { + listContacts, + getContactById, + removeContact, + addContact, + updateContact, +} = require("../../models/contacts"); -router.get('/:contactId', async (req, res, next) => { - res.json({ message: 'template message' }) -}) +router.get("/", async (req, res, next) => { + try { + const contacts = await listContacts(); + res.status(200).json(contacts); + } catch (error) { + next(error); + } +}); -router.post('/', async (req, res, next) => { - res.json({ message: 'template message' }) -}) +router.get("/:id", async (req, res, next) => { + try { + const { id } = req.params; + const contact = await getContactById(id); + if (!contact) { + return res.status(404).json({ message: "Not found" }); + } + res.status(200).json(contact); + } catch (error) { + next(error); + } +}); -router.delete('/:contactId', async (req, res, next) => { - res.json({ message: 'template message' }) -}) +router.post("/", async (req, res, next) => { + try { + const { error } = joi + .object({ + name: joi.string().required(), + email: joi.string().email().required(), + phone: joi + .string() + .pattern(/^[0-9]+$/) + .required(), + }) + .validate(req.body); -router.put('/:contactId', async (req, res, next) => { - res.json({ message: 'template message' }) -}) + if (error) { + return res.status(400).json({ message: error.details[0].message }); + } -module.exports = router + const { name, email, phone } = req.body; + const newContact = await addContact({ name, email, phone }); + res.status(201).json(newContact); + } catch (error) { + next(error); + } +}); + +router.delete("/:id", async (req, res, next) => { + try { + const { id } = req.params; + const contact = await removeContact(id); + if (!contact) { + return res.status(404).json({ message: "Not found" }); + } + res.status(200).json({ message: "contact deleted" }); + } catch (error) { + next(error); + } +}); + +router.put("/:id", async (req, res, next) => { + try { + const { error } = joi + .object({ + name: joi.string(), + email: joi.string().email(), + phone: joi.string().pattern(/^[0-9]+$/), + }) + .min(1) + .validate(req.body); + + if (error) { + return res.status(400).json({ message: error.details[0].message }); + } + + const { id } = req.params; + const { name, email, phone } = req.body; + const updatedContact = await updateContact(id, { name, email, phone }); + if (!updatedContact) { + return res.status(404).json({ message: "Not found" }); + } + res.status(200).json(updatedContact); + } catch (error) { + next(error); + } +}); + +module.exports = router; From 64798d775289c0c160f858fc4e51e82c410a59ed Mon Sep 17 00:00:00 2001 From: Szyszeekk Date: Sun, 3 Nov 2024 18:29:04 +0100 Subject: [PATCH 2/2] hw2 poprawki --- models/contacts.js | 54 ++++++++++++++++++++++++++++++++++++++++------ package-lock.json | 25 ++++++++++++++++++++- package.json | 3 ++- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/models/contacts.js b/models/contacts.js index 409d11c7c09..48cf30f1049 100644 --- a/models/contacts.js +++ b/models/contacts.js @@ -1,14 +1,54 @@ -// const fs = require('fs/promises') +const fs = require("fs/promises"); +const path = require("path"); +const nanoid = require("nanoid"); -const listContacts = async () => {} +const contactsPath = path.join(__dirname, "./contacts.json"); -const getContactById = async (contactId) => {} +const readContacts = async () => { + const data = await fs.readFile(contactsPath, "utf8"); + return JSON.parse(data); +}; -const removeContact = async (contactId) => {} +const writeContacts = async (contacts) => { + await fs.writeFile(contactsPath, JSON.stringify(contacts, null, 2)); +}; -const addContact = async (body) => {} +const listContacts = async () => { + return await readContacts(); +}; -const updateContact = async (contactId, body) => {} +const getContactById = async (contactId) => { + const contacts = await readContacts(); + return contacts.find((contact) => contact.id === contactId) || null; +}; + +const removeContact = async (contactId) => { + const contacts = await readContacts(); + const index = contacts.findIndex((contact) => contact.id === contactId); + if (index === -1) return null; + + const [removedContact] = contacts.splice(index, 1); + await writeContacts(contacts); + return removedContact; +}; + +const addContact = async ({ name, email, phone }) => { + const contacts = await readContacts(); + const newContact = { id: nanoid(), name, email, phone }; + contacts.push(newContact); + await writeContacts(contacts); + return newContact; +}; + +const updateContact = async (contactId, { name, email, phone }) => { + const contacts = await readContacts(); + const index = contacts.findIndex((contact) => contact.id === contactId); + if (index === -1) return null; + + contacts[index] = { ...contacts[index], name, email, phone }; + await writeContacts(contacts); + return contacts[index]; +}; module.exports = { listContacts, @@ -16,4 +56,4 @@ module.exports = { removeContact, addContact, updateContact, -} +}; diff --git a/package-lock.json b/package-lock.json index b3aa40a93ed..5df62f3e39d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "cross-env": "7.0.3", "express": "4.17.1", "joi": "^17.13.3", - "morgan": "1.10.0" + "morgan": "1.10.0", + "nanoid": "^5.0.8" }, "devDependencies": { "eslint": "7.19.0", @@ -2483,6 +2484,23 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanoid": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.8.tgz", + "integrity": "sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5573,6 +5591,11 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanoid": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.8.tgz", + "integrity": "sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", diff --git a/package.json b/package.json index 3c7b3ab3e2a..855531afbad 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "cross-env": "7.0.3", "express": "4.17.1", "joi": "^17.13.3", - "morgan": "1.10.0" + "morgan": "1.10.0", + "nanoid": "^5.0.8" }, "devDependencies": { "eslint": "7.19.0",