diff --git a/.env-example b/.env-example index dfce8c4d..74ca79de 100644 --- a/.env-example +++ b/.env-example @@ -1,7 +1,7 @@ PORT=3000 -MONGO_USER= +MONGO_USER=root MONGO_PASSWORD= -MONGO_HOST= -MONGO_DB_NAME= -MONGO_PORT= +MONGO_HOST=localhot +MONGO_DB_NAME=platzi +MONGO_PORT=3306 MONGO_CONNECTION= \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 76a7fcef..aefc3f07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,13 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "body-parser": "^1.19.0", "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", - "mongodb": "^3.6.6" + "mongodb": "^3.6.6", + "mysql": "^2.18.1", + "swagger-ui-express": "^4.1.6" }, "devDependencies": { "jest": "^26.6.3", @@ -1894,6 +1897,14 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -6716,6 +6727,20 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dependencies": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -8465,6 +8490,14 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -8881,6 +8914,25 @@ "node": ">=8" } }, + "node_modules/swagger-ui-dist": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.49.0.tgz", + "integrity": "sha512-R1+eT16XNP1bBLfacISifZAkFJlpwvWsS2vVurF5pbIFZnmCasD/hj+9r/q7urYdQyb0B6v11mDnuYU7rUpfQg==" + }, + "node_modules/swagger-ui-express": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.1.6.tgz", + "integrity": "sha512-Xs2BGGudvDBtL7RXcYtNvHsFtP1DBFPMJFRxHe5ez/VG/rzVOEjazJOOSc/kSCyxreCTKfJrII6MJlL9a6t8vw==", + "dependencies": { + "swagger-ui-dist": "^3.18.1" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -11273,6 +11325,11 @@ "tweetnacl": "^0.14.3" } }, + "bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" + }, "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", @@ -14975,6 +15032,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "requires": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + } + }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -16372,6 +16440,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -16685,6 +16758,19 @@ } } }, + "swagger-ui-dist": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.49.0.tgz", + "integrity": "sha512-R1+eT16XNP1bBLfacISifZAkFJlpwvWsS2vVurF5pbIFZnmCasD/hj+9r/q7urYdQyb0B6v11mDnuYU7rUpfQg==" + }, + "swagger-ui-express": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.1.6.tgz", + "integrity": "sha512-Xs2BGGudvDBtL7RXcYtNvHsFtP1DBFPMJFRxHe5ez/VG/rzVOEjazJOOSc/kSCyxreCTKfJrII6MJlL9a6t8vw==", + "requires": { + "swagger-ui-dist": "^3.18.1" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 279a5416..b2f225f1 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,13 @@ "description": "Reto 9 Octubre 26: Curso de Backend con Node", "main": "index.js", "dependencies": { + "body-parser": "^1.19.0", "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", - "mongodb": "^3.6.6" + "mongodb": "^3.6.6", + "mysql": "^2.18.1", + "swagger-ui-express": "^4.1.6" }, "devDependencies": { "jest": "^26.6.3", @@ -25,7 +28,7 @@ }, "keywords": [], "author": "", - "license": "ISC", + "license": "MIT", "bugs": { "url": "https://github.com/platzi/escuelajs-reto-09/issues" }, diff --git a/platzi.mwb b/platzi.mwb new file mode 100644 index 00000000..e99dfc07 Binary files /dev/null and b/platzi.mwb differ diff --git a/platzi.postman_collection.json b/platzi.postman_collection.json new file mode 100644 index 00000000..30811872 --- /dev/null +++ b/platzi.postman_collection.json @@ -0,0 +1,204 @@ +{ + "info": { + "_postman_id": "66f5d3f4-e55a-4668-81e7-538753045f65", + "name": "platzi", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json" + }, + "item": [ + { + "name": "get products", + "request": { + "method": "GET", + "header": [], + "url": "localhost:3000/api/products" + }, + "response": [] + }, + { + "name": "get products id", + "request": { + "method": "GET", + "header": [], + "url": "localhost:3000/api/products/2" + }, + "response": [] + }, + { + "name": "post products", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "name", + "value": "queso", + "type": "text" + }, + { + "key": "price", + "value": "10", + "type": "text" + }, + { + "key": "description", + "value": "manchego", + "type": "text" + }, + { + "key": "img", + "value": "asdasdasd", + "type": "text" + }, + { + "key": "category_id", + "value": "1", + "type": "text" + } + ] + }, + "url": "localhost:3000/api/products" + }, + "response": [] + }, + { + "name": "put products id", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "name", + "value": "leche", + "type": "text" + }, + { + "key": "price", + "value": "10", + "type": "text" + }, + { + "key": "description", + "value": "leche ligh", + "type": "text" + }, + { + "key": "img", + "value": "asdasdasd", + "type": "text" + }, + { + "key": "category_id", + "value": "1", + "type": "text" + }, + { + "key": "", + "value": "", + "type": "text", + "disabled": true + } + ] + }, + "url": "localhost:3000/api/products/1" + }, + "response": [] + }, + { + "name": "delete products id", + "request": { + "method": "DELETE", + "header": [], + "url": "localhost:3000/api/products/2" + }, + "response": [] + }, + { + "name": "get categories", + "request": { + "method": "GET", + "header": [], + "url": "localhost:3000/api/categories" + }, + "response": [] + }, + { + "name": "get categories id", + "request": { + "method": "GET", + "header": [], + "url": "localhost:3000/api/categories/1" + }, + "response": [] + }, + { + "name": "post categories", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "name", + "value": "electronicos", + "type": "text" + }, + { + "key": "img", + "value": "asdasd", + "type": "text" + } + ] + }, + "url": "localhost:3000/api/categories" + }, + "response": [] + }, + { + "name": "put categories id", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "name", + "value": "electronicos2", + "type": "text" + }, + { + "key": "img", + "value": "asdasdasd", + "type": "text" + } + ] + }, + "url": "localhost:3000/api/categories/2" + }, + "response": [] + }, + { + "name": "delete categories id", + "request": { + "method": "DELETE", + "header": [], + "url": "localhost:3000/api/categories/2" + }, + "response": [] + }, + { + "name": "get categories id products", + "request": { + "method": "GET", + "header": [], + "url": "localhost:3000/api/categories/1/products" + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/src/app.js b/src/app.js index 62a46b5e..8d6903f7 100644 --- a/src/app.js +++ b/src/app.js @@ -1,10 +1,19 @@ const express = require('express'); const cors = require('cors'); +const bodyParser = require('body-parser'); +const swaggerUi = require('swagger-ui-express'); +const swaggerDoc = require('./swagger.json'); +const errors = require('./utils/network/errors'); -function createApp() { +function createApp() { const app = express(); app.use(cors()); app.use(express.json()); + app.use(bodyParser.urlencoded({ extended: false })); + app.use(bodyParser.json()); + app.use('/api', require('./routes/index')); + app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc)); + app.use(errors); // ADD YOUR ROUTES return app; diff --git a/src/config/config.js b/src/config/config.js new file mode 100644 index 00000000..774074a8 --- /dev/null +++ b/src/config/config.js @@ -0,0 +1,20 @@ +module.exports = { + api: { + port: process.env.API_PORT || 3000, + }, + mysql: { + host: 'localhost', + port: '3306', + user: 'root', + password: '', + database: 'platzi', + }, + jwt: { + secret: process.env.JWT_SECRET || '9786asdghjg87asdg', + expiresIn: 60 * 60 , + }, + host: { + url: 'http://localhost:3000/', + }, + }; + \ No newline at end of file diff --git a/src/controllers/categories/controller.js b/src/controllers/categories/controller.js new file mode 100644 index 00000000..cd7b3328 --- /dev/null +++ b/src/controllers/categories/controller.js @@ -0,0 +1,51 @@ +module.exports = function (injectedStore) { + let store = injectedStore; + + function getCategories() { + return store.getCategories(); + } + function getCategoriesId(json) { + const data = { + id: json.id, + }; + return store.getCategoriesId(data); + } + function postCategories(json) { + const data = { + name: json.name, + img: json.img + }; + return store.postCategories(data); + } + function putCategories(json,id) { + console.log(json, id); + const data = { + name: json.name, + img: json.img, + id: id.id, + }; + console.log(data); + return store.putCategories(data); + } + function deleteCategories(json) { + const data = { + id: json.id, + }; + return store.deleteCategories(data); + } + function getCategoriesIdProducts(json) { + const data = { + id: json.id, + }; + return store.getCategoriesIdProducts(data); + } + + return { + getCategories, + getCategoriesId, + postCategories, + putCategories, + deleteCategories, + getCategoriesIdProducts, + }; +}; diff --git a/src/controllers/categories/index.js b/src/controllers/categories/index.js new file mode 100644 index 00000000..8b9392c3 --- /dev/null +++ b/src/controllers/categories/index.js @@ -0,0 +1,4 @@ +const store = require('../../models/categories'); +const ctrl = require('./controller'); + +module.exports = ctrl(store); diff --git a/src/controllers/products/controller.js b/src/controllers/products/controller.js new file mode 100644 index 00000000..57361670 --- /dev/null +++ b/src/controllers/products/controller.js @@ -0,0 +1,50 @@ +module.exports = function (injectedStore) { + let store = injectedStore; + + function getProducts(json) { + return store.getProducts(json); + } + + function getProductsId(json) { + const data = { + id: json.id, + }; + return store.getProductsId(data); + } + function postProducts(json) { + const data = { + name: json.name, + price: json.price, + description: json.description, + img: json.img, + category_id: json.category_id, + }; + return store.postProducts(data); + } + function putProducts(json, params) { + const data = { + name: json.name, + price: json.price, + description: json.description, + img: json.img, + category_id: json.category_id, + id: params.id, + }; + console.log(data); + return store.putProducts(data); + } + function deleteProducts(json) { + const data = { + id: json.id, + }; + return store.deleteProducts(data); + } + + return { + getProducts, + getProductsId, + postProducts, + putProducts, + deleteProducts, + }; +}; diff --git a/src/controllers/products/index.js b/src/controllers/products/index.js new file mode 100644 index 00000000..546e9641 --- /dev/null +++ b/src/controllers/products/index.js @@ -0,0 +1,4 @@ +const store = require('../../models/products'); +const ctrl = require('./controller'); + +module.exports = ctrl(store); diff --git a/src/db.sql b/src/db.sql new file mode 100644 index 00000000..39d76695 --- /dev/null +++ b/src/db.sql @@ -0,0 +1,28 @@ +CREATE SCHEMA IF NOT EXISTS `platzi` DEFAULT CHARACTER SET utf8 ; +USE `platzi` ; + + +CREATE TABLE IF NOT EXISTS `platzi`.`categorys` ( + `id` INT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(85) NULL, + `img` VARCHAR(200) NULL, + PRIMARY KEY (`id`)) +ENGINE = InnoDB; + + + +CREATE TABLE IF NOT EXISTS `platzi`.`products` ( + `id` INT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(85) NULL, + `price` VARCHAR(20) NULL, + `description` TEXT NULL, + `img` VARCHAR(200) NULL, + `categorys_id` INT NOT NULL, + PRIMARY KEY (`id`), + INDEX `fk_products_categorys_idx` (`categorys_id` ASC) , + CONSTRAINT `fk_products_categorys` + FOREIGN KEY (`categorys_id`) + REFERENCES `platzi`.`categorys` (`id`) + ON DELETE NO ACTION + ON UPDATE NO ACTION) +ENGINE = InnoDB; diff --git a/src/models/categories.js b/src/models/categories.js new file mode 100644 index 00000000..ef4f9396 --- /dev/null +++ b/src/models/categories.js @@ -0,0 +1,66 @@ +const conn = require('./connection.js'); + +function getCategories() { + return new Promise((resolve, reject) => { + conn.query(`SELECT * FROM categoris`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function getCategoriesId(json) { + return new Promise((resolve, reject) => { + conn.query(`SELECT * FROM categoris WHERE id = ${json.id}`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function postCategories(json) { + return new Promise((resolve, reject) => { + conn.query(`INSERT INTO platzi.categoris + (name, img) + VALUES('${json.name}', '${json.img}'); + `, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function putCategories(json) { + return new Promise((resolve, reject) => { + conn.query(`UPDATE platzi.categoris + SET name='${json.name}', img='${json.img}' + WHERE id=${json.id}; + `, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function deleteCategories(json) { + return new Promise((resolve, reject) => { + conn.query(`DELETE FROM platzi.categoris + WHERE id=${json.id};`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function getCategoriesIdProducts(json) { + return new Promise((resolve, reject) => { + conn.query(`SELECT * FROM products WHERE categorys_id = ${json.id}`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} + +module.exports = { + getCategories, + getCategoriesId, + postCategories, + putCategories, + deleteCategories, + getCategoriesIdProducts, +}; diff --git a/src/models/connection.js b/src/models/connection.js new file mode 100644 index 00000000..9a67a934 --- /dev/null +++ b/src/models/connection.js @@ -0,0 +1,36 @@ +const mysql = require('mysql'); +const config = require('../config/config'); + +const dbconf = { + host: config.mysql.host, + port: config.mysql.port, + user: config.mysql.user, + password: config.mysql.password, + database: config.mysql.database, +}; + +let connection; +function handleCon() { + connection = mysql.createConnection(dbconf); + + connection.connect((err) => { + if (err) { + console.error('[db err]', err); + setTimeout(handleCon, 2000); + } else { + console.log('DB Connected'); + } + }); + + connection.on('error', (err) => { + console.error('[db err]', err); + if (err.code === 'PROTOCOL_CONNECTION_LOST') { + handleCon(); + } else { + throw err; + } + }); +} + +handleCon(); +module.exports= connection; \ No newline at end of file diff --git a/src/models/products.js b/src/models/products.js new file mode 100644 index 00000000..d05ea087 --- /dev/null +++ b/src/models/products.js @@ -0,0 +1,68 @@ +const conn = require('./connection.js'); + +function getProducts(json) { + console.log(json); + return new Promise((resolve, reject) => { + conn.query(`SELECT * FROM products`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} + +function getProductsId(json) { + return new Promise((resolve, reject) => { + conn.query(`SELECT * FROM products WHERE id = ${json.id}`, (err, data) => { + if (err) return reject(err); + resolve(data); + }); + }); +} +function postProducts(json) { + return new Promise((resolve, reject) => { + conn.query( + `INSERT INTO platzi.products + (name, price, description, img, categorys_id) + VALUES('${json.name}', '${json.price}', '${json.description}', '${json.img}', ${json.category_id}); + `, + (err, data) => { + if (err) return reject(err); + resolve(data); + } + ); + }); +} +function putProducts(json) { + return new Promise((resolve, reject) => { + conn.query( + `UPDATE platzi.products + SET name='${json.name}', price='${json.price}', description='${json.description}', img='${json.img}', categorys_id=${json.category_id} + WHERE id=${json.id}; + `, + (err, data) => { + if (err) return reject(err); + resolve(data); + } + ); + }); +} +function deleteProducts(json) { + return new Promise((resolve, reject) => { + conn.query( + `DELETE FROM platzi.products + WHERE id=${json.id};`, + (err, data) => { + if (err) return reject(err); + resolve(data); + } + ); + }); +} + +module.exports = { + getProducts, + getProductsId, + postProducts, + putProducts, + deleteProducts, +}; diff --git a/src/routes/categories.js b/src/routes/categories.js new file mode 100644 index 00000000..7850e1b1 --- /dev/null +++ b/src/routes/categories.js @@ -0,0 +1,70 @@ +const express = require('express'); +const response = require('../utils/network/response'); +const Controller = require('../controllers/categories/index'); + +const app = express(); + +app.get('/categories', getCategories); +app.get('/categories/:id', getCategoriesId); +app.post('/categories', postCategories); +app.put('/categories/:id', putCategories); +app.delete('/categories/:id', deleteCategories); +app.get('/categories/:id/products', getCategoriesIdProducts); + +function getCategories(req, res) { + Controller.getCategories() + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} +function getCategoriesId(req, res) { + Controller.getCategoriesId(req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} +function postCategories(req, res) { + Controller.postCategories(req.body) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} +function putCategories(req, res) { + console.log('entro'); + Controller.putCategories(req.body, req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} +function deleteCategories(req, res) { + Controller.deleteCategories(req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} +function getCategoriesIdProducts(req, res) { + Controller.getCategoriesIdProducts(req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 400); + }); +} + +module.exports = app; diff --git a/src/routes/index.js b/src/routes/index.js new file mode 100644 index 00000000..8c99b02b --- /dev/null +++ b/src/routes/index.js @@ -0,0 +1,9 @@ +const express = require('express'); + +const app = express(); + +app.use(require('./products')); +app.use(require('./categories')); + + +module.exports = app; diff --git a/src/routes/products.js b/src/routes/products.js new file mode 100644 index 00000000..0de0bd84 --- /dev/null +++ b/src/routes/products.js @@ -0,0 +1,59 @@ +const express = require('express'); +const response = require('../utils/network/response'); +const Controller = require('../controllers/products/index'); + +const app = express(); + +app.get('/products', getProducts); +app.get('/products/:id', getProductsId); +app.post('/products', postProducts); +app.put('/products/:id', putProducts); +app.delete('/products/:id', deleteProducts); + +function getProducts(req, res) { + Controller.getProducts() + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 500); + }); +} +function getProductsId(req, res) { + Controller.getProductsId(req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 500); + }); +} +function postProducts(req, res) { + Controller.postProducts(req.body) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 500); + }); +} +function putProducts(req, res) { + Controller.putProducts(req.body, req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 500); + }); +} +function deleteProducts(req, res) { + Controller.deleteProducts(req.params) + .then((user) => { + response.success(req, res, user, 200); + }) + .catch((err) => { + response.error(req, res, err.message, 500); + }); +} + +module.exports = app; diff --git a/src/swagger.json b/src/swagger.json new file mode 100644 index 00000000..2fec5ebc --- /dev/null +++ b/src/swagger.json @@ -0,0 +1,357 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0", + "title": "platzi", + "contact": {} + }, + "host": "localhost:3000", + "basePath": "/api", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/products": { + "get": { + "summary": "get products", + "tags": [ + "Misc" + ], + "operationId": "getproducts", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + }, + "post": { + "summary": "post products", + "tags": [ + "Misc" + ], + "operationId": "postproducts", + "deprecated": false, + "produces": [ + "application/json" + ], + "consumes": [ + "application/x-www-form-urlencoded" + ], + "parameters": [ + { + "name": "name", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "price", + "in": "formData", + "required": true, + "type": "integer", + "format": "int32", + "description": "" + }, + { + "name": "description", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "img", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "category_id", + "in": "formData", + "required": true, + "type": "integer", + "format": "int32", + "description": "" + } + ], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/products/2": { + "get": { + "summary": "get products id", + "tags": [ + "Misc" + ], + "operationId": "getproductsid", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + }, + "delete": { + "summary": "delete products id", + "tags": [ + "Misc" + ], + "operationId": "deleteproductsid", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/products/1": { + "put": { + "summary": "put products id", + "tags": [ + "Misc" + ], + "operationId": "putproductsid", + "deprecated": false, + "produces": [ + "application/json" + ], + "consumes": [ + "application/x-www-form-urlencoded" + ], + "parameters": [ + { + "name": "name", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "price", + "in": "formData", + "required": true, + "type": "integer", + "format": "int32", + "description": "" + }, + { + "name": "description", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "img", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "category_id", + "in": "formData", + "required": true, + "type": "integer", + "format": "int32", + "description": "" + } + ], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/categories": { + "get": { + "summary": "get categories", + "tags": [ + "Misc" + ], + "operationId": "getcategories", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + }, + "post": { + "summary": "post categories", + "tags": [ + "Misc" + ], + "operationId": "postcategories", + "deprecated": false, + "produces": [ + "application/json" + ], + "consumes": [ + "application/x-www-form-urlencoded" + ], + "parameters": [ + { + "name": "name", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "img", + "in": "formData", + "required": true, + "type": "string", + "description": "" + } + ], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/categories/1": { + "get": { + "summary": "get categories id", + "tags": [ + "Misc" + ], + "operationId": "getcategoriesid", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/categories/2": { + "put": { + "summary": "put categories id", + "tags": [ + "Misc" + ], + "operationId": "putcategoriesid", + "deprecated": false, + "produces": [ + "application/json" + ], + "consumes": [ + "application/x-www-form-urlencoded" + ], + "parameters": [ + { + "name": "name", + "in": "formData", + "required": true, + "type": "string", + "description": "" + }, + { + "name": "img", + "in": "formData", + "required": true, + "type": "string", + "description": "" + } + ], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + }, + "delete": { + "summary": "delete categories id", + "tags": [ + "Misc" + ], + "operationId": "deletecategoriesid", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + }, + "/categories/1/products": { + "get": { + "summary": "get categories id products", + "tags": [ + "Misc" + ], + "operationId": "getcategoriesidproducts", + "deprecated": false, + "produces": [ + "application/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "", + "headers": {} + } + } + } + } + }, + "tags": [ + { + "name": "Misc", + "description": "" + } + ] +} \ No newline at end of file diff --git a/src/utils/error.js b/src/utils/error.js new file mode 100644 index 00000000..3ff82644 --- /dev/null +++ b/src/utils/error.js @@ -0,0 +1,9 @@ +function err(message, code) { + let e = new Error(message); + + if (code) { + e.statusCode = code; + } + return e; + +} \ No newline at end of file diff --git a/src/utils/network/errors.js b/src/utils/network/errors.js new file mode 100644 index 00000000..6a072803 --- /dev/null +++ b/src/utils/network/errors.js @@ -0,0 +1,13 @@ +const response = require('./response'); + +function errors(err, req, res, next) { + console.error('[error]', err); + + const message = err.message || 'Internal Error'; + const status = err.statusCode || 500; + + response.error(req, res, message, status) + +} + +module.exports = errors; \ No newline at end of file diff --git a/src/utils/network/response.js b/src/utils/network/response.js new file mode 100644 index 00000000..1d40e687 --- /dev/null +++ b/src/utils/network/response.js @@ -0,0 +1,22 @@ +exports.success = function (req, res, message, status) { + let statusCode = status || 200; + let statusMessage = message || ''; + + res.status(statusCode).send({ + error: false, + status: status, + body: statusMessage, + }); + }; + + exports.error = function (req, res, message, status) { + let statusCode = status || 500; + let statusMessage = message || 'Internal server error'; + + res.status(statusCode).send({ + error: false, + status: status, + body: statusMessage, + }); + }; + \ No newline at end of file