From c17f1bced6df6615064132b43cf55c50c81577c0 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Wed, 20 Mar 2024 17:10:22 -0600 Subject: [PATCH 01/57] 1er modulo --- .gitignore | 2 + backend/.env | 6 + backend/app.js | 22 + backend/config/config.php | 0 backend/config/database.js | 12 + backend/config/database.php | 0 .../controllers/herramientas_controller.js | 180 +++ .../controllers/tipoHerramienta_controller.js | 182 +++ backend/helpers/return_error.js | 11 + backend/includes/db_connection.php | 0 backend/includes/functions.php | 0 backend/index.php | 0 backend/routes/herramientas_routes.js | 16 + backend/routes/tipoHerramienta_routes.js | 16 + backend/routes/web.php | 0 package-lock.json | 1176 +++++++++++++++++ package.json | 21 + 17 files changed, 1644 insertions(+) create mode 100644 .gitignore create mode 100644 backend/.env create mode 100644 backend/app.js delete mode 100644 backend/config/config.php create mode 100644 backend/config/database.js delete mode 100644 backend/config/database.php create mode 100644 backend/controllers/herramientas_controller.js create mode 100644 backend/controllers/tipoHerramienta_controller.js create mode 100644 backend/helpers/return_error.js delete mode 100644 backend/includes/db_connection.php delete mode 100644 backend/includes/functions.php delete mode 100644 backend/index.php create mode 100644 backend/routes/herramientas_routes.js create mode 100644 backend/routes/tipoHerramienta_routes.js delete mode 100644 backend/routes/web.php create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..933ca2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +frontend/ \ No newline at end of file diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..0933ef1 --- /dev/null +++ b/backend/.env @@ -0,0 +1,6 @@ +NODE_PORT="3000" +HOST="localhost" +PORT="3306" +USER="root" +PASSWORD="root" +DATABASE="dbsistemas" \ No newline at end of file diff --git a/backend/app.js b/backend/app.js new file mode 100644 index 0000000..dcd90cf --- /dev/null +++ b/backend/app.js @@ -0,0 +1,22 @@ +const express = require('express'); +const app = express(); +require('dotenv').config({path: 'backend/.env'}); + + + +app.listen(process.env.NODE_PORT, () => { + console.log('server running '+ process.env.NODE_PORT); +}); + +app.use(express.json()); +app.use('/herramientas', require('./routes/herramientas_routes')) +app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) + + +/* app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); + next(); +})*/ diff --git a/backend/config/config.php b/backend/config/config.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/config/database.js b/backend/config/database.js new file mode 100644 index 0000000..7f07a6e --- /dev/null +++ b/backend/config/database.js @@ -0,0 +1,12 @@ +const mariadb = require('mariadb'); +require('dotenv').config(); + +const pool = mariadb.createPool({ + host: process.env.HOST, + port: process.env.PORT, + user: process.env.USER, + password: process.env.PASSWORD, + database: process.env.DATABASE +}); + +module.exports = pool \ No newline at end of file diff --git a/backend/config/database.php b/backend/config/database.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js new file mode 100644 index 0000000..4e829da --- /dev/null +++ b/backend/controllers/herramientas_controller.js @@ -0,0 +1,180 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js') + +const post_herramienta = async(req, res)=>{ + await pool.getConnection().then(async (conn) => { + try{ + const {tipo, estatus, observaciones} = req.body; + const data = [tipo, estatus, observaciones]; + + //validacion expresss validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato o extensión incorrecta'); + conn.end; + return res.status(400).json(result) + } + + //validation tipo exists, estatus exists + const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", tipo) + const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", estatus) + + if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ + const result = return_error(400,'El tipo de herramienta o el estatus no existe'); + conn.end; + return res.status(400).json(result) + } + + //query + const query = await conn.query("INSERT INTO herramientas (tipo, estatus, observaciones) VALUES (?,?,?)",data) + const insert_id = parseInt(query.insertId) + //res estatus + res.status(201).json({ + "ok": true, + "id_herramienta": insert_id, + "message": { + "code": 201, + "messageText": "Registrado con éxito" + } + }) + + conn.end; + + } + catch (error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + console.log(error.message) + + } + }) +} + +const get_herramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + //query + const query = await conn.query("SELECT * FROM herramientas"); + res.status(200).json(query) + conn.end; + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + } + + }) +} + +const put_herramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + const {id_herramienta, tipo, estatus, observaciones} = req.body; + const data = [tipo, estatus, observaciones, id_herramienta]; + + //validacion expresss validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato o extensión incorrecta'); + conn.end; + return res.status(400).json(result) + } + + //validation tipo exists, estatus exists + const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", tipo) + const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", estatus) + + if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ + const result = return_error(400,'El tipo de herramienta o el estatus no existe'); + conn.end; + return res.status(400).json(result) + } + + //query + const query = await conn.query("UPDATE herramientas SET tipo = ?, estatus = ?, observaciones = ? WHERE id_herramienta = ?",data) + const insert_id = parseInt(query.insertId) + //res estatus + res.status(201).json({ + "ok": true, + "id_herramienta": insert_id, + "message": { + "code": 201, + "messageText": "Actualizado con éxito" + } + }) + + conn.end; + + + + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + } + + }) +} + +const delete_herramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + const id_herramienta = req.param + + //validation express validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato incorrecto'); + conn.end; + return res.status(400).json(result) + } + + //validation id_herramienta exists + const validation_id_herr = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?",id_herramienta) + + if(parseInt(validation_id_herr[0].result) === 0){ + const result = return_error(400,'El ID de herramienta no existe'); + conn.end; + return res.status(400).json(result) + } + + //query + await conn.query("DELETE FROM herramientas WHERE id_herramienta = ?", id_herramienta); + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Herramienta eliminada con éxito" + } + }) + conn.end; + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + + } + + }) +} + + + +module.exports = { + post_herramienta, + get_herramienta, + put_herramienta, + delete_herramienta +} \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js new file mode 100644 index 0000000..916a6e2 --- /dev/null +++ b/backend/controllers/tipoHerramienta_controller.js @@ -0,0 +1,182 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js') + +const post_tipoHerramienta = async(req, res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + const {nombre_tipo, descripcion} = req.body; + const data = [nombre_tipo, descripcion]; + + //validacion expresss validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato o extensión incorrecta'); + conn.end; + return res.status(400).json(result) + } + + //query + const query = await conn.query("INSERT INTO tipo_herramienta (nombre_tipo, descripcion) VALUES (?,?)", data); + const insert_id = parseInt(query.insertId) + + //res estatus + res.status(201).json({ + "ok": true, + "id_tipo": insert_id, + "message": { + "code": 201, + "messageText": "Tipo registrado con éxito" + } + }) + + conn.end; + + } + catch (error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + console.log(error.message) + } + }) +} + +const get_tipoHerramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + + //query + const query = await conn.query("SELECT * FROM tipo_herramienta"); + res.status(200).json(query) + conn.end; + + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + } + + }) +} + + +const put_tipoHerramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + + const {id_tipo, nombre_tipo, descripcion} = req.body + const data = [nombre_tipo, descripcion, id_tipo] + + //validation error express validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato incorrecto'); + conn.end; + return res.status(400).json(result) + } + + //validation id_tipo exists + const validation_id_tipo = await conn.query("SELECT COUNT(id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?",id_tipo) + //const validation_idtipo2= await conn.query("SELECT id_tipo FROM tipo_herramienta WHERE id_tipo = ? ", id_tipo) + + //console.log((validation_idtipo2[0])) + //console.log(validation_id_tipo) + + + + if(parseInt(validation_id_tipo[0].result) === 0){ + const result = return_error(400,'El ID del tipo de herramienta no existe'); + conn.end; + return res.status(400).json(result) + } + + //query + await conn.query("UPDATE tipo_herramienta SET nombre_tipo = ?, descripcion = ? WHERE id_tipo = ?", data); + res.status(201).json({ + "ok": true, + "message": { + "code": 201, + "messageText": "Tipo de herramienta actualizado con éxito" + } + }) + conn.end; + + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + //console.log(error) + } + + }) +} + +const delete_tipoHerramienta = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + const id_tipo = req.params.id_tipo + + //validation express validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato incorrecto'); + conn.end; + return res.status(400).json(result) + } + //validation id_tipo exists + const validation_id_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?",id_tipo) + + if(parseInt(validation_id_tipo[0].result) === 0){ + const result = return_error(400,'El ID del tipo de herramienta no existe'); + conn.end; + return res.status(400).json(result) + } + + + //validation: no hay herramientas de ese tipo + const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?",id_tipo) + if(parseInt(validation_herramientas[0].result) !== 0){ + const result = return_error(400,'Aún hay herramientas registradas con ese tipo'); + conn.end; + return res.status(400).json(result) + } + + //query + await conn.query("DELETE FROM tipo_herramienta WHERE id_tipo = ?", id_tipo); + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Tipo eliminado con éxito" + } + }) + conn.end; + + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.end; + res.status(500).json(result) + //console.log(error) + } + + }) +} + +module.exports = { + post_tipoHerramienta, + get_tipoHerramienta, + put_tipoHerramienta, + delete_tipoHerramienta +} \ No newline at end of file diff --git a/backend/helpers/return_error.js b/backend/helpers/return_error.js new file mode 100644 index 0000000..49fd1e7 --- /dev/null +++ b/backend/helpers/return_error.js @@ -0,0 +1,11 @@ +const return_error = (codigo, mensaje) => { + return { + 'ok': false, + 'message': { + 'status': codigo, + 'error_text': mensaje + } + }; +} + +module.exports = return_error diff --git a/backend/includes/db_connection.php b/backend/includes/db_connection.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/includes/functions.php b/backend/includes/functions.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/index.php b/backend/index.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js new file mode 100644 index 0000000..cd42c73 --- /dev/null +++ b/backend/routes/herramientas_routes.js @@ -0,0 +1,16 @@ +const express = require('express'); +const router = express.Router(); + +const { body, param } = require("express-validator"); + +const { post_herramienta, get_herramienta, put_herramienta, delete_herramienta} = require('../controllers/herramientas_controller.js'); + +router.post('/', body('tipo').isNumeric(),body('estatus').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); + +router.get('/', get_herramienta); + +router.put('/', body('tipo').isNumeric(),body('estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); + +router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); + +module.exports = router \ No newline at end of file diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js new file mode 100644 index 0000000..cb3494e --- /dev/null +++ b/backend/routes/tipoHerramienta_routes.js @@ -0,0 +1,16 @@ +const express = require('express'); +const router = express.Router(); + +const { body, param } = require("express-validator"); + +const { post_tipoHerramienta, get_tipoHerramienta, put_tipoHerramienta, delete_tipoHerramienta } = require('../controllers/tipoHerramienta_controller.js'); + +router.post('/', body('nombre_tipo').isLength({max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); + +router.get('/', get_tipoHerramienta); + +router.put('/', body('nombre_tipo').isLength({max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); + +router.delete('/:id_tipo', param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ + +module.exports = router \ No newline at end of file diff --git a/backend/routes/web.php b/backend/routes/web.php deleted file mode 100644 index e69de29..0000000 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..94c8a16 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1176 @@ +{ + "name": "pjctinvlabsis", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "pjctinvlabsis", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "dotenv": "^16.4.5", + "express": "^4.18.3", + "express-validator": "^7.0.1", + "mariadb": "^3.2.3" + }, + "devDependencies": { + "nodemon": "^3.1.0" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "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.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-validator": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", + "integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==", + "dependencies": { + "lodash": "^4.17.21", + "validator": "^13.9.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mariadb": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.2.3.tgz", + "integrity": "sha512-Hyc1ehdUJwzvvzcLU2juZS528wJ6oE8pUlpgY0BAOdpKWcdN1motuugi5lC3jkpCkFpyNknHG7Yg66KASl3aPg==", + "dependencies": { + "@types/geojson": "^7946.0.10", + "@types/node": "^17.0.45", + "denque": "^2.1.0", + "iconv-lite": "^0.6.3", + "lru-cache": "^10.0.1" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mariadb/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mariadb/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", + "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "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", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..63f79e6 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "pjctinvlabsis", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "dotenv": "^16.4.5", + "express": "^4.18.3", + "express-validator": "^7.0.1", + "mariadb": "^3.2.3" + }, + "devDependencies": { + "nodemon": "^3.1.0" + } +} From dc8f3a965344c904520240d5f3758ab751af29c8 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sun, 7 Apr 2024 22:43:55 -0600 Subject: [PATCH 02/57] correccion base de datos --- .../controllers/herramientas_controller.js | 20 +++++++++---------- .../controllers/tipoHerramienta_controller.js | 4 ++-- backend/routes/herramientas_routes.js | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index 4e829da..65fc1cc 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -6,8 +6,8 @@ const return_error = require('../helpers/return_error.js') const post_herramienta = async(req, res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {tipo, estatus, observaciones} = req.body; - const data = [tipo, estatus, observaciones]; + const {id_tipo, id_estatus, observaciones} = req.body; + const data = [id_tipo, id_estatus, observaciones]; //validacion expresss validator const validation_error = validationResult(req); @@ -18,8 +18,8 @@ const post_herramienta = async(req, res)=>{ } //validation tipo exists, estatus exists - const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", tipo) - const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", estatus) + const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) + const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", id_estatus) if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); @@ -28,7 +28,7 @@ const post_herramienta = async(req, res)=>{ } //query - const query = await conn.query("INSERT INTO herramientas (tipo, estatus, observaciones) VALUES (?,?,?)",data) + const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones) VALUES (?,?,?)",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ @@ -76,8 +76,8 @@ const put_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {id_herramienta, tipo, estatus, observaciones} = req.body; - const data = [tipo, estatus, observaciones, id_herramienta]; + const {id_herramienta, id_tipo, id_estatus, observaciones} = req.body; + const data = [id_tipo, id_estatus, observaciones, id_herramienta]; //validacion expresss validator const validation_error = validationResult(req); @@ -88,8 +88,8 @@ const put_herramienta = async (req,res)=>{ } //validation tipo exists, estatus exists - const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", tipo) - const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", estatus) + const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) + const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", id_estatus) if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); @@ -165,7 +165,7 @@ const delete_herramienta = async (req,res)=>{ conn.end; res.status(500).json(result) - } + } }) } diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 916a6e2..be4a90d 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -74,8 +74,8 @@ const put_tipoHerramienta = async (req,res)=>{ const {id_tipo, nombre_tipo, descripcion} = req.body const data = [nombre_tipo, descripcion, id_tipo] - //validation error express validator - const validation_error = validationResult(req); + //validation error express validator + const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); conn.end; diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index cd42c73..9609c89 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -5,11 +5,11 @@ const { body, param } = require("express-validator"); const { post_herramienta, get_herramienta, put_herramienta, delete_herramienta} = require('../controllers/herramientas_controller.js'); -router.post('/', body('tipo').isNumeric(),body('estatus').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); +router.post('/', body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); router.get('/', get_herramienta); -router.put('/', body('tipo').isNumeric(),body('estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); +router.put('/', body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); From 875809786e46fc995475c2431164900303e20685 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Mon, 8 Apr 2024 23:11:44 -0600 Subject: [PATCH 03/57] Se permite las solicitudes de cualquier origen -CORS- con el fin de hacer pruebas --- .vscode/settings.json | 3 +++ backend/app.js | 8 ++++--- .../controllers/tipoHerramienta_controller.js | 4 ++-- frontend.rar | Bin 0 -> 148406 bytes package-lock.json | 21 ++++++++++++++++++ package.json | 1 + 6 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 frontend.rar diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d3636ab --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.multiRootWorkspaceName": "PjctInvLabSis" +} \ No newline at end of file diff --git a/backend/app.js b/backend/app.js index dcd90cf..0efc645 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1,7 +1,8 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); - +const cors = require('cors'); +app.use(cors()); app.listen(process.env.NODE_PORT, () => { @@ -13,10 +14,11 @@ app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) -/* app.use((req, res, next) => { +/*app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); -})*/ +}) +*/ \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index be4a90d..9ddb3d8 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -7,9 +7,9 @@ const post_tipoHerramienta = async(req, res)=>{ await pool.getConnection().then(async (conn) => { try{ + const {nombre_tipo, descripcion} = req.body; const data = [nombre_tipo, descripcion]; - //validacion expresss validator const validation_error = validationResult(req); if(!validation_error.isEmpty()){ @@ -38,7 +38,7 @@ const post_tipoHerramienta = async(req, res)=>{ catch (error){ const result = return_error(500,'Internal server error'); conn.end; - res.status(500).json(result) + res.status(500).json(result) //console.log(error) console.log(error.message) } }) diff --git a/frontend.rar b/frontend.rar new file mode 100644 index 0000000000000000000000000000000000000000..0984b57aad02c297177865992ff24ff39d38b1fe GIT binary patch literal 148406 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%0AxfaZX&^)mU4H2MJp{Rq08t7N5)?5=2DCjvY8#+4 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 o~(`Y%rJLqlQz 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 F{|Bd6g5v-H literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json index 94c8a16..50ad395 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.3", "express-validator": "^7.0.1", @@ -215,6 +216,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -823,6 +836,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", diff --git a/package.json b/package.json index 63f79e6..799d4f2 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "dependencies": { + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.3", "express-validator": "^7.0.1", From f310e2c8eb45714a9ef7dca38b5426b58a1e1020 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Mon, 8 Apr 2024 23:35:44 -0600 Subject: [PATCH 04/57] min length para nombre_tipo de tipo_herramienta --- backend/controllers/tipoHerramienta_controller.js | 2 +- backend/routes/tipoHerramienta_routes.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 9ddb3d8..0c9fc86 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -14,7 +14,7 @@ const post_tipoHerramienta = async(req, res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.end; + conn.end; return res.status(400).json(result) } diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js index cb3494e..906842c 100644 --- a/backend/routes/tipoHerramienta_routes.js +++ b/backend/routes/tipoHerramienta_routes.js @@ -5,11 +5,11 @@ const { body, param } = require("express-validator"); const { post_tipoHerramienta, get_tipoHerramienta, put_tipoHerramienta, delete_tipoHerramienta } = require('../controllers/tipoHerramienta_controller.js'); -router.post('/', body('nombre_tipo').isLength({max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); +router.post('/', body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); router.get('/', get_tipoHerramienta); -router.put('/', body('nombre_tipo').isLength({max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); +router.put('/', body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); router.delete('/:id_tipo', param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ From edae42d2f1ff4ec28b2a7748c4793c5c50bb7814 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 26 Apr 2024 10:53:12 -0600 Subject: [PATCH 05/57] procedimientos almacenados herramientas y login sin auth --- backend/.env | 4 +- backend/app.js | 11 +- .../controllers/herramientas_controller.js | 106 +++++++++++++----- backend/controllers/login_controller.js | 90 +++++++++++++++ .../controllers/tipoHerramienta_controller.js | 35 +++--- backend/controllers/usuarios_controllers.js | 0 backend/helpers/generate_token.js | 32 ++++++ backend/helpers/handle_bcrybpt.js | 17 +++ backend/helpers/return_date.js | 14 +++ backend/helpers/return_error.js | 1 + backend/routes/authPass_routes.js | 0 backend/routes/herramientas_routes.js | 6 +- backend/routes/login_routes.js | 8 ++ backend/routes/usuarios_routes.js | 0 package-lock.json | 105 ++++++++++++++++- package.json | 2 + 16 files changed, 372 insertions(+), 59 deletions(-) create mode 100644 backend/controllers/login_controller.js create mode 100644 backend/controllers/usuarios_controllers.js create mode 100644 backend/helpers/generate_token.js create mode 100644 backend/helpers/handle_bcrybpt.js create mode 100644 backend/helpers/return_date.js create mode 100644 backend/routes/authPass_routes.js create mode 100644 backend/routes/login_routes.js create mode 100644 backend/routes/usuarios_routes.js diff --git a/backend/.env b/backend/.env index 0933ef1..480fc89 100644 --- a/backend/.env +++ b/backend/.env @@ -3,4 +3,6 @@ HOST="localhost" PORT="3306" USER="root" PASSWORD="root" -DATABASE="dbsistemas" \ No newline at end of file +DATABASE="dbsistemas" +JWT_SECRET = "589696852" + diff --git a/backend/app.js b/backend/app.js index 0efc645..c51fcac 100644 --- a/backend/app.js +++ b/backend/app.js @@ -12,6 +12,7 @@ app.listen(process.env.NODE_PORT, () => { app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) +app.use('/login', require('./routes/login_routes')) /*app.use((req, res, next) => { @@ -21,4 +22,12 @@ app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }) -*/ \ No newline at end of file +*/ + +/*NODE_PORT="3000" +HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" +PORT="3306" +USER="ugpwh5vn4olvh15t" +PASSWORD="DHGMBoPlzbo6Q9rFxHRW" +DATABASE="bqvpx1qe8f1g2jhxyxjj" +JWT_SECRET = "589696852"*/ \ No newline at end of file diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index 65fc1cc..e6e3e56 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -1,34 +1,37 @@ const express = require('express'); const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); -const return_error = require('../helpers/return_error.js') +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') const post_herramienta = async(req, res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {id_tipo, id_estatus, observaciones} = req.body; - const data = [id_tipo, id_estatus, observaciones]; + const id_estatus = 1; //id _estatus = 1 es el estatus "Disponible" + const fecha_alta = fecha_hora(); + const {id_tipo, observaciones,id_origen} = req.body; + const data = [id_tipo, id_estatus, observaciones,fecha_alta,id_origen]; //validacion expresss validator const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.end; + conn.release; return res.status(400).json(result) } //validation tipo exists, estatus exists const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) - const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", id_estatus) + //const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramienta WHERE id_estatus = ?", id_estatus) - if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ + if(parseInt(validation_tipo[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); - conn.end; + conn.release; return res.status(400).json(result) } //query - const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones) VALUES (?,?,?)",data) + const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones, fecha_alta, id_origen) VALUES (?,?,?,?,?)",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ @@ -40,12 +43,12 @@ const post_herramienta = async(req, res)=>{ } }) - conn.end; + conn.release; } catch (error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) console.log(error.message) @@ -58,47 +61,88 @@ const get_herramienta = async (req,res)=>{ try{ //query - const query = await conn.query("SELECT * FROM herramientas"); - res.status(200).json(query) - conn.end; + const query = await conn.query("CALL consultar_herramientas()"); + //console.log(query[0]) + res.status(200).json(query[0]) + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) + console.log (error) } }) } +const get_herramienta_por_tipo = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + const id_tipo = req.params.id_tipo; + + //validation error express validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato incorrecto'); + conn.release; + return res.status(400).json(result) + } + + //validation id_tipo exists + const validation_id_tipo = await conn.query("SELECT COUNT(id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo); + + if(parseInt(validation_id_tipo[0].result) === 0){ + const result = return_error(400,`El ID del tipo de herramienta no existe: ${id_tipo}`); + conn.release; + return res.status(400).json(result) + } + + + //query + const query = await conn.query("CALL consultar_herramientas_por_tipo (?)", id_tipo); + res.status(200).json(query[0]) + conn.release; + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release; + res.status(500).json(result) + } + + }) +} +/*******la fecha de alta no se debe modificar ********/ const put_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {id_herramienta, id_tipo, id_estatus, observaciones} = req.body; - const data = [id_tipo, id_estatus, observaciones, id_herramienta]; + const {id_herramienta, id_tipo, id_estatus, observaciones, origen} = req.body; + const data = [id_tipo, id_estatus, observaciones, origen, id_herramienta]; //validacion expresss validator const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.end; + conn.release; return res.status(400).json(result) } //validation tipo exists, estatus exists const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) - const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramientas WHERE id_estatus = ?", id_estatus) + const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramienta WHERE id_estatus = ?", id_estatus) if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); - conn.end; + conn.release; return res.status(400).json(result) } //query - const query = await conn.query("UPDATE herramientas SET tipo = ?, estatus = ?, observaciones = ? WHERE id_herramienta = ?",data) + const query = await conn.query("UPDATE herramientas SET id_tipo = ?, id_estatus = ?, observaciones = ?, origen = ? WHERE id_herramienta = ?",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ @@ -110,16 +154,14 @@ const put_herramienta = async (req,res)=>{ } }) - conn.end; - - - + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) + console.log(error) } }) @@ -129,13 +171,13 @@ const delete_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { try{ - const id_herramienta = req.param + const id_herramienta = req.params.id_herramienta //validation express validator const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -144,7 +186,7 @@ const delete_herramienta = async (req,res)=>{ if(parseInt(validation_id_herr[0].result) === 0){ const result = return_error(400,'El ID de herramienta no existe'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -157,13 +199,14 @@ const delete_herramienta = async (req,res)=>{ "messageText": "Herramienta eliminada con éxito" } }) - conn.end; + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) + console.log(error) } @@ -175,6 +218,7 @@ const delete_herramienta = async (req,res)=>{ module.exports = { post_herramienta, get_herramienta, + get_herramienta_por_tipo, put_herramienta, delete_herramienta -} \ No newline at end of file +} \ No newline at end of file diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js new file mode 100644 index 0000000..a0d13ba --- /dev/null +++ b/backend/controllers/login_controller.js @@ -0,0 +1,90 @@ +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const {encrypt, compare} = require ('../helpers/handle_bcrybpt.js'); +const pool = require('../config/database.js'); +const { token_sign, verify_token, decode_sign } = require('../helpers/generate_token.js'); + +const post_login = async (req, res) =>{ + await pool.getConnection().then(async (conn) =>{ + try{ + const {nombre_login, password} = req.body; + + //validation error express validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const mensajeError = validation_error.array()[0].msg; + const result = return_error(400,`Datos con formato incorrecto. ${mensajeError}`); + conn.release; + return res.status(400).json(result) + } + + + //validation user exist + const user_validation = await conn.query("SELECT COUNT (nombre_login) as result FROM usuarios WHERE nombre_login = ?",nombre_login); + + if(parseInt(user_validation[0].result) === 0){ + const result = return_error(404,'El usuario no está registrado'); + conn.release; + return res.status(400).json(result) + } + + + + //compare password del usuario que hace la solicitud + const pass_user = await conn.query("SELECT password from usuarios WHERE nombre_login = ?", nombre_login) + const pass_hash = await pass_user[0]["password"] //pass_user[0] + const checkPassword = await compare(password, pass_hash) + + if(!checkPassword){ + const result = return_error(400,'Contraseña incorrecta'); + conn.release; + return res.status(400).json(result) + } + + //user activo + const user_activo_validation = await conn.query("SELECT estatus_activo from usuarios WHERE nombre_login = ? ", nombre_login) + + if (!user_activo_validation[0]["estatus_activo"]){ + const result = return_error(403,'Usuario no activo'); + conn.release; + return res.status(403).json(result) + } + + + + if(checkPassword && user_activo_validation){ + + + //obtener id de usuario y rol + const user = await conn.query("SELECT id_usuario FROM usuarios WHERE nombre_login = ? and password = ?", [nombre_login, pass_hash]) + const rol = await conn.query ("SELECT ru.nombre_rol FROM roles_usuarios ru INNER JOIN usuarios u ON ru.id_rol = u.id_rol WHERE id_usuario = ?", user) + + console.log("Sesion iniciada exitosamente "); + + const token_session = await token_sign(user, rol); + //res estatus + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Sesion iniciada exitosamente " + }, + "tokenSession": token_session + }) + conn.release; + } + + } + catch (error){ + const result = return_error(500,'Internal server error'); + conn.release; + res.status(500).json(result) //console.log(error) + console.log(error) + } + }) + +} + +module.exports = { + post_login +} \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 0c9fc86..10f8cca 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -3,6 +3,7 @@ const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); const return_error = require('../helpers/return_error.js') + const post_tipoHerramienta = async(req, res)=>{ await pool.getConnection().then(async (conn) => { @@ -14,7 +15,7 @@ const post_tipoHerramienta = async(req, res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -32,12 +33,12 @@ const post_tipoHerramienta = async(req, res)=>{ } }) - conn.end; + conn.release; } catch (error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) //console.log(error) console.log(error.message) } @@ -52,13 +53,13 @@ const get_tipoHerramienta = async (req,res)=>{ //query const query = await conn.query("SELECT * FROM tipo_herramienta"); res.status(200).json(query) - conn.end; + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) } @@ -78,22 +79,16 @@ const put_tipoHerramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.end; + conn.release; return res.status(400).json(result) } //validation id_tipo exists const validation_id_tipo = await conn.query("SELECT COUNT(id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?",id_tipo) - //const validation_idtipo2= await conn.query("SELECT id_tipo FROM tipo_herramienta WHERE id_tipo = ? ", id_tipo) - - //console.log((validation_idtipo2[0])) - //console.log(validation_id_tipo) - - if(parseInt(validation_id_tipo[0].result) === 0){ const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -106,13 +101,13 @@ const put_tipoHerramienta = async (req,res)=>{ "messageText": "Tipo de herramienta actualizado con éxito" } }) - conn.end; + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) //console.log(error) } @@ -130,7 +125,7 @@ const delete_tipoHerramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.end; + conn.release; return res.status(400).json(result) } //validation id_tipo exists @@ -138,7 +133,7 @@ const delete_tipoHerramienta = async (req,res)=>{ if(parseInt(validation_id_tipo[0].result) === 0){ const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -147,7 +142,7 @@ const delete_tipoHerramienta = async (req,res)=>{ const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?",id_tipo) if(parseInt(validation_herramientas[0].result) !== 0){ const result = return_error(400,'Aún hay herramientas registradas con ese tipo'); - conn.end; + conn.release; return res.status(400).json(result) } @@ -160,13 +155,13 @@ const delete_tipoHerramienta = async (req,res)=>{ "messageText": "Tipo eliminado con éxito" } }) - conn.end; + conn.release; } catch(error){ const result = return_error(500,'Internal server error'); - conn.end; + conn.release; res.status(500).json(result) //console.log(error) } diff --git a/backend/controllers/usuarios_controllers.js b/backend/controllers/usuarios_controllers.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js new file mode 100644 index 0000000..b4539a1 --- /dev/null +++ b/backend/helpers/generate_token.js @@ -0,0 +1,32 @@ +const jwt = require ('jsonwebtoken'); + +const token_sign = async (user, rol) =>{ + return jwt.sign( + { + id: user, + rol: rol + }, + process.env.JWT_SECRET, + { + expiresIn: "2h" + } + ) +} +const verify_token = async (token) =>{ + try{ + return jwt.verify(token, process.env.JWT_SECRET) + } + catch(error){ + return null; + } +} +const decode_sign = async (token) =>{ + +} + + +module.exports = { + token_sign, + verify_token, + decode_sign +} \ No newline at end of file diff --git a/backend/helpers/handle_bcrybpt.js b/backend/helpers/handle_bcrybpt.js new file mode 100644 index 0000000..7139037 --- /dev/null +++ b/backend/helpers/handle_bcrybpt.js @@ -0,0 +1,17 @@ +const bcrypt = require('bcryptjs'); + +const encrypt = async(text) =>{ + const hash = await bcrypt.hash(text, 11); + return hash; +} + +const compare = async(text, textHash) => { + return await bcrypt.compare(text, textHash); +} + + +module.exports = { + encrypt, + compare +} + diff --git a/backend/helpers/return_date.js b/backend/helpers/return_date.js new file mode 100644 index 0000000..04072cc --- /dev/null +++ b/backend/helpers/return_date.js @@ -0,0 +1,14 @@ +const fechaHoraFormateada = ()=>{ + const fechaHoraActual = new Date(); + // Obtener los componentes de fecha y hora + const year = fechaHoraActual.getFullYear(); + const month = String(fechaHoraActual.getMonth() + 1).padStart(2, '0'); // Añadir cero al mes si es necesario + const day = String(fechaHoraActual.getDate()).padStart(2, '0'); // Añadir cero al día si es necesario + const hour = String(fechaHoraActual.getHours()).padStart(2, '0'); // Añadir cero a la hora si es necesario + const minute = String(fechaHoraActual.getMinutes()).padStart(2, '0'); // Añadir cero al minuto si es necesario + const second = String(fechaHoraActual.getSeconds()).padStart(2, '0'); // Añadir cero al segundo si es necesario + return `${year}-${month}-${day} ${hour}:${minute}:${second}`; +} + +module.exports = fechaHoraFormateada; +//console.log(fechaHoraFormateada); diff --git a/backend/helpers/return_error.js b/backend/helpers/return_error.js index 49fd1e7..999f023 100644 --- a/backend/helpers/return_error.js +++ b/backend/helpers/return_error.js @@ -8,4 +8,5 @@ const return_error = (codigo, mensaje) => { }; } + module.exports = return_error diff --git a/backend/routes/authPass_routes.js b/backend/routes/authPass_routes.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index 9609c89..a4f5f93 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -3,12 +3,14 @@ const router = express.Router(); const { body, param } = require("express-validator"); -const { post_herramienta, get_herramienta, put_herramienta, delete_herramienta} = require('../controllers/herramientas_controller.js'); +const { post_herramienta, get_herramienta, get_herramienta_por_tipo, put_herramienta, delete_herramienta} = require('../controllers/herramientas_controller.js'); -router.post('/', body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); +router.post('/', body('id_tipo').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); router.get('/', get_herramienta); +router.get('/tipo/:id_tipo', param('id_tipo').isNumeric(), get_herramienta_por_tipo); + router.put('/', body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); diff --git a/backend/routes/login_routes.js b/backend/routes/login_routes.js new file mode 100644 index 0000000..1c2931c --- /dev/null +++ b/backend/routes/login_routes.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); +const { body, param } = require("express-validator"); +const {post_login} = require ('../controllers/login_controller.js'); + +router.post('/', body('nombre_login').exists().withMessage('Ingresar un nombre de usuario').notEmpty().withMessage("Ingresar un nombre de ususario válido"), post_login); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/usuarios_routes.js b/backend/routes/usuarios_routes.js new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json index 50ad395..65f50ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.3", "express-validator": "^7.0.1", + "jsonwebtoken": "^9.0.2", "mariadb": "^3.2.3" }, "devDependencies": { @@ -71,6 +73,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -128,6 +135,11 @@ "node": ">=8" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -288,6 +300,14 @@ "url": "https://dotenvx.com" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -634,16 +654,95 @@ "node": ">=0.12.0" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -982,7 +1081,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -1190,8 +1288,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/package.json b/package.json index 799d4f2..3876c1d 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ "author": "", "license": "ISC", "dependencies": { + "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.3", "express-validator": "^7.0.1", + "jsonwebtoken": "^9.0.2", "mariadb": "^3.2.3" }, "devDependencies": { From e74f202c19f81bfe1069ea9c74a4b94b37b52a4c Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sat, 27 Apr 2024 16:32:23 -0600 Subject: [PATCH 06/57] get origen --- backend/app.js | 1 + backend/controllers/login_controller.js | 15 ++++++++---- backend/controllers/origen_controllers.js | 30 +++++++++++++++++++++++ backend/routes/origen_routes.js | 8 ++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 backend/controllers/origen_controllers.js create mode 100644 backend/routes/origen_routes.js diff --git a/backend/app.js b/backend/app.js index c51fcac..b5e56f0 100644 --- a/backend/app.js +++ b/backend/app.js @@ -13,6 +13,7 @@ app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) app.use('/login', require('./routes/login_routes')) +app.use('/origen', require('./routes/origen_routes')) /*app.use((req, res, next) => { diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js index a0d13ba..1173090 100644 --- a/backend/controllers/login_controller.js +++ b/backend/controllers/login_controller.js @@ -6,7 +6,7 @@ const { token_sign, verify_token, decode_sign } = require('../helpers/generate_t const post_login = async (req, res) =>{ await pool.getConnection().then(async (conn) =>{ - try{ + try{ const {nombre_login, password} = req.body; //validation error express validator @@ -56,11 +56,16 @@ const post_login = async (req, res) =>{ //obtener id de usuario y rol - const user = await conn.query("SELECT id_usuario FROM usuarios WHERE nombre_login = ? and password = ?", [nombre_login, pass_hash]) - const rol = await conn.query ("SELECT ru.nombre_rol FROM roles_usuarios ru INNER JOIN usuarios u ON ru.id_rol = u.id_rol WHERE id_usuario = ?", user) - + //pass_hash surge de un select a la base de datos con el fin de obtener el passwor registrado ahí + //se hace un select para obtener el id_usuario usando el nombre_login y passhash + const user_query = await conn.query("SELECT id_usuario FROM usuarios WHERE nombre_login = ? and password = ?", [nombre_login, pass_hash]) + const user = user_query[0].id_usuario; + const rol_query = await conn.query ("SELECT ru.nombre_rol FROM roles_usuarios ru INNER JOIN usuarios u ON ru.id_rol = u.id_rol WHERE id_usuario = ?", user) + const rol = rol_query[0].nombre_rol; + + console.log(user) + console.log(rol) console.log("Sesion iniciada exitosamente "); - const token_session = await token_sign(user, rol); //res estatus res.status(200).json({ diff --git a/backend/controllers/origen_controllers.js b/backend/controllers/origen_controllers.js new file mode 100644 index 0000000..ed601a6 --- /dev/null +++ b/backend/controllers/origen_controllers.js @@ -0,0 +1,30 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') + +const get_origen = async (req,res)=>{ + await pool.getConnection().then(async (conn) => { + + try{ + //query + const query = await conn.query("select * from origen"); + //console.log(query[0]) + res.status(200).json(query) + conn.release; + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release; + res.status(500).json(result) + console.log (error) + } + + }) +} + +module.exports = { + get_origen +} \ No newline at end of file diff --git a/backend/routes/origen_routes.js b/backend/routes/origen_routes.js new file mode 100644 index 0000000..4b6a376 --- /dev/null +++ b/backend/routes/origen_routes.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); +const {get_origen} = require('../controllers/origen_controllers.js'); + +router.get('/', get_origen); + + +module.exports = router \ No newline at end of file From 5950f23c096a039d030b6307124effb04a593844 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Wed, 8 May 2024 18:27:22 -0600 Subject: [PATCH 07/57] =?UTF-8?q?token=5Fcheck=20y=20check=5Frol=20para=20?= =?UTF-8?q?las=20rutas.=20generaci=C3=B3n=20de=20token=20para=20el=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- backend/.env | 3 +- .../estatus_herramienta_controller.js | 7 +++ backend/controllers/login_controller.js | 1 - backend/helpers/generate_token.js | 10 +++-- backend/helpers/handle_bcrybpt.js | 7 ++- backend/middlewares/check_rol.js | 36 +++++++++++++++ backend/middlewares/check_token.js | 41 ++++++++++++++++++ backend/routes/tipoHerramienta_routes.js | 7 +-- frontend.rar | Bin 148406 -> 0 bytes 10 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 backend/controllers/estatus_herramienta_controller.js create mode 100644 backend/middlewares/check_rol.js create mode 100644 backend/middlewares/check_token.js delete mode 100644 frontend.rar diff --git a/.gitignore b/.gitignore index 933ca2e..eedeea1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ node_modules/ -frontend/ \ No newline at end of file +front/ \ No newline at end of file diff --git a/backend/.env b/backend/.env index 480fc89..8e53dbd 100644 --- a/backend/.env +++ b/backend/.env @@ -4,5 +4,4 @@ PORT="3306" USER="root" PASSWORD="root" DATABASE="dbsistemas" -JWT_SECRET = "589696852" - +JWT_SECRET = "589696852" \ No newline at end of file diff --git a/backend/controllers/estatus_herramienta_controller.js b/backend/controllers/estatus_herramienta_controller.js new file mode 100644 index 0000000..8bce0c4 --- /dev/null +++ b/backend/controllers/estatus_herramienta_controller.js @@ -0,0 +1,7 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') + + diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js index 1173090..0db2021 100644 --- a/backend/controllers/login_controller.js +++ b/backend/controllers/login_controller.js @@ -54,7 +54,6 @@ const post_login = async (req, res) =>{ if(checkPassword && user_activo_validation){ - //obtener id de usuario y rol //pass_hash surge de un select a la base de datos con el fin de obtener el passwor registrado ahí //se hace un select para obtener el id_usuario usando el nombre_login y passhash diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index b4539a1..0082e71 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -1,20 +1,22 @@ const jwt = require ('jsonwebtoken'); - +require('dotenv').config({path: 'backend/.env'}); +//generar un token const token_sign = async (user, rol) =>{ return jwt.sign( { - id: user, + id_user: user, rol: rol }, process.env.JWT_SECRET, { - expiresIn: "2h" + expiresIn: "5h" } ) } +//verificar token const verify_token = async (token) =>{ try{ - return jwt.verify(token, process.env.JWT_SECRET) + return jwt.verify(token, process.env.JWT_SECRET) } catch(error){ return null; diff --git a/backend/helpers/handle_bcrybpt.js b/backend/helpers/handle_bcrybpt.js index 7139037..990b650 100644 --- a/backend/helpers/handle_bcrybpt.js +++ b/backend/helpers/handle_bcrybpt.js @@ -8,7 +8,12 @@ const encrypt = async(text) =>{ const compare = async(text, textHash) => { return await bcrypt.compare(text, textHash); } - +/* +encrypt("").then( + (hashh) =>{ + console.log(hashh) + } +)*/ module.exports = { encrypt, diff --git a/backend/middlewares/check_rol.js b/backend/middlewares/check_rol.js new file mode 100644 index 0000000..bce439f --- /dev/null +++ b/backend/middlewares/check_rol.js @@ -0,0 +1,36 @@ +const { verify_token } = require('../helpers/generate_token') +const return_error = require('../helpers/return_error.js'); +const pool = require('../config/database.js'); + +const check_rol = (rol) => async (req, res, next)=>{ + await pool.getConnection().then(async (conn) => { + + try { + const token = req.headers.authorization + const token_data = await verify_token(token) + const user_rol_database = await conn.query("SELECT roles_usuarios.nombre_rol FROM roles_usuarios JOIN usuarios ON roles_usuarios.id_rol = usuarios.id_rol WHERE usuarios.id_usuario = ?", token_data.id_user) //tomar el rol del id de us + const estatus = await conn.query("SELECT estatus_activo FROM usuarios WHERE id_usuario = ?", token_data.id_user) + + if ( [].concat(rol).includes(user_rol_database[0].nombre_rol) && parseInt(estatus[0].estatus_activo) === 1){ + conn.release; + next() + } + else{ + conn.release; + const result = return_error(409,'Acceso denegado: no hay permisos suficientes'); + res.status(409).json(result) + } + } + catch (error) { + conn.release; + const result = return_error(500,'Internal server error'); + res.status(500).json(result) + } + + }) + + +} +module.exports = { + check_rol +} \ No newline at end of file diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js new file mode 100644 index 0000000..c8ac686 --- /dev/null +++ b/backend/middlewares/check_token.js @@ -0,0 +1,41 @@ +const { verify_token } = require('../helpers/generate_token') +const return_error = require('../helpers/return_error.js'); +require('dotenv').config({path: 'backend/.env'}); + +const check_token = async (req, res, next) => { + try { + const token = req.headers.authorization + //tokent = token.split(' ').pop() + //console.log(token) + const token_data = await verify_token(token) + //console.log(token_data) + if (token_data) { + next() + } + else{ + const result = return_error(409,'Acceso denegado: token no válido'); + res.status(409).json(result) + } + + } catch (error) { + const result = return_error(500,'Internal server error'); + res.status(500).json(result) + //console.log(error) + } +} +/* const prueba = async()=>{ + console.log(process.env.JWT_SECRET) +const token_data = await verify_token("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZF91c2VyIjoxLCJyb2wiOiJBZG1pbmlzdHJhZG9yIiwiaWF0IjoxNzE1MDQyNzEzLCJleHAiOjE3MTUwNDk5MTN9.hOQyiTjEguFLLrCBPmd4gCszAiVKfyg2XNIW2klwsL8") +console.log(token_data) +if (token_data) { + console.log("PASA") +} + +} + +prueba() + */ + +module.exports = { + check_token +} \ No newline at end of file diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js index 906842c..2753f9c 100644 --- a/backend/routes/tipoHerramienta_routes.js +++ b/backend/routes/tipoHerramienta_routes.js @@ -1,13 +1,14 @@ const express = require('express'); const router = express.Router(); - +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator"); const { post_tipoHerramienta, get_tipoHerramienta, put_tipoHerramienta, delete_tipoHerramienta } = require('../controllers/tipoHerramienta_controller.js'); -router.post('/', body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); +router.post('/', check_token, body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); -router.get('/', get_tipoHerramienta); +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']), get_tipoHerramienta); router.put('/', body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); diff --git a/frontend.rar b/frontend.rar deleted file mode 100644 index 0984b57aad02c297177865992ff24ff39d38b1fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148406 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%0AxfaZX&^)mU4H2MJp{Rq08t7N5)?5=2DCjvY8#+4 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 o~(`Y%rJLqlQz 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 F{|Bd6g5v-H From fb1a2a86c71efd27463286a7b2abc2dd53daf174 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Wed, 15 May 2024 11:59:08 -0600 Subject: [PATCH 08/57] consultar, registrar bajas --- .gitignore | 3 +- backend/app.js | 1 + backend/controllers/bajas_controller.js | 129 ++++++++++++++++++ .../controllers/herramientas_controller.js | 62 +++++---- backend/controllers/login_controller.js | 19 +-- backend/controllers/origen_controllers.js | 4 +- backend/controllers/prestamos_controller.js | 15 ++ .../controllers/tipoHerramienta_controller.js | 30 ++-- backend/helpers/return_id_user_token.js | 10 ++ backend/middlewares/check_rol.js | 6 +- backend/routes/bajas_routes.js | 17 +++ backend/routes/herramientas_routes.js | 4 +- 12 files changed, 245 insertions(+), 55 deletions(-) create mode 100644 backend/controllers/bajas_controller.js create mode 100644 backend/controllers/prestamos_controller.js create mode 100644 backend/helpers/return_id_user_token.js create mode 100644 backend/routes/bajas_routes.js diff --git a/.gitignore b/.gitignore index eedeea1..ca5b3da 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -front/ \ No newline at end of file +front/ +backend/pruebas.js \ No newline at end of file diff --git a/backend/app.js b/backend/app.js index b5e56f0..66848e6 100644 --- a/backend/app.js +++ b/backend/app.js @@ -14,6 +14,7 @@ app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) app.use('/login', require('./routes/login_routes')) app.use('/origen', require('./routes/origen_routes')) +app.use('/bajas', require('./routes/bajas_routes')) /*app.use((req, res, next) => { diff --git a/backend/controllers/bajas_controller.js b/backend/controllers/bajas_controller.js new file mode 100644 index 0000000..17d30ba --- /dev/null +++ b/backend/controllers/bajas_controller.js @@ -0,0 +1,129 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') +const id_user_token = require ('../helpers/return_id_user_token.js') + +const post_baja = async (req, res) => { + await pool.getConnection().then(async (conn) =>{ + + try{ + + const id_user = await id_user_token(req.headers.authorization) + const fecha_baja = fecha_hora(); + console.log(fecha_baja) + const {id_herramienta, id_motivo, observaciones} = req.body + const data = [id_herramienta, id_motivo, id_user, fecha_baja, observaciones] + + //validacion expresss validator + const validation_error = validationResult(req); + if(!validation_error.isEmpty()){ + const result = return_error(400,'Datos con formato o extensión incorrecta'); + conn.release(); + return res.status(400).json(result) + } + + + //validacion id_herramienta exist + const validation_id_herramienta = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?", id_herramienta) + + if(parseInt(validation_id_herramienta[0].result) === 0){ + const result = return_error(400,'La herramienta no está registrada'); + conn.release(); + return res.status(400).json(result) + } + + //validation user exist + const validation_user = await conn.query("SELECT COUNT (id_usuario) as result FROM usuarios WHERE id_usuario = ?", id_user) + + + if(parseInt(validation_user[0].result) === 0){ + const result = return_error(400,'Error al ingresar el id de usuario, internal server error'); + conn.release(); + return res.status(400).json(result) + } + + //validation motivo exist + const validation_motivo = await conn.query("SELECT COUNT (id_usuario) as result FROM usuarios WHERE id_usuario = ?", id_user) + + + if(parseInt(validation_motivo[0].result) === 0){ + const result = return_error(400,'La solicitud contiene un motivo inexistente, es recomendable contactar al equipo de desarrollo'); + conn.release(); + return res.status(400).json(result) + } + + //validacion herramienta activa + + const validation_herramienta_activa = await conn.query ("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) + //console.log((validation_herramienta_activa)) + if(parseInt(validation_herramienta_activa[0].id_estatus)===3){ + const result = return_error(400,'La herramienta ya está en estatus de baja'); + conn.release(); + return res.status(400).json(result) + } + + //QUERY + const query = await conn.query("CALL registrar_baja (?,?,?,?,?)",data) + //const insert_id = parseInt(query.insertId) + //res estatus + res.status(201).json({ + "ok": true, + "message": { + "code": 201, + "messageText": "Baja realizada con éxito" + } + }) + + conn.release(); + + }catch(error){ + + const result = return_error(500,'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + + }) +} + +const get_bajas = async (req, res) => { + await pool.getConnection().then(async (conn) =>{ + + try{ + //query + const query = await conn.query("CALL consultar_bajas()"); + //console.log(query[0]) + res.status(200).json(query[0]) + conn.release(); + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log (error) + } + + + }) +} + +//no put + +const delete_baja = async (req, res) => { + await pool.getConnection().then(async (conn) =>{ + + + + }) +} + + +module.exports = { + post_baja, + get_bajas, + delete_baja +} \ No newline at end of file diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index e6e3e56..93cc508 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -3,35 +3,49 @@ const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); const return_error = require('../helpers/return_error.js'); const fecha_hora = require('../helpers/return_date.js') +const id_user_token = require ('../helpers/return_id_user_token.js') const post_herramienta = async(req, res)=>{ await pool.getConnection().then(async (conn) => { try{ + + //console.log(req.headers.authorization) + const id_user = await id_user_token(req.headers.authorization) const id_estatus = 1; //id _estatus = 1 es el estatus "Disponible" const fecha_alta = fecha_hora(); const {id_tipo, observaciones,id_origen} = req.body; - const data = [id_tipo, id_estatus, observaciones,fecha_alta,id_origen]; + const data = [id_tipo, id_estatus, observaciones,fecha_alta,id_origen, id_user]; //validacion expresss validator const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.release; + conn.release(); return res.status(400).json(result) } - //validation tipo exists, estatus exists + //validation tipo exists const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) //const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramienta WHERE id_estatus = ?", id_estatus) if(parseInt(validation_tipo[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); - conn.release; + conn.release(); + return res.status(400).json(result) + } + + //validation user exist + const validation_user = await conn.query("SELECT COUNT (id_usuario) as result FROM usuarios WHERE id_usuario = ?", id_user) + //const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramienta WHERE id_estatus = ?", id_estatus) + + if(parseInt(validation_user[0].result) === 0){ + const result = return_error(400,'Error al ingresar el id de usuario, internal server error'); + conn.release(); return res.status(400).json(result) } //query - const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones, fecha_alta, id_origen) VALUES (?,?,?,?,?)",data) + const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones, fecha_alta, id_origen, id_usuario) VALUES (?,?,?,?,?,?)",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ @@ -43,14 +57,14 @@ const post_herramienta = async(req, res)=>{ } }) - conn.release; + conn.release(); } catch (error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) - console.log(error.message) + //console.log(error) } }) @@ -64,12 +78,12 @@ const get_herramienta = async (req,res)=>{ const query = await conn.query("CALL consultar_herramientas()"); //console.log(query[0]) res.status(200).json(query[0]) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) console.log (error) } @@ -87,7 +101,7 @@ const get_herramienta_por_tipo = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -96,7 +110,7 @@ const get_herramienta_por_tipo = async (req,res)=>{ if(parseInt(validation_id_tipo[0].result) === 0){ const result = return_error(400,`El ID del tipo de herramienta no existe: ${id_tipo}`); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -104,18 +118,18 @@ const get_herramienta_por_tipo = async (req,res)=>{ //query const query = await conn.query("CALL consultar_herramientas_por_tipo (?)", id_tipo); res.status(200).json(query[0]) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) } }) } -/*******la fecha de alta no se debe modificar ********/ +/*******la fecha de alta no se debe modificar ni el usuario que hace el alta********/ const put_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { @@ -127,7 +141,7 @@ const put_herramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -137,7 +151,7 @@ const put_herramienta = async (req,res)=>{ if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -149,17 +163,17 @@ const put_herramienta = async (req,res)=>{ "ok": true, "id_herramienta": insert_id, "message": { - "code": 201, + "code": 200, "messageText": "Actualizado con éxito" } }) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) console.log(error) } @@ -177,7 +191,7 @@ const delete_herramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -186,7 +200,7 @@ const delete_herramienta = async (req,res)=>{ if(parseInt(validation_id_herr[0].result) === 0){ const result = return_error(400,'El ID de herramienta no existe'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -199,12 +213,12 @@ const delete_herramienta = async (req,res)=>{ "messageText": "Herramienta eliminada con éxito" } }) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) console.log(error) diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js index 0db2021..2cf25ee 100644 --- a/backend/controllers/login_controller.js +++ b/backend/controllers/login_controller.js @@ -14,7 +14,7 @@ const post_login = async (req, res) =>{ if(!validation_error.isEmpty()){ const mensajeError = validation_error.array()[0].msg; const result = return_error(400,`Datos con formato incorrecto. ${mensajeError}`); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -24,7 +24,7 @@ const post_login = async (req, res) =>{ if(parseInt(user_validation[0].result) === 0){ const result = return_error(404,'El usuario no está registrado'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -37,7 +37,7 @@ const post_login = async (req, res) =>{ if(!checkPassword){ const result = return_error(400,'Contraseña incorrecta'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -46,13 +46,13 @@ const post_login = async (req, res) =>{ if (!user_activo_validation[0]["estatus_activo"]){ const result = return_error(403,'Usuario no activo'); - conn.release; + conn.release(); return res.status(403).json(result) } - if(checkPassword && user_activo_validation){ + if(checkPassword && parseInt(user_validation[0].result) !== 0){ //obtener id de usuario y rol //pass_hash surge de un select a la base de datos con el fin de obtener el passwor registrado ahí @@ -62,8 +62,6 @@ const post_login = async (req, res) =>{ const rol_query = await conn.query ("SELECT ru.nombre_rol FROM roles_usuarios ru INNER JOIN usuarios u ON ru.id_rol = u.id_rol WHERE id_usuario = ?", user) const rol = rol_query[0].nombre_rol; - console.log(user) - console.log(rol) console.log("Sesion iniciada exitosamente "); const token_session = await token_sign(user, rol); //res estatus @@ -75,16 +73,19 @@ const post_login = async (req, res) =>{ }, "tokenSession": token_session }) - conn.release; + conn.release(); } } catch (error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) //console.log(error) console.log(error) } + finally{ + conn.release() + } }) } diff --git a/backend/controllers/origen_controllers.js b/backend/controllers/origen_controllers.js index ed601a6..54ae278 100644 --- a/backend/controllers/origen_controllers.js +++ b/backend/controllers/origen_controllers.js @@ -12,12 +12,12 @@ const get_origen = async (req,res)=>{ const query = await conn.query("select * from origen"); //console.log(query[0]) res.status(200).json(query) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) console.log (error) } diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js new file mode 100644 index 0000000..5cc59d7 --- /dev/null +++ b/backend/controllers/prestamos_controller.js @@ -0,0 +1,15 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') +const id_user_token = require ('../helpers/return_id_user_token.js') + + +const post_prestamo = async (req, res) => { + await pool.getConnection().then(async (conn) =>{ + + + + }) +} \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 10f8cca..50f23e8 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -15,7 +15,7 @@ const post_tipoHerramienta = async(req, res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -33,12 +33,12 @@ const post_tipoHerramienta = async(req, res)=>{ } }) - conn.release; + conn.release(); } catch (error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) //console.log(error) console.log(error.message) } @@ -53,13 +53,13 @@ const get_tipoHerramienta = async (req,res)=>{ //query const query = await conn.query("SELECT * FROM tipo_herramienta"); res.status(200).json(query) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) } @@ -79,7 +79,7 @@ const put_tipoHerramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -88,7 +88,7 @@ const put_tipoHerramienta = async (req,res)=>{ if(parseInt(validation_id_tipo[0].result) === 0){ const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -97,17 +97,17 @@ const put_tipoHerramienta = async (req,res)=>{ res.status(201).json({ "ok": true, "message": { - "code": 201, + "code": 200, "messageText": "Tipo de herramienta actualizado con éxito" } }) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) //console.log(error) } @@ -125,7 +125,7 @@ const delete_tipoHerramienta = async (req,res)=>{ const validation_error = validationResult(req); if(!validation_error.isEmpty()){ const result = return_error(400,'Datos con formato incorrecto'); - conn.release; + conn.release(); return res.status(400).json(result) } //validation id_tipo exists @@ -133,7 +133,7 @@ const delete_tipoHerramienta = async (req,res)=>{ if(parseInt(validation_id_tipo[0].result) === 0){ const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -142,7 +142,7 @@ const delete_tipoHerramienta = async (req,res)=>{ const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?",id_tipo) if(parseInt(validation_herramientas[0].result) !== 0){ const result = return_error(400,'Aún hay herramientas registradas con ese tipo'); - conn.release; + conn.release(); return res.status(400).json(result) } @@ -155,13 +155,13 @@ const delete_tipoHerramienta = async (req,res)=>{ "messageText": "Tipo eliminado con éxito" } }) - conn.release; + conn.release(); } catch(error){ const result = return_error(500,'Internal server error'); - conn.release; + conn.release(); res.status(500).json(result) //console.log(error) } diff --git a/backend/helpers/return_id_user_token.js b/backend/helpers/return_id_user_token.js new file mode 100644 index 0000000..5cacc3b --- /dev/null +++ b/backend/helpers/return_id_user_token.js @@ -0,0 +1,10 @@ +const {verify_token} = require('./generate_token') + +const id_user_token = async (token) =>{ + const token_data = await verify_token(token) + return token_data.id_user +} + + +module.exports = + id_user_token diff --git a/backend/middlewares/check_rol.js b/backend/middlewares/check_rol.js index bce439f..6a6bea0 100644 --- a/backend/middlewares/check_rol.js +++ b/backend/middlewares/check_rol.js @@ -12,17 +12,17 @@ const check_rol = (rol) => async (req, res, next)=>{ const estatus = await conn.query("SELECT estatus_activo FROM usuarios WHERE id_usuario = ?", token_data.id_user) if ( [].concat(rol).includes(user_rol_database[0].nombre_rol) && parseInt(estatus[0].estatus_activo) === 1){ - conn.release; + conn.release(); next() } else{ - conn.release; + conn.release(); const result = return_error(409,'Acceso denegado: no hay permisos suficientes'); res.status(409).json(result) } } catch (error) { - conn.release; + conn.release(); const result = return_error(500,'Internal server error'); res.status(500).json(result) } diff --git a/backend/routes/bajas_routes.js b/backend/routes/bajas_routes.js new file mode 100644 index 0000000..2a5252e --- /dev/null +++ b/backend/routes/bajas_routes.js @@ -0,0 +1,17 @@ +const express = require('express'); +const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') + +const { body, param } = require("express-validator") + +const { post_baja, get_bajas, delete_baja} = require('../controllers/bajas_controller.js'); +//const { route } = require('./herramientas_routes.js'); + +router.post('/', body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) + +router.get('/',get_bajas) + +/*router.delete()*/ + +module.exports = router diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index a4f5f93..40d3421 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -1,11 +1,13 @@ const express = require('express'); const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator"); const { post_herramienta, get_herramienta, get_herramienta_por_tipo, put_herramienta, delete_herramienta} = require('../controllers/herramientas_controller.js'); -router.post('/', body('id_tipo').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); +router.post('/', check_token, check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); router.get('/', get_herramienta); From 1367a6a0b59573a2b4e6fcf871866ea64706553e Mon Sep 17 00:00:00 2001 From: JUrielC Date: Wed, 15 May 2024 17:24:18 -0600 Subject: [PATCH 09/57] post_prestamo con route --- backend/app.js | 1 + backend/controllers/bajas_controller.js | 1 - backend/controllers/prestamos_controller.js | 87 ++++++++++++++++++++- backend/routes/prestamo_routes.js | 11 +++ 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 backend/routes/prestamo_routes.js diff --git a/backend/app.js b/backend/app.js index 66848e6..72b140c 100644 --- a/backend/app.js +++ b/backend/app.js @@ -15,6 +15,7 @@ app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) app.use('/login', require('./routes/login_routes')) app.use('/origen', require('./routes/origen_routes')) app.use('/bajas', require('./routes/bajas_routes')) +app.use('/prestamos', require('./routes/prestamo_routes')) /*app.use((req, res, next) => { diff --git a/backend/controllers/bajas_controller.js b/backend/controllers/bajas_controller.js index 17d30ba..8bcaaa0 100644 --- a/backend/controllers/bajas_controller.js +++ b/backend/controllers/bajas_controller.js @@ -12,7 +12,6 @@ const post_baja = async (req, res) => { const id_user = await id_user_token(req.headers.authorization) const fecha_baja = fecha_hora(); - console.log(fecha_baja) const {id_herramienta, id_motivo, observaciones} = req.body const data = [id_herramienta, id_motivo, id_user, fecha_baja, observaciones] diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index 5cc59d7..f3669e5 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -3,13 +3,94 @@ const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); const return_error = require('../helpers/return_error.js'); const fecha_hora = require('../helpers/return_date.js') -const id_user_token = require ('../helpers/return_id_user_token.js') +const id_user_token = require('../helpers/return_id_user_token.js') const post_prestamo = async (req, res) => { - await pool.getConnection().then(async (conn) =>{ + await pool.getConnection().then(async (conn) => { + + try{ + const encargado_entrega = await id_user_token(req.headers.authorization) + const fecha_prestamo = fecha_hora(); + const id_estatus = 1; //estatus de prestamo en curso, revisar tabla estatus_prestamo de la db + const { id_herramienta, id_carrera, id_solicitante, observaciones } = req.body + const data = [encargado_entrega, id_herramienta, id_carrera, id_estatus, id_solicitante, fecha_prestamo, observaciones] + + //validacion expresss validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato o extensión incorrecta'); + conn.release(); + return res.status(400).json(result) + } + + + //validacion id_herramienta exist + const validation_id_herramienta = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?", id_herramienta) + + if(parseInt(validation_id_herramienta[0].result) === 0){ + const result = return_error(400,'La herramienta no está registrada'); + conn.release(); + return res.status(400).json(result) + } + + //validation herramienta disponible + const validation_herramienta_disponible = await conn.query ("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) + //console.log((validation_herramienta_activa)) + if(parseInt(validation_herramienta_disponible[0].id_estatus)!==1){ + const result = return_error(400,'La herramienta no está disponible, verifique el estatus'); + conn.release(); + return res.status(400).json(result) + } + + //validacion carrera, id_ solicitante + const validation_carrera = await conn.query("SELECT COUNT (id_carrera) as result FROM carreras WHERE id_carrera = ?", id_carrera) + + + if(parseInt(validation_carrera[0].result) === 0){ + const result = return_error(400,'La solicitud contiene parámetros incorrectos, se recomienda contactar al equipo de desarrollo: no se encuentra el ID de la carrera.'); + conn.release(); + return res.status(400).json(result) + } + + const validation_solicitante = await conn.query("SELECT COUNT (id_solicitante) as result FROM solicitantes WHERE id_solicitante = ?", id_solicitante) + + if(parseInt(validation_solicitante[0].result) === 0){ + const result = return_error(400,'El no se encuentra el solicitante. Compruebe si el solicitante está registrado en el sistema'); + conn.release(); + return res.status(400).json(result) + } + + + //QUERY + const query = await conn.query("CALL registrar_prestamo (?,?,?,?,?,?,?)", data) + //console.log(query) + //const insert_id = parseInt(query[0].insertId) + res.status(201).json({ + "ok": true, + "message": { + "code": 201, + "messageText": "Prestamo registrado con éxito" + } + }) + + conn.release(); + } + catch(error){ + + const result = return_error(500,'Internal server error'); + console.log (error) + conn.release(); + res.status(500).json(result) + + } + - }) +} + + +module.exports = { + post_prestamo } \ No newline at end of file diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js new file mode 100644 index 0000000..cdbd845 --- /dev/null +++ b/backend/routes/prestamo_routes.js @@ -0,0 +1,11 @@ +const express = require('express'); +const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') + +const { body, param } = require("express-validator") +const { post_prestamo, get_bajas, delete_baja} = require('../controllers/prestamos_controller.js'); + +router.post('/', post_prestamo) + +module.exports = router \ No newline at end of file From 622b4232a9315e1b3b4022947ab5bcbe02bdbefc Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sun, 26 May 2024 16:53:32 -0600 Subject: [PATCH 10/57] =?UTF-8?q?login=20regresa=20nombre=20de=20user,=20a?= =?UTF-8?q?ctualizaci=C3=B3n=20de=20prestamos=20c=20y=20r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.env | 2 +- backend/controllers/login_controller.js | 7 +++-- backend/controllers/prestamos_controller.js | 32 ++++++++++++++++++++- backend/routes/prestamo_routes.js | 4 ++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/backend/.env b/backend/.env index 8e53dbd..82aaaa2 100644 --- a/backend/.env +++ b/backend/.env @@ -1,4 +1,4 @@ -NODE_PORT="3000" +NODE_PORT="3001" HOST="localhost" PORT="3306" USER="root" diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js index 2cf25ee..0dbf28d 100644 --- a/backend/controllers/login_controller.js +++ b/backend/controllers/login_controller.js @@ -61,7 +61,9 @@ const post_login = async (req, res) =>{ const user = user_query[0].id_usuario; const rol_query = await conn.query ("SELECT ru.nombre_rol FROM roles_usuarios ru INNER JOIN usuarios u ON ru.id_rol = u.id_rol WHERE id_usuario = ?", user) const rol = rol_query[0].nombre_rol; - + + const data_user_query = await conn.query("SELECT nombre_usuario, apellido_paterno from usuarios WHERE id_usuario = ?", user) + console.log(data_user_query) console.log("Sesion iniciada exitosamente "); const token_session = await token_sign(user, rol); //res estatus @@ -71,7 +73,8 @@ const post_login = async (req, res) =>{ "code": 200, "messageText": "Sesion iniciada exitosamente " }, - "tokenSession": token_session + "tokenSession": token_session, + "user_data" : data_user_query[0] }) conn.release(); } diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index f3669e5..05fd58e 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -90,7 +90,37 @@ const post_prestamo = async (req, res) => { }) } +const get_prestamos_activos = async (req, res) => ( + await pool.getConnection().then (async (conn) => { + + + try{ + //query + const query = await conn.query("CALL consultar_prestamo_activos()"); + //console.log(query[0]) + res.status(200).json(query[0]) + conn.release(); + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log (error) + } + }) +) + + +const put_prestamo_devuelto = async (req,res)=>{ + pool.getConnection().then(async(conn) => { + + const usuario_recibe = await id_user_token(req.headers.authorization) + + }) +} module.exports = { - post_prestamo + post_prestamo, + get_prestamos_activos } \ No newline at end of file diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index cdbd845..84e50b4 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -4,7 +4,9 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") -const { post_prestamo, get_bajas, delete_baja} = require('../controllers/prestamos_controller.js'); +const { post_prestamo, get_prestamos_activos, delete_baja} = require('../controllers/prestamos_controller.js'); + +router.get('/', get_prestamos_activos) router.post('/', post_prestamo) From 00bfd9d0c629664afce63704f79f3e8b047c23c1 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Wed, 5 Jun 2024 23:16:31 -0600 Subject: [PATCH 11/57] =?UTF-8?q?avance=20endpoints=20usuarios=20y=20solic?= =?UTF-8?q?itantes.=20Asignaci=C3=B3n=20de=20permisos=20a=20las=20rutas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.env | 10 +- backend/app.js | 2 + backend/config/database.js | 3 +- backend/controllers/login_controller.js | 7 +- backend/controllers/prestamos_controller.js | 44 ++++- .../controllers/solititantes_controller.js | 30 ++++ .../controllers/tipoHerramienta_controller.js | 137 +++++++++------ backend/controllers/usuarios_controllers.js | 166 ++++++++++++++++++ backend/helpers/generate_token.js | 22 ++- backend/middlewares/check_rol.js | 5 +- backend/middlewares/check_token.js | 27 ++- backend/routes/bajas_routes.js | 4 +- backend/routes/herramientas_routes.js | 6 +- backend/routes/prestamo_routes.js | 10 +- backend/routes/solicitantes_routes.js | 11 ++ backend/routes/tipoHerramienta_routes.js | 12 +- backend/routes/usuarios_routes.js | 23 +++ 17 files changed, 425 insertions(+), 94 deletions(-) create mode 100644 backend/controllers/solititantes_controller.js create mode 100644 backend/routes/solicitantes_routes.js diff --git a/backend/.env b/backend/.env index 82aaaa2..44d1af9 100644 --- a/backend/.env +++ b/backend/.env @@ -4,4 +4,12 @@ PORT="3306" USER="root" PASSWORD="root" DATABASE="dbsistemas" -JWT_SECRET = "589696852" \ No newline at end of file +JWT_SECRET = "589696852" + +#NODE_PORT="3001" +#HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" +#PORT="3306" +#USER="ugpwh5vn4olvh15t" +#PASSWORD="DHGMBoPlzbo6Q9rFxHRW" +#DATABASE="bqvpx1qe8f1g2jhxyxjj" +#JWT_SECRET = "589696852" \ No newline at end of file diff --git a/backend/app.js b/backend/app.js index 72b140c..c1b94e2 100644 --- a/backend/app.js +++ b/backend/app.js @@ -16,6 +16,8 @@ app.use('/login', require('./routes/login_routes')) app.use('/origen', require('./routes/origen_routes')) app.use('/bajas', require('./routes/bajas_routes')) app.use('/prestamos', require('./routes/prestamo_routes')) +app.use('/usuarios', require('./routes/usuarios_routes')) +app.use('/solicitantes', require('./routes/solicitantes_routes')) /*app.use((req, res, next) => { diff --git a/backend/config/database.js b/backend/config/database.js index 7f07a6e..de0e194 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -6,7 +6,8 @@ const pool = mariadb.createPool({ port: process.env.PORT, user: process.env.USER, password: process.env.PASSWORD, - database: process.env.DATABASE + database: process.env.DATABASE, + connectionLimit: 3 }); module.exports = pool \ No newline at end of file diff --git a/backend/controllers/login_controller.js b/backend/controllers/login_controller.js index 0dbf28d..2a041e8 100644 --- a/backend/controllers/login_controller.js +++ b/backend/controllers/login_controller.js @@ -63,8 +63,8 @@ const post_login = async (req, res) =>{ const rol = rol_query[0].nombre_rol; const data_user_query = await conn.query("SELECT nombre_usuario, apellido_paterno from usuarios WHERE id_usuario = ?", user) - console.log(data_user_query) - console.log("Sesion iniciada exitosamente "); + /* console.log(data_user_query) + console.log("Sesion iniciada exitosamente "); */ const token_session = await token_sign(user, rol); //res estatus res.status(200).json({ @@ -74,8 +74,9 @@ const post_login = async (req, res) =>{ "messageText": "Sesion iniciada exitosamente " }, "tokenSession": token_session, - "user_data" : data_user_query[0] + "user_data" : data_user_query[0].nombre_usuario + " " +data_user_query[0].apellido_paterno }) + //console.log(typeof(data_user_query[0].nombre_usuario)) conn.release(); } diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index 05fd58e..04f9ee4 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -102,6 +102,26 @@ const get_prestamos_activos = async (req, res) => ( conn.release(); } + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release(); + res.status(500).json(result) + } + }) +) + +const get_prestamos = async (req, res) => ( + await pool.getConnection().then (async (conn) => { + + + try{ + //query + const query = await conn.query("CALL consultar_prestamos()"); + //console.log(query[0]) + res.status(200).json(query[0]) + conn.release(); + } + catch(error){ const result = return_error(500,'Internal server error'); conn.release(); @@ -111,6 +131,26 @@ const get_prestamos_activos = async (req, res) => ( }) ) +const get_prestamos_concluidos = async (req, res) => ( + await pool.getConnection().then (async (conn) => { + + + try{ + //query + const query = await conn.query("CALL consultar_prestamos_concluidos()"); + //console.log(query[0]) + res.status(200).json(query[0]) + conn.release(); + } + + catch(error){ + const result = return_error(500,'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log (error) + } + }) +) const put_prestamo_devuelto = async (req,res)=>{ pool.getConnection().then(async(conn) => { @@ -122,5 +162,7 @@ const put_prestamo_devuelto = async (req,res)=>{ module.exports = { post_prestamo, - get_prestamos_activos + get_prestamos, + get_prestamos_activos, + get_prestamos_concluidos } \ No newline at end of file diff --git a/backend/controllers/solititantes_controller.js b/backend/controllers/solititantes_controller.js new file mode 100644 index 0000000..eeeec1d --- /dev/null +++ b/backend/controllers/solititantes_controller.js @@ -0,0 +1,30 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const { encrypt } = require('../helpers/handle_bcrybpt.js') +const return_error = require('../helpers/return_error.js') + +const get_solicitantes = async(req, res)=>{ + pool.getConnection().then(async (conn)=>{ + try { + + //query + const query = await conn.query("SELECT id_solicitante, nombre, apellido_paterno, COALESCE(apellido_materno, '') as apellido_materno, control_nomina, telefono, mail FROM solicitantes ORDER BY nombre ASC"); + res.status(200).json(query) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) +} + + +module.exports ={ + get_solicitantes +} \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 50f23e8..00f108a 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -4,21 +4,21 @@ const { validationResult } = require('express-validator'); const return_error = require('../helpers/return_error.js') -const post_tipoHerramienta = async(req, res)=>{ +const post_tipoHerramienta = async (req, res) => { await pool.getConnection().then(async (conn) => { - - try{ - - const {nombre_tipo, descripcion} = req.body; + + try { + + const { nombre_tipo, descripcion } = req.body; const data = [nombre_tipo, descripcion]; //validacion expresss validator - const validation_error = validationResult(req); - if(!validation_error.isEmpty()){ - const result = return_error(400,'Datos con formato o extensión incorrecta'); + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato o extensión incorrecta'); conn.release(); - return res.status(400).json(result) + return res.status(400).json(result) } - + //query const query = await conn.query("INSERT INTO tipo_herramienta (nombre_tipo, descripcion) VALUES (?,?)", data); const insert_id = parseInt(query.insertId) @@ -30,25 +30,25 @@ const post_tipoHerramienta = async(req, res)=>{ "message": { "code": 201, "messageText": "Tipo registrado con éxito" - } + } }) conn.release(); } - catch (error){ - const result = return_error(500,'Internal server error'); - conn.release(); + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); res.status(500).json(result) //console.log(error) - console.log(error.message) + console.log(error.message) } }) } -const get_tipoHerramienta = async (req,res)=>{ +const get_tipoHerramienta = async (req, res) => { await pool.getConnection().then(async (conn) => { - try{ + try { //query const query = await conn.query("SELECT * FROM tipo_herramienta"); @@ -56,40 +56,62 @@ const get_tipoHerramienta = async (req,res)=>{ conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) - } + } }) } +const get_items_disp_por_tipo = async (red, res) => { + await pool.getConnection().then(async (conn) => { + try { + + //query + const query = await conn.query("SELECT t.id_tipo, t.nombre_tipo, IFNULL(JSON_ARRAYAGG(" + + " h.id_herramienta), '[]') AS herramientas " + + "FROM tipo_herramienta t LEFT JOIN herramientas h ON t.id_tipo = h.id_tipo " + + "WHERE h.id_estatus = 1 GROUP BY t.id_tipo, t.nombre_tipo"); + res.status(200).json(query) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) +} -const put_tipoHerramienta = async (req,res)=>{ +const put_tipoHerramienta = async (req, res) => { await pool.getConnection().then(async (conn) => { - try{ + try { - const {id_tipo, nombre_tipo, descripcion} = req.body + const { id_tipo, nombre_tipo, descripcion } = req.body const data = [nombre_tipo, descripcion, id_tipo] //validation error express validator const validation_error = validationResult(req); - if(!validation_error.isEmpty()){ - const result = return_error(400,'Datos con formato incorrecto'); - conn.release(); - return res.status(400).json(result) + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato incorrecto'); + conn.release(); + return res.status(400).json(result) } //validation id_tipo exists - const validation_id_tipo = await conn.query("SELECT COUNT(id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?",id_tipo) - - if(parseInt(validation_id_tipo[0].result) === 0){ - const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.release(); - return res.status(400).json(result) + const validation_id_tipo = await conn.query("SELECT COUNT(id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) + + if (parseInt(validation_id_tipo[0].result) === 0) { + const result = return_error(400, 'El ID del tipo de herramienta no existe'); + conn.release(); + return res.status(400).json(result) } //query @@ -105,8 +127,8 @@ const put_tipoHerramienta = async (req,res)=>{ } - catch(error){ - const result = return_error(500,'Internal server error'); + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) //console.log(error) @@ -115,37 +137,37 @@ const put_tipoHerramienta = async (req,res)=>{ }) } -const delete_tipoHerramienta = async (req,res)=>{ +const delete_tipoHerramienta = async (req, res) => { await pool.getConnection().then(async (conn) => { - try{ + try { const id_tipo = req.params.id_tipo //validation express validator - const validation_error = validationResult(req); - if(!validation_error.isEmpty()){ - const result = return_error(400,'Datos con formato incorrecto'); - conn.release(); - return res.status(400).json(result) + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato incorrecto'); + conn.release(); + return res.status(400).json(result) } //validation id_tipo exists - const validation_id_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?",id_tipo) + const validation_id_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) - if(parseInt(validation_id_tipo[0].result) === 0){ - const result = return_error(400,'El ID del tipo de herramienta no existe'); - conn.release(); - return res.status(400).json(result) + if (parseInt(validation_id_tipo[0].result) === 0) { + const result = return_error(400, 'El ID del tipo de herramienta no existe'); + conn.release(); + return res.status(400).json(result) } //validation: no hay herramientas de ese tipo - const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?",id_tipo) - if(parseInt(validation_herramientas[0].result) !== 0){ - const result = return_error(400,'Aún hay herramientas registradas con ese tipo'); - conn.release(); - return res.status(400).json(result) + const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?", id_tipo) + if (parseInt(validation_herramientas[0].result) !== 0) { + const result = return_error(400, 'Aún hay herramientas registradas con ese tipo'); + conn.release(); + return res.status(400).json(result) } - + //query await conn.query("DELETE FROM tipo_herramienta WHERE id_tipo = ?", id_tipo); res.status(200).json({ @@ -158,9 +180,9 @@ const delete_tipoHerramienta = async (req,res)=>{ conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) //console.log(error) @@ -172,6 +194,7 @@ const delete_tipoHerramienta = async (req,res)=>{ module.exports = { post_tipoHerramienta, get_tipoHerramienta, + get_items_disp_por_tipo, put_tipoHerramienta, delete_tipoHerramienta } \ No newline at end of file diff --git a/backend/controllers/usuarios_controllers.js b/backend/controllers/usuarios_controllers.js index e69de29..871b557 100644 --- a/backend/controllers/usuarios_controllers.js +++ b/backend/controllers/usuarios_controllers.js @@ -0,0 +1,166 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const { encrypt } = require('../helpers/handle_bcrybpt.js') +const return_error = require('../helpers/return_error.js') + + +const post_usuario = async (req, res) => { + pool.getConnection().then(async (conn) => { + + try { + + const { id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, password, estatus_activo } = req.body; + const pass_encrypt = await encrypt(password); + const data = [id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, pass_encrypt, estatus_activo]; + + //validacion expresss validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const mensajeError = validation_error.array()[0].msg; + const result = return_error(400, `Datos con formato o extensión incorrecta ${mensajeError}`); + conn.release(); + return res.status(400).json(result) + } + + //validation nombre de usuario ya existe + const validation_nom_login = await conn.query("SELECT COUNT(nombre_login) as result FROM usuarios WHERE nombre_login = ?", nombre_login) + + if (parseInt(validation_nom_login[0].result) !== 0) { + const result = return_error(400, 'El nombre usuario ya existe '); + conn.release(); + return res.status(400).json(result) + } + + const query = await conn.query("INSERT INTO usuarios (id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, password, estatus_activo) values (?, ?, ?, ?, ?, ?, ?) ", data) + insert_id = parseInt(query.insert_id) + //res estatus + res.status(201).json({ + "ok": true, + "id_tipo": insert_id, + "message": { + "code": 201, + "messageText": "Usuario registrado con éxito" + } + }) + + conn.release() + + } catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) //console.log(error) + console.log(error.message) + } + + + }) +} + +const get_usuarios = async (req, res) => { + pool.getConnection().then(async (conn) => { + + try { + + //query + const query = await conn.query("CALL consultar_usuarios()"); + res.status(200).json(query[0]) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) +} + +const put_usuario = async (req, res) => { + pool.getConnection().then(async (conn) => { + try { + + const { id_usuario, id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, estatus_activo } = req.body + const data = [id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, estatus_activo, id_usuario] + + //validation error express validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato incorrecto'); + conn.release(); + return res.status(400).json(result) + } + + //validation nombre de usuario ya existe + const validation_nom_login = await conn.query("SELECT COUNT(nombre_login) as result FROM usuarios WHERE nombre_login = ? and id_usuario != ?", [nombre_login, id_usuario]) + + if (parseInt(validation_nom_login[0].result) !== 0) { + const result = return_error(400, 'El nuevo nombre de usuario ya existe para un usuario registrado'); + conn.release(); + return res.status(400).json(result) + } + + + + //query + await conn.query("UPDATE usuarios SET id_rol = ?, nombre_usuario = ?, apellido_paterno = ?, apellido_materno = ?, nombre_login = ?, estatus_activo = ? WHERE id_usuario = ?", data); + res.status(201).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Usuario actualizado con éxito" + } + }) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) + +} + +const put_usuario_password = async(req, res) =>{ + pool.getConnection().then(async (conn)=>{ + + try { + + const {id_usuario, password} = req.body + const pass_encrypt = await encrypt(password); + const data = [pass_encrypt, id_usuario] + + await conn.query("UPDATE usuarios SET password = ? WHERE id_usuario = ?", data) + res.status(201).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Password actualizado con éxito" + } + }) + conn.release(); + + + } catch (error) { + + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) +} + +module.exports = { + post_usuario, + get_usuarios, + put_usuario, + put_usuario_password +} + diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index 0082e71..12a4e60 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -9,19 +9,25 @@ const token_sign = async (user, rol) =>{ }, process.env.JWT_SECRET, { - expiresIn: "5h" + expiresIn: "1h" } ) } //verificar token -const verify_token = async (token) =>{ - try{ - return jwt.verify(token, process.env.JWT_SECRET) - } - catch(error){ - return null; +const verify_token = async (token) => { + try { + //console.log(jwt.verify(token, process.env.JWT_SECRET)) + return jwt.verify(token, process.env.JWT_SECRET); + } + catch (error) { + if (error instanceof jwt.TokenExpiredError) { + console.log("Token has expired"); + return "Token has expired"; + } else { + return null; + } } -} +}; const decode_sign = async (token) =>{ } diff --git a/backend/middlewares/check_rol.js b/backend/middlewares/check_rol.js index 6a6bea0..2a1cc82 100644 --- a/backend/middlewares/check_rol.js +++ b/backend/middlewares/check_rol.js @@ -17,12 +17,13 @@ const check_rol = (rol) => async (req, res, next)=>{ } else{ conn.release(); - const result = return_error(409,'Acceso denegado: no hay permisos suficientes'); - res.status(409).json(result) + const result = return_error(403,'Acceso denegado: no hay permisos suficientes'); + res.status(403).json(result) } } catch (error) { conn.release(); + console.log(error) const result = return_error(500,'Internal server error'); res.status(500).json(result) } diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index c8ac686..2da8b04 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -1,6 +1,6 @@ const { verify_token } = require('../helpers/generate_token') const return_error = require('../helpers/return_error.js'); -require('dotenv').config({path: 'backend/.env'}); +require('dotenv').config({ path: 'backend/.env' }); const check_token = async (req, res, next) => { try { @@ -9,18 +9,29 @@ const check_token = async (req, res, next) => { //console.log(token) const token_data = await verify_token(token) //console.log(token_data) - if (token_data) { + if ((token_data) && (token_data !== "Token has expired")) { next() } - else{ - const result = return_error(409,'Acceso denegado: token no válido'); - res.status(409).json(result) + else { + + if (token_data === "Token has expired") { + + const result = return_error(401, `${token_data}: La sesión ha expirado`); + res.status(401).json(result) + + } + else { + + const result = return_error(403, 'Acceso denegado: no hay permisos suficientes'); + res.status(403).json(result) + } + } } catch (error) { - const result = return_error(500,'Internal server error'); - res.status(500).json(result) - //console.log(error) + const result = return_error(500, 'Internal server error'); + res.status(500).json(result) + console.log(error) } } /* const prueba = async()=>{ diff --git a/backend/routes/bajas_routes.js b/backend/routes/bajas_routes.js index 2a5252e..774f002 100644 --- a/backend/routes/bajas_routes.js +++ b/backend/routes/bajas_routes.js @@ -8,9 +8,9 @@ const { body, param } = require("express-validator") const { post_baja, get_bajas, delete_baja} = require('../controllers/bajas_controller.js'); //const { route } = require('./herramientas_routes.js'); -router.post('/', body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) +router.post('/',check_token,check_rol(['Administrador', 'Laboratorista']), body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) -router.get('/',get_bajas) +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']),get_bajas) /*router.delete()*/ diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index 40d3421..f3e87d9 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -9,11 +9,11 @@ const { post_herramienta, get_herramienta, get_herramienta_por_tipo, put_herrami router.post('/', check_token, check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(),body('observaciones').isLength({max: 255}), post_herramienta); -router.get('/', get_herramienta); +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_herramienta); -router.get('/tipo/:id_tipo', param('id_tipo').isNumeric(), get_herramienta_por_tipo); +router.get('/tipo/:id_tipo',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), param('id_tipo').isNumeric(), get_herramienta_por_tipo); -router.put('/', body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); +router.put('/',check_token,check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index 84e50b4..46df500 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -4,10 +4,14 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") -const { post_prestamo, get_prestamos_activos, delete_baja} = require('../controllers/prestamos_controller.js'); +const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos} = require('../controllers/prestamos_controller.js'); -router.get('/', get_prestamos_activos) +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos) -router.post('/', post_prestamo) +router.get('/prestamos_activos',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos_activos) + +router.get('/prestamos_concluidos',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos_concluidos) + +router.post('/',check_token,check_rol(['Administrador', 'Laboratorista','Asistente ']), post_prestamo) module.exports = router \ No newline at end of file diff --git a/backend/routes/solicitantes_routes.js b/backend/routes/solicitantes_routes.js new file mode 100644 index 0000000..ab69f60 --- /dev/null +++ b/backend/routes/solicitantes_routes.js @@ -0,0 +1,11 @@ +const express = require('express'); +const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') +const { body, param } = require("express-validator"); + +const {get_solicitantes} = require('../controllers/solititantes_controller.js') + +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']), get_solicitantes) + +module.exports = router diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js index 2753f9c..1960092 100644 --- a/backend/routes/tipoHerramienta_routes.js +++ b/backend/routes/tipoHerramienta_routes.js @@ -4,14 +4,16 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator"); -const { post_tipoHerramienta, get_tipoHerramienta, put_tipoHerramienta, delete_tipoHerramienta } = require('../controllers/tipoHerramienta_controller.js'); +const { post_tipoHerramienta, get_tipoHerramienta, put_tipoHerramienta, delete_tipoHerramienta,get_items_disp_por_tipo } = require('../controllers/tipoHerramienta_controller.js'); -router.post('/', check_token, body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); +router.post('/',check_token,check_rol(['Administrador', 'Laboratorista']), body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), post_tipoHerramienta); -router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']), get_tipoHerramienta); +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_tipoHerramienta); -router.put('/', body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); +router.get('/tipos_mas_herramientas' ,check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_items_disp_por_tipo) -router.delete('/:id_tipo', param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ +router.put('/' ,check_token,check_rol(['Administrador', 'Laboratorista']), body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); + +router.delete('/:id_tipo',check_token,check_rol(['Administrador', 'Laboratorista']), param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ module.exports = router \ No newline at end of file diff --git a/backend/routes/usuarios_routes.js b/backend/routes/usuarios_routes.js index e69de29..1e13ac5 100644 --- a/backend/routes/usuarios_routes.js +++ b/backend/routes/usuarios_routes.js @@ -0,0 +1,23 @@ +const express = require('express'); +const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') +const { body, param } = require("express-validator"); + + +const {post_usuario, get_usuarios, put_usuario, put_usuario_password} = require('../controllers/usuarios_controllers.js') + +router.post('/', body('id_rol').isNumeric(), +body(['nombre_usuario', 'apellido_paterno']).isLength({min:3, max: 45}).withMessage('El nombre y el apellido deben tener mínimo 3 caracteres y máximo 45'), +body('nombre_login').isLength({min: 3, max:20}).withMessage('El nombre de usuario debe ser de mínimo 3 caracteres y máximo de 20'), +body('password').isLength({min:5, max:60}).withMessage('El password debe tener al menos 5 caracteres y máximo 60'), body('estatus_activo').isNumeric({min:0, max:1}), +post_usuario) + + +router.get('/',check_token,check_rol(['Administrador']), get_usuarios ) + +router.put('/',check_token,check_rol(['Administrador']),put_usuario) + +router.put ('/rec_pass',check_token,check_rol(['Administrador']), put_usuario_password) + +module.exports = router \ No newline at end of file From 2d3e2d4dbd7781d96b959d179349ad36c49322d7 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 6 Jun 2024 23:41:37 -0600 Subject: [PATCH 12/57] Permisos para Asistente en get solicitantes, Procedure para insert varias herramientas a la vez --- backend/.env | 2 +- backend/app.js | 1 + backend/controllers/carreras_controller.js | 32 +++++++++++++++++++ .../controllers/herramientas_controller.js | 26 +++++++-------- backend/controllers/prestamos_controller.js | 2 +- ...ntroller.js => solicitantes_controller.js} | 0 .../controllers/tipoHerramienta_controller.js | 2 +- backend/routes/carreras_routes.js | 12 +++++++ backend/routes/prestamo_routes.js | 4 ++- backend/routes/solicitantes_routes.js | 4 +-- 10 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 backend/controllers/carreras_controller.js rename backend/controllers/{solititantes_controller.js => solicitantes_controller.js} (100%) create mode 100644 backend/routes/carreras_routes.js diff --git a/backend/.env b/backend/.env index 44d1af9..2b82cad 100644 --- a/backend/.env +++ b/backend/.env @@ -1,4 +1,4 @@ -NODE_PORT="3001" + NODE_PORT="3001" HOST="localhost" PORT="3306" USER="root" diff --git a/backend/app.js b/backend/app.js index c1b94e2..874cad8 100644 --- a/backend/app.js +++ b/backend/app.js @@ -18,6 +18,7 @@ app.use('/bajas', require('./routes/bajas_routes')) app.use('/prestamos', require('./routes/prestamo_routes')) app.use('/usuarios', require('./routes/usuarios_routes')) app.use('/solicitantes', require('./routes/solicitantes_routes')) +app.use('/carreras', require('./routes/carreras_routes')) /*app.use((req, res, next) => { diff --git a/backend/controllers/carreras_controller.js b/backend/controllers/carreras_controller.js new file mode 100644 index 0000000..25b8e26 --- /dev/null +++ b/backend/controllers/carreras_controller.js @@ -0,0 +1,32 @@ +const express = require('express'); +const pool = require('../config/database.js'); +const { validationResult } = require('express-validator'); +const return_error = require('../helpers/return_error.js'); +const fecha_hora = require('../helpers/return_date.js') +const id_user_token = require('../helpers/return_id_user_token.js') + + + +const get_carreras = async (req, res) => { + pool.getConnection().then(async (conn) => { + try { + + //query + const query = await conn.query("SELECT * FROM carreras"); + res.status(200).json(query) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + }) +} + +module.exports = { + get_carreras +} \ No newline at end of file diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index 93cc508..c1d545a 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -13,8 +13,8 @@ const post_herramienta = async(req, res)=>{ const id_user = await id_user_token(req.headers.authorization) const id_estatus = 1; //id _estatus = 1 es el estatus "Disponible" const fecha_alta = fecha_hora(); - const {id_tipo, observaciones,id_origen} = req.body; - const data = [id_tipo, id_estatus, observaciones,fecha_alta,id_origen, id_user]; + const {id_tipo, observaciones,id_origen, cantidad} = req.body; + const data = [id_tipo, id_estatus,id_origen,fecha_alta, observaciones, id_user, cantidad]; //validacion expresss validator const validation_error = validationResult(req); @@ -45,15 +45,16 @@ const post_herramienta = async(req, res)=>{ } //query - const query = await conn.query("INSERT INTO herramientas (id_tipo, id_estatus, observaciones, fecha_alta, id_origen, id_usuario) VALUES (?,?,?,?,?,?)",data) - const insert_id = parseInt(query.insertId) + const query = await conn.query("CALL insertar_herramientas (?,?,?,?,?,?,?)",data) + const idsArray = query[0] + const ids = idsArray.map(item => item.id_herramienta); + const idsString = ids.join(' '); //res estatus res.status(201).json({ "ok": true, - "id_herramienta": insert_id, "message": { "code": 201, - "messageText": "Registrado con éxito" + "messageText": "Registrada(s) con éxito. ID(s) registrados: " + idsString } }) @@ -129,13 +130,13 @@ const get_herramienta_por_tipo = async (req,res)=>{ }) } -/*******la fecha de alta no se debe modificar ni el usuario que hace el alta********/ +/*******la fecha de alta no se debe modificar ni el usuario que hace el alta. Tampoco el estatus********/ const put_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {id_herramienta, id_tipo, id_estatus, observaciones, origen} = req.body; - const data = [id_tipo, id_estatus, observaciones, origen, id_herramienta]; + const {id_herramienta, id_tipo, observaciones, origen} = req.body; + const data = [id_tipo, observaciones, origen, id_herramienta]; //validacion expresss validator const validation_error = validationResult(req); @@ -147,16 +148,15 @@ const put_herramienta = async (req,res)=>{ //validation tipo exists, estatus exists const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) - const validation_estatus = await conn.query("SELECT COUNT (id_estatus) as result FROM estatus_herramienta WHERE id_estatus = ?", id_estatus) - - if(parseInt(validation_tipo[0].result) === 0 || parseInt(validation_estatus[0].result) === 0){ + + if(parseInt(validation_tipo[0].result) === 0){ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); conn.release(); return res.status(400).json(result) } //query - const query = await conn.query("UPDATE herramientas SET id_tipo = ?, id_estatus = ?, observaciones = ?, origen = ? WHERE id_herramienta = ?",data) + const query = await conn.query("UPDATE herramientas SET id_tipo = ?, observaciones = ?, origen = ? WHERE id_herramienta = ?",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index 04f9ee4..2cd1f67 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -44,7 +44,7 @@ const post_prestamo = async (req, res) => { } //validacion carrera, id_ solicitante - const validation_carrera = await conn.query("SELECT COUNT (id_carrera) as result FROM carreras WHERE id_carrera = ?", id_carrera) + const validation_carrera = await conn.query("SELECT COUNT(id_carrera) as result FROM carreras WHERE id_carrera = ?", id_carrera) if(parseInt(validation_carrera[0].result) === 0){ diff --git a/backend/controllers/solititantes_controller.js b/backend/controllers/solicitantes_controller.js similarity index 100% rename from backend/controllers/solititantes_controller.js rename to backend/controllers/solicitantes_controller.js diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 00f108a..7a2104e 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -74,7 +74,7 @@ const get_items_disp_por_tipo = async (red, res) => { const query = await conn.query("SELECT t.id_tipo, t.nombre_tipo, IFNULL(JSON_ARRAYAGG(" + " h.id_herramienta), '[]') AS herramientas " + "FROM tipo_herramienta t LEFT JOIN herramientas h ON t.id_tipo = h.id_tipo " + - "WHERE h.id_estatus = 1 GROUP BY t.id_tipo, t.nombre_tipo"); + "WHERE h.id_estatus = 1 GROUP BY t.id_tipo, t.nombre_tipo ORDER BY t.nombre_tipo asc"); res.status(200).json(query) conn.release(); diff --git a/backend/routes/carreras_routes.js b/backend/routes/carreras_routes.js new file mode 100644 index 0000000..5540b32 --- /dev/null +++ b/backend/routes/carreras_routes.js @@ -0,0 +1,12 @@ +const express = require('express'); +const router = express.Router(); +const {check_token} = require('../middlewares/check_token.js') +const {check_rol} = require('../middlewares/check_rol.js') + +const { body, param } = require("express-validator") + +const {get_carreras} = require('../controllers/carreras_controller.js') + +router.get('/', get_carreras) + +module.exports = router \ No newline at end of file diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index 46df500..47fb5bf 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -6,7 +6,9 @@ const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos} = require('../controllers/prestamos_controller.js'); -router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos) +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), +body(['id_herramienta', 'id_carrera', 'id_solicitante']).isNumeric(), +get_prestamos) router.get('/prestamos_activos',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos_activos) diff --git a/backend/routes/solicitantes_routes.js b/backend/routes/solicitantes_routes.js index ab69f60..ab37eb2 100644 --- a/backend/routes/solicitantes_routes.js +++ b/backend/routes/solicitantes_routes.js @@ -4,8 +4,8 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator"); -const {get_solicitantes} = require('../controllers/solititantes_controller.js') +const {get_solicitantes} = require('../controllers/solicitantes_controller.js') -router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']), get_solicitantes) +router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_solicitantes) module.exports = router From 57813ab520d1fdba647a6c0b5299f959ab66ab47 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sat, 8 Jun 2024 23:12:10 -0600 Subject: [PATCH 13/57] validacion de rest password --- backend/controllers/bajas_controller.js | 1 - .../controllers/herramientas_controller.js | 30 +++- backend/controllers/prestamos_controller.js | 143 +++++++++++------- .../controllers/tipoHerramienta_controller.js | 12 +- backend/controllers/usuarios_controllers.js | 41 ++--- backend/helpers/return_error.js | 2 +- backend/routes/herramientas_routes.js | 2 +- backend/routes/prestamo_routes.js | 4 +- backend/routes/tipoHerramienta_routes.js | 2 +- backend/routes/usuarios_routes.js | 2 +- 10 files changed, 150 insertions(+), 89 deletions(-) diff --git a/backend/controllers/bajas_controller.js b/backend/controllers/bajas_controller.js index 8bcaaa0..f6d0069 100644 --- a/backend/controllers/bajas_controller.js +++ b/backend/controllers/bajas_controller.js @@ -116,7 +116,6 @@ const delete_baja = async (req, res) => { await pool.getConnection().then(async (conn) =>{ - }) } diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index c1d545a..9cd1b50 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -136,7 +136,7 @@ const put_herramienta = async (req,res)=>{ try{ const {id_herramienta, id_tipo, observaciones, origen} = req.body; - const data = [id_tipo, observaciones, origen, id_herramienta]; + const data = [ id_herramienta, id_tipo, origen, observaciones]; //validacion expresss validator const validation_error = validationResult(req); @@ -145,7 +145,7 @@ const put_herramienta = async (req,res)=>{ conn.release(); return res.status(400).json(result) } - +/* //validation tipo exists, estatus exists const validation_tipo = await conn.query("SELECT COUNT (id_tipo) as result FROM tipo_herramienta WHERE id_tipo = ?", id_tipo) @@ -153,10 +153,10 @@ const put_herramienta = async (req,res)=>{ const result = return_error(400,'El tipo de herramienta o el estatus no existe'); conn.release(); return res.status(400).json(result) - } + } */ //query - const query = await conn.query("UPDATE herramientas SET id_tipo = ?, observaciones = ?, origen = ? WHERE id_herramienta = ?",data) + const query = await conn.query("call actualizar_herramienta(?,?,?,?)",data) const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ @@ -196,7 +196,7 @@ const delete_herramienta = async (req,res)=>{ } //validation id_herramienta exists - const validation_id_herr = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?",id_herramienta) + const validation_id_herr = await conn.query("SELECT COUNT(id_herramienta) as result FROM herramientas WHERE id_herramienta = ?",id_herramienta) if(parseInt(validation_id_herr[0].result) === 0){ const result = return_error(400,'El ID de herramienta no existe'); @@ -204,6 +204,26 @@ const delete_herramienta = async (req,res)=>{ return res.status(400).json(result) } + //validation estatus == disponible + + const validation_estatus = await conn.query("SELECT id_estatus from herramientas where id_herramienta = ?", id_herramienta) + const validation_registro = await conn.query ("SELECT id_herramienta FROM prestamos where id_herramienta = ?", id_herramienta) + if(parseInt(validation_estatus[0].id_estatus) == 2){ + const result = return_error(400,'La herramienta tiene un prestamo en curso'); + conn.release(); + return res.status(400).json(result) + } + //console.log(validation_registro[0].id_herramienta) + if(validation_registro[0] !== undefined){ + + if(parseInt(validation_registro[0].id_herramienta) === parseInt(id_herramienta)){ + + const result = return_error(400,'La herramienta tiene un registro de prestamo concluido, elimine el registro antes'); + conn.release(); + return res.status(400).json(result) + } + } + //query await conn.query("DELETE FROM herramientas WHERE id_herramienta = ?", id_herramienta); res.status(200).json({ diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index 2cd1f67..afc58dd 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -9,7 +9,7 @@ const id_user_token = require('../helpers/return_id_user_token.js') const post_prestamo = async (req, res) => { await pool.getConnection().then(async (conn) => { - try{ + try { const encargado_entrega = await id_user_token(req.headers.authorization) const fecha_prestamo = fecha_hora(); const id_estatus = 1; //estatus de prestamo en curso, revisar tabla estatus_prestamo de la db @@ -28,37 +28,37 @@ const post_prestamo = async (req, res) => { //validacion id_herramienta exist const validation_id_herramienta = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?", id_herramienta) - if(parseInt(validation_id_herramienta[0].result) === 0){ - const result = return_error(400,'La herramienta no está registrada'); - conn.release(); - return res.status(400).json(result) + if (parseInt(validation_id_herramienta[0].result) === 0) { + const result = return_error(400, 'La herramienta no está registrada'); + conn.release(); + return res.status(400).json(result) } //validation herramienta disponible - const validation_herramienta_disponible = await conn.query ("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) - //console.log((validation_herramienta_activa)) - if(parseInt(validation_herramienta_disponible[0].id_estatus)!==1){ - const result = return_error(400,'La herramienta no está disponible, verifique el estatus'); - conn.release(); - return res.status(400).json(result) - } + const validation_herramienta_disponible = await conn.query("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) + //console.log((validation_herramienta_activa)) + if (parseInt(validation_herramienta_disponible[0].id_estatus) !== 1) { + const result = return_error(400, 'La herramienta no está disponible, verifique el estatus'); + conn.release(); + return res.status(400).json(result) + } //validacion carrera, id_ solicitante const validation_carrera = await conn.query("SELECT COUNT(id_carrera) as result FROM carreras WHERE id_carrera = ?", id_carrera) - if(parseInt(validation_carrera[0].result) === 0){ - const result = return_error(400,'La solicitud contiene parámetros incorrectos, se recomienda contactar al equipo de desarrollo: no se encuentra el ID de la carrera.'); - conn.release(); - return res.status(400).json(result) + if (parseInt(validation_carrera[0].result) === 0) { + const result = return_error(400, 'La solicitud contiene parámetros incorrectos, se recomienda contactar al equipo de desarrollo: no se encuentra el ID de la carrera.'); + conn.release(); + return res.status(400).json(result) } const validation_solicitante = await conn.query("SELECT COUNT (id_solicitante) as result FROM solicitantes WHERE id_solicitante = ?", id_solicitante) - if(parseInt(validation_solicitante[0].result) === 0){ - const result = return_error(400,'El no se encuentra el solicitante. Compruebe si el solicitante está registrado en el sistema'); - conn.release(); - return res.status(400).json(result) + if (parseInt(validation_solicitante[0].result) === 0) { + const result = return_error(400, 'El no se encuentra el solicitante. Compruebe si el solicitante está registrado en el sistema'); + conn.release(); + return res.status(400).json(result) } @@ -68,20 +68,20 @@ const post_prestamo = async (req, res) => { //const insert_id = parseInt(query[0].insertId) res.status(201).json({ "ok": true, - "message": { + "message": { "code": 201, "messageText": "Prestamo registrado con éxito" - } + } }) conn.release(); } - catch(error){ + catch (error) { - const result = return_error(500,'Internal server error'); - console.log (error) - conn.release(); - res.status(500).json(result) + const result = return_error(500, 'Internal server error'); + console.log(error) + conn.release(); + res.status(500).json(result) } @@ -91,72 +91,104 @@ const post_prestamo = async (req, res) => { } const get_prestamos_activos = async (req, res) => ( - await pool.getConnection().then (async (conn) => { + await pool.getConnection().then(async (conn) => { - try{ + try { //query const query = await conn.query("CALL consultar_prestamo_activos()"); //console.log(query[0]) res.status(200).json(query[0]) - conn.release(); + conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) } - }) + }) ) const get_prestamos = async (req, res) => ( - await pool.getConnection().then (async (conn) => { + await pool.getConnection().then(async (conn) => { - try{ + try { //query const query = await conn.query("CALL consultar_prestamos()"); //console.log(query[0]) res.status(200).json(query[0]) - conn.release(); + conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) - console.log (error) + console.log(error) } - }) + }) ) const get_prestamos_concluidos = async (req, res) => ( - await pool.getConnection().then (async (conn) => { + await pool.getConnection().then(async (conn) => { - try{ + try { //query const query = await conn.query("CALL consultar_prestamos_concluidos()"); //console.log(query[0]) res.status(200).json(query[0]) - conn.release(); + conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) - console.log (error) + console.log(error) } - }) + }) ) -const put_prestamo_devuelto = async (req,res)=>{ - pool.getConnection().then(async(conn) => { +const put_prestamo_devuelto = async (req, res) => { + pool.getConnection().then(async (conn) => { + try { + + const { id_prestamo } = req.body + const usuario_recibe = await id_user_token(req.headers.authorization) + const fecha_devolucion = fecha_hora(); + + const data = [id_prestamo, usuario_recibe, fecha_devolucion] + + //validacion expresss validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato o extensión incorrecta'); + conn.release(); + return res.status(400).json(result) + } + + await conn.query("CALL prestamo_devuelto (?,?,?)", data) + + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Préstamo concluido exitosamente" + } + }) + + conn.release(); + } catch (error) { + + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } - const usuario_recibe = await id_user_token(req.headers.authorization) - }) } @@ -164,5 +196,6 @@ module.exports = { post_prestamo, get_prestamos, get_prestamos_activos, - get_prestamos_concluidos + get_prestamos_concluidos, + put_prestamo_devuelto } \ No newline at end of file diff --git a/backend/controllers/tipoHerramienta_controller.js b/backend/controllers/tipoHerramienta_controller.js index 7a2104e..f9dac37 100644 --- a/backend/controllers/tipoHerramienta_controller.js +++ b/backend/controllers/tipoHerramienta_controller.js @@ -51,7 +51,7 @@ const get_tipoHerramienta = async (req, res) => { try { //query - const query = await conn.query("SELECT * FROM tipo_herramienta"); + const query = await conn.query("SELECT * FROM tipo_herramienta ORDER BY nombre_tipo ASC"); res.status(200).json(query) conn.release(); @@ -95,7 +95,7 @@ const put_tipoHerramienta = async (req, res) => { try { const { id_tipo, nombre_tipo, descripcion } = req.body - const data = [nombre_tipo, descripcion, id_tipo] + const data = [id_tipo, nombre_tipo, descripcion ] //validation error express validator const validation_error = validationResult(req); @@ -115,12 +115,12 @@ const put_tipoHerramienta = async (req, res) => { } //query - await conn.query("UPDATE tipo_herramienta SET nombre_tipo = ?, descripcion = ? WHERE id_tipo = ?", data); + await conn.query("call actualizar_tipo_herramienta(?,?,?)", data); res.status(201).json({ "ok": true, "message": { "code": 200, - "messageText": "Tipo de herramienta actualizado con éxito" + "messageText": "Tipo actualizado con éxito" } }) conn.release(); @@ -161,7 +161,7 @@ const delete_tipoHerramienta = async (req, res) => { //validation: no hay herramientas de ese tipo - const validation_herramientas = await conn.query("SELECT COUNT (tipo) as result FROM herramientas WHERE tipo = ?", id_tipo) + const validation_herramientas = await conn.query("SELECT COUNT (id_tipo) as result FROM herramientas WHERE id_tipo = ?", id_tipo) if (parseInt(validation_herramientas[0].result) !== 0) { const result = return_error(400, 'Aún hay herramientas registradas con ese tipo'); conn.release(); @@ -185,7 +185,7 @@ const delete_tipoHerramienta = async (req, res) => { const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) - //console.log(error) + console.log(error) } }) diff --git a/backend/controllers/usuarios_controllers.js b/backend/controllers/usuarios_controllers.js index 871b557..ea9f4d5 100644 --- a/backend/controllers/usuarios_controllers.js +++ b/backend/controllers/usuarios_controllers.js @@ -127,28 +127,28 @@ const put_usuario = async (req, res) => { } -const put_usuario_password = async(req, res) =>{ - pool.getConnection().then(async (conn)=>{ +const put_usuario_password = async (req, res) => { + pool.getConnection().then(async (conn) => { try { - const {id_usuario, password} = req.body - const pass_encrypt = await encrypt(password); - const data = [pass_encrypt, id_usuario] + const { id_usuario, password } = req.body + const pass_encrypt = await encrypt(password); + const data = [pass_encrypt, id_usuario] + + await conn.query("UPDATE usuarios SET password = ? WHERE id_usuario = ?", data) + res.status(201).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Password actualizado con éxito" + } + }) + conn.release(); + - await conn.query("UPDATE usuarios SET password = ? WHERE id_usuario = ?", data) - res.status(201).json({ - "ok": true, - "message": { - "code": 200, - "messageText": "Password actualizado con éxito" - } - }) - conn.release(); - - } catch (error) { - + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) @@ -157,6 +157,13 @@ const put_usuario_password = async(req, res) =>{ }) } +const put_user_estatus = async (req, res) => { + pool.getConnection().then(async (conn) => { + + }) +} + + module.exports = { post_usuario, get_usuarios, diff --git a/backend/helpers/return_error.js b/backend/helpers/return_error.js index 999f023..248e289 100644 --- a/backend/helpers/return_error.js +++ b/backend/helpers/return_error.js @@ -1,4 +1,4 @@ -const return_error = (codigo, mensaje) => { +const return_error = (codigo, mensaje) => { return { 'ok': false, 'message': { diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index f3e87d9..bba941a 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -13,7 +13,7 @@ router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asisten router.get('/tipo/:id_tipo',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), param('id_tipo').isNumeric(), get_herramienta_por_tipo); -router.put('/',check_token,check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(),body('id_estatus').isNumeric(),body('observaciones').isLength({max: 255}), put_herramienta); +router.put('/',check_token,check_rol(['Administrador', 'Laboratorista']), body('id_herramienta').isNumeric(), put_herramienta); router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index 47fb5bf..f346916 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -4,7 +4,7 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") -const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos} = require('../controllers/prestamos_controller.js'); +const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos, put_prestamo_devuelto} = require('../controllers/prestamos_controller.js'); router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), body(['id_herramienta', 'id_carrera', 'id_solicitante']).isNumeric(), @@ -16,4 +16,6 @@ router.get('/prestamos_concluidos',check_token,check_rol(['Administrador', 'Labo router.post('/',check_token,check_rol(['Administrador', 'Laboratorista','Asistente ']), post_prestamo) +router.put('/devolver_prestamo',check_token,check_rol(['Administrador', 'Laboratorista','Asistente ']), put_prestamo_devuelto) + module.exports = router \ No newline at end of file diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js index 1960092..0a88ef4 100644 --- a/backend/routes/tipoHerramienta_routes.js +++ b/backend/routes/tipoHerramienta_routes.js @@ -12,7 +12,7 @@ router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asisten router.get('/tipos_mas_herramientas' ,check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_items_disp_por_tipo) -router.put('/' ,check_token,check_rol(['Administrador', 'Laboratorista']), body('nombre_tipo').isLength({min:1, max:35}),body('descripcion').isLength({max:255}), put_tipoHerramienta); +router.put('/' ,check_token,check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(), put_tipoHerramienta); router.delete('/:id_tipo',check_token,check_rol(['Administrador', 'Laboratorista']), param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ diff --git a/backend/routes/usuarios_routes.js b/backend/routes/usuarios_routes.js index 1e13ac5..004b6dc 100644 --- a/backend/routes/usuarios_routes.js +++ b/backend/routes/usuarios_routes.js @@ -7,7 +7,7 @@ const { body, param } = require("express-validator"); const {post_usuario, get_usuarios, put_usuario, put_usuario_password} = require('../controllers/usuarios_controllers.js') -router.post('/', body('id_rol').isNumeric(), +router.post('/',check_token,check_rol(['Administrador']), body('id_rol').isNumeric(), body(['nombre_usuario', 'apellido_paterno']).isLength({min:3, max: 45}).withMessage('El nombre y el apellido deben tener mínimo 3 caracteres y máximo 45'), body('nombre_login').isLength({min: 3, max:20}).withMessage('El nombre de usuario debe ser de mínimo 3 caracteres y máximo de 20'), body('password').isLength({min:5, max:60}).withMessage('El password debe tener al menos 5 caracteres y máximo 60'), body('estatus_activo').isNumeric({min:0, max:1}), From 0356dfb4a9fff53953b7c92ce00d36b765baa8e3 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sat, 8 Jun 2024 23:12:32 -0600 Subject: [PATCH 14/57] -> --- .../controllers/herramientas_controller.js | 4 +- backend/controllers/usuarios_controllers.js | 56 +++++++++++++++++-- backend/routes/usuarios_routes.js | 12 ++-- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/backend/controllers/herramientas_controller.js b/backend/controllers/herramientas_controller.js index 9cd1b50..c44a6eb 100644 --- a/backend/controllers/herramientas_controller.js +++ b/backend/controllers/herramientas_controller.js @@ -135,8 +135,8 @@ const put_herramienta = async (req,res)=>{ await pool.getConnection().then(async (conn) => { try{ - const {id_herramienta, id_tipo, observaciones, origen} = req.body; - const data = [ id_herramienta, id_tipo, origen, observaciones]; + const {id_herramienta, id_tipo, observaciones, id_origen} = req.body; + const data = [ id_herramienta, id_tipo, id_origen, observaciones]; //validacion expresss validator const validation_error = validationResult(req); diff --git a/backend/controllers/usuarios_controllers.js b/backend/controllers/usuarios_controllers.js index ea9f4d5..2e93684 100644 --- a/backend/controllers/usuarios_controllers.js +++ b/backend/controllers/usuarios_controllers.js @@ -3,6 +3,7 @@ const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); const { encrypt } = require('../helpers/handle_bcrybpt.js') const return_error = require('../helpers/return_error.js') +const id_user_token = require('../helpers/return_id_user_token.js') const post_usuario = async (req, res) => { @@ -82,8 +83,8 @@ const put_usuario = async (req, res) => { pool.getConnection().then(async (conn) => { try { - const { id_usuario, id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, estatus_activo } = req.body - const data = [id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, estatus_activo, id_usuario] + const { id_usuario, id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login } = req.body + const data = [id_rol, nombre_usuario, apellido_paterno, apellido_materno, nombre_login, id_usuario] //validation error express validator const validation_error = validationResult(req); @@ -105,7 +106,7 @@ const put_usuario = async (req, res) => { //query - await conn.query("UPDATE usuarios SET id_rol = ?, nombre_usuario = ?, apellido_paterno = ?, apellido_materno = ?, nombre_login = ?, estatus_activo = ? WHERE id_usuario = ?", data); + await conn.query("UPDATE usuarios SET id_rol = ?, nombre_usuario = ?, apellido_paterno = ?, apellido_materno = ?, nombre_login = ? WHERE id_usuario = ?", data); res.status(201).json({ "ok": true, "message": { @@ -136,6 +137,14 @@ const put_usuario_password = async (req, res) => { const pass_encrypt = await encrypt(password); const data = [pass_encrypt, id_usuario] + //validation error express validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato incorrecto, ingrese mínimo 5 caracteres'); + conn.release(); + return res.status(400).json(result) + } + await conn.query("UPDATE usuarios SET password = ? WHERE id_usuario = ?", data) res.status(201).json({ "ok": true, @@ -159,7 +168,43 @@ const put_usuario_password = async (req, res) => { const put_user_estatus = async (req, res) => { pool.getConnection().then(async (conn) => { - + try { + const { id_usuario } = req.body + const data = id_usuario; + const usuario_actual = await id_user_token(req.headers.authorization) + + + //validation error express validator + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato incorrecto'); + conn.release(); + return res.status(400).json(result) + } + + if (parseInt(id_usuario) === parseInt(usuario_actual)) { + + const result = return_error(400, 'No puede desactivarse a sí mismo'); + conn.release(); + return res.status(400).json(result) + } + + await conn.query("call cambiar_estatus_user(?)", data) + res.status(201).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Actualizado con éxito" + } + }) + conn.release(); + + } catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } }) } @@ -168,6 +213,7 @@ module.exports = { post_usuario, get_usuarios, put_usuario, - put_usuario_password + put_usuario_password, + put_user_estatus } diff --git a/backend/routes/usuarios_routes.js b/backend/routes/usuarios_routes.js index 004b6dc..16eea1b 100644 --- a/backend/routes/usuarios_routes.js +++ b/backend/routes/usuarios_routes.js @@ -5,7 +5,7 @@ const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator"); -const {post_usuario, get_usuarios, put_usuario, put_usuario_password} = require('../controllers/usuarios_controllers.js') +const {post_usuario, get_usuarios, put_usuario, put_usuario_password, put_user_estatus} = require('../controllers/usuarios_controllers.js') router.post('/',check_token,check_rol(['Administrador']), body('id_rol').isNumeric(), body(['nombre_usuario', 'apellido_paterno']).isLength({min:3, max: 45}).withMessage('El nombre y el apellido deben tener mínimo 3 caracteres y máximo 45'), @@ -14,10 +14,14 @@ body('password').isLength({min:5, max:60}).withMessage('El password debe tener a post_usuario) -router.get('/',check_token,check_rol(['Administrador']), get_usuarios ) +router.get('/',check_token,check_rol(['Administrador']),get_usuarios ) -router.put('/',check_token,check_rol(['Administrador']),put_usuario) +router.put('/',check_token,check_rol(['Administrador']),body('id_rol').isNumeric(), +body(['nombre_usuario', 'apellido_paterno']).isLength({min:3, max: 45}).withMessage('El nombre y el apellido deben tener mínimo 3 caracteres y máximo 45'), +body('nombre_login').isLength({min: 3, max:20}).withMessage('El nombre de usuario debe ser de mínimo 3 caracteres y máximo de 20'), put_usuario) + +router.put ('/rec_pass',check_token,check_rol(['Administrador']),body('password').isLength({min: 5, max:60}), put_usuario_password) -router.put ('/rec_pass',check_token,check_rol(['Administrador']), put_usuario_password) +router.put ('/estatus_activo',check_token,check_rol(['Administrador']), put_user_estatus) module.exports = router \ No newline at end of file From 6f3282b3384bd1c404ac947fba3eddfc982d3347 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Sun, 9 Jun 2024 18:45:02 -0600 Subject: [PATCH 15/57] avance --- backend/.env | 2 +- backend/controllers/bajas_controller.js | 162 ++++++++++++++------ backend/controllers/prestamos_controller.js | 5 +- backend/helpers/generate_token.js | 2 +- backend/middlewares/check_token.js | 2 +- backend/routes/bajas_routes.js | 6 +- 6 files changed, 122 insertions(+), 57 deletions(-) diff --git a/backend/.env b/backend/.env index 2b82cad..44d1af9 100644 --- a/backend/.env +++ b/backend/.env @@ -1,4 +1,4 @@ - NODE_PORT="3001" +NODE_PORT="3001" HOST="localhost" PORT="3306" USER="root" diff --git a/backend/controllers/bajas_controller.js b/backend/controllers/bajas_controller.js index f6d0069..38b6b0c 100644 --- a/backend/controllers/bajas_controller.js +++ b/backend/controllers/bajas_controller.js @@ -3,118 +3,177 @@ const pool = require('../config/database.js'); const { validationResult } = require('express-validator'); const return_error = require('../helpers/return_error.js'); const fecha_hora = require('../helpers/return_date.js') -const id_user_token = require ('../helpers/return_id_user_token.js') +const id_user_token = require('../helpers/return_id_user_token.js') const post_baja = async (req, res) => { - await pool.getConnection().then(async (conn) =>{ + await pool.getConnection().then(async (conn) => { + + try { - try{ - const id_user = await id_user_token(req.headers.authorization) const fecha_baja = fecha_hora(); - const {id_herramienta, id_motivo, observaciones} = req.body + const { id_herramienta, id_motivo, observaciones } = req.body const data = [id_herramienta, id_motivo, id_user, fecha_baja, observaciones] //validacion expresss validator - const validation_error = validationResult(req); - if(!validation_error.isEmpty()){ - const result = return_error(400,'Datos con formato o extensión incorrecta'); - conn.release(); - return res.status(400).json(result) + const validation_error = validationResult(req); + if (!validation_error.isEmpty()) { + const result = return_error(400, 'Datos con formato o extensión incorrecta'); + conn.release(); + return res.status(400).json(result) } //validacion id_herramienta exist const validation_id_herramienta = await conn.query("SELECT COUNT (id_herramienta) as result FROM herramientas WHERE id_herramienta = ?", id_herramienta) - if(parseInt(validation_id_herramienta[0].result) === 0){ - const result = return_error(400,'La herramienta no está registrada'); - conn.release(); - return res.status(400).json(result) + if (parseInt(validation_id_herramienta[0].result) === 0) { + const result = return_error(400, 'La herramienta no está registrada'); + conn.release(); + return res.status(400).json(result) } //validation user exist const validation_user = await conn.query("SELECT COUNT (id_usuario) as result FROM usuarios WHERE id_usuario = ?", id_user) - - if(parseInt(validation_user[0].result) === 0){ - const result = return_error(400,'Error al ingresar el id de usuario, internal server error'); - conn.release(); - return res.status(400).json(result) + + if (parseInt(validation_user[0].result) === 0) { + const result = return_error(400, 'Error al ingresar el id de usuario, internal server error'); + conn.release(); + return res.status(400).json(result) } //validation motivo exist const validation_motivo = await conn.query("SELECT COUNT (id_usuario) as result FROM usuarios WHERE id_usuario = ?", id_user) - - if(parseInt(validation_motivo[0].result) === 0){ - const result = return_error(400,'La solicitud contiene un motivo inexistente, es recomendable contactar al equipo de desarrollo'); - conn.release(); - return res.status(400).json(result) + + if (parseInt(validation_motivo[0].result) === 0) { + const result = return_error(400, 'La solicitud contiene un motivo inexistente, es recomendable contactar al equipo de desarrollo'); + conn.release(); + return res.status(400).json(result) } - //validacion herramienta activa + //validacion herramienta activa + + const validation_herramienta_activa = await conn.query("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) + //console.log((validation_herramienta_activa)) + if (parseInt(validation_herramienta_activa[0].id_estatus) === 3) { + const result = return_error(400, 'La herramienta ya está en estatus de baja'); + conn.release(); + return res.status(400).json(result) + } + + if (parseInt(validation_herramienta_activa[0].id_estatus) === 2) { + const result = return_error(400, 'No realizado, herramienta tiene un préstamo en curso'); + conn.release(); + return res.status(400).json(result) + } - const validation_herramienta_activa = await conn.query ("SELECT id_estatus FROM herramientas WHERE id_herramienta = ?", id_herramienta) - //console.log((validation_herramienta_activa)) - if(parseInt(validation_herramienta_activa[0].id_estatus)===3){ - const result = return_error(400,'La herramienta ya está en estatus de baja'); - conn.release(); - return res.status(400).json(result) - } //QUERY - const query = await conn.query("CALL registrar_baja (?,?,?,?,?)",data) + const query = await conn.query("CALL registrar_baja (?,?,?,?,?)", data) //const insert_id = parseInt(query.insertId) //res estatus res.status(201).json({ "ok": true, - "message": { + "message": { "code": 201, "messageText": "Baja realizada con éxito" - } + } }) conn.release(); - }catch(error){ - - const result = return_error(500,'Internal server error'); - conn.release(); - res.status(500).json(result) - console.log(error) + } catch (error) { + + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) } - + }) } const get_bajas = async (req, res) => { - await pool.getConnection().then(async (conn) =>{ + await pool.getConnection().then(async (conn) => { - try{ + try { //query const query = await conn.query("CALL consultar_bajas()"); //console.log(query[0]) res.status(200).json(query[0]) - conn.release(); + conn.release(); } - - catch(error){ - const result = return_error(500,'Internal server error'); + + catch (error) { + const result = return_error(500, 'Internal server error'); conn.release(); res.status(500).json(result) - console.log (error) + console.log(error) } - + }) } //no put +const delete_clear_bajas = async (req, res) => { + await pool.getConnection().then(async (conn) => { + + try { + + //query + await conn.query("CALL clear_bajas()"); + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Registros eliminados con éxito" + } + }) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + + + + }) +} const delete_baja = async (req, res) => { - await pool.getConnection().then(async (conn) =>{ + await pool.getConnection().then(async (conn) => { + try { + + const id_baja = req.params.id_baja + + //query + await conn.query("CALL delete_baja(?)", id_baja); + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Registro eliminado con éxito" + } + }) + conn.release(); + + } + + catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } }) } @@ -123,5 +182,6 @@ const delete_baja = async (req, res) => { module.exports = { post_baja, get_bajas, + delete_clear_bajas, delete_baja } \ No newline at end of file diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index afc58dd..663f742 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -96,7 +96,7 @@ const get_prestamos_activos = async (req, res) => ( try { //query - const query = await conn.query("CALL consultar_prestamo_activos()"); + const query = await conn.query("CALL consultar_prestamos_activos()"); //console.log(query[0]) res.status(200).json(query[0]) conn.release(); @@ -192,6 +192,9 @@ const put_prestamo_devuelto = async (req, res) => { }) } + +/* Delete solo prestamos concluidos */ + module.exports = { post_prestamo, get_prestamos, diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index 12a4e60..a1ebc37 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -9,7 +9,7 @@ const token_sign = async (user, rol) =>{ }, process.env.JWT_SECRET, { - expiresIn: "1h" + expiresIn: "3h" } ) } diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 2da8b04..6603583 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -16,7 +16,7 @@ const check_token = async (req, res, next) => { if (token_data === "Token has expired") { - const result = return_error(401, `${token_data}: La sesión ha expirado`); + const result = return_error(401, `La sesión ha expirado, reinice la sesión`); res.status(401).json(result) } diff --git a/backend/routes/bajas_routes.js b/backend/routes/bajas_routes.js index 774f002..9bd0493 100644 --- a/backend/routes/bajas_routes.js +++ b/backend/routes/bajas_routes.js @@ -5,13 +5,15 @@ const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") -const { post_baja, get_bajas, delete_baja} = require('../controllers/bajas_controller.js'); +const { post_baja, get_bajas, delete_clear_bajas, delete_baja} = require('../controllers/bajas_controller.js'); //const { route } = require('./herramientas_routes.js'); router.post('/',check_token,check_rol(['Administrador', 'Laboratorista']), body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']),get_bajas) -/*router.delete()*/ +router.delete('/clear_bajas/all', check_token,check_rol(['Administrador', 'Laboratorista']),delete_clear_bajas) + +router.delete('/:id_baja', check_token,check_rol(['Administrador', 'Laboratorista']),param('id_baja').isNumeric(),delete_baja) module.exports = router From 6cd82948b4baa06e046153d168b3de57ae07079e Mon Sep 17 00:00:00 2001 From: JUrielC Date: Tue, 11 Jun 2024 01:48:11 -0600 Subject: [PATCH 16/57] solucionado: asistente no podia hacer prestamos --- backend/app.js | 20 ++++++++++--------- .../controllers/solicitantes_controller.js | 11 ++++++++++ backend/middlewares/check_rol.js | 2 +- backend/middlewares/check_token.js | 2 +- backend/routes/herramientas_routes.js | 2 +- backend/routes/prestamo_routes.js | 4 ++-- 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/backend/app.js b/backend/app.js index 874cad8..d7a11bb 100644 --- a/backend/app.js +++ b/backend/app.js @@ -2,13 +2,21 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); -app.use(cors()); +/* app.use(cors()); */ app.listen(process.env.NODE_PORT, () => { console.log('server running '+ process.env.NODE_PORT); }); +app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); + next(); +}) + app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) @@ -21,14 +29,8 @@ app.use('/solicitantes', require('./routes/solicitantes_routes')) app.use('/carreras', require('./routes/carreras_routes')) -/*app.use((req, res, next) => { - res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); - res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); - res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); - next(); -}) -*/ + + /*NODE_PORT="3000" HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" diff --git a/backend/controllers/solicitantes_controller.js b/backend/controllers/solicitantes_controller.js index eeeec1d..09b8dcd 100644 --- a/backend/controllers/solicitantes_controller.js +++ b/backend/controllers/solicitantes_controller.js @@ -24,6 +24,17 @@ const get_solicitantes = async(req, res)=>{ }) } +/* const delete_solicitante = async(req, res)=>{ + pool.getConnection().then(async(conn)=>{ + + const id_solicitante = req.id_param.id_solicitante + + await conn.query ("DELETE FROM solicitantes WHERE id_solicitante = ?", id_solicitante) + + + + }) +} */ module.exports ={ get_solicitantes diff --git a/backend/middlewares/check_rol.js b/backend/middlewares/check_rol.js index 2a1cc82..17bd1bd 100644 --- a/backend/middlewares/check_rol.js +++ b/backend/middlewares/check_rol.js @@ -17,7 +17,7 @@ const check_rol = (rol) => async (req, res, next)=>{ } else{ conn.release(); - const result = return_error(403,'Acceso denegado: no hay permisos suficientes'); + const result = return_error(403,'Acceso denegado!!'); res.status(403).json(result) } } diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 6603583..915e3db 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -22,7 +22,7 @@ const check_token = async (req, res, next) => { } else { - const result = return_error(403, 'Acceso denegado: no hay permisos suficientes'); + const result = return_error(403, 'No realizado: Acceso denegado'); res.status(403).json(result) } diff --git a/backend/routes/herramientas_routes.js b/backend/routes/herramientas_routes.js index bba941a..99413d5 100644 --- a/backend/routes/herramientas_routes.js +++ b/backend/routes/herramientas_routes.js @@ -15,6 +15,6 @@ router.get('/tipo/:id_tipo',check_token,check_rol(['Administrador', 'Laboratoris router.put('/',check_token,check_rol(['Administrador', 'Laboratorista']), body('id_herramienta').isNumeric(), put_herramienta); -router.delete('/:id_herramienta', param('id_herramienta').isNumeric(), delete_herramienta); +router.delete('/:id_herramienta',check_token,check_rol(['Administrador', 'Laboratorista']), param('id_herramienta').isNumeric(), delete_herramienta); module.exports = router \ No newline at end of file diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index f346916..3b5b390 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -14,8 +14,8 @@ router.get('/prestamos_activos',check_token,check_rol(['Administrador', 'Laborat router.get('/prestamos_concluidos',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_prestamos_concluidos) -router.post('/',check_token,check_rol(['Administrador', 'Laboratorista','Asistente ']), post_prestamo) +router.post('/',check_token,check_rol(['Administrador', 'Laboratorista','Asistente']), post_prestamo) -router.put('/devolver_prestamo',check_token,check_rol(['Administrador', 'Laboratorista','Asistente ']), put_prestamo_devuelto) +router.put('/devolver_prestamo',check_token,check_rol(['Administrador', 'Laboratorista','Asistente']), put_prestamo_devuelto) module.exports = router \ No newline at end of file From ea410afcfd3f486b3f796612681beb0b18a86de6 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 17:44:02 -0600 Subject: [PATCH 17/57] config para vercel --- backend/.env | 26 ++++++------ backend/controllers/prestamos_controller.js | 44 +++++++++++++++------ backend/helpers/generate_token.js | 2 +- backend/{app.js => index.js} | 0 backend/routes/bajas_routes.js | 8 ++-- backend/routes/prestamo_routes.js | 5 ++- backend/routes/tipoHerramienta_routes.js | 4 +- backend/routes/usuarios_routes.js | 1 - vercel.json | 12 ++++++ 9 files changed, 67 insertions(+), 35 deletions(-) rename backend/{app.js => index.js} (100%) create mode 100644 vercel.json diff --git a/backend/.env b/backend/.env index 44d1af9..d4a436a 100644 --- a/backend/.env +++ b/backend/.env @@ -1,15 +1,15 @@ +# NODE_PORT="3001" +# HOST="localhost" +# PORT="3306" +# USER="root" +# PASSWORD="root" +# DATABASE="dbsistemas" +# JWT_SECRET = "589696852" + NODE_PORT="3001" -HOST="localhost" +HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" PORT="3306" -USER="root" -PASSWORD="root" -DATABASE="dbsistemas" -JWT_SECRET = "589696852" - -#NODE_PORT="3001" -#HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" -#PORT="3306" -#USER="ugpwh5vn4olvh15t" -#PASSWORD="DHGMBoPlzbo6Q9rFxHRW" -#DATABASE="bqvpx1qe8f1g2jhxyxjj" -#JWT_SECRET = "589696852" \ No newline at end of file +USER="ugpwh5vn4olvh15t" +PASSWORD="K791zFWMmQibYVYBuF4r" +DATABASE="bqvpx1qe8f1g2jhxyxjj" +JWT_SECRET = "589696852" \ No newline at end of file diff --git a/backend/controllers/prestamos_controller.js b/backend/controllers/prestamos_controller.js index 663f742..450ddb0 100644 --- a/backend/controllers/prestamos_controller.js +++ b/backend/controllers/prestamos_controller.js @@ -13,8 +13,8 @@ const post_prestamo = async (req, res) => { const encargado_entrega = await id_user_token(req.headers.authorization) const fecha_prestamo = fecha_hora(); const id_estatus = 1; //estatus de prestamo en curso, revisar tabla estatus_prestamo de la db - const { id_herramienta, id_carrera, id_solicitante, observaciones } = req.body - const data = [encargado_entrega, id_herramienta, id_carrera, id_estatus, id_solicitante, fecha_prestamo, observaciones] + const { id_herramienta, id_solicitante, observaciones } = req.body + const data = [encargado_entrega, id_herramienta, id_estatus, id_solicitante, fecha_prestamo, observaciones] //validacion expresss validator const validation_error = validationResult(req); @@ -43,15 +43,6 @@ const post_prestamo = async (req, res) => { return res.status(400).json(result) } - //validacion carrera, id_ solicitante - const validation_carrera = await conn.query("SELECT COUNT(id_carrera) as result FROM carreras WHERE id_carrera = ?", id_carrera) - - - if (parseInt(validation_carrera[0].result) === 0) { - const result = return_error(400, 'La solicitud contiene parámetros incorrectos, se recomienda contactar al equipo de desarrollo: no se encuentra el ID de la carrera.'); - conn.release(); - return res.status(400).json(result) - } const validation_solicitante = await conn.query("SELECT COUNT (id_solicitante) as result FROM solicitantes WHERE id_solicitante = ?", id_solicitante) @@ -63,7 +54,7 @@ const post_prestamo = async (req, res) => { //QUERY - const query = await conn.query("CALL registrar_prestamo (?,?,?,?,?,?,?)", data) + const query = await conn.query("CALL registrar_prestamo (?,?,?,?,?,?)", data) //console.log(query) //const insert_id = parseInt(query[0].insertId) res.status(201).json({ @@ -195,10 +186,37 @@ const put_prestamo_devuelto = async (req, res) => { /* Delete solo prestamos concluidos */ +const delete_prestamos_concluidos = async (req, res) => { + pool.getConnection().then(async (conn) => { + try { + + await conn.query("DELETE FROM prestamos where id_estatus = 2") + + res.status(200).json({ + "ok": true, + "message": { + "code": 200, + "messageText": "Historial eliminado exitosamente" + } + }) + conn.release(); + + } catch (error) { + const result = return_error(500, 'Internal server error'); + conn.release(); + res.status(500).json(result) + console.log(error) + } + + + }) +} + module.exports = { post_prestamo, get_prestamos, get_prestamos_activos, get_prestamos_concluidos, - put_prestamo_devuelto + put_prestamo_devuelto, + delete_prestamos_concluidos } \ No newline at end of file diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index a1ebc37..a98f99a 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -21,7 +21,7 @@ const verify_token = async (token) => { } catch (error) { if (error instanceof jwt.TokenExpiredError) { - console.log("Token has expired"); + //console.log("Token has expired"); return "Token has expired"; } else { return null; diff --git a/backend/app.js b/backend/index.js similarity index 100% rename from backend/app.js rename to backend/index.js diff --git a/backend/routes/bajas_routes.js b/backend/routes/bajas_routes.js index 9bd0493..d81a50c 100644 --- a/backend/routes/bajas_routes.js +++ b/backend/routes/bajas_routes.js @@ -8,12 +8,12 @@ const { body, param } = require("express-validator") const { post_baja, get_bajas, delete_clear_bajas, delete_baja} = require('../controllers/bajas_controller.js'); //const { route } = require('./herramientas_routes.js'); -router.post('/',check_token,check_rol(['Administrador', 'Laboratorista']), body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) +router.post('/',check_token,check_rol(['Administrador']), body(['id_herramienta', 'id_motivo']).isNumeric(), body('observaciones').isLength({max: 255}), post_baja) -router.get('/',check_token,check_rol(['Administrador', 'Laboratorista']),get_bajas) +router.get('/',check_token,check_rol(['Administrador']),get_bajas) -router.delete('/clear_bajas/all', check_token,check_rol(['Administrador', 'Laboratorista']),delete_clear_bajas) +router.delete('/clear_bajas/all', check_token,check_rol(['Administrador']),delete_clear_bajas) -router.delete('/:id_baja', check_token,check_rol(['Administrador', 'Laboratorista']),param('id_baja').isNumeric(),delete_baja) +router.delete('/:id_baja', check_token,check_rol(['Administrador']),param('id_baja').isNumeric(),delete_baja) module.exports = router diff --git a/backend/routes/prestamo_routes.js b/backend/routes/prestamo_routes.js index 3b5b390..0fabdd5 100644 --- a/backend/routes/prestamo_routes.js +++ b/backend/routes/prestamo_routes.js @@ -4,7 +4,8 @@ const {check_token} = require('../middlewares/check_token.js') const {check_rol} = require('../middlewares/check_rol.js') const { body, param } = require("express-validator") -const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos, put_prestamo_devuelto} = require('../controllers/prestamos_controller.js'); +const { post_prestamo, get_prestamos_activos, get_prestamos_concluidos, get_prestamos, put_prestamo_devuelto, delete_prestamos_concluidos} = require('../controllers/prestamos_controller.js'); +const { route } = require('./tipoHerramienta_routes.js'); router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), body(['id_herramienta', 'id_carrera', 'id_solicitante']).isNumeric(), @@ -18,4 +19,6 @@ router.post('/',check_token,check_rol(['Administrador', 'Laboratorista','Asisten router.put('/devolver_prestamo',check_token,check_rol(['Administrador', 'Laboratorista','Asistente']), put_prestamo_devuelto) +router.delete('/concluidos/delete_all',check_token,check_rol(['Administrador']), delete_prestamos_concluidos) + module.exports = router \ No newline at end of file diff --git a/backend/routes/tipoHerramienta_routes.js b/backend/routes/tipoHerramienta_routes.js index 0a88ef4..55c69a4 100644 --- a/backend/routes/tipoHerramienta_routes.js +++ b/backend/routes/tipoHerramienta_routes.js @@ -12,8 +12,8 @@ router.get('/',check_token,check_rol(['Administrador', 'Laboratorista', 'Asisten router.get('/tipos_mas_herramientas' ,check_token,check_rol(['Administrador', 'Laboratorista', 'Asistente']), get_items_disp_por_tipo) -router.put('/' ,check_token,check_rol(['Administrador', 'Laboratorista']), body('id_tipo').isNumeric(), put_tipoHerramienta); +router.put('/' ,check_token,check_rol(['Administrador']), body('id_tipo').isNumeric(), put_tipoHerramienta); -router.delete('/:id_tipo',check_token,check_rol(['Administrador', 'Laboratorista']), param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ +router.delete('/:id_tipo',check_token,check_rol(['Administrador']), param('id_tipo').isNumeric(), delete_tipoHerramienta); /**/ module.exports = router \ No newline at end of file diff --git a/backend/routes/usuarios_routes.js b/backend/routes/usuarios_routes.js index 16eea1b..4b0480b 100644 --- a/backend/routes/usuarios_routes.js +++ b/backend/routes/usuarios_routes.js @@ -13,7 +13,6 @@ body('nombre_login').isLength({min: 3, max:20}).withMessage('El nombre de usuari body('password').isLength({min:5, max:60}).withMessage('El password debe tener al menos 5 caracteres y máximo 60'), body('estatus_activo').isNumeric({min:0, max:1}), post_usuario) - router.get('/',check_token,check_rol(['Administrador']),get_usuarios ) router.put('/',check_token,check_rol(['Administrador']),body('id_rol').isNumeric(), diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..3437cd1 --- /dev/null +++ b/vercel.json @@ -0,0 +1,12 @@ +{ + "builds":[ + { + "src": "./index.js", + "use": "@vercel-node" + } + ], + "routes":{ + "src": "/(.*)", + "dest": "/" + } +} \ No newline at end of file From e35a716dad91d0ce2dde6ad2070c6147ff9ceb54 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:13:54 -0600 Subject: [PATCH 18/57] a --- package-lock.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package-lock.json b/package-lock.json index 65f50ab..86834a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,9 @@ "version": "1.0.0", "lockfileVersion": 3, "requires": true, + "scripts": { + "start": "node backend/index.js" + }, "packages": { "": { "name": "pjctinvlabsis", From 75b6f317f528e1bca8bf960dc370afba779590b4 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:28:52 -0600 Subject: [PATCH 19/57] . --- backend/config/config.php | 0 backend/config/database.php | 0 backend/includes/db_connection.php | 0 backend/includes/functions.php | 0 backend/index.php | 0 backend/routes/web.php | 0 frontend/index.html | 0 7 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 backend/config/config.php delete mode 100644 backend/config/database.php delete mode 100644 backend/includes/db_connection.php delete mode 100644 backend/includes/functions.php delete mode 100644 backend/index.php delete mode 100644 backend/routes/web.php delete mode 100644 frontend/index.html diff --git a/backend/config/config.php b/backend/config/config.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/config/database.php b/backend/config/database.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/includes/db_connection.php b/backend/includes/db_connection.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/includes/functions.php b/backend/includes/functions.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/index.php b/backend/index.php deleted file mode 100644 index e69de29..0000000 diff --git a/backend/routes/web.php b/backend/routes/web.php deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/index.html b/frontend/index.html deleted file mode 100644 index e69de29..0000000 From 80fdc712ffc766cd7d8d4188e731ba52d2ef719c Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:38:08 -0600 Subject: [PATCH 20/57] config vercel correccion de roiutes --- vercel.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/vercel.json b/vercel.json index 3437cd1..981da4a 100644 --- a/vercel.json +++ b/vercel.json @@ -1,12 +1,14 @@ { - "builds":[ + "builds": [ { - "src": "./index.js", + "src": "backend/index.js", "use": "@vercel-node" } ], - "routes":{ - "src": "/(.*)", - "dest": "/" - } + "routes": [ + { + "src": "/(.*)", + "dest": "/" + } + ] } \ No newline at end of file From 305a3fb612ef50b89e4f37da08cc6ff757f3aebb Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:45:53 -0600 Subject: [PATCH 21/57] use_node --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 981da4a..0e8cf30 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "@vercel-node" + "use": "node" } ], "routes": [ From a8e484189b9deb2a8e4bd075065df62f5bdd00b7 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:45:53 -0600 Subject: [PATCH 22/57] use_node --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 981da4a..0e8cf30 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "@vercel-node" + "use": "node" } ], "routes": [ From 10154d4203656e18169ea097878443dd508f57cc Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:56:42 -0600 Subject: [PATCH 23/57] vercel -i --- package-lock.json | 1572 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + vercel.json | 2 +- 3 files changed, 1548 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 86834a9..6997f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,15 +3,13 @@ "version": "1.0.0", "lockfileVersion": 3, "requires": true, - "scripts": { - "start": "node backend/index.js" - }, "packages": { "": { "name": "pjctinvlabsis", "version": "1.0.0", "license": "ISC", "dependencies": { + "@vercel/node": "^3.1.7", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", @@ -24,21 +22,299 @@ "nodemon": "^3.1.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@edge-runtime/format": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@edge-runtime/format/-/format-2.2.1.tgz", + "integrity": "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/node-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/node-utils/-/node-utils-2.3.0.tgz", + "integrity": "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/ponyfill": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.2.tgz", + "integrity": "sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/primitives": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.1.0.tgz", + "integrity": "sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/vm": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.2.0.tgz", + "integrity": "sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==", + "dependencies": { + "@edge-runtime/primitives": "4.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz", + "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==", + "dependencies": { + "fast-glob": "^3.2.7", + "minimatch": "^3.0.4", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, "node_modules/@types/geojson": { "version": "7946.0.14", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, + "node_modules/@vercel/build-utils": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-8.2.2.tgz", + "integrity": "sha512-+Nf/Yk3GeMI47L/g5KYEvsj7yqVkhb6vZqjxavUBRVPSsgJ7fuNVfYvvpFj/Y0BYysEF8XNUxKFuwGROiop/ow==" + }, + "node_modules/@vercel/error-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.2.tgz", + "integrity": "sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ==" + }, + "node_modules/@vercel/nft": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.2.tgz", + "integrity": "sha512-7LeioS1yE5hwPpQfD3DdH04tuugKjo5KrJk3yK5kAI3Lh76iSsK/ezoFQfzuT08X3ZASQOd1y9ePjLNI9+TxTQ==", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "@rollup/pluginutils": "^4.0.0", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.5", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.2", + "node-gyp-build": "^4.2.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/node": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.1.7.tgz", + "integrity": "sha512-EYSHEt0Up70cOlawkSzb5CFHyHoOMuJG9Q/hWU+4zIpnXefZSanR/oaZMd+UFoaAKDVryBz35FVV7gNo6HxX9A==", + "dependencies": { + "@edge-runtime/node-utils": "2.3.0", + "@edge-runtime/primitives": "4.1.0", + "@edge-runtime/vm": "3.2.0", + "@types/node": "16.18.11", + "@vercel/build-utils": "8.2.2", + "@vercel/error-utils": "2.0.2", + "@vercel/nft": "0.27.2", + "@vercel/static-config": "3.0.0", + "async-listen": "3.0.0", + "cjs-module-lexer": "1.2.3", + "edge-runtime": "2.5.9", + "es-module-lexer": "1.4.1", + "esbuild": "0.14.47", + "etag": "1.8.1", + "node-fetch": "2.6.9", + "path-to-regexp": "6.2.1", + "ts-morph": "12.0.0", + "ts-node": "10.9.1", + "typescript": "4.9.5", + "undici": "5.26.5" + } + }, + "node_modules/@vercel/node/node_modules/@types/node": { + "version": "16.18.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.11.tgz", + "integrity": "sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==" + }, + "node_modules/@vercel/node/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/@vercel/static-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vercel/static-config/-/static-config-3.0.0.tgz", + "integrity": "sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==", + "dependencies": { + "ajv": "8.6.3", + "json-schema-to-ts": "1.6.4", + "ts-morph": "12.0.0" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/accepts": { "version": "1.3.8", @@ -52,6 +328,88 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -65,16 +423,51 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/async-listen": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.0.tgz", + "integrity": "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bcryptjs": { "version": "2.4.3", @@ -93,6 +486,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -120,19 +521,17 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -193,11 +592,41 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "node_modules/code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -218,6 +647,14 @@ "node": ">= 0.6" } }, + "node_modules/convert-hrtime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", + "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", + "engines": { + "node": ">=8" + } + }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -243,6 +680,11 @@ "node": ">= 0.10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -267,6 +709,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -292,6 +739,22 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -311,11 +774,46 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/edge-runtime": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.9.tgz", + "integrity": "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==", + "dependencies": { + "@edge-runtime/format": "2.2.1", + "@edge-runtime/ponyfill": "2.4.2", + "@edge-runtime/vm": "3.2.0", + "async-listen": "3.0.1", + "mri": "1.2.0", + "picocolors": "1.0.0", + "pretty-ms": "7.0.1", + "signal-exit": "4.0.2", + "time-span": "4.0.0" + }, + "bin": { + "edge-runtime": "dist/cli/index.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/edge-runtime/node_modules/async-listen": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.1.tgz", + "integrity": "sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==", + "engines": { + "node": ">= 14" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -343,11 +841,355 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/esbuild": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", + "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-64": "0.14.47", + "esbuild-android-arm64": "0.14.47", + "esbuild-darwin-64": "0.14.47", + "esbuild-darwin-arm64": "0.14.47", + "esbuild-freebsd-64": "0.14.47", + "esbuild-freebsd-arm64": "0.14.47", + "esbuild-linux-32": "0.14.47", + "esbuild-linux-64": "0.14.47", + "esbuild-linux-arm": "0.14.47", + "esbuild-linux-arm64": "0.14.47", + "esbuild-linux-mips64le": "0.14.47", + "esbuild-linux-ppc64le": "0.14.47", + "esbuild-linux-riscv64": "0.14.47", + "esbuild-linux-s390x": "0.14.47", + "esbuild-netbsd-64": "0.14.47", + "esbuild-openbsd-64": "0.14.47", + "esbuild-sunos-64": "0.14.47", + "esbuild-windows-32": "0.14.47", + "esbuild-windows-64": "0.14.47", + "esbuild-windows-arm64": "0.14.47" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", + "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", + "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", + "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", + "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", + "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", + "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", + "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", + "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", + "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", + "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", + "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", + "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", + "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", + "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", + "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", + "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", + "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", + "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", + "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", + "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -409,11 +1251,43 @@ "node": ">= 8.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "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==", - "dev": true, + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -454,6 +1328,33 @@ "node": ">= 0.6" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -476,6 +1377,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -494,11 +1420,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -517,6 +1462,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -559,6 +1509,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -585,6 +1540,39 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -602,6 +1590,16 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -631,16 +1629,22 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -652,11 +1656,24 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } }, + "node_modules/json-schema-to-ts": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz", + "integrity": "sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==", + "dependencies": { + "@types/json-schema": "^7.0.6", + "ts-toolbelt": "^6.15.5" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -753,6 +1770,33 @@ "node": ">=10" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "node_modules/mariadb": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.2.3.tgz", @@ -800,6 +1844,14 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -808,6 +1860,18 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -842,7 +1906,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -850,6 +1913,56 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -863,6 +1976,35 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/nodemon": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", @@ -938,6 +2080,18 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -965,6 +2119,22 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -973,16 +2143,33 @@ "node": ">= 0.8" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -990,6 +2177,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1008,6 +2209,14 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1022,6 +2231,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1044,6 +2272,19 @@ "node": ">= 0.8" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1056,6 +2297,68 @@ "node": ">=8.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1136,6 +2439,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -1174,6 +2482,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -1194,6 +2513,38 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1206,11 +2557,40 @@ "node": ">=4" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/time-span": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-4.0.0.tgz", + "integrity": "sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==", + "dependencies": { + "convert-hrtime": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -1238,6 +2618,67 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-morph": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.0.0.tgz", + "integrity": "sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==", + "dependencies": { + "@ts-morph/common": "~0.11.0", + "code-block-writer": "^10.1.1" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1250,12 +2691,35 @@ "node": ">= 0.6" } }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/undici": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", + "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1264,6 +2728,19 @@ "node": ">= 0.8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1272,6 +2749,11 @@ "node": ">= 0.4.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, "node_modules/validator": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", @@ -1288,10 +2770,48 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } } + }, + "scripts": { + "start": "node backend/index.js" } } diff --git a/package.json b/package.json index 3876c1d..ffecd8f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "dependencies": { + "@vercel/node": "^3.1.7", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", diff --git a/vercel.json b/vercel.json index 0e8cf30..981da4a 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "node" + "use": "@vercel-node" } ], "routes": [ From e7bc7cdacfdaef9c1fadc83663c4f6f33733fa15 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:56:42 -0600 Subject: [PATCH 24/57] vercel -i --- package-lock.json | 1572 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + vercel.json | 2 +- 3 files changed, 1548 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 86834a9..6997f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,15 +3,13 @@ "version": "1.0.0", "lockfileVersion": 3, "requires": true, - "scripts": { - "start": "node backend/index.js" - }, "packages": { "": { "name": "pjctinvlabsis", "version": "1.0.0", "license": "ISC", "dependencies": { + "@vercel/node": "^3.1.7", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", @@ -24,21 +22,299 @@ "nodemon": "^3.1.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@edge-runtime/format": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@edge-runtime/format/-/format-2.2.1.tgz", + "integrity": "sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/node-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/node-utils/-/node-utils-2.3.0.tgz", + "integrity": "sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/ponyfill": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.2.tgz", + "integrity": "sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/primitives": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.1.0.tgz", + "integrity": "sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/vm": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.2.0.tgz", + "integrity": "sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==", + "dependencies": { + "@edge-runtime/primitives": "4.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz", + "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==", + "dependencies": { + "fast-glob": "^3.2.7", + "minimatch": "^3.0.4", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, "node_modules/@types/geojson": { "version": "7946.0.14", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { "version": "17.0.45", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, + "node_modules/@vercel/build-utils": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-8.2.2.tgz", + "integrity": "sha512-+Nf/Yk3GeMI47L/g5KYEvsj7yqVkhb6vZqjxavUBRVPSsgJ7fuNVfYvvpFj/Y0BYysEF8XNUxKFuwGROiop/ow==" + }, + "node_modules/@vercel/error-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.2.tgz", + "integrity": "sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ==" + }, + "node_modules/@vercel/nft": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.27.2.tgz", + "integrity": "sha512-7LeioS1yE5hwPpQfD3DdH04tuugKjo5KrJk3yK5kAI3Lh76iSsK/ezoFQfzuT08X3ZASQOd1y9ePjLNI9+TxTQ==", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "@rollup/pluginutils": "^4.0.0", + "acorn": "^8.6.0", + "acorn-import-attributes": "^1.9.5", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.2", + "node-gyp-build": "^4.2.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/node": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.1.7.tgz", + "integrity": "sha512-EYSHEt0Up70cOlawkSzb5CFHyHoOMuJG9Q/hWU+4zIpnXefZSanR/oaZMd+UFoaAKDVryBz35FVV7gNo6HxX9A==", + "dependencies": { + "@edge-runtime/node-utils": "2.3.0", + "@edge-runtime/primitives": "4.1.0", + "@edge-runtime/vm": "3.2.0", + "@types/node": "16.18.11", + "@vercel/build-utils": "8.2.2", + "@vercel/error-utils": "2.0.2", + "@vercel/nft": "0.27.2", + "@vercel/static-config": "3.0.0", + "async-listen": "3.0.0", + "cjs-module-lexer": "1.2.3", + "edge-runtime": "2.5.9", + "es-module-lexer": "1.4.1", + "esbuild": "0.14.47", + "etag": "1.8.1", + "node-fetch": "2.6.9", + "path-to-regexp": "6.2.1", + "ts-morph": "12.0.0", + "ts-node": "10.9.1", + "typescript": "4.9.5", + "undici": "5.26.5" + } + }, + "node_modules/@vercel/node/node_modules/@types/node": { + "version": "16.18.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.11.tgz", + "integrity": "sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==" + }, + "node_modules/@vercel/node/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "node_modules/@vercel/static-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vercel/static-config/-/static-config-3.0.0.tgz", + "integrity": "sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==", + "dependencies": { + "ajv": "8.6.3", + "json-schema-to-ts": "1.6.4", + "ts-morph": "12.0.0" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/accepts": { "version": "1.3.8", @@ -52,6 +328,88 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -65,16 +423,51 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/async-listen": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.0.tgz", + "integrity": "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bcryptjs": { "version": "2.4.3", @@ -93,6 +486,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -120,19 +521,17 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -193,11 +592,41 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "node_modules/code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -218,6 +647,14 @@ "node": ">= 0.6" } }, + "node_modules/convert-hrtime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", + "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", + "engines": { + "node": ">=8" + } + }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -243,6 +680,11 @@ "node": ">= 0.10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -267,6 +709,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denque": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", @@ -292,6 +739,22 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -311,11 +774,46 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/edge-runtime": { + "version": "2.5.9", + "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.9.tgz", + "integrity": "sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==", + "dependencies": { + "@edge-runtime/format": "2.2.1", + "@edge-runtime/ponyfill": "2.4.2", + "@edge-runtime/vm": "3.2.0", + "async-listen": "3.0.1", + "mri": "1.2.0", + "picocolors": "1.0.0", + "pretty-ms": "7.0.1", + "signal-exit": "4.0.2", + "time-span": "4.0.0" + }, + "bin": { + "edge-runtime": "dist/cli/index.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/edge-runtime/node_modules/async-listen": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.1.tgz", + "integrity": "sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==", + "engines": { + "node": ">= 14" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -343,11 +841,355 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/esbuild": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", + "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-64": "0.14.47", + "esbuild-android-arm64": "0.14.47", + "esbuild-darwin-64": "0.14.47", + "esbuild-darwin-arm64": "0.14.47", + "esbuild-freebsd-64": "0.14.47", + "esbuild-freebsd-arm64": "0.14.47", + "esbuild-linux-32": "0.14.47", + "esbuild-linux-64": "0.14.47", + "esbuild-linux-arm": "0.14.47", + "esbuild-linux-arm64": "0.14.47", + "esbuild-linux-mips64le": "0.14.47", + "esbuild-linux-ppc64le": "0.14.47", + "esbuild-linux-riscv64": "0.14.47", + "esbuild-linux-s390x": "0.14.47", + "esbuild-netbsd-64": "0.14.47", + "esbuild-openbsd-64": "0.14.47", + "esbuild-sunos-64": "0.14.47", + "esbuild-windows-32": "0.14.47", + "esbuild-windows-64": "0.14.47", + "esbuild-windows-arm64": "0.14.47" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", + "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", + "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", + "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", + "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", + "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", + "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", + "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", + "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", + "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", + "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", + "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", + "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", + "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", + "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", + "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", + "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", + "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", + "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", + "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", + "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -409,11 +1251,43 @@ "node": ">= 8.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, "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==", - "dev": true, + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -454,6 +1328,33 @@ "node": ">= 0.6" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -476,6 +1377,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -494,11 +1420,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -517,6 +1462,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -559,6 +1509,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -585,6 +1540,39 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -602,6 +1590,16 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -631,16 +1629,22 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -652,11 +1656,24 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } }, + "node_modules/json-schema-to-ts": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz", + "integrity": "sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==", + "dependencies": { + "@types/json-schema": "^7.0.6", + "ts-toolbelt": "^6.15.5" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -753,6 +1770,33 @@ "node": ">=10" } }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "node_modules/mariadb": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.2.3.tgz", @@ -800,6 +1844,14 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -808,6 +1860,18 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -842,7 +1906,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -850,6 +1913,56 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -863,6 +1976,35 @@ "node": ">= 0.6" } }, + "node_modules/node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/nodemon": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", @@ -938,6 +2080,18 @@ "node": ">=0.10.0" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -965,6 +2119,22 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -973,16 +2143,33 @@ "node": ">= 0.8" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -990,6 +2177,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1008,6 +2209,14 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1022,6 +2231,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1044,6 +2272,19 @@ "node": ">= 0.8" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -1056,6 +2297,68 @@ "node": ">=8.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1136,6 +2439,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -1174,6 +2482,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -1194,6 +2513,38 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1206,11 +2557,40 @@ "node": ">=4" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/time-span": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-4.0.0.tgz", + "integrity": "sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==", + "dependencies": { + "convert-hrtime": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -1238,6 +2618,67 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-morph": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.0.0.tgz", + "integrity": "sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==", + "dependencies": { + "@ts-morph/common": "~0.11.0", + "code-block-writer": "^10.1.1" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1250,12 +2691,35 @@ "node": ">= 0.6" } }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/undici": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", + "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1264,6 +2728,19 @@ "node": ">= 0.8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1272,6 +2749,11 @@ "node": ">= 0.4.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, "node_modules/validator": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", @@ -1288,10 +2770,48 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } } + }, + "scripts": { + "start": "node backend/index.js" } } diff --git a/package.json b/package.json index 3876c1d..ffecd8f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "dependencies": { + "@vercel/node": "^3.1.7", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^16.4.5", diff --git a/vercel.json b/vercel.json index 0e8cf30..981da4a 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "node" + "use": "@vercel-node" } ], "routes": [ From e6365699438a296092c2e62b7731c79735317097 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:59:51 -0600 Subject: [PATCH 25/57] / --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 981da4a..3900a62 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "@vercel-node" + "use": "@vercel/node" } ], "routes": [ From 4fff000496951ec527c3cc6e881ad639b4dd185d Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 18:59:51 -0600 Subject: [PATCH 26/57] / --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 981da4a..3900a62 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "builds": [ { "src": "backend/index.js", - "use": "@vercel-node" + "use": "@vercel/node" } ], "routes": [ From e88cdde248ae81d210dbc123b14a481fbaddf1d7 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:08:00 -0600 Subject: [PATCH 27/57] dest vercel --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 3900a62..69b10cc 100644 --- a/vercel.json +++ b/vercel.json @@ -8,7 +8,7 @@ "routes": [ { "src": "/(.*)", - "dest": "/" + "dest": "/backend/index.js" } ] } \ No newline at end of file From ac4cff9cb81f55bc76321d27c5c8cc8599d193b2 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:08:00 -0600 Subject: [PATCH 28/57] dest vercel --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 3900a62..69b10cc 100644 --- a/vercel.json +++ b/vercel.json @@ -8,7 +8,7 @@ "routes": [ { "src": "/(.*)", - "dest": "/" + "dest": "/backend/index.js" } ] } \ No newline at end of file From f24b9f141321b82a11b1c1b60a7b33dc26d6d11b Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:17:47 -0600 Subject: [PATCH 29/57] cors --- backend/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/index.js b/backend/index.js index d7a11bb..39070ac 100644 --- a/backend/index.js +++ b/backend/index.js @@ -2,7 +2,7 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); -/* app.use(cors()); */ +app.use(cors()); app.listen(process.env.NODE_PORT, () => { From 567edcc6bed6384a9cb286a64a366281805db2aa Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:17:47 -0600 Subject: [PATCH 30/57] cors --- backend/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/index.js b/backend/index.js index d7a11bb..39070ac 100644 --- a/backend/index.js +++ b/backend/index.js @@ -2,7 +2,7 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); -/* app.use(cors()); */ +app.use(cors()); app.listen(process.env.NODE_PORT, () => { From f27bb484e0ca8b89acde341c9610d9fbbbf3c9e8 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:24:03 -0600 Subject: [PATCH 31/57] routes --- vercel.json | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/vercel.json b/vercel.json index 69b10cc..1cb6e30 100644 --- a/vercel.json +++ b/vercel.json @@ -1,14 +1,21 @@ { "builds": [ - { - "src": "backend/index.js", - "use": "@vercel/node" - } + { + "src": "backend/index.js", + "use": "@vercel/node" + } ], "routes": [ - { - "src": "/(.*)", - "dest": "/backend/index.js" - } + { "src": "/herramientas(.*)", "dest": "/backend/routes/herramientas_routes$1" }, + { "src": "/tipo_herramienta(.*)", "dest": "/backend/routes/tipoHerramienta_routes$1" }, + { "src": "/login(.*)", "dest": "/backend/routes/login_routes$1" }, + { "src": "/origen(.*)", "dest": "/backend/routes/origen_routes$1" }, + { "src": "/bajas(.*)", "dest": "/backend/routes/bajas_routes$1" }, + { "src": "/prestamos(.*)", "dest": "/backend/routes/prestamo_routes$1" }, + { "src": "/usuarios(.*)", "dest": "/backend/routes/usuarios_routes$1" }, + { "src": "/solicitantes(.*)", "dest": "/backend/routes/solicitantes_routes$1" }, + { "src": "/carreras(.*)", "dest": "/backend/routes/carreras_routes$1" }, + { "src": "/(.*)", "dest": "/backend/index.js" } ] -} \ No newline at end of file + } + \ No newline at end of file From 65c6c9f28880e70924cbc4688084463bd88d75e9 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:24:03 -0600 Subject: [PATCH 32/57] routes --- vercel.json | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/vercel.json b/vercel.json index 69b10cc..1cb6e30 100644 --- a/vercel.json +++ b/vercel.json @@ -1,14 +1,21 @@ { "builds": [ - { - "src": "backend/index.js", - "use": "@vercel/node" - } + { + "src": "backend/index.js", + "use": "@vercel/node" + } ], "routes": [ - { - "src": "/(.*)", - "dest": "/backend/index.js" - } + { "src": "/herramientas(.*)", "dest": "/backend/routes/herramientas_routes$1" }, + { "src": "/tipo_herramienta(.*)", "dest": "/backend/routes/tipoHerramienta_routes$1" }, + { "src": "/login(.*)", "dest": "/backend/routes/login_routes$1" }, + { "src": "/origen(.*)", "dest": "/backend/routes/origen_routes$1" }, + { "src": "/bajas(.*)", "dest": "/backend/routes/bajas_routes$1" }, + { "src": "/prestamos(.*)", "dest": "/backend/routes/prestamo_routes$1" }, + { "src": "/usuarios(.*)", "dest": "/backend/routes/usuarios_routes$1" }, + { "src": "/solicitantes(.*)", "dest": "/backend/routes/solicitantes_routes$1" }, + { "src": "/carreras(.*)", "dest": "/backend/routes/carreras_routes$1" }, + { "src": "/(.*)", "dest": "/backend/index.js" } ] -} \ No newline at end of file + } + \ No newline at end of file From 8ce5f21ea3c69beec9704a24ae406d68bfbefece Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:41:32 -0600 Subject: [PATCH 33/57] .env --- .gitignore | 2 +- backend/.env | 7 ------- backend/config/database.js | 2 +- backend/helpers/generate_token.js | 2 +- backend/index.js | 9 +-------- backend/middlewares/check_token.js | 2 +- 6 files changed, 5 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index ca5b3da..baf27f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules/ front/ -backend/pruebas.js \ No newline at end of file +backend/pruebas.js diff --git a/backend/.env b/backend/.env index d4a436a..ac9dc2f 100644 --- a/backend/.env +++ b/backend/.env @@ -6,10 +6,3 @@ # DATABASE="dbsistemas" # JWT_SECRET = "589696852" -NODE_PORT="3001" -HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" -PORT="3306" -USER="ugpwh5vn4olvh15t" -PASSWORD="K791zFWMmQibYVYBuF4r" -DATABASE="bqvpx1qe8f1g2jhxyxjj" -JWT_SECRET = "589696852" \ No newline at end of file diff --git a/backend/config/database.js b/backend/config/database.js index de0e194..9f40513 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,5 +1,5 @@ const mariadb = require('mariadb'); -require('dotenv').config(); +//require('dotenv').config(); const pool = mariadb.createPool({ host: process.env.HOST, diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index a98f99a..7ab5ca1 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -1,5 +1,5 @@ const jwt = require ('jsonwebtoken'); -require('dotenv').config({path: 'backend/.env'}); +//require('dotenv').config({path: 'backend/.env'}); //generar un token const token_sign = async (user, rol) =>{ return jwt.sign( diff --git a/backend/index.js b/backend/index.js index 39070ac..d0b3553 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,6 +1,6 @@ const express = require('express'); const app = express(); -require('dotenv').config({path: 'backend/.env'}); +//require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); app.use(cors()); @@ -32,10 +32,3 @@ app.use('/carreras', require('./routes/carreras_routes')) -/*NODE_PORT="3000" -HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" -PORT="3306" -USER="ugpwh5vn4olvh15t" -PASSWORD="DHGMBoPlzbo6Q9rFxHRW" -DATABASE="bqvpx1qe8f1g2jhxyxjj" -JWT_SECRET = "589696852"*/ \ No newline at end of file diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 915e3db..983ed3b 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -1,6 +1,6 @@ const { verify_token } = require('../helpers/generate_token') const return_error = require('../helpers/return_error.js'); -require('dotenv').config({ path: 'backend/.env' }); +//require('dotenv').config({ path: 'backend/.env' }); const check_token = async (req, res, next) => { try { From 7ead8ac90de4918a462dab41254db8971dd1311b Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:41:32 -0600 Subject: [PATCH 34/57] .env --- .gitignore | 2 +- backend/config/database.js | 2 +- backend/helpers/generate_token.js | 2 +- backend/index.js | 9 +-------- backend/middlewares/check_token.js | 2 +- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index ca5b3da..baf27f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ node_modules/ front/ -backend/pruebas.js \ No newline at end of file +backend/pruebas.js diff --git a/backend/config/database.js b/backend/config/database.js index de0e194..9f40513 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,5 +1,5 @@ const mariadb = require('mariadb'); -require('dotenv').config(); +//require('dotenv').config(); const pool = mariadb.createPool({ host: process.env.HOST, diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index a98f99a..7ab5ca1 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -1,5 +1,5 @@ const jwt = require ('jsonwebtoken'); -require('dotenv').config({path: 'backend/.env'}); +//require('dotenv').config({path: 'backend/.env'}); //generar un token const token_sign = async (user, rol) =>{ return jwt.sign( diff --git a/backend/index.js b/backend/index.js index 39070ac..d0b3553 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,6 +1,6 @@ const express = require('express'); const app = express(); -require('dotenv').config({path: 'backend/.env'}); +//require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); app.use(cors()); @@ -32,10 +32,3 @@ app.use('/carreras', require('./routes/carreras_routes')) -/*NODE_PORT="3000" -HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" -PORT="3306" -USER="ugpwh5vn4olvh15t" -PASSWORD="DHGMBoPlzbo6Q9rFxHRW" -DATABASE="bqvpx1qe8f1g2jhxyxjj" -JWT_SECRET = "589696852"*/ \ No newline at end of file diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 915e3db..983ed3b 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -1,6 +1,6 @@ const { verify_token } = require('../helpers/generate_token') const return_error = require('../helpers/return_error.js'); -require('dotenv').config({ path: 'backend/.env' }); +//require('dotenv').config({ path: 'backend/.env' }); const check_token = async (req, res, next) => { try { From 245fb16ce1a0aed8c4f7da3c9ee5374d85959799 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:45:45 -0600 Subject: [PATCH 35/57] rev .env --- backend/.env | 7 +++++++ backend/config/database.js | 2 +- backend/helpers/generate_token.js | 2 +- backend/index.js | 2 +- backend/middlewares/check_token.js | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/backend/.env b/backend/.env index ac9dc2f..d289bc7 100644 --- a/backend/.env +++ b/backend/.env @@ -6,3 +6,10 @@ # DATABASE="dbsistemas" # JWT_SECRET = "589696852" +NODE_PORT="3001" +HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" +PORT="3306" +USER="ugpwh5vn4olvh15t" +PASSWORD="K791zFWMmQibYVYBuF4r" +DATABASE="bqvpx1qe8f1g2jhxyxjj" +JWT_SECRET = "ssd86sfd9 \ No newline at end of file diff --git a/backend/config/database.js b/backend/config/database.js index 9f40513..de0e194 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,5 +1,5 @@ const mariadb = require('mariadb'); -//require('dotenv').config(); +require('dotenv').config(); const pool = mariadb.createPool({ host: process.env.HOST, diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index 7ab5ca1..a98f99a 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -1,5 +1,5 @@ const jwt = require ('jsonwebtoken'); -//require('dotenv').config({path: 'backend/.env'}); +require('dotenv').config({path: 'backend/.env'}); //generar un token const token_sign = async (user, rol) =>{ return jwt.sign( diff --git a/backend/index.js b/backend/index.js index d0b3553..950744c 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,6 +1,6 @@ const express = require('express'); const app = express(); -//require('dotenv').config({path: 'backend/.env'}); +require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); app.use(cors()); diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 983ed3b..915e3db 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -1,6 +1,6 @@ const { verify_token } = require('../helpers/generate_token') const return_error = require('../helpers/return_error.js'); -//require('dotenv').config({ path: 'backend/.env' }); +require('dotenv').config({ path: 'backend/.env' }); const check_token = async (req, res, next) => { try { From db73bde9af1fdfb9b2267cadfbc58924f308bf63 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:45:45 -0600 Subject: [PATCH 36/57] rev .env --- backend/config/database.js | 2 +- backend/helpers/generate_token.js | 2 +- backend/index.js | 2 +- backend/middlewares/check_token.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/config/database.js b/backend/config/database.js index 9f40513..de0e194 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,5 +1,5 @@ const mariadb = require('mariadb'); -//require('dotenv').config(); +require('dotenv').config(); const pool = mariadb.createPool({ host: process.env.HOST, diff --git a/backend/helpers/generate_token.js b/backend/helpers/generate_token.js index 7ab5ca1..a98f99a 100644 --- a/backend/helpers/generate_token.js +++ b/backend/helpers/generate_token.js @@ -1,5 +1,5 @@ const jwt = require ('jsonwebtoken'); -//require('dotenv').config({path: 'backend/.env'}); +require('dotenv').config({path: 'backend/.env'}); //generar un token const token_sign = async (user, rol) =>{ return jwt.sign( diff --git a/backend/index.js b/backend/index.js index d0b3553..950744c 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,6 +1,6 @@ const express = require('express'); const app = express(); -//require('dotenv').config({path: 'backend/.env'}); +require('dotenv').config({path: 'backend/.env'}); const cors = require('cors'); app.use(cors()); diff --git a/backend/middlewares/check_token.js b/backend/middlewares/check_token.js index 983ed3b..915e3db 100644 --- a/backend/middlewares/check_token.js +++ b/backend/middlewares/check_token.js @@ -1,6 +1,6 @@ const { verify_token } = require('../helpers/generate_token') const return_error = require('../helpers/return_error.js'); -//require('dotenv').config({ path: 'backend/.env' }); +require('dotenv').config({ path: 'backend/.env' }); const check_token = async (req, res, next) => { try { From 305aac5ef8a535285bfc2530f009b32de148ed48 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:50:16 -0600 Subject: [PATCH 37/57] cors 2.0 --- backend/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/index.js b/backend/index.js index 950744c..1abdc25 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,10 +5,6 @@ const cors = require('cors'); app.use(cors()); -app.listen(process.env.NODE_PORT, () => { - console.log('server running '+ process.env.NODE_PORT); -}); - app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); @@ -17,6 +13,13 @@ app.use((req, res, next) => { next(); }) + + + +app.listen(process.env.NODE_PORT, () => { + console.log('server running '+ process.env.NODE_PORT); +}); + app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) From 498e24412c3e49aec9478548ee033722a154e95c Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:50:16 -0600 Subject: [PATCH 38/57] cors 2.0 --- backend/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/index.js b/backend/index.js index 950744c..1abdc25 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,10 +5,6 @@ const cors = require('cors'); app.use(cors()); -app.listen(process.env.NODE_PORT, () => { - console.log('server running '+ process.env.NODE_PORT); -}); - app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); @@ -17,6 +13,13 @@ app.use((req, res, next) => { next(); }) + + + +app.listen(process.env.NODE_PORT, () => { + console.log('server running '+ process.env.NODE_PORT); +}); + app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) From 88a412cd262b2e3a34b9e88ce62d319115931538 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:56:56 -0600 Subject: [PATCH 39/57] cors 3.0 --- backend/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/index.js b/backend/index.js index 1abdc25..592b9df 100644 --- a/backend/index.js +++ b/backend/index.js @@ -7,12 +7,11 @@ app.use(cors()); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); -}) - +}); From 4e76333388cbc814dea98c950db078801079c52a Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 19:56:56 -0600 Subject: [PATCH 40/57] cors 3.0 --- backend/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/index.js b/backend/index.js index 1abdc25..592b9df 100644 --- a/backend/index.js +++ b/backend/index.js @@ -7,12 +7,11 @@ app.use(cors()); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); -}) - +}); From 12cddc5a0fdd7fe5f9eaa8176fba95a11d8ea334 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:06:19 -0600 Subject: [PATCH 41/57] cors 3.1 --- backend/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/index.js b/backend/index.js index 592b9df..2789b52 100644 --- a/backend/index.js +++ b/backend/index.js @@ -14,11 +14,6 @@ app.use((req, res, next) => { }); - -app.listen(process.env.NODE_PORT, () => { - console.log('server running '+ process.env.NODE_PORT); -}); - app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) @@ -30,6 +25,11 @@ app.use('/usuarios', require('./routes/usuarios_routes')) app.use('/solicitantes', require('./routes/solicitantes_routes')) app.use('/carreras', require('./routes/carreras_routes')) +app.listen(process.env.NODE_PORT, () => { + console.log('server running '+ process.env.NODE_PORT); +}); + + From 1d9790efe876d464db7ed14b2e52f4835f85b8f5 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:06:19 -0600 Subject: [PATCH 42/57] cors 3.1 --- backend/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/index.js b/backend/index.js index 592b9df..2789b52 100644 --- a/backend/index.js +++ b/backend/index.js @@ -14,11 +14,6 @@ app.use((req, res, next) => { }); - -app.listen(process.env.NODE_PORT, () => { - console.log('server running '+ process.env.NODE_PORT); -}); - app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) @@ -30,6 +25,11 @@ app.use('/usuarios', require('./routes/usuarios_routes')) app.use('/solicitantes', require('./routes/solicitantes_routes')) app.use('/carreras', require('./routes/carreras_routes')) +app.listen(process.env.NODE_PORT, () => { + console.log('server running '+ process.env.NODE_PORT); +}); + + From b0d5a8c0df4c39ac39febfa6c5e18bfc7025a22e Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:32:17 -0600 Subject: [PATCH 43/57] cors 4.0 --- backend/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/index.js b/backend/index.js index 2789b52..0273146 100644 --- a/backend/index.js +++ b/backend/index.js @@ -7,13 +7,14 @@ app.use(cors()); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); + app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) From 3020260c651e44d4c05f899434772da00d53b7e5 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:32:17 -0600 Subject: [PATCH 44/57] cors 4.0 --- backend/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/index.js b/backend/index.js index 2789b52..0273146 100644 --- a/backend/index.js +++ b/backend/index.js @@ -7,13 +7,14 @@ app.use(cors()); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); + app.use(express.json()); app.use('/herramientas', require('./routes/herramientas_routes')) app.use('/tipo_herramienta', require('./routes/tipoHerramienta_routes')) From a5849d0bdb434a8ec522c9f9166211ba81c6df9a Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:35:32 -0600 Subject: [PATCH 45/57] sin cors --- backend/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/index.js b/backend/index.js index 0273146..50469de 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,14 +5,14 @@ const cors = require('cors'); app.use(cors()); -app.use((req, res, next) => { +/* app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - + */ app.use(express.json()); From 217cb2fa20543bada4e6a25c5ed4517a287c3a34 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:35:32 -0600 Subject: [PATCH 46/57] sin cors --- backend/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/index.js b/backend/index.js index 0273146..50469de 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,14 +5,14 @@ const cors = require('cors'); app.use(cors()); -app.use((req, res, next) => { +/* app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - + */ app.use(express.json()); From 60661a5c7b00917e37ca23205b81b93949633761 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:37:40 -0600 Subject: [PATCH 47/57] cors con lh3000 --- backend/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/index.js b/backend/index.js index 50469de..6852c2f 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,14 +5,14 @@ const cors = require('cors'); app.use(cors()); -/* app.use((req, res, next) => { - res.header('Access-Control-Allow-Origin', '*'); +/**/ app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', 'http://localhost:3000/'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - */ + app.use(express.json()); From 07d0b058566dd72985484535cdac37693214cc8d Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:37:40 -0600 Subject: [PATCH 48/57] cors con lh3000 --- backend/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/index.js b/backend/index.js index 50469de..6852c2f 100644 --- a/backend/index.js +++ b/backend/index.js @@ -5,14 +5,14 @@ const cors = require('cors'); app.use(cors()); -/* app.use((req, res, next) => { - res.header('Access-Control-Allow-Origin', '*'); +/**/ app.use((req, res, next) => { + res.header('Access-Control-Allow-Origin', 'http://localhost:3000/'); res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - */ + app.use(express.json()); From 4ba4fe929bfa8ec52acc0ee0a85aff441cf7eef0 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:44:02 -0600 Subject: [PATCH 49/57] solo aco * --- backend/index.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/index.js b/backend/index.js index 6852c2f..0cf612a 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,15 +1,17 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); -const cors = require('cors'); +//const cors = require('cors'); +import cors from 'cors'; + app.use(cors()); /**/ app.use((req, res, next) => { - res.header('Access-Control-Allow-Origin', 'http://localhost:3000/'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Origin', '*'); + /* res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); - res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); */ next(); }); From 9d6922bd408e4eef97fae14d182b8d264b17fb6d Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:44:02 -0600 Subject: [PATCH 50/57] solo aco * --- backend/index.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/index.js b/backend/index.js index 6852c2f..0cf612a 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,15 +1,17 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); -const cors = require('cors'); +//const cors = require('cors'); +import cors from 'cors'; + app.use(cors()); /**/ app.use((req, res, next) => { - res.header('Access-Control-Allow-Origin', 'http://localhost:3000/'); - res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Origin', '*'); + /* res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); - res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); */ next(); }); From 6d7d172bd0c68c53d6567656a66d5b24762f3ee2 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:50:33 -0600 Subject: [PATCH 51/57] asdfghjkjhgfdsa --- backend/index.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/backend/index.js b/backend/index.js index 0cf612a..f1e2c0b 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,20 +1,19 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); -//const cors = require('cors'); -import cors from 'cors'; +const cors = require('cors'); -app.use(cors()); +// Habilitar CORS +app.use(cors()); - -/**/ app.use((req, res, next) => { +// Middleware para cabeceras CORS +app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - /* res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); - res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); */ + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - app.use(express.json()); From e4cc23165d628e650c4ab145815f3151d5af042a Mon Sep 17 00:00:00 2001 From: JUrielC Date: Thu, 13 Jun 2024 20:50:33 -0600 Subject: [PATCH 52/57] asdfghjkjhgfdsa --- backend/index.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/backend/index.js b/backend/index.js index 0cf612a..f1e2c0b 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,20 +1,19 @@ const express = require('express'); const app = express(); require('dotenv').config({path: 'backend/.env'}); -//const cors = require('cors'); -import cors from 'cors'; +const cors = require('cors'); -app.use(cors()); +// Habilitar CORS +app.use(cors()); - -/**/ app.use((req, res, next) => { +// Middleware para cabeceras CORS +app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - /* res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method'); + res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Methods'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); - res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); */ + res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE'); next(); }); - app.use(express.json()); From b7391231c7f25262d8ed213888bcc9ccf97acb75 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 31 Jan 2025 20:18:13 -0600 Subject: [PATCH 53/57] add .env to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index baf27f3..e4fdc48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ front/ backend/pruebas.js +.env From cbd15858062bb06ebfe23ab462e3d092b8f9f5c3 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 31 Jan 2025 20:18:13 -0600 Subject: [PATCH 54/57] add .env to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index baf27f3..e4fdc48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ front/ backend/pruebas.js +.env From 8cedfed8bc45d0fa9f360fa736da83787eaff77e Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 31 Jan 2025 20:19:28 -0600 Subject: [PATCH 55/57] update .gitignore to exclude backend/.env file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e4fdc48..5ab6892 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules/ front/ backend/pruebas.js -.env +backend/.env From ac55457084dddddc6abe2ebdb633d05d9b01dce6 Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 31 Jan 2025 20:19:28 -0600 Subject: [PATCH 56/57] update .gitignore to exclude backend/.env file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e4fdc48..5ab6892 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules/ front/ backend/pruebas.js -.env +backend/.env From 749cf745b81a6b2589b7ca7a62b2d74715d84a1c Mon Sep 17 00:00:00 2001 From: JUrielC Date: Fri, 31 Jan 2025 20:22:16 -0600 Subject: [PATCH 57/57] remove sensitive information from backend/.env file --- backend/.env | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 backend/.env diff --git a/backend/.env b/backend/.env deleted file mode 100644 index d289bc7..0000000 --- a/backend/.env +++ /dev/null @@ -1,15 +0,0 @@ -# NODE_PORT="3001" -# HOST="localhost" -# PORT="3306" -# USER="root" -# PASSWORD="root" -# DATABASE="dbsistemas" -# JWT_SECRET = "589696852" - -NODE_PORT="3001" -HOST="bqvpx1qe8f1g2jhxyxjj-mysql.services.clever-cloud.com" -PORT="3306" -USER="ugpwh5vn4olvh15t" -PASSWORD="K791zFWMmQibYVYBuF4r" -DATABASE="bqvpx1qe8f1g2jhxyxjj" -JWT_SECRET = "ssd86sfd9 \ No newline at end of file