├── .DS_Store ├── .gitignore ├── README.md ├── api-learn ├── .env ├── app.js ├── package-lock.json ├── package.json └── src │ ├── controllers │ └── auth.controllers.js │ ├── models │ └── user.model.js │ └── routes │ ├── auth.routes.js │ └── index.js ├── api-learnv2 ├── .env ├── app.js ├── package-lock.json ├── package.json └── src │ └── middlewares │ └── middleware.js ├── e-commerce-mysql ├── .DS_Store ├── README.md ├── data │ └── db.js ├── default_index.js ├── index.js ├── package-lock.json ├── package.json ├── public │ ├── .DS_Store │ └── images │ │ ├── 1.webp │ │ ├── 2.webp │ │ ├── 3.webp │ │ ├── 4.webp │ │ └── 5.webp ├── routes │ └── users.js └── views │ ├── 404.ejs │ ├── index.ejs │ ├── partials │ ├── navbar.ejs │ └── product.ejs │ ├── product_details.ejs │ └── products.ejs ├── patient-system-api ├── package-lock.json ├── package.json └── src │ ├── api │ ├── config │ │ └── index.js │ ├── controllers │ │ └── auth.js │ └── routes │ │ ├── auth.js │ │ └── index.js │ └── app.js ├── question-answer-api ├── README.MD ├── app.js ├── package-lock.json ├── package.json └── src │ ├── controllers │ ├── admin.contoller.js │ ├── answer.controller.js │ ├── auth.controller.js │ ├── quesitons.controller.js │ └── user.controller.js │ ├── helpers │ ├── auth │ │ └── auth.helper.js │ ├── db │ │ ├── db.error.helpers.js │ │ └── db.js │ ├── error │ │ └── CustomError.js │ ├── input │ │ └── input.helper.js │ └── libraries │ │ └── sendEmail.js │ ├── middlewares │ ├── auth.middleware.js │ ├── error.handler.js │ └── image.upload.js │ ├── models │ ├── answer.model.js │ ├── question.model.js │ └── user.model.js │ └── routes │ ├── admin.js │ ├── answer.js │ ├── auth.js │ ├── index.js │ ├── questions.js │ └── users.js └── todo-mysql ├── .DS_Store ├── README.MD ├── db └── db.js ├── index.js ├── package-lock.json ├── package.json ├── routes └── route.js └── views └── index.ejs /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # npm 2 | node_modules 3 | 4 | # config 5 | config.js 6 | *.env 7 | 8 | # ---- 9 | .DS_Store 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Learn Node.js 2 | My development and learning process with node.js per day. 3 | 4 | - First Project (Basic E-commerce App) 5 | - Second Project (Basic Todo App) 6 | - Third Project (Stack-Overflow Clone Rest Api) 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /api-learn/.env: -------------------------------------------------------------------------------- 1 | PORT = 8080 2 | -------------------------------------------------------------------------------- /api-learn/app.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const app = express() 3 | const port = process.env.PORT || 8081 4 | 5 | app.use("/", (req, res) => { 6 | res.json({ 7 | message: "Hello world" 8 | }) 9 | }) 10 | 11 | app.listen(port, () => { 12 | console.log(`The server was listening ${port}`) 13 | }) -------------------------------------------------------------------------------- /api-learn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-learn", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "nodemon app.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "dotenv": "^16.0.3", 15 | "express": "^4.18.2", 16 | "express-async-errors": "^3.1.1", 17 | "jsonwebtoken": "^8.5.1", 18 | "mongoose": "^6.6.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api-learn/src/controllers/auth.controllers.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/controllers/auth.controllers.js -------------------------------------------------------------------------------- /api-learn/src/models/user.model.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose") 2 | 3 | const userShema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | trim: true 8 | }, 9 | lastname: { 10 | type: String, 11 | required: true, 12 | trim: true 13 | }, 14 | email: { 15 | type: String, 16 | required: true, 17 | trim: true, 18 | unique: true 19 | }, 20 | password: { 21 | type: String, 22 | required: true, 23 | trim: true 24 | } 25 | }, { collection: "users", timestamps: true }) 26 | 27 | const user = mongoose.model("users", userShema) 28 | 29 | module.exports = user -------------------------------------------------------------------------------- /api-learn/src/routes/auth.routes.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/routes/auth.routes.js -------------------------------------------------------------------------------- /api-learn/src/routes/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/api-learn/src/routes/index.js -------------------------------------------------------------------------------- /api-learnv2/.env: -------------------------------------------------------------------------------- 1 | PORT = 4040 -------------------------------------------------------------------------------- /api-learnv2/app.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const app = express() 3 | const port = process.env.PORT || 4041 4 | const { authControl, banControl, homeControl } = require("./src/middlewares/middleware") 5 | 6 | const users = [ 7 | { 8 | id: 1, 9 | name: "Ahmet Kaan", 10 | surname: "Uzman", 11 | type: "user", 12 | createdTime: Date.now(), 13 | isActive: true, 14 | }, 15 | { 16 | id: 2, 17 | name: "Test", 18 | surname: "User", 19 | type: "user", 20 | createdTime: Date.now(), 21 | isActive: true, 22 | }, 23 | { 24 | id: 3, 25 | name: "Test", 26 | surname: "Admin", 27 | type: "admin", 28 | createdTime: Date.now(), 29 | isActive: true, 30 | }, 31 | ] 32 | 33 | app.use(express.json()) 34 | 35 | /// Middlewares usage in general routes 36 | app.use(authControl, banControl) 37 | 38 | 39 | /// Middlewares usage in only a route 40 | app.get("/", homeControl, (req, res) => { 41 | res.send("hello world") 42 | }) 43 | 44 | app.get("/users", (req, res) => { 45 | res.json(users) 46 | }) 47 | 48 | app.get("/users/:id", (req, res) => { 49 | res.json( 50 | users.find(e => e.id == req.params.id) 51 | ) 52 | }) 53 | 54 | app.post("/addUser", (req, res) => { 55 | const newUser = req.body 56 | users.push(newUser) 57 | res.json({ 58 | succes: true, 59 | user: newUser 60 | }) 61 | }) 62 | 63 | app.put("/updateUser/:id", (req, res) => { 64 | let updatedUser = users.find(e => e.id == req.params.id) 65 | updatedUser = req.body 66 | res.json({ 67 | succes: true, 68 | body: updatedUser 69 | }) 70 | }) 71 | 72 | app.delete("/deleteUser/:id", (req, res) => { 73 | for (let i = 0; i < users.length; i++) { 74 | if (users[i].id == req.params.id) { 75 | users.splice(i, 1) 76 | } 77 | } 78 | res.json({ 79 | succes: true, 80 | body: users, 81 | }) 82 | }) 83 | 84 | /// General error route 85 | app.get("*", (req, res) => { 86 | res.status(404).json( 87 | { 88 | message: "This page doesn't exist." 89 | } 90 | ) 91 | }) 92 | 93 | app.listen(port, () => { 94 | console.log("The server was started!") 95 | }) -------------------------------------------------------------------------------- /api-learnv2/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-learnv2", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "api-learnv2", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.18.2" 13 | } 14 | }, 15 | "node_modules/accepts": { 16 | "version": "1.3.8", 17 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 18 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 19 | "dependencies": { 20 | "mime-types": "~2.1.34", 21 | "negotiator": "0.6.3" 22 | }, 23 | "engines": { 24 | "node": ">= 0.6" 25 | } 26 | }, 27 | "node_modules/array-flatten": { 28 | "version": "1.1.1", 29 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 30 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 31 | }, 32 | "node_modules/body-parser": { 33 | "version": "1.20.1", 34 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 35 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 36 | "dependencies": { 37 | "bytes": "3.1.2", 38 | "content-type": "~1.0.4", 39 | "debug": "2.6.9", 40 | "depd": "2.0.0", 41 | "destroy": "1.2.0", 42 | "http-errors": "2.0.0", 43 | "iconv-lite": "0.4.24", 44 | "on-finished": "2.4.1", 45 | "qs": "6.11.0", 46 | "raw-body": "2.5.1", 47 | "type-is": "~1.6.18", 48 | "unpipe": "1.0.0" 49 | }, 50 | "engines": { 51 | "node": ">= 0.8", 52 | "npm": "1.2.8000 || >= 1.4.16" 53 | } 54 | }, 55 | "node_modules/bytes": { 56 | "version": "3.1.2", 57 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 58 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 59 | "engines": { 60 | "node": ">= 0.8" 61 | } 62 | }, 63 | "node_modules/call-bind": { 64 | "version": "1.0.2", 65 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 66 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 67 | "dependencies": { 68 | "function-bind": "^1.1.1", 69 | "get-intrinsic": "^1.0.2" 70 | }, 71 | "funding": { 72 | "url": "https://github.com/sponsors/ljharb" 73 | } 74 | }, 75 | "node_modules/content-disposition": { 76 | "version": "0.5.4", 77 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 78 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 79 | "dependencies": { 80 | "safe-buffer": "5.2.1" 81 | }, 82 | "engines": { 83 | "node": ">= 0.6" 84 | } 85 | }, 86 | "node_modules/content-type": { 87 | "version": "1.0.4", 88 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 89 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 90 | "engines": { 91 | "node": ">= 0.6" 92 | } 93 | }, 94 | "node_modules/cookie": { 95 | "version": "0.5.0", 96 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 97 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 98 | "engines": { 99 | "node": ">= 0.6" 100 | } 101 | }, 102 | "node_modules/cookie-signature": { 103 | "version": "1.0.6", 104 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 105 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 106 | }, 107 | "node_modules/debug": { 108 | "version": "2.6.9", 109 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 110 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 111 | "dependencies": { 112 | "ms": "2.0.0" 113 | } 114 | }, 115 | "node_modules/depd": { 116 | "version": "2.0.0", 117 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 118 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 119 | "engines": { 120 | "node": ">= 0.8" 121 | } 122 | }, 123 | "node_modules/destroy": { 124 | "version": "1.2.0", 125 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 126 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 127 | "engines": { 128 | "node": ">= 0.8", 129 | "npm": "1.2.8000 || >= 1.4.16" 130 | } 131 | }, 132 | "node_modules/ee-first": { 133 | "version": "1.1.1", 134 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 135 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 136 | }, 137 | "node_modules/encodeurl": { 138 | "version": "1.0.2", 139 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 140 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 141 | "engines": { 142 | "node": ">= 0.8" 143 | } 144 | }, 145 | "node_modules/escape-html": { 146 | "version": "1.0.3", 147 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 148 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 149 | }, 150 | "node_modules/etag": { 151 | "version": "1.8.1", 152 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 153 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 154 | "engines": { 155 | "node": ">= 0.6" 156 | } 157 | }, 158 | "node_modules/express": { 159 | "version": "4.18.2", 160 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 161 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 162 | "dependencies": { 163 | "accepts": "~1.3.8", 164 | "array-flatten": "1.1.1", 165 | "body-parser": "1.20.1", 166 | "content-disposition": "0.5.4", 167 | "content-type": "~1.0.4", 168 | "cookie": "0.5.0", 169 | "cookie-signature": "1.0.6", 170 | "debug": "2.6.9", 171 | "depd": "2.0.0", 172 | "encodeurl": "~1.0.2", 173 | "escape-html": "~1.0.3", 174 | "etag": "~1.8.1", 175 | "finalhandler": "1.2.0", 176 | "fresh": "0.5.2", 177 | "http-errors": "2.0.0", 178 | "merge-descriptors": "1.0.1", 179 | "methods": "~1.1.2", 180 | "on-finished": "2.4.1", 181 | "parseurl": "~1.3.3", 182 | "path-to-regexp": "0.1.7", 183 | "proxy-addr": "~2.0.7", 184 | "qs": "6.11.0", 185 | "range-parser": "~1.2.1", 186 | "safe-buffer": "5.2.1", 187 | "send": "0.18.0", 188 | "serve-static": "1.15.0", 189 | "setprototypeof": "1.2.0", 190 | "statuses": "2.0.1", 191 | "type-is": "~1.6.18", 192 | "utils-merge": "1.0.1", 193 | "vary": "~1.1.2" 194 | }, 195 | "engines": { 196 | "node": ">= 0.10.0" 197 | } 198 | }, 199 | "node_modules/finalhandler": { 200 | "version": "1.2.0", 201 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 202 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 203 | "dependencies": { 204 | "debug": "2.6.9", 205 | "encodeurl": "~1.0.2", 206 | "escape-html": "~1.0.3", 207 | "on-finished": "2.4.1", 208 | "parseurl": "~1.3.3", 209 | "statuses": "2.0.1", 210 | "unpipe": "~1.0.0" 211 | }, 212 | "engines": { 213 | "node": ">= 0.8" 214 | } 215 | }, 216 | "node_modules/forwarded": { 217 | "version": "0.2.0", 218 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 219 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 220 | "engines": { 221 | "node": ">= 0.6" 222 | } 223 | }, 224 | "node_modules/fresh": { 225 | "version": "0.5.2", 226 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 227 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 228 | "engines": { 229 | "node": ">= 0.6" 230 | } 231 | }, 232 | "node_modules/function-bind": { 233 | "version": "1.1.1", 234 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 235 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 236 | }, 237 | "node_modules/get-intrinsic": { 238 | "version": "1.1.3", 239 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 240 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 241 | "dependencies": { 242 | "function-bind": "^1.1.1", 243 | "has": "^1.0.3", 244 | "has-symbols": "^1.0.3" 245 | }, 246 | "funding": { 247 | "url": "https://github.com/sponsors/ljharb" 248 | } 249 | }, 250 | "node_modules/has": { 251 | "version": "1.0.3", 252 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 253 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 254 | "dependencies": { 255 | "function-bind": "^1.1.1" 256 | }, 257 | "engines": { 258 | "node": ">= 0.4.0" 259 | } 260 | }, 261 | "node_modules/has-symbols": { 262 | "version": "1.0.3", 263 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 264 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 265 | "engines": { 266 | "node": ">= 0.4" 267 | }, 268 | "funding": { 269 | "url": "https://github.com/sponsors/ljharb" 270 | } 271 | }, 272 | "node_modules/http-errors": { 273 | "version": "2.0.0", 274 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 275 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 276 | "dependencies": { 277 | "depd": "2.0.0", 278 | "inherits": "2.0.4", 279 | "setprototypeof": "1.2.0", 280 | "statuses": "2.0.1", 281 | "toidentifier": "1.0.1" 282 | }, 283 | "engines": { 284 | "node": ">= 0.8" 285 | } 286 | }, 287 | "node_modules/iconv-lite": { 288 | "version": "0.4.24", 289 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 290 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 291 | "dependencies": { 292 | "safer-buffer": ">= 2.1.2 < 3" 293 | }, 294 | "engines": { 295 | "node": ">=0.10.0" 296 | } 297 | }, 298 | "node_modules/inherits": { 299 | "version": "2.0.4", 300 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 301 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 302 | }, 303 | "node_modules/ipaddr.js": { 304 | "version": "1.9.1", 305 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 306 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 307 | "engines": { 308 | "node": ">= 0.10" 309 | } 310 | }, 311 | "node_modules/media-typer": { 312 | "version": "0.3.0", 313 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 314 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 315 | "engines": { 316 | "node": ">= 0.6" 317 | } 318 | }, 319 | "node_modules/merge-descriptors": { 320 | "version": "1.0.1", 321 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 322 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 323 | }, 324 | "node_modules/methods": { 325 | "version": "1.1.2", 326 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 327 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 328 | "engines": { 329 | "node": ">= 0.6" 330 | } 331 | }, 332 | "node_modules/mime": { 333 | "version": "1.6.0", 334 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 335 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 336 | "bin": { 337 | "mime": "cli.js" 338 | }, 339 | "engines": { 340 | "node": ">=4" 341 | } 342 | }, 343 | "node_modules/mime-db": { 344 | "version": "1.52.0", 345 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 346 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 347 | "engines": { 348 | "node": ">= 0.6" 349 | } 350 | }, 351 | "node_modules/mime-types": { 352 | "version": "2.1.35", 353 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 354 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 355 | "dependencies": { 356 | "mime-db": "1.52.0" 357 | }, 358 | "engines": { 359 | "node": ">= 0.6" 360 | } 361 | }, 362 | "node_modules/ms": { 363 | "version": "2.0.0", 364 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 365 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 366 | }, 367 | "node_modules/negotiator": { 368 | "version": "0.6.3", 369 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 370 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 371 | "engines": { 372 | "node": ">= 0.6" 373 | } 374 | }, 375 | "node_modules/object-inspect": { 376 | "version": "1.12.2", 377 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 378 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 379 | "funding": { 380 | "url": "https://github.com/sponsors/ljharb" 381 | } 382 | }, 383 | "node_modules/on-finished": { 384 | "version": "2.4.1", 385 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 386 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 387 | "dependencies": { 388 | "ee-first": "1.1.1" 389 | }, 390 | "engines": { 391 | "node": ">= 0.8" 392 | } 393 | }, 394 | "node_modules/parseurl": { 395 | "version": "1.3.3", 396 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 397 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 398 | "engines": { 399 | "node": ">= 0.8" 400 | } 401 | }, 402 | "node_modules/path-to-regexp": { 403 | "version": "0.1.7", 404 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 405 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 406 | }, 407 | "node_modules/proxy-addr": { 408 | "version": "2.0.7", 409 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 410 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 411 | "dependencies": { 412 | "forwarded": "0.2.0", 413 | "ipaddr.js": "1.9.1" 414 | }, 415 | "engines": { 416 | "node": ">= 0.10" 417 | } 418 | }, 419 | "node_modules/qs": { 420 | "version": "6.11.0", 421 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 422 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 423 | "dependencies": { 424 | "side-channel": "^1.0.4" 425 | }, 426 | "engines": { 427 | "node": ">=0.6" 428 | }, 429 | "funding": { 430 | "url": "https://github.com/sponsors/ljharb" 431 | } 432 | }, 433 | "node_modules/range-parser": { 434 | "version": "1.2.1", 435 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 436 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 437 | "engines": { 438 | "node": ">= 0.6" 439 | } 440 | }, 441 | "node_modules/raw-body": { 442 | "version": "2.5.1", 443 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 444 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 445 | "dependencies": { 446 | "bytes": "3.1.2", 447 | "http-errors": "2.0.0", 448 | "iconv-lite": "0.4.24", 449 | "unpipe": "1.0.0" 450 | }, 451 | "engines": { 452 | "node": ">= 0.8" 453 | } 454 | }, 455 | "node_modules/safe-buffer": { 456 | "version": "5.2.1", 457 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 458 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 459 | "funding": [ 460 | { 461 | "type": "github", 462 | "url": "https://github.com/sponsors/feross" 463 | }, 464 | { 465 | "type": "patreon", 466 | "url": "https://www.patreon.com/feross" 467 | }, 468 | { 469 | "type": "consulting", 470 | "url": "https://feross.org/support" 471 | } 472 | ] 473 | }, 474 | "node_modules/safer-buffer": { 475 | "version": "2.1.2", 476 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 477 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 478 | }, 479 | "node_modules/send": { 480 | "version": "0.18.0", 481 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 482 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 483 | "dependencies": { 484 | "debug": "2.6.9", 485 | "depd": "2.0.0", 486 | "destroy": "1.2.0", 487 | "encodeurl": "~1.0.2", 488 | "escape-html": "~1.0.3", 489 | "etag": "~1.8.1", 490 | "fresh": "0.5.2", 491 | "http-errors": "2.0.0", 492 | "mime": "1.6.0", 493 | "ms": "2.1.3", 494 | "on-finished": "2.4.1", 495 | "range-parser": "~1.2.1", 496 | "statuses": "2.0.1" 497 | }, 498 | "engines": { 499 | "node": ">= 0.8.0" 500 | } 501 | }, 502 | "node_modules/send/node_modules/ms": { 503 | "version": "2.1.3", 504 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 505 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 506 | }, 507 | "node_modules/serve-static": { 508 | "version": "1.15.0", 509 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 510 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 511 | "dependencies": { 512 | "encodeurl": "~1.0.2", 513 | "escape-html": "~1.0.3", 514 | "parseurl": "~1.3.3", 515 | "send": "0.18.0" 516 | }, 517 | "engines": { 518 | "node": ">= 0.8.0" 519 | } 520 | }, 521 | "node_modules/setprototypeof": { 522 | "version": "1.2.0", 523 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 524 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 525 | }, 526 | "node_modules/side-channel": { 527 | "version": "1.0.4", 528 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 529 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 530 | "dependencies": { 531 | "call-bind": "^1.0.0", 532 | "get-intrinsic": "^1.0.2", 533 | "object-inspect": "^1.9.0" 534 | }, 535 | "funding": { 536 | "url": "https://github.com/sponsors/ljharb" 537 | } 538 | }, 539 | "node_modules/statuses": { 540 | "version": "2.0.1", 541 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 542 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 543 | "engines": { 544 | "node": ">= 0.8" 545 | } 546 | }, 547 | "node_modules/toidentifier": { 548 | "version": "1.0.1", 549 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 550 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 551 | "engines": { 552 | "node": ">=0.6" 553 | } 554 | }, 555 | "node_modules/type-is": { 556 | "version": "1.6.18", 557 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 558 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 559 | "dependencies": { 560 | "media-typer": "0.3.0", 561 | "mime-types": "~2.1.24" 562 | }, 563 | "engines": { 564 | "node": ">= 0.6" 565 | } 566 | }, 567 | "node_modules/unpipe": { 568 | "version": "1.0.0", 569 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 570 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 571 | "engines": { 572 | "node": ">= 0.8" 573 | } 574 | }, 575 | "node_modules/utils-merge": { 576 | "version": "1.0.1", 577 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 578 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 579 | "engines": { 580 | "node": ">= 0.4.0" 581 | } 582 | }, 583 | "node_modules/vary": { 584 | "version": "1.1.2", 585 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 586 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 587 | "engines": { 588 | "node": ">= 0.8" 589 | } 590 | } 591 | }, 592 | "dependencies": { 593 | "accepts": { 594 | "version": "1.3.8", 595 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 596 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 597 | "requires": { 598 | "mime-types": "~2.1.34", 599 | "negotiator": "0.6.3" 600 | } 601 | }, 602 | "array-flatten": { 603 | "version": "1.1.1", 604 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 605 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 606 | }, 607 | "body-parser": { 608 | "version": "1.20.1", 609 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 610 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 611 | "requires": { 612 | "bytes": "3.1.2", 613 | "content-type": "~1.0.4", 614 | "debug": "2.6.9", 615 | "depd": "2.0.0", 616 | "destroy": "1.2.0", 617 | "http-errors": "2.0.0", 618 | "iconv-lite": "0.4.24", 619 | "on-finished": "2.4.1", 620 | "qs": "6.11.0", 621 | "raw-body": "2.5.1", 622 | "type-is": "~1.6.18", 623 | "unpipe": "1.0.0" 624 | } 625 | }, 626 | "bytes": { 627 | "version": "3.1.2", 628 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 629 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 630 | }, 631 | "call-bind": { 632 | "version": "1.0.2", 633 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 634 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 635 | "requires": { 636 | "function-bind": "^1.1.1", 637 | "get-intrinsic": "^1.0.2" 638 | } 639 | }, 640 | "content-disposition": { 641 | "version": "0.5.4", 642 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 643 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 644 | "requires": { 645 | "safe-buffer": "5.2.1" 646 | } 647 | }, 648 | "content-type": { 649 | "version": "1.0.4", 650 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 651 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 652 | }, 653 | "cookie": { 654 | "version": "0.5.0", 655 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 656 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 657 | }, 658 | "cookie-signature": { 659 | "version": "1.0.6", 660 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 661 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 662 | }, 663 | "debug": { 664 | "version": "2.6.9", 665 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 666 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 667 | "requires": { 668 | "ms": "2.0.0" 669 | } 670 | }, 671 | "depd": { 672 | "version": "2.0.0", 673 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 674 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 675 | }, 676 | "destroy": { 677 | "version": "1.2.0", 678 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 679 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 680 | }, 681 | "ee-first": { 682 | "version": "1.1.1", 683 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 684 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 685 | }, 686 | "encodeurl": { 687 | "version": "1.0.2", 688 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 689 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 690 | }, 691 | "escape-html": { 692 | "version": "1.0.3", 693 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 694 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 695 | }, 696 | "etag": { 697 | "version": "1.8.1", 698 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 699 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 700 | }, 701 | "express": { 702 | "version": "4.18.2", 703 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 704 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 705 | "requires": { 706 | "accepts": "~1.3.8", 707 | "array-flatten": "1.1.1", 708 | "body-parser": "1.20.1", 709 | "content-disposition": "0.5.4", 710 | "content-type": "~1.0.4", 711 | "cookie": "0.5.0", 712 | "cookie-signature": "1.0.6", 713 | "debug": "2.6.9", 714 | "depd": "2.0.0", 715 | "encodeurl": "~1.0.2", 716 | "escape-html": "~1.0.3", 717 | "etag": "~1.8.1", 718 | "finalhandler": "1.2.0", 719 | "fresh": "0.5.2", 720 | "http-errors": "2.0.0", 721 | "merge-descriptors": "1.0.1", 722 | "methods": "~1.1.2", 723 | "on-finished": "2.4.1", 724 | "parseurl": "~1.3.3", 725 | "path-to-regexp": "0.1.7", 726 | "proxy-addr": "~2.0.7", 727 | "qs": "6.11.0", 728 | "range-parser": "~1.2.1", 729 | "safe-buffer": "5.2.1", 730 | "send": "0.18.0", 731 | "serve-static": "1.15.0", 732 | "setprototypeof": "1.2.0", 733 | "statuses": "2.0.1", 734 | "type-is": "~1.6.18", 735 | "utils-merge": "1.0.1", 736 | "vary": "~1.1.2" 737 | } 738 | }, 739 | "finalhandler": { 740 | "version": "1.2.0", 741 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 742 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 743 | "requires": { 744 | "debug": "2.6.9", 745 | "encodeurl": "~1.0.2", 746 | "escape-html": "~1.0.3", 747 | "on-finished": "2.4.1", 748 | "parseurl": "~1.3.3", 749 | "statuses": "2.0.1", 750 | "unpipe": "~1.0.0" 751 | } 752 | }, 753 | "forwarded": { 754 | "version": "0.2.0", 755 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 756 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 757 | }, 758 | "fresh": { 759 | "version": "0.5.2", 760 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 761 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 762 | }, 763 | "function-bind": { 764 | "version": "1.1.1", 765 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 766 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 767 | }, 768 | "get-intrinsic": { 769 | "version": "1.1.3", 770 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 771 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 772 | "requires": { 773 | "function-bind": "^1.1.1", 774 | "has": "^1.0.3", 775 | "has-symbols": "^1.0.3" 776 | } 777 | }, 778 | "has": { 779 | "version": "1.0.3", 780 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 781 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 782 | "requires": { 783 | "function-bind": "^1.1.1" 784 | } 785 | }, 786 | "has-symbols": { 787 | "version": "1.0.3", 788 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 789 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 790 | }, 791 | "http-errors": { 792 | "version": "2.0.0", 793 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 794 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 795 | "requires": { 796 | "depd": "2.0.0", 797 | "inherits": "2.0.4", 798 | "setprototypeof": "1.2.0", 799 | "statuses": "2.0.1", 800 | "toidentifier": "1.0.1" 801 | } 802 | }, 803 | "iconv-lite": { 804 | "version": "0.4.24", 805 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 806 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 807 | "requires": { 808 | "safer-buffer": ">= 2.1.2 < 3" 809 | } 810 | }, 811 | "inherits": { 812 | "version": "2.0.4", 813 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 814 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 815 | }, 816 | "ipaddr.js": { 817 | "version": "1.9.1", 818 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 819 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 820 | }, 821 | "media-typer": { 822 | "version": "0.3.0", 823 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 824 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 825 | }, 826 | "merge-descriptors": { 827 | "version": "1.0.1", 828 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 829 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 830 | }, 831 | "methods": { 832 | "version": "1.1.2", 833 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 834 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 835 | }, 836 | "mime": { 837 | "version": "1.6.0", 838 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 839 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 840 | }, 841 | "mime-db": { 842 | "version": "1.52.0", 843 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 844 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 845 | }, 846 | "mime-types": { 847 | "version": "2.1.35", 848 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 849 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 850 | "requires": { 851 | "mime-db": "1.52.0" 852 | } 853 | }, 854 | "ms": { 855 | "version": "2.0.0", 856 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 857 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 858 | }, 859 | "negotiator": { 860 | "version": "0.6.3", 861 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 862 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 863 | }, 864 | "object-inspect": { 865 | "version": "1.12.2", 866 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 867 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 868 | }, 869 | "on-finished": { 870 | "version": "2.4.1", 871 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 872 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 873 | "requires": { 874 | "ee-first": "1.1.1" 875 | } 876 | }, 877 | "parseurl": { 878 | "version": "1.3.3", 879 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 880 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 881 | }, 882 | "path-to-regexp": { 883 | "version": "0.1.7", 884 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 885 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 886 | }, 887 | "proxy-addr": { 888 | "version": "2.0.7", 889 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 890 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 891 | "requires": { 892 | "forwarded": "0.2.0", 893 | "ipaddr.js": "1.9.1" 894 | } 895 | }, 896 | "qs": { 897 | "version": "6.11.0", 898 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 899 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 900 | "requires": { 901 | "side-channel": "^1.0.4" 902 | } 903 | }, 904 | "range-parser": { 905 | "version": "1.2.1", 906 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 907 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 908 | }, 909 | "raw-body": { 910 | "version": "2.5.1", 911 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 912 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 913 | "requires": { 914 | "bytes": "3.1.2", 915 | "http-errors": "2.0.0", 916 | "iconv-lite": "0.4.24", 917 | "unpipe": "1.0.0" 918 | } 919 | }, 920 | "safe-buffer": { 921 | "version": "5.2.1", 922 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 923 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 924 | }, 925 | "safer-buffer": { 926 | "version": "2.1.2", 927 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 928 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 929 | }, 930 | "send": { 931 | "version": "0.18.0", 932 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 933 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 934 | "requires": { 935 | "debug": "2.6.9", 936 | "depd": "2.0.0", 937 | "destroy": "1.2.0", 938 | "encodeurl": "~1.0.2", 939 | "escape-html": "~1.0.3", 940 | "etag": "~1.8.1", 941 | "fresh": "0.5.2", 942 | "http-errors": "2.0.0", 943 | "mime": "1.6.0", 944 | "ms": "2.1.3", 945 | "on-finished": "2.4.1", 946 | "range-parser": "~1.2.1", 947 | "statuses": "2.0.1" 948 | }, 949 | "dependencies": { 950 | "ms": { 951 | "version": "2.1.3", 952 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 953 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 954 | } 955 | } 956 | }, 957 | "serve-static": { 958 | "version": "1.15.0", 959 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 960 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 961 | "requires": { 962 | "encodeurl": "~1.0.2", 963 | "escape-html": "~1.0.3", 964 | "parseurl": "~1.3.3", 965 | "send": "0.18.0" 966 | } 967 | }, 968 | "setprototypeof": { 969 | "version": "1.2.0", 970 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 971 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 972 | }, 973 | "side-channel": { 974 | "version": "1.0.4", 975 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 976 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 977 | "requires": { 978 | "call-bind": "^1.0.0", 979 | "get-intrinsic": "^1.0.2", 980 | "object-inspect": "^1.9.0" 981 | } 982 | }, 983 | "statuses": { 984 | "version": "2.0.1", 985 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 986 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 987 | }, 988 | "toidentifier": { 989 | "version": "1.0.1", 990 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 991 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 992 | }, 993 | "type-is": { 994 | "version": "1.6.18", 995 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 996 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 997 | "requires": { 998 | "media-typer": "0.3.0", 999 | "mime-types": "~2.1.24" 1000 | } 1001 | }, 1002 | "unpipe": { 1003 | "version": "1.0.0", 1004 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1005 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1006 | }, 1007 | "utils-merge": { 1008 | "version": "1.0.1", 1009 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1010 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1011 | }, 1012 | "vary": { 1013 | "version": "1.1.2", 1014 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1015 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1016 | } 1017 | } 1018 | } 1019 | -------------------------------------------------------------------------------- /api-learnv2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-learnv2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "nodemon app.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.18.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /api-learnv2/src/middlewares/middleware.js: -------------------------------------------------------------------------------- 1 | const authControl = (req, res, next) => { 2 | const isToken = true 3 | if (isToken) { 4 | next() 5 | } else { 6 | res.json({ 7 | succes: false, 8 | message: "No token provided!" 9 | }) 10 | } 11 | } 12 | 13 | const banControl = (req, res, next) => { 14 | const isBanned = false 15 | if (isBanned) { 16 | res.json({ 17 | succes: false, 18 | message: "You are banned user!" 19 | }) 20 | } else { 21 | next() 22 | } 23 | } 24 | 25 | const homeControl = (req, res, next) => { 26 | console.log("home control") 27 | next() 28 | } 29 | 30 | module.exports = { 31 | authControl, 32 | banControl, 33 | homeControl, 34 | } -------------------------------------------------------------------------------- /e-commerce-mysql/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/.DS_Store -------------------------------------------------------------------------------- /e-commerce-mysql/README.md: -------------------------------------------------------------------------------- 1 | ## 💻 Basic E-Commerce 2 | 3 | ### 🔎 Preview 4 | https://user-images.githubusercontent.com/55639112/194768553-8f44f112-6c84-4933-9ad8-2e44834eddec.mov 5 | 6 | ### 📁 Description 7 | Hello everyone! This is my first back-end project in software development. The project was written node.js programming langueage and with MySql Database. Project shows data on mysql database with ejs template engine. Also when I was coding of the design I used Bootstrap 5.2 version. The Home Screen was shown products. If you click to product name You can visit product detail page. Aside from that If you click to product tab on of the website You can visit product page and If you click to home tab on of the website You can visit home page. In pages of all data were come from mysql database. I am gonna show database scheme under chapter. 8 | 9 | ### 🚀 Database 10 | database_scheme 11 | data 12 | 13 | ### 🧑🏻‍💻 Coding 14 | I tried to write the code of this project as clean as possible and I learnt node.js, node.js routes, express, ejs and mysql. 15 | -------------------------------------------------------------------------------- /e-commerce-mysql/data/db.js: -------------------------------------------------------------------------------- 1 | const mysql = require("mysql2") 2 | const config = require("../config") 3 | 4 | let dbConnection = mysql.createConnection(config.db) 5 | 6 | dbConnection.connect(function (err) { 7 | if (err) { 8 | console.error(err); 9 | } 10 | dbConnection.query("select * from Products", function (err, res) { 11 | console.log(res[0]) 12 | console.log("********") 13 | }) 14 | dbConnection.query("select * from Products where price > 25000.00", function (err, res) { 15 | console.log(res) 16 | console.log("********") 17 | }) 18 | console.log("db connection was successful") 19 | 20 | }) 21 | 22 | module.exports = dbConnection.promise(); -------------------------------------------------------------------------------- /e-commerce-mysql/default_index.js: -------------------------------------------------------------------------------- 1 | 2 | var http = require("http"); 3 | var fs = require("fs"); 4 | 5 | var server = http.createServer((req, res) => { 6 | switch (req.url) { 7 | case "/": 8 | readFile("views/index.html", res); 9 | break; 10 | case "/products": 11 | readFile("views/products.html", res); 12 | break; 13 | default: 14 | readFile("views/404.html", res); 15 | break; 16 | } 17 | }); 18 | 19 | function readFile(path, res) { 20 | fs.readFile(path, (err, html) => { 21 | if (err) { 22 | res.write("

the page was crashed!

"); 23 | res.end(); 24 | } else { 25 | res.write(html); 26 | res.end(); 27 | } 28 | }) 29 | } 30 | 31 | server.listen(5096, () => { 32 | console.log("node.js server was opened at port 5096!"); 33 | }); -------------------------------------------------------------------------------- /e-commerce-mysql/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const app = express() 3 | const port = 5097 4 | const routes = require("./routes/users") 5 | 6 | app.set("view engine", "ejs") 7 | app.use(express.static("public")) 8 | app.use(express.static("node_modules")) 9 | 10 | app.use(routes) 11 | 12 | 13 | app.listen(port, () => { 14 | /// [If you wanna use variable in string, you should use the code below.] 15 | console.log(`Example app listening on port ${port}`); 16 | }); 17 | 18 | 19 | -------------------------------------------------------------------------------- /e-commerce-mysql/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learn_node", 3 | "version": "1.0.0", 4 | "description": "Will be continued!", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/akaanuzman/learn_node.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/akaanuzman/learn_node/issues" 18 | }, 19 | "homepage": "https://github.com/akaanuzman/learn_node#readme", 20 | "dependencies": { 21 | "bootstrap": "^5.2.2", 22 | "ejs": "^3.1.8", 23 | "express": "^4.18.1", 24 | "mysql2": "^2.3.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /e-commerce-mysql/public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/.DS_Store -------------------------------------------------------------------------------- /e-commerce-mysql/public/images/1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/images/1.webp -------------------------------------------------------------------------------- /e-commerce-mysql/public/images/2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/images/2.webp -------------------------------------------------------------------------------- /e-commerce-mysql/public/images/3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/images/3.webp -------------------------------------------------------------------------------- /e-commerce-mysql/public/images/4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/images/4.webp -------------------------------------------------------------------------------- /e-commerce-mysql/public/images/5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/e-commerce-mysql/public/images/5.webp -------------------------------------------------------------------------------- /e-commerce-mysql/routes/users.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const router = express.Router() 3 | const db = require("../data/db") 4 | 5 | /// Nodejs route struct 6 | router.get("/products/:id", async (req, res) => { 7 | try { 8 | const [products,] = await db.execute("select * from Products where id=?", [req.params.id]) 9 | res.render("product_details", { 10 | products: products[0] 11 | }) 12 | } catch (err) { 13 | console.error(err) 14 | } 15 | }); 16 | 17 | router.get("/products", (req, res) => { 18 | try { 19 | fetchData(res, "select * from Products where isActive = 1", "products") 20 | } catch (err) { 21 | console.error(err) 22 | } 23 | }); 24 | 25 | router.get("/", (req, res) => { 26 | 27 | /// MARK: Async - await usage 28 | try { 29 | fetchData(res, "select * from Products where isHome = 1 and isActive = 1", "index") 30 | } catch (err) { 31 | console.error(err) 32 | } 33 | 34 | /// MARK: Then - catch usage 35 | // db.execute("select * from Products") 36 | // .then(response => { 37 | // console.log(response[0]); 38 | // res.render("index", { 39 | // products: response[0] 40 | // }) 41 | // }) 42 | // .catch(err => console.error(err)) 43 | }); 44 | 45 | async function fetchData(res, query, pageUrl) { 46 | const [products,] = await db.execute(query) 47 | res.render(pageUrl, { 48 | products: products 49 | }) 50 | } 51 | 52 | module.exports = router; -------------------------------------------------------------------------------- /e-commerce-mysql/views/404.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 404 8 | 9 | 10 |

404 Page is not found!

11 | 12 | -------------------------------------------------------------------------------- /e-commerce-mysql/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Home 10 | 11 | 12 | 13 | <%- include("partials/navbar.ejs") %> 14 |

Home

15 |
16 |
17 |
18 | <% products.forEach(product=> { %> 19 | <% if (product.isHome) { %> 20 | <%- include("partials/product.ejs",product) %> 21 | <% } %> 22 | <% }) %> 23 |
24 |
25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /e-commerce-mysql/views/partials/navbar.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /e-commerce-mysql/views/partials/product.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 | 9 |
10 | Product: <%= name %> 11 |
12 |
13 |

14 | Price: <%= price %>₺ 15 |

16 |

17 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum, a? Dicta 18 | libero quibusdam amet similique iusto inventore aut labore molestias natus 19 | cum explicabo odio unde, repellat sed in, nam perspiciatis fuga a ratione. 20 | Quis, animi odit! Officia, odio soluta cupiditate nesciunt error sequi 21 | tempore dolores, quia ea quas ipsa possimus! Perspiciatis nihil modi eum 22 | facere deleniti totam, repellat mollitia, quos dicta iste quisquam fuga, 23 | voluptatem a ipsam similique. Id quia beatae reprehenderit rerum dicta 24 | nostrum saepe ullam, commodi maxime? Reiciendis nisi minima mollitia! 25 | Quaerat, corporis excepturi tempora debitis minima similique voluptates quas 26 | reprehenderit, labore earum amet? Expedita, dolore sunt? A! 27 |

28 |

29 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Rerum, a? Dicta 30 | libero quibusdam amet similique iusto inventore aut labore molestias natus 31 | cum explicabo odio unde, repellat sed in, nam perspiciatis fuga a ratione. 32 | Quis, animi odit! Officia, odio soluta cupiditate nesciunt error sequi 33 | tempore dolores, quia ea quas ipsa possimus! Perspiciatis nihil modi eum 34 | facere deleniti totam, repellat mollitia, quos dicta iste quisquam fuga, 35 | voluptatem a ipsam similique. Id quia beatae reprehenderit rerum dicta 36 | nostrum saepe ullam, commodi maxime? Reiciendis nisi minima mollitia! 37 | Quaerat, corporis excepturi tempora debitis minima similique voluptates quas 38 | reprehenderit, labore earum amet? Expedita, dolore sunt? A! 39 |

40 |
41 |
42 |
43 |
-------------------------------------------------------------------------------- /e-commerce-mysql/views/product_details.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Product Details 10 | 11 | 12 | 13 | <%- include("partials/navbar.ejs") %> 14 |

Product Details

15 |
16 |
17 |
18 | <%- include("partials/product.ejs",products) %> 19 |
20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /e-commerce-mysql/views/products.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Products 10 | 11 | 12 | 13 | <%- include("partials/navbar.ejs") %> 14 |

Products

15 |
16 |
17 |
18 | <% products.forEach(product=> { %> 19 | <% if (product.isActive) { %> 20 | <%- include("partials/product.ejs",product) %> 21 | <% } %> 22 | <% }) %> 23 |
24 |
25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /patient-system-api/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patient-system-api", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "patient-system-api", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "dotenv": "^16.0.3", 13 | "express": "^4.18.2" 14 | } 15 | }, 16 | "node_modules/accepts": { 17 | "version": "1.3.8", 18 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 19 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 20 | "dependencies": { 21 | "mime-types": "~2.1.34", 22 | "negotiator": "0.6.3" 23 | }, 24 | "engines": { 25 | "node": ">= 0.6" 26 | } 27 | }, 28 | "node_modules/array-flatten": { 29 | "version": "1.1.1", 30 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 31 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 32 | }, 33 | "node_modules/body-parser": { 34 | "version": "1.20.1", 35 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 36 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 37 | "dependencies": { 38 | "bytes": "3.1.2", 39 | "content-type": "~1.0.4", 40 | "debug": "2.6.9", 41 | "depd": "2.0.0", 42 | "destroy": "1.2.0", 43 | "http-errors": "2.0.0", 44 | "iconv-lite": "0.4.24", 45 | "on-finished": "2.4.1", 46 | "qs": "6.11.0", 47 | "raw-body": "2.5.1", 48 | "type-is": "~1.6.18", 49 | "unpipe": "1.0.0" 50 | }, 51 | "engines": { 52 | "node": ">= 0.8", 53 | "npm": "1.2.8000 || >= 1.4.16" 54 | } 55 | }, 56 | "node_modules/bytes": { 57 | "version": "3.1.2", 58 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 59 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 60 | "engines": { 61 | "node": ">= 0.8" 62 | } 63 | }, 64 | "node_modules/call-bind": { 65 | "version": "1.0.2", 66 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 67 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 68 | "dependencies": { 69 | "function-bind": "^1.1.1", 70 | "get-intrinsic": "^1.0.2" 71 | }, 72 | "funding": { 73 | "url": "https://github.com/sponsors/ljharb" 74 | } 75 | }, 76 | "node_modules/content-disposition": { 77 | "version": "0.5.4", 78 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 79 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 80 | "dependencies": { 81 | "safe-buffer": "5.2.1" 82 | }, 83 | "engines": { 84 | "node": ">= 0.6" 85 | } 86 | }, 87 | "node_modules/content-type": { 88 | "version": "1.0.4", 89 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 90 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 91 | "engines": { 92 | "node": ">= 0.6" 93 | } 94 | }, 95 | "node_modules/cookie": { 96 | "version": "0.5.0", 97 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 98 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 99 | "engines": { 100 | "node": ">= 0.6" 101 | } 102 | }, 103 | "node_modules/cookie-signature": { 104 | "version": "1.0.6", 105 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 106 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 107 | }, 108 | "node_modules/debug": { 109 | "version": "2.6.9", 110 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 111 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 112 | "dependencies": { 113 | "ms": "2.0.0" 114 | } 115 | }, 116 | "node_modules/depd": { 117 | "version": "2.0.0", 118 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 119 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 120 | "engines": { 121 | "node": ">= 0.8" 122 | } 123 | }, 124 | "node_modules/destroy": { 125 | "version": "1.2.0", 126 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 127 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 128 | "engines": { 129 | "node": ">= 0.8", 130 | "npm": "1.2.8000 || >= 1.4.16" 131 | } 132 | }, 133 | "node_modules/dotenv": { 134 | "version": "16.0.3", 135 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", 136 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", 137 | "engines": { 138 | "node": ">=12" 139 | } 140 | }, 141 | "node_modules/ee-first": { 142 | "version": "1.1.1", 143 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 144 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 145 | }, 146 | "node_modules/encodeurl": { 147 | "version": "1.0.2", 148 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 149 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 150 | "engines": { 151 | "node": ">= 0.8" 152 | } 153 | }, 154 | "node_modules/escape-html": { 155 | "version": "1.0.3", 156 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 157 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 158 | }, 159 | "node_modules/etag": { 160 | "version": "1.8.1", 161 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 162 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 163 | "engines": { 164 | "node": ">= 0.6" 165 | } 166 | }, 167 | "node_modules/express": { 168 | "version": "4.18.2", 169 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 170 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 171 | "dependencies": { 172 | "accepts": "~1.3.8", 173 | "array-flatten": "1.1.1", 174 | "body-parser": "1.20.1", 175 | "content-disposition": "0.5.4", 176 | "content-type": "~1.0.4", 177 | "cookie": "0.5.0", 178 | "cookie-signature": "1.0.6", 179 | "debug": "2.6.9", 180 | "depd": "2.0.0", 181 | "encodeurl": "~1.0.2", 182 | "escape-html": "~1.0.3", 183 | "etag": "~1.8.1", 184 | "finalhandler": "1.2.0", 185 | "fresh": "0.5.2", 186 | "http-errors": "2.0.0", 187 | "merge-descriptors": "1.0.1", 188 | "methods": "~1.1.2", 189 | "on-finished": "2.4.1", 190 | "parseurl": "~1.3.3", 191 | "path-to-regexp": "0.1.7", 192 | "proxy-addr": "~2.0.7", 193 | "qs": "6.11.0", 194 | "range-parser": "~1.2.1", 195 | "safe-buffer": "5.2.1", 196 | "send": "0.18.0", 197 | "serve-static": "1.15.0", 198 | "setprototypeof": "1.2.0", 199 | "statuses": "2.0.1", 200 | "type-is": "~1.6.18", 201 | "utils-merge": "1.0.1", 202 | "vary": "~1.1.2" 203 | }, 204 | "engines": { 205 | "node": ">= 0.10.0" 206 | } 207 | }, 208 | "node_modules/finalhandler": { 209 | "version": "1.2.0", 210 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 211 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 212 | "dependencies": { 213 | "debug": "2.6.9", 214 | "encodeurl": "~1.0.2", 215 | "escape-html": "~1.0.3", 216 | "on-finished": "2.4.1", 217 | "parseurl": "~1.3.3", 218 | "statuses": "2.0.1", 219 | "unpipe": "~1.0.0" 220 | }, 221 | "engines": { 222 | "node": ">= 0.8" 223 | } 224 | }, 225 | "node_modules/forwarded": { 226 | "version": "0.2.0", 227 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 228 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 229 | "engines": { 230 | "node": ">= 0.6" 231 | } 232 | }, 233 | "node_modules/fresh": { 234 | "version": "0.5.2", 235 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 236 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 237 | "engines": { 238 | "node": ">= 0.6" 239 | } 240 | }, 241 | "node_modules/function-bind": { 242 | "version": "1.1.1", 243 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 244 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 245 | }, 246 | "node_modules/get-intrinsic": { 247 | "version": "1.1.3", 248 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 249 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 250 | "dependencies": { 251 | "function-bind": "^1.1.1", 252 | "has": "^1.0.3", 253 | "has-symbols": "^1.0.3" 254 | }, 255 | "funding": { 256 | "url": "https://github.com/sponsors/ljharb" 257 | } 258 | }, 259 | "node_modules/has": { 260 | "version": "1.0.3", 261 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 262 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 263 | "dependencies": { 264 | "function-bind": "^1.1.1" 265 | }, 266 | "engines": { 267 | "node": ">= 0.4.0" 268 | } 269 | }, 270 | "node_modules/has-symbols": { 271 | "version": "1.0.3", 272 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 273 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 274 | "engines": { 275 | "node": ">= 0.4" 276 | }, 277 | "funding": { 278 | "url": "https://github.com/sponsors/ljharb" 279 | } 280 | }, 281 | "node_modules/http-errors": { 282 | "version": "2.0.0", 283 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 284 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 285 | "dependencies": { 286 | "depd": "2.0.0", 287 | "inherits": "2.0.4", 288 | "setprototypeof": "1.2.0", 289 | "statuses": "2.0.1", 290 | "toidentifier": "1.0.1" 291 | }, 292 | "engines": { 293 | "node": ">= 0.8" 294 | } 295 | }, 296 | "node_modules/iconv-lite": { 297 | "version": "0.4.24", 298 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 299 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 300 | "dependencies": { 301 | "safer-buffer": ">= 2.1.2 < 3" 302 | }, 303 | "engines": { 304 | "node": ">=0.10.0" 305 | } 306 | }, 307 | "node_modules/inherits": { 308 | "version": "2.0.4", 309 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 310 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 311 | }, 312 | "node_modules/ipaddr.js": { 313 | "version": "1.9.1", 314 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 315 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 316 | "engines": { 317 | "node": ">= 0.10" 318 | } 319 | }, 320 | "node_modules/media-typer": { 321 | "version": "0.3.0", 322 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 323 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 324 | "engines": { 325 | "node": ">= 0.6" 326 | } 327 | }, 328 | "node_modules/merge-descriptors": { 329 | "version": "1.0.1", 330 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 331 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 332 | }, 333 | "node_modules/methods": { 334 | "version": "1.1.2", 335 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 336 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 337 | "engines": { 338 | "node": ">= 0.6" 339 | } 340 | }, 341 | "node_modules/mime": { 342 | "version": "1.6.0", 343 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 344 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 345 | "bin": { 346 | "mime": "cli.js" 347 | }, 348 | "engines": { 349 | "node": ">=4" 350 | } 351 | }, 352 | "node_modules/mime-db": { 353 | "version": "1.52.0", 354 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 355 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 356 | "engines": { 357 | "node": ">= 0.6" 358 | } 359 | }, 360 | "node_modules/mime-types": { 361 | "version": "2.1.35", 362 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 363 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 364 | "dependencies": { 365 | "mime-db": "1.52.0" 366 | }, 367 | "engines": { 368 | "node": ">= 0.6" 369 | } 370 | }, 371 | "node_modules/ms": { 372 | "version": "2.0.0", 373 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 374 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 375 | }, 376 | "node_modules/negotiator": { 377 | "version": "0.6.3", 378 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 379 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 380 | "engines": { 381 | "node": ">= 0.6" 382 | } 383 | }, 384 | "node_modules/object-inspect": { 385 | "version": "1.12.2", 386 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 387 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", 388 | "funding": { 389 | "url": "https://github.com/sponsors/ljharb" 390 | } 391 | }, 392 | "node_modules/on-finished": { 393 | "version": "2.4.1", 394 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 395 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 396 | "dependencies": { 397 | "ee-first": "1.1.1" 398 | }, 399 | "engines": { 400 | "node": ">= 0.8" 401 | } 402 | }, 403 | "node_modules/parseurl": { 404 | "version": "1.3.3", 405 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 406 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 407 | "engines": { 408 | "node": ">= 0.8" 409 | } 410 | }, 411 | "node_modules/path-to-regexp": { 412 | "version": "0.1.7", 413 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 414 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 415 | }, 416 | "node_modules/proxy-addr": { 417 | "version": "2.0.7", 418 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 419 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 420 | "dependencies": { 421 | "forwarded": "0.2.0", 422 | "ipaddr.js": "1.9.1" 423 | }, 424 | "engines": { 425 | "node": ">= 0.10" 426 | } 427 | }, 428 | "node_modules/qs": { 429 | "version": "6.11.0", 430 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 431 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 432 | "dependencies": { 433 | "side-channel": "^1.0.4" 434 | }, 435 | "engines": { 436 | "node": ">=0.6" 437 | }, 438 | "funding": { 439 | "url": "https://github.com/sponsors/ljharb" 440 | } 441 | }, 442 | "node_modules/range-parser": { 443 | "version": "1.2.1", 444 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 445 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 446 | "engines": { 447 | "node": ">= 0.6" 448 | } 449 | }, 450 | "node_modules/raw-body": { 451 | "version": "2.5.1", 452 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 453 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 454 | "dependencies": { 455 | "bytes": "3.1.2", 456 | "http-errors": "2.0.0", 457 | "iconv-lite": "0.4.24", 458 | "unpipe": "1.0.0" 459 | }, 460 | "engines": { 461 | "node": ">= 0.8" 462 | } 463 | }, 464 | "node_modules/safe-buffer": { 465 | "version": "5.2.1", 466 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 467 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 468 | "funding": [ 469 | { 470 | "type": "github", 471 | "url": "https://github.com/sponsors/feross" 472 | }, 473 | { 474 | "type": "patreon", 475 | "url": "https://www.patreon.com/feross" 476 | }, 477 | { 478 | "type": "consulting", 479 | "url": "https://feross.org/support" 480 | } 481 | ] 482 | }, 483 | "node_modules/safer-buffer": { 484 | "version": "2.1.2", 485 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 486 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 487 | }, 488 | "node_modules/send": { 489 | "version": "0.18.0", 490 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 491 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 492 | "dependencies": { 493 | "debug": "2.6.9", 494 | "depd": "2.0.0", 495 | "destroy": "1.2.0", 496 | "encodeurl": "~1.0.2", 497 | "escape-html": "~1.0.3", 498 | "etag": "~1.8.1", 499 | "fresh": "0.5.2", 500 | "http-errors": "2.0.0", 501 | "mime": "1.6.0", 502 | "ms": "2.1.3", 503 | "on-finished": "2.4.1", 504 | "range-parser": "~1.2.1", 505 | "statuses": "2.0.1" 506 | }, 507 | "engines": { 508 | "node": ">= 0.8.0" 509 | } 510 | }, 511 | "node_modules/send/node_modules/ms": { 512 | "version": "2.1.3", 513 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 514 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 515 | }, 516 | "node_modules/serve-static": { 517 | "version": "1.15.0", 518 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 519 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 520 | "dependencies": { 521 | "encodeurl": "~1.0.2", 522 | "escape-html": "~1.0.3", 523 | "parseurl": "~1.3.3", 524 | "send": "0.18.0" 525 | }, 526 | "engines": { 527 | "node": ">= 0.8.0" 528 | } 529 | }, 530 | "node_modules/setprototypeof": { 531 | "version": "1.2.0", 532 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 533 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 534 | }, 535 | "node_modules/side-channel": { 536 | "version": "1.0.4", 537 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 538 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 539 | "dependencies": { 540 | "call-bind": "^1.0.0", 541 | "get-intrinsic": "^1.0.2", 542 | "object-inspect": "^1.9.0" 543 | }, 544 | "funding": { 545 | "url": "https://github.com/sponsors/ljharb" 546 | } 547 | }, 548 | "node_modules/statuses": { 549 | "version": "2.0.1", 550 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 551 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 552 | "engines": { 553 | "node": ">= 0.8" 554 | } 555 | }, 556 | "node_modules/toidentifier": { 557 | "version": "1.0.1", 558 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 559 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 560 | "engines": { 561 | "node": ">=0.6" 562 | } 563 | }, 564 | "node_modules/type-is": { 565 | "version": "1.6.18", 566 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 567 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 568 | "dependencies": { 569 | "media-typer": "0.3.0", 570 | "mime-types": "~2.1.24" 571 | }, 572 | "engines": { 573 | "node": ">= 0.6" 574 | } 575 | }, 576 | "node_modules/unpipe": { 577 | "version": "1.0.0", 578 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 579 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 580 | "engines": { 581 | "node": ">= 0.8" 582 | } 583 | }, 584 | "node_modules/utils-merge": { 585 | "version": "1.0.1", 586 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 587 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 588 | "engines": { 589 | "node": ">= 0.4.0" 590 | } 591 | }, 592 | "node_modules/vary": { 593 | "version": "1.1.2", 594 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 595 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 596 | "engines": { 597 | "node": ">= 0.8" 598 | } 599 | } 600 | }, 601 | "dependencies": { 602 | "accepts": { 603 | "version": "1.3.8", 604 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 605 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 606 | "requires": { 607 | "mime-types": "~2.1.34", 608 | "negotiator": "0.6.3" 609 | } 610 | }, 611 | "array-flatten": { 612 | "version": "1.1.1", 613 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 614 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 615 | }, 616 | "body-parser": { 617 | "version": "1.20.1", 618 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 619 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 620 | "requires": { 621 | "bytes": "3.1.2", 622 | "content-type": "~1.0.4", 623 | "debug": "2.6.9", 624 | "depd": "2.0.0", 625 | "destroy": "1.2.0", 626 | "http-errors": "2.0.0", 627 | "iconv-lite": "0.4.24", 628 | "on-finished": "2.4.1", 629 | "qs": "6.11.0", 630 | "raw-body": "2.5.1", 631 | "type-is": "~1.6.18", 632 | "unpipe": "1.0.0" 633 | } 634 | }, 635 | "bytes": { 636 | "version": "3.1.2", 637 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 638 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 639 | }, 640 | "call-bind": { 641 | "version": "1.0.2", 642 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 643 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 644 | "requires": { 645 | "function-bind": "^1.1.1", 646 | "get-intrinsic": "^1.0.2" 647 | } 648 | }, 649 | "content-disposition": { 650 | "version": "0.5.4", 651 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 652 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 653 | "requires": { 654 | "safe-buffer": "5.2.1" 655 | } 656 | }, 657 | "content-type": { 658 | "version": "1.0.4", 659 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 660 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 661 | }, 662 | "cookie": { 663 | "version": "0.5.0", 664 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 665 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 666 | }, 667 | "cookie-signature": { 668 | "version": "1.0.6", 669 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 670 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 671 | }, 672 | "debug": { 673 | "version": "2.6.9", 674 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 675 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 676 | "requires": { 677 | "ms": "2.0.0" 678 | } 679 | }, 680 | "depd": { 681 | "version": "2.0.0", 682 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 683 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 684 | }, 685 | "destroy": { 686 | "version": "1.2.0", 687 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 688 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 689 | }, 690 | "dotenv": { 691 | "version": "16.0.3", 692 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", 693 | "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" 694 | }, 695 | "ee-first": { 696 | "version": "1.1.1", 697 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 698 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 699 | }, 700 | "encodeurl": { 701 | "version": "1.0.2", 702 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 703 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 704 | }, 705 | "escape-html": { 706 | "version": "1.0.3", 707 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 708 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 709 | }, 710 | "etag": { 711 | "version": "1.8.1", 712 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 713 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 714 | }, 715 | "express": { 716 | "version": "4.18.2", 717 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 718 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 719 | "requires": { 720 | "accepts": "~1.3.8", 721 | "array-flatten": "1.1.1", 722 | "body-parser": "1.20.1", 723 | "content-disposition": "0.5.4", 724 | "content-type": "~1.0.4", 725 | "cookie": "0.5.0", 726 | "cookie-signature": "1.0.6", 727 | "debug": "2.6.9", 728 | "depd": "2.0.0", 729 | "encodeurl": "~1.0.2", 730 | "escape-html": "~1.0.3", 731 | "etag": "~1.8.1", 732 | "finalhandler": "1.2.0", 733 | "fresh": "0.5.2", 734 | "http-errors": "2.0.0", 735 | "merge-descriptors": "1.0.1", 736 | "methods": "~1.1.2", 737 | "on-finished": "2.4.1", 738 | "parseurl": "~1.3.3", 739 | "path-to-regexp": "0.1.7", 740 | "proxy-addr": "~2.0.7", 741 | "qs": "6.11.0", 742 | "range-parser": "~1.2.1", 743 | "safe-buffer": "5.2.1", 744 | "send": "0.18.0", 745 | "serve-static": "1.15.0", 746 | "setprototypeof": "1.2.0", 747 | "statuses": "2.0.1", 748 | "type-is": "~1.6.18", 749 | "utils-merge": "1.0.1", 750 | "vary": "~1.1.2" 751 | } 752 | }, 753 | "finalhandler": { 754 | "version": "1.2.0", 755 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 756 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 757 | "requires": { 758 | "debug": "2.6.9", 759 | "encodeurl": "~1.0.2", 760 | "escape-html": "~1.0.3", 761 | "on-finished": "2.4.1", 762 | "parseurl": "~1.3.3", 763 | "statuses": "2.0.1", 764 | "unpipe": "~1.0.0" 765 | } 766 | }, 767 | "forwarded": { 768 | "version": "0.2.0", 769 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 770 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 771 | }, 772 | "fresh": { 773 | "version": "0.5.2", 774 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 775 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 776 | }, 777 | "function-bind": { 778 | "version": "1.1.1", 779 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 780 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 781 | }, 782 | "get-intrinsic": { 783 | "version": "1.1.3", 784 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", 785 | "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", 786 | "requires": { 787 | "function-bind": "^1.1.1", 788 | "has": "^1.0.3", 789 | "has-symbols": "^1.0.3" 790 | } 791 | }, 792 | "has": { 793 | "version": "1.0.3", 794 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 795 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 796 | "requires": { 797 | "function-bind": "^1.1.1" 798 | } 799 | }, 800 | "has-symbols": { 801 | "version": "1.0.3", 802 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 803 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 804 | }, 805 | "http-errors": { 806 | "version": "2.0.0", 807 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 808 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 809 | "requires": { 810 | "depd": "2.0.0", 811 | "inherits": "2.0.4", 812 | "setprototypeof": "1.2.0", 813 | "statuses": "2.0.1", 814 | "toidentifier": "1.0.1" 815 | } 816 | }, 817 | "iconv-lite": { 818 | "version": "0.4.24", 819 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 820 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 821 | "requires": { 822 | "safer-buffer": ">= 2.1.2 < 3" 823 | } 824 | }, 825 | "inherits": { 826 | "version": "2.0.4", 827 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 828 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 829 | }, 830 | "ipaddr.js": { 831 | "version": "1.9.1", 832 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 833 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 834 | }, 835 | "media-typer": { 836 | "version": "0.3.0", 837 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 838 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 839 | }, 840 | "merge-descriptors": { 841 | "version": "1.0.1", 842 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 843 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 844 | }, 845 | "methods": { 846 | "version": "1.1.2", 847 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 848 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 849 | }, 850 | "mime": { 851 | "version": "1.6.0", 852 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 853 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 854 | }, 855 | "mime-db": { 856 | "version": "1.52.0", 857 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 858 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 859 | }, 860 | "mime-types": { 861 | "version": "2.1.35", 862 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 863 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 864 | "requires": { 865 | "mime-db": "1.52.0" 866 | } 867 | }, 868 | "ms": { 869 | "version": "2.0.0", 870 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 871 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 872 | }, 873 | "negotiator": { 874 | "version": "0.6.3", 875 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 876 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 877 | }, 878 | "object-inspect": { 879 | "version": "1.12.2", 880 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", 881 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" 882 | }, 883 | "on-finished": { 884 | "version": "2.4.1", 885 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 886 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 887 | "requires": { 888 | "ee-first": "1.1.1" 889 | } 890 | }, 891 | "parseurl": { 892 | "version": "1.3.3", 893 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 894 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 895 | }, 896 | "path-to-regexp": { 897 | "version": "0.1.7", 898 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 899 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 900 | }, 901 | "proxy-addr": { 902 | "version": "2.0.7", 903 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 904 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 905 | "requires": { 906 | "forwarded": "0.2.0", 907 | "ipaddr.js": "1.9.1" 908 | } 909 | }, 910 | "qs": { 911 | "version": "6.11.0", 912 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 913 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 914 | "requires": { 915 | "side-channel": "^1.0.4" 916 | } 917 | }, 918 | "range-parser": { 919 | "version": "1.2.1", 920 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 921 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 922 | }, 923 | "raw-body": { 924 | "version": "2.5.1", 925 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 926 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 927 | "requires": { 928 | "bytes": "3.1.2", 929 | "http-errors": "2.0.0", 930 | "iconv-lite": "0.4.24", 931 | "unpipe": "1.0.0" 932 | } 933 | }, 934 | "safe-buffer": { 935 | "version": "5.2.1", 936 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 937 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 938 | }, 939 | "safer-buffer": { 940 | "version": "2.1.2", 941 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 942 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 943 | }, 944 | "send": { 945 | "version": "0.18.0", 946 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 947 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 948 | "requires": { 949 | "debug": "2.6.9", 950 | "depd": "2.0.0", 951 | "destroy": "1.2.0", 952 | "encodeurl": "~1.0.2", 953 | "escape-html": "~1.0.3", 954 | "etag": "~1.8.1", 955 | "fresh": "0.5.2", 956 | "http-errors": "2.0.0", 957 | "mime": "1.6.0", 958 | "ms": "2.1.3", 959 | "on-finished": "2.4.1", 960 | "range-parser": "~1.2.1", 961 | "statuses": "2.0.1" 962 | }, 963 | "dependencies": { 964 | "ms": { 965 | "version": "2.1.3", 966 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 967 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 968 | } 969 | } 970 | }, 971 | "serve-static": { 972 | "version": "1.15.0", 973 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 974 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 975 | "requires": { 976 | "encodeurl": "~1.0.2", 977 | "escape-html": "~1.0.3", 978 | "parseurl": "~1.3.3", 979 | "send": "0.18.0" 980 | } 981 | }, 982 | "setprototypeof": { 983 | "version": "1.2.0", 984 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 985 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 986 | }, 987 | "side-channel": { 988 | "version": "1.0.4", 989 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 990 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 991 | "requires": { 992 | "call-bind": "^1.0.0", 993 | "get-intrinsic": "^1.0.2", 994 | "object-inspect": "^1.9.0" 995 | } 996 | }, 997 | "statuses": { 998 | "version": "2.0.1", 999 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1000 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 1001 | }, 1002 | "toidentifier": { 1003 | "version": "1.0.1", 1004 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1005 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1006 | }, 1007 | "type-is": { 1008 | "version": "1.6.18", 1009 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1010 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1011 | "requires": { 1012 | "media-typer": "0.3.0", 1013 | "mime-types": "~2.1.24" 1014 | } 1015 | }, 1016 | "unpipe": { 1017 | "version": "1.0.0", 1018 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1019 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1020 | }, 1021 | "utils-merge": { 1022 | "version": "1.0.1", 1023 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1024 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1025 | }, 1026 | "vary": { 1027 | "version": "1.1.2", 1028 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1029 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1030 | } 1031 | } 1032 | } 1033 | -------------------------------------------------------------------------------- /patient-system-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patient-system-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "nodemon src/app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "dotenv": "^16.0.3", 16 | "express": "^4.18.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /patient-system-api/src/api/config/index.js: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv" 2 | 3 | dotenv.config() 4 | console.log(process.env.PORT) 5 | 6 | const { PORT, JWT_SECRET_KEY, JWT_EXPIRE } = process.env 7 | 8 | export const api = { 9 | port: PORT || 3001, 10 | jwtSecretKey: JWT_SECRET_KEY, 11 | jwtExpire: JWT_EXPIRE 12 | } -------------------------------------------------------------------------------- /patient-system-api/src/api/controllers/auth.js: -------------------------------------------------------------------------------- 1 | 2 | const login = (req, res, next) => { 3 | res.json({ 4 | status: true, 5 | message: "login" 6 | }) 7 | } 8 | 9 | const register = (req, res, next) => { 10 | res.json({ 11 | status: true, 12 | message: "register" 13 | }) 14 | } 15 | 16 | export { login, register } -------------------------------------------------------------------------------- /patient-system-api/src/api/routes/auth.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { login, register } from "../controllers/auth.js" 3 | 4 | const router = express.Router() 5 | 6 | router.get("/login", login) 7 | router.get("/register", register) 8 | 9 | export default router -------------------------------------------------------------------------------- /patient-system-api/src/api/routes/index.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import auth from "./auth.js" 3 | 4 | const router = express.Router() 5 | 6 | router.use("/auth", auth) 7 | 8 | export default router -------------------------------------------------------------------------------- /patient-system-api/src/app.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import router from "./api/routes/index.js" 3 | import { api } from "./api/config/index.js" 4 | 5 | const app = express() 6 | const port = api.port 7 | 8 | 9 | // api url'lerimiz localhost:3001/api/ 10 | // şeklinde başlamasını sağlayan middleware 11 | app.use("/api", router) 12 | 13 | app.listen(port, () => { 14 | console.log(`The server was started on ${port} port.`) 15 | }) -------------------------------------------------------------------------------- /question-answer-api/README.MD: -------------------------------------------------------------------------------- 1 | # 💻 Stack Overflow Rest API 2 | 3 | ## 📁 Description 4 | Hello everyone! This is my third back-end project in software development. The project was written in node.js and with MongoDB Database. 5 | I learned mongodb crud operations, jsonwebtoken, authentications,image upload, postman usage,error handling, rest api, password encryption and send mail this project. 6 | 7 | 8 | ## 🚀 Getting started 9 | 10 | To get the Node server running locally: 11 | 12 | - Clone this repo 13 | - `npm install` to install all required dependencies 14 | - Create MongoDb Cluster and Get Connection MongoDb URI 15 | - Set environment variables in `config.env` under `./config/env` 16 | * Set `PORT = ` 17 | * Set `MONGO_URI = ` 18 | * Set `JWT_SECRET_KEY = ` 19 | * Set `JWT_EXPIRE = ` 20 | * Set `SMTP_HOST=` 21 | * Set `SMTP_PORT=` 22 | * Set `SMTP_EMAIL=` 23 | * Set `SMTP_PASS=` 24 | 25 | - `npm start` to start the local server 26 | 27 | # 🔥 Code Overview 28 | 29 | ## 📚 Dependencies 30 | 31 | - [expressjs](https://github.com/expressjs/express) - The server for handling and routing HTTP requests 32 | - [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) - For generating JWTs used by authentication 33 | - [mongoose](https://github.com/Automattic/mongoose) - For modeling and mapping MongoDB data to JavaScript 34 | - [slugify](https://github.com/simov/slugify) - For encoding titles into a URL-friendly format 35 | - [bcryptjs](https://github.com/dodo/node-slug) - Hashing Password 36 | - [dotenv](https://github.com/motdotla/dotenv) - Zero-Dependency module that loads environment variables 37 | - [multer](https://github.com/expressjs/multer) - Node.js middleware for uploading files 38 | - [nodemailer](https://github.com/nodemailer/nodemailer) - Send e-mails from Node.js 39 | 40 | 41 | ## 👨🏻‍💻 Application Structure 42 | 43 | - `app.js` - The entry point to our application. This file defines our express server and connects it to MongoDB using mongoose. It also inncludes the routes we'll be using in the application. 44 | - `config/` - This folder contains configuration for central location environment variables and other configurations. 45 | - `routes/` - This folder contains the route definitions (answer, question etc. ) for our API. 46 | - `models/` - This folder contains the schema definitions for our Mongoose models (User, Question). 47 | - `controllers/` - This folder contains controllers for our API. 48 | - `public/` - This folder contains static files for our API. 49 | - `middlewares/` - This folder contains middlewares for our API. 50 | - `helpers/` - This folder contains helper functions for adapting 3rd party libraries for our API. 51 | 52 | ## ‼️ Error Handling 53 | 54 | In `middlewares/errors/errorHandler.js`, we define a error-handling middleware for handling Mongoose's errors and our own errors. 55 | 56 | ## 🔐 Authentication 57 | 58 | Requests are authenticated using the `Authorization` header and value `Bearer: {{token}}`. with a valid JWT. 59 | 60 | We define express middlewares in `middlewares/authorization/auth.js` that can be used to authenticate requests. The `required` middlewares returns `401` or `403`. 61 | -------------------------------------------------------------------------------- /question-answer-api/app.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import dotenv from "dotenv" 3 | import path from "path" 4 | import { fileURLToPath } from 'url'; 5 | import router from "./src/routes/index.js" 6 | import connectDb from "./src/helpers/db/db.js" 7 | import { errorHandler } from "./src/middlewares/error.handler.js" 8 | 9 | const app = express() 10 | const __filename = fileURLToPath(import.meta.url); 11 | const __dirname = path.dirname(__filename); 12 | 13 | dotenv.config( 14 | { 15 | path: "./src/config/config.env" 16 | } 17 | ) 18 | connectDb() 19 | const port = process.env.PORT || 3029 20 | 21 | // Express - Body Middleware 22 | app.use(express.json()) 23 | 24 | // Router Middlewares 25 | app.use("/api", router) 26 | 27 | app.use(express.static(path.join(__dirname, "public"))) 28 | 29 | app.use(errorHandler) 30 | 31 | app.get("*", (req, res) => { 32 | res.status(404).json( 33 | { 34 | err: "This page doesn't exist." 35 | } 36 | ) 37 | }) 38 | 39 | app.listen(port, () => { 40 | console.log(`The server was started on ${port} port.`) 41 | }) -------------------------------------------------------------------------------- /question-answer-api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "question-answer-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "nodemon app.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "bcryptjs": "^2.4.3", 16 | "dotenv": "^16.0.3", 17 | "express": "^4.18.2", 18 | "express-async-handler": "^1.2.0", 19 | "jsonwebtoken": "^8.5.1", 20 | "mongoose": "^6.6.5", 21 | "multer": "^1.4.5-lts.1", 22 | "nodemailer": "^6.8.0", 23 | "slugify": "^1.6.5" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /question-answer-api/src/controllers/admin.contoller.js: -------------------------------------------------------------------------------- 1 | import asyncErrorHandler from "express-async-handler" 2 | import User from "../models/user.model.js" 3 | 4 | const blockUser = asyncErrorHandler(async (req, res, next) => { 5 | const { id } = req.params 6 | const user = await User.findById({ _id: id }) 7 | 8 | user.isBlocked = !user.isBlocked 9 | await user.save() 10 | return res.status(200) 11 | .json({ 12 | success: true, 13 | message: user.isBlocked ? "The user is blocked." : "The user is unblocked", 14 | user: user, 15 | }) 16 | }) 17 | 18 | const deleteUser = asyncErrorHandler(async (req, res, next) => { 19 | const { id } = req.params 20 | const user = await User.findById({ _id: id }) 21 | 22 | user.isActive = false 23 | await user.save() 24 | return res.status(200) 25 | .json({ 26 | success: true, 27 | message: "The user is deleted.", 28 | }) 29 | }) 30 | 31 | export { blockUser, deleteUser } -------------------------------------------------------------------------------- /question-answer-api/src/controllers/answer.controller.js: -------------------------------------------------------------------------------- 1 | import Answer from "../models/answer.model.js" 2 | import User from "../models/user.model.js" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import asyncErrorHandler from "express-async-handler" 5 | import Question from "../models/question.model.js" 6 | 7 | const getAllAnswers = asyncErrorHandler(async (req, res, next) => { 8 | const { id } = req.params 9 | 10 | const question = await Question.findOne({ _id: id, isActive: true }) 11 | 12 | if (question) { 13 | const answer = await Answer.find({ question: id, isActive: true }) 14 | .populate("user").populate("fav").populate("question") 15 | 16 | answer.sort((a, b) => b.createdAt - a.createdAt) 17 | res.status(200).json({ 18 | success: true, 19 | answers: answer 20 | }) 21 | } else { 22 | return next(new CustomError("This question was deleted.")) 23 | } 24 | }) 25 | 26 | const getAnswerById = asyncErrorHandler(async (req, res, next) => { 27 | const { answerId } = req.params 28 | const answer = await Answer.findOne({ _id: answerId, isActive: true }) 29 | 30 | if (answer) { 31 | res.status(200).json({ 32 | success: true, 33 | answer: answer 34 | }) 35 | } else { 36 | return next(new CustomError("This answer was deleted.")) 37 | } 38 | 39 | }) 40 | 41 | const addNewAnswerToQuestion = asyncErrorHandler(async (req, res, next) => { 42 | const { id } = req.params 43 | const params = req.body 44 | const answer = await Answer.create({ 45 | ...params, 46 | user: req.user.id, 47 | question: id 48 | }) 49 | 50 | const user = await User.findById({ _id: req.user.id }) 51 | user.answer.push(answer) 52 | 53 | await user.save() 54 | 55 | res.status(200) 56 | .json({ 57 | success: true, 58 | message: "You added answer in successful!", 59 | answer: answer 60 | }) 61 | }) 62 | 63 | const updateAnswer = asyncErrorHandler(async (req, res, next) => { 64 | const id = req.params.answerId 65 | const body = req.body 66 | const answer = await Answer.findByIdAndUpdate( 67 | { _id: id }, 68 | { ...body }, 69 | { new: true, runValidators: true } 70 | ) 71 | 72 | res.status(200) 73 | .json({ 74 | success: true, 75 | updatedAnswer: answer 76 | }) 77 | }) 78 | 79 | const deleteAnswer = asyncErrorHandler(async (req, res, next) => { 80 | const id = req.params.answerId 81 | const answer = await Answer.findById({ _id: id }) 82 | answer.isActive = false 83 | await answer.save() 84 | 85 | res.status(200) 86 | .json({ 87 | success: true, 88 | message: "This answer is deleted" 89 | }) 90 | }) 91 | 92 | const favAnswer = asyncErrorHandler(async (req, res, next) => { 93 | const answer = req.answer 94 | if (answer.fav.includes(req.user.id)) { 95 | return next(new CustomError("You already fav this answer", 400)) 96 | } 97 | answer.fav.push(req.user.id) 98 | await answer.save() 99 | return res.status(200) 100 | .json({ 101 | success: true, 102 | answer: answer 103 | }) 104 | }) 105 | 106 | const unFavAnswer = asyncErrorHandler(async (req, res, next) => { 107 | const answer = req.answer 108 | if (!answer.fav.includes(req.user.id)) { 109 | return next(new CustomError("You already unfav this answer", 400)) 110 | } 111 | answer.fav = answer.fav.filter(e => !answer.fav.includes(e)) 112 | await answer.save() 113 | res.status(200) 114 | .json({ 115 | success: true, 116 | answer: answer 117 | }) 118 | }) 119 | 120 | export { 121 | getAllAnswers, getAnswerById, 122 | addNewAnswerToQuestion, updateAnswer, 123 | deleteAnswer, favAnswer, 124 | unFavAnswer 125 | } 126 | -------------------------------------------------------------------------------- /question-answer-api/src/controllers/auth.controller.js: -------------------------------------------------------------------------------- 1 | import asyncErrorHandler from "express-async-handler" 2 | import User from "../models/user.model.js"; 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import { validateUserInput, comparePassword } from "../helpers/input/input.helper.js"; 5 | import sendMail from "../helpers/libraries/sendEmail.js"; 6 | 7 | const register = asyncErrorHandler(async (req, res) => { 8 | const user = await User.create(req.body) 9 | if (!user) { 10 | return next(new CustomError(err.message, 400)) 11 | } 12 | const token = user.generateJwtFromUser() 13 | res.json({ 14 | success: true, 15 | message: "You registered in successful", 16 | token: token, 17 | body: user, 18 | }) 19 | }) 20 | 21 | const login = asyncErrorHandler(async (req, res, next) => { 22 | const { email, password } = req.body 23 | validateUserInput(email, password, next) 24 | const user = await User.findOne({ email }) 25 | .select("+password") 26 | .populate("question") 27 | .populate("answer") 28 | if (!user) { 29 | return next(new CustomError( 30 | "Invalid email.\nPlease check email and try again.", 400) 31 | ) 32 | } 33 | if (!comparePassword(password, user.password)) { 34 | return next(new CustomError( 35 | "Invalid password.\nPlease check password and try again.", 400) 36 | ) 37 | } 38 | user.token = user.generateJwtFromUser() 39 | await user.save() 40 | res.json({ 41 | success: true, 42 | message: "You logged in successful.", 43 | token: user.token, 44 | body: user 45 | }) 46 | }) 47 | 48 | const tokenControl = (req, res, next) => { 49 | res.json( 50 | { 51 | success: true 52 | } 53 | ) 54 | } 55 | 56 | const forgotPassword = asyncErrorHandler(async (req, res, next) => { 57 | 58 | const resetEmail = req.body.email 59 | const user = await User.findOne({ email: resetEmail }) 60 | if (!user) { 61 | return next(new CustomError("There is no user with that email", 400)) 62 | } 63 | const token = Math.floor(100000 + Math.random() * 900000) 64 | const emailTemplate = ` 65 |

Reset Your Password

66 |

This is your reset password token : ${token}.

67 | ` 68 | 69 | try { 70 | await sendMail({ 71 | from: process.env.SMTP_USER, 72 | to: resetEmail, 73 | subject: "Reset ur password.", 74 | html: emailTemplate 75 | }) 76 | user.resetPasswordToken = token 77 | await user.save() 78 | res.status(200).json( 79 | { 80 | success: true, 81 | message: "Password reset successful. A 6-digit password reset token has been sent to your email.", 82 | token: token 83 | } 84 | ) 85 | } catch (err) { 86 | user.resetPasswordToken = undefined 87 | await user.save() 88 | return next(new CustomError("Email could not be sent", 500)) 89 | } 90 | 91 | }) 92 | 93 | const resetPassword = asyncErrorHandler(async (req, res, next) => { 94 | 95 | const { resetPasswordToken } = req.query 96 | const { password } = req.body 97 | 98 | if (!resetPasswordToken) { 99 | return next(new CustomError("Please provide a valid token", 400)) 100 | } 101 | let user = await User.findOne({ 102 | resetPasswordToken: resetPasswordToken, 103 | }) 104 | if (!user) { 105 | return next(new CustomError("Please provide a valid token", 400)) 106 | } else { 107 | user.password = password 108 | await user.save() 109 | 110 | return res.status(200).json( 111 | { 112 | success: true, 113 | message: "Reset password process successful!", 114 | user: user 115 | } 116 | ) 117 | } 118 | 119 | 120 | }) 121 | 122 | const imageUpload = asyncErrorHandler(async (req, res, next) => { 123 | 124 | const user = await User.findByIdAndUpdate(req.user.id, { 125 | "img": req.savedProfileImage 126 | }, { new: true, runValidators: true }) 127 | 128 | res.status(200).json({ 129 | success: true, 130 | message: "Image Upload Successful", 131 | user: user 132 | }) 133 | }) 134 | 135 | export { 136 | register, login, 137 | tokenControl, forgotPassword, 138 | resetPassword, imageUpload 139 | } -------------------------------------------------------------------------------- /question-answer-api/src/controllers/quesitons.controller.js: -------------------------------------------------------------------------------- 1 | import Question from "../models/question.model.js" 2 | import User from "../models/user.model.js" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import asyncErrorHandler from "express-async-handler" 5 | import Answer from "../models/answer.model.js" 6 | 7 | const getAllQuestions = asyncErrorHandler(async (req, res, next) => { 8 | let query = Question.find({ isActive: true }) 9 | .populate( 10 | { 11 | path: "user", 12 | select: "id name lastname question" 13 | } 14 | ).populate( 15 | { 16 | path: "answer", 17 | match: { isActive: true } 18 | } 19 | ).populate( 20 | { 21 | path: "fav" 22 | } 23 | ) 24 | 25 | 26 | const questions = await query 27 | questions.sort((a, b) => b.createdAt - a.createdAt) 28 | 29 | return res.status(200) 30 | .json({ 31 | questions 32 | }) 33 | }) 34 | 35 | const getQuestion = asyncErrorHandler(async (req, res, next) => { 36 | const question = await Question.findOne( 37 | { 38 | _id: req.question.id, 39 | isActive: true 40 | } 41 | ) 42 | .populate( 43 | { 44 | path: "user", 45 | select: "id name lastname question" 46 | } 47 | ).populate( 48 | { 49 | path: "answer", 50 | match: { isActive: true } 51 | } 52 | ).populate( 53 | { 54 | path: "fav" 55 | } 56 | ) 57 | if (question) { 58 | return res.status(200) 59 | .json({ 60 | success: true, 61 | question: question 62 | }) 63 | } else { 64 | return next(new CustomError("This question was deleted.")) 65 | } 66 | 67 | }) 68 | 69 | const addQuestion = asyncErrorHandler(async (req, res, next) => { 70 | const params = req.body 71 | const question = await Question.create({ 72 | ...params, 73 | user: req.user.id, 74 | }) 75 | const user = await User.findById({ _id: req.user.id }) 76 | user.question.push(question) 77 | await user.save() 78 | res.status(200) 79 | .json({ 80 | success: true, 81 | message: "You added a question in successful!", 82 | question: question, 83 | }) 84 | }) 85 | 86 | const updateQuestion = asyncErrorHandler(async (req, res, next) => { 87 | const params = req.body 88 | const question = req.question 89 | let updatedQuestion = await Question.findByIdAndUpdate(question.id, { 90 | ...params 91 | }, { new: true, runValidators: true }).populate( 92 | { 93 | path: "user", 94 | select: "id name lastname" 95 | } 96 | ).populate( 97 | { 98 | path: "answer", 99 | } 100 | ) 101 | 102 | updatedQuestion = await updatedQuestion.save() 103 | 104 | return res.status(200) 105 | .json({ 106 | success: true, 107 | question: updatedQuestion, 108 | }) 109 | }) 110 | 111 | const deleteQuestion = asyncErrorHandler(async (req, res, next) => { 112 | const userId = req.user.id 113 | 114 | const question = req.question 115 | question.isActive = false 116 | question.answer.forEach(async e => { 117 | await Answer.findByIdAndUpdate(e, { isActive: false }) 118 | }); 119 | 120 | await question.save() 121 | return res.status(200) 122 | .json({ 123 | success: true, 124 | deletedQuestion: question 125 | }) 126 | }) 127 | 128 | const favQuestion = asyncErrorHandler(async (req, res, next) => { 129 | const question = req.question 130 | if (question.fav.includes(req.user.id)) { 131 | return next(new CustomError("You already fav this question", 400)) 132 | } 133 | question.fav.push(req.user.id) 134 | await question.save() 135 | return res.status(200) 136 | .json({ 137 | success: true, 138 | question: question 139 | }) 140 | }) 141 | 142 | const unFavQuestion = asyncErrorHandler(async (req, res, next) => { 143 | let question = req.question 144 | if (!question.fav.includes(req.user.id)) { 145 | return next(new CustomError("You already unfav this question", 400)) 146 | } 147 | question.fav = question.fav.filter(e => !question.fav.includes(e)) 148 | await question.save() 149 | return res.status(200) 150 | .json({ 151 | success: true, 152 | question: question 153 | }) 154 | }) 155 | 156 | export { 157 | getAllQuestions, getQuestion, 158 | addQuestion, updateQuestion, 159 | deleteQuestion, favQuestion, 160 | unFavQuestion 161 | } -------------------------------------------------------------------------------- /question-answer-api/src/controllers/user.controller.js: -------------------------------------------------------------------------------- 1 | 2 | import User from "../models/user.model.js" 3 | import asyncErrorHandler from "express-async-handler" 4 | 5 | const getAllUsers = asyncErrorHandler(async (req, res, next) => { 6 | const users = await User.find() 7 | return res.status(200) 8 | .json({ 9 | success: true, 10 | users: users 11 | }) 12 | }) 13 | 14 | const getUserById = asyncErrorHandler(async (req, res, next) => { 15 | const user = await User.findById({ _id: req.params.id }) 16 | .populate({ 17 | path: "question", 18 | match: { isActive: true }, 19 | populate: { 20 | path: "answer", 21 | match: { isActive: true } 22 | } 23 | }) 24 | .populate({ 25 | path: "answer", 26 | match: { isActive: true } 27 | }) 28 | return res.status(200) 29 | .json({ 30 | success: true, 31 | user: user 32 | }) 33 | }) 34 | 35 | const editProfile = asyncErrorHandler(async (req, res, next) => { 36 | const body = req.body 37 | const user = await User.findByIdAndUpdate(req.user.id, 38 | { ...body, email: req.user.email }, 39 | { new: true }) 40 | return res.status(200) 41 | .json({ 42 | succes: true, 43 | updatedUser: user 44 | }) 45 | }) 46 | 47 | export { getAllUsers, getUserById, editProfile } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/auth/auth.helper.js: -------------------------------------------------------------------------------- 1 | const isTokenIncluded = (req) => { 2 | return (req.headers['authorization'] 3 | .startsWith("Bearer ")) 4 | } 5 | 6 | const getAccessTokenFromHeader = (req) => { 7 | const authorization = req.headers['authorization'] 8 | // [Bearer:] First index of list 9 | // [token] Second index of list 10 | const token = authorization.split(" ")[1] 11 | return token 12 | } 13 | 14 | export { isTokenIncluded, getAccessTokenFromHeader } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/db/db.error.helpers.js: -------------------------------------------------------------------------------- 1 | import asyncErrorHandler from "express-async-handler" 2 | import User from "../../models/user.model.js" 3 | import Question from "../../models/question.model.js" 4 | import Answer from "../../models/answer.model.js" 5 | import CustomError from "../../helpers/error/CustomError.js" 6 | 7 | const checkUserExist = asyncErrorHandler(async (req, res, next) => { 8 | const { id } = req.params 9 | const user = await User.findById({ _id: id }) 10 | if (!user) { 11 | return next(new CustomError("There is no such user with that id"), 400) 12 | } 13 | req.user = user 14 | next() 15 | }) 16 | 17 | const checkQuesitonExist = asyncErrorHandler(async (req, res, next) => { 18 | const { id } = req.params 19 | const question = await Question.findById({ _id: id, }) 20 | if (!question) { 21 | return next(new CustomError("There is no such question with that id"), 400) 22 | } 23 | req.question = question 24 | next() 25 | }) 26 | 27 | const checkAnswerExist = asyncErrorHandler(async (req, res, next) => { 28 | const { answerId } = req.params 29 | const questionId = req.question._id 30 | const question = await Question.findOne( 31 | { _id: questionId, isActive: true } 32 | ) 33 | if (question) { 34 | const answer = await Answer.findOne({ 35 | _id: answerId, 36 | question: questionId 37 | }).populate({ 38 | path: "user", 39 | select: "id name lastname " 40 | }) 41 | .populate({ 42 | path: "question", 43 | select: "id title subtitle" 44 | }) 45 | if (!answer) { 46 | return next(new CustomError("There is no such answer with that id"), 400) 47 | } 48 | req.answer = answer 49 | next() 50 | } else { 51 | return next(new CustomError("This question was deleted.")) 52 | } 53 | 54 | }) 55 | 56 | export { checkUserExist, checkQuesitonExist, checkAnswerExist } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/db/db.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | const connectDb = async () => { 4 | try { 5 | await mongoose.connect(process.env.MONGO_URI) 6 | console.log("connection successful!") 7 | } catch (err) { 8 | console.error(err) 9 | } 10 | } 11 | 12 | export default connectDb -------------------------------------------------------------------------------- /question-answer-api/src/helpers/error/CustomError.js: -------------------------------------------------------------------------------- 1 | class CustomError extends Error { 2 | constructor(message, status) { 3 | super(message) 4 | this.status = status 5 | } 6 | } 7 | 8 | export default CustomError -------------------------------------------------------------------------------- /question-answer-api/src/helpers/input/input.helper.js: -------------------------------------------------------------------------------- 1 | import bcrypt from "bcryptjs" 2 | import CustomError from "../error/CustomError.js" 3 | 4 | const validateUserInput = (email, pass, next) => { 5 | if (!email) { 6 | return next(new CustomError("Please enter email.", 400)) 7 | } else if (!pass) { 8 | return next(new CustomError("Please enter password.", 400)) 9 | } else if (!email && !pass) { 10 | return next(new CustomError("Please enter email and password.", 400)) 11 | } 12 | } 13 | 14 | const comparePassword = (pass, hashPass) => { 15 | return bcrypt.compareSync(pass, hashPass) 16 | } 17 | 18 | export { validateUserInput, comparePassword } -------------------------------------------------------------------------------- /question-answer-api/src/helpers/libraries/sendEmail.js: -------------------------------------------------------------------------------- 1 | import nodemailer from "nodemailer" 2 | 3 | const sendMail = async (mailOptions) => { 4 | const { SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD } = process.env 5 | let transporter = nodemailer.createTransport({ 6 | host: SMTP_HOST, 7 | port: SMTP_PORT, 8 | secure: true, 9 | auth: { 10 | user: SMTP_USER, 11 | pass: SMTP_PASSWORD 12 | } 13 | }) 14 | 15 | let info = await transporter.sendMail(mailOptions) 16 | console.log(`Message send: ${info.messageId}`) 17 | } 18 | 19 | export default sendMail -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/auth.middleware.js: -------------------------------------------------------------------------------- 1 | import jwt from "jsonwebtoken" 2 | import asyncErrorHandler from "express-async-handler" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | import User from "../models/user.model.js" 5 | import Question from "../models/question.model.js" 6 | import { 7 | isTokenIncluded, 8 | getAccessTokenFromHeader 9 | } from "../helpers/auth/auth.helper.js" 10 | 11 | const getAccessToRoute = (req, res, next) => { 12 | const unAuthorizedError = new CustomError("No token provided", 401) 13 | const { JWT_SECRET_KEY } = process.env 14 | if (!isTokenIncluded(req)) { 15 | return next(unAuthorizedError) 16 | } 17 | const token = getAccessTokenFromHeader(req) 18 | 19 | 20 | jwt.verify(token, JWT_SECRET_KEY, (err, decoded) => { 21 | if (err) { 22 | return next(unAuthorizedError) 23 | } 24 | req.user = { 25 | id: decoded.id, 26 | name: decoded.name, 27 | } 28 | next() 29 | }) 30 | } 31 | 32 | const getAdminAccess = asyncErrorHandler(async (req, res, next) => { 33 | const { id } = req.user 34 | const user = await User.findById({ _id: id }) 35 | 36 | if (user.role != "admin") { 37 | return next(new CustomError("Only admins can access this route", 403)) 38 | } 39 | next() 40 | }) 41 | 42 | const getQuestionOwnerAccess = asyncErrorHandler(async (req, res, next) => { 43 | const userId = req.user.id 44 | const { id } = req.params 45 | const question = await Question.findById({ _id: id }) 46 | 47 | if (question.user != userId) { 48 | return next(new CustomError("Only owner can handle this operation", 403)) 49 | } 50 | req.question = question 51 | next() 52 | }) 53 | 54 | export { 55 | getAccessToRoute, 56 | getAdminAccess, 57 | getQuestionOwnerAccess 58 | } -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/error.handler.js: -------------------------------------------------------------------------------- 1 | import CustomError from "../helpers/error/CustomError.js" 2 | 3 | const errorHandler = (err, req, res, next) => { 4 | let customError = err 5 | console.log(customError.name, customError.message) 6 | if (err.name == "SyntaxError") { 7 | customError = new CustomError("Unexpected Syntax", 400) 8 | } 9 | if (err.name == "ValidationError") { 10 | if (err.message.includes("content") && err.message.includes("a content")) { 11 | customError = new CustomError("Please provide a content.", 400) 12 | } else if (err.message.includes("content")) { 13 | customError = new CustomError("Please provide a title at least 10 characters.", 400) 14 | } else { 15 | customError = new CustomError(err.message, 400) 16 | } 17 | } 18 | if (err.code == 11000) { 19 | // Duplicate Key error 20 | if (err.message.includes("email")) { 21 | const message = "Your email address is used.\nPlease try again with enter other email." 22 | customError = new CustomError(message, 400) 23 | 24 | } else if (err.message.includes("title")) { 25 | const message = "This title is used.\nPlease try again with enter other title." 26 | customError = new CustomError(message, 400) 27 | } else { 28 | customError = new CustomError("Duplicate Key Error", 400) 29 | } 30 | } 31 | 32 | res.status(customError.status || 500).json( 33 | { 34 | succes: false, 35 | message: customError.message || "Internal Server Error" 36 | } 37 | ) 38 | } 39 | 40 | export { errorHandler } -------------------------------------------------------------------------------- /question-answer-api/src/middlewares/image.upload.js: -------------------------------------------------------------------------------- 1 | import multer from "multer" 2 | import path from "path" 3 | import CustomError from "../helpers/error/CustomError.js" 4 | 5 | const storage = multer.diskStorage({ 6 | destination: function (req, file, cb) { 7 | const rootDir = path.dirname(require.main.filename) 8 | cb(null, path.join(rootDir, "/public/uploads")) 9 | }, 10 | filename: function (req, file, cb) { 11 | // File - Mimetype - image/png, image/jpg 12 | const extension = file.mimetype.split("/")[1] 13 | req.savedProfileImage = `image_${req.user.id}.${extension}` 14 | cb(null, req.savedProfileImage) 15 | } 16 | }) 17 | 18 | const fileFilter = (req, file, cb) => { 19 | let allowedTypes = ["image/jpg", "image/jpeg", "image/png"] 20 | 21 | if (!allowedTypes.includes(file.mimetype)) { 22 | return cb(new CustomError("Please provide a valid image file", 400), false) 23 | } 24 | return cb(null, true) 25 | } 26 | 27 | const profileImageUpload = multer({ storage, fileFilter }) 28 | 29 | export default profileImageUpload -------------------------------------------------------------------------------- /question-answer-api/src/models/answer.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import Question from "../models/question.model.js" 3 | 4 | const AnswerSchema = new mongoose.Schema({ 5 | content: { 6 | type: String, 7 | required: [true, "Please provide a content"], 8 | minlength: [10, "Please provide a title at least 10 characters"] 9 | }, 10 | createdAt: { 11 | type: Date, 12 | default: Date.now() 13 | }, 14 | fav: [ 15 | { 16 | type: mongoose.Schema.ObjectId, 17 | ref: "User" 18 | } 19 | ], 20 | user: { 21 | type: mongoose.Schema.ObjectId, 22 | ref: "User", 23 | required: true 24 | }, 25 | question: { 26 | type: mongoose.Schema.ObjectId, 27 | ref: "Question", 28 | required: true 29 | }, 30 | isActive: { 31 | type: Boolean, 32 | default: true, 33 | } 34 | }) 35 | 36 | AnswerSchema.pre("save", async function (next) { 37 | if (!this.isModified("user")) return next() 38 | 39 | try { 40 | const question = await Question.findById({ _id: this.question }) 41 | question.answer.push(this._id) 42 | await question.save() 43 | next() 44 | } catch (err) { 45 | return next(err) 46 | } 47 | }) 48 | 49 | const Answer = mongoose.model("Answer", AnswerSchema) 50 | 51 | export default Answer -------------------------------------------------------------------------------- /question-answer-api/src/models/question.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import slugify from "slugify" 3 | 4 | const QuesitonSchema = new mongoose.Schema({ 5 | title: { 6 | type: String, 7 | required: [true, "Please provide a title"], 8 | minlength: [10, "Please provide a title at least 10 characters"], 9 | unique: true, 10 | }, 11 | subtitle: { 12 | type: String, 13 | required: [true, "Please provide a subtitle"], 14 | minlength: [10, "Please provide a subtitle at least 10 characters"], 15 | }, 16 | slug: String, 17 | createdAt: { 18 | type: Date, 19 | default: Date.now() 20 | }, 21 | isActive: { 22 | type: Boolean, 23 | default: true, 24 | }, 25 | user: { 26 | type: mongoose.Schema.ObjectId, 27 | required: true, 28 | ref: "User", 29 | }, 30 | fav: [ 31 | { 32 | type: mongoose.Schema.ObjectId, 33 | ref: "User" 34 | } 35 | ], 36 | answer: [ 37 | { 38 | type: mongoose.Schema.ObjectId, 39 | ref: "Answer" 40 | } 41 | ], 42 | }) 43 | 44 | QuesitonSchema.pre("save", function (next) { 45 | if (!this.isModified("title")) { 46 | next() 47 | } 48 | this.slug = this.createSlugify() 49 | next() 50 | }) 51 | 52 | QuesitonSchema.methods.createSlugify = function () { 53 | return slugify(this.title, { 54 | replacement: "-", 55 | remove: /[*+~.()'"!:@]/g, 56 | lower: true, 57 | trim: true, 58 | }) 59 | } 60 | 61 | const Question = mongoose.model("Question", QuesitonSchema) 62 | export default Question -------------------------------------------------------------------------------- /question-answer-api/src/models/user.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import bcrypt from "bcryptjs" 3 | import jwt from "jsonwebtoken" 4 | import crypto from "crypto" 5 | import Question from "../models/question.model.js" 6 | 7 | const UserSchema = new mongoose.Schema({ 8 | name: { 9 | type: String, 10 | required: [true, "Please provide a name"], 11 | trim: true 12 | }, 13 | lastname: { 14 | type: String, 15 | required: [true, "Please provide a lastname"], 16 | trim: true 17 | }, 18 | email: { 19 | type: String, 20 | required: [true, "Please provide a email"], 21 | unique: true, 22 | match: [ 23 | /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 24 | "Please provide a valid email" 25 | ], 26 | }, 27 | role: { 28 | type: String, 29 | default: "user", 30 | enum: ["user", "admin"] 31 | }, 32 | password: { 33 | type: String, 34 | minLength: [6, "Please provide a password with min lenght 6"], 35 | required: [true, "Please provide a password"], 36 | select: false 37 | }, 38 | createdAt: { 39 | type: Date, 40 | default: Date.now 41 | }, 42 | title: { 43 | type: String 44 | }, 45 | about: { 46 | type: String 47 | }, 48 | place: { 49 | type: String 50 | }, 51 | website: { 52 | type: String 53 | }, 54 | img: { 55 | type: String, 56 | default: "default.svg" 57 | }, 58 | isBlocked: { 59 | type: Boolean, 60 | default: false, 61 | }, 62 | isActive: { 63 | type: Boolean, 64 | default: true, 65 | }, 66 | resetPasswordToken: { 67 | type: String 68 | }, 69 | question: [ 70 | { 71 | type: mongoose.Schema.ObjectId, 72 | ref: "Question" 73 | } 74 | ], 75 | answer: [ 76 | { 77 | type: mongoose.Schema.ObjectId, 78 | ref: "Answer" 79 | } 80 | ], 81 | token: { 82 | type: String 83 | } 84 | }) 85 | 86 | UserSchema.methods.generateJwtFromUser = function () { 87 | const { JWT_SECRET_KEY, JWT_EXPIRE } = process.env 88 | const payload = { 89 | id: this._id, 90 | name: this.name 91 | } 92 | const token = jwt.sign(payload, JWT_SECRET_KEY, { expiresIn: JWT_EXPIRE }) 93 | return token 94 | } 95 | 96 | UserSchema.methods.getResetPasswordTokenFromUser = function () { 97 | const randomHexString = crypto.randomBytes(16).toString("hex") 98 | const resetPasswordToken = crypto 99 | .createHash("SHA256") 100 | .update(randomHexString) 101 | .digest("hex") 102 | const { RESET_PASSWORD_EXPIRE } = process.env 103 | this.resetPasswordToken = resetPasswordToken 104 | this.resetPasswordExpire = Date.now() + parseInt(RESET_PASSWORD_EXPIRE) 105 | return resetPasswordToken 106 | } 107 | 108 | UserSchema.pre("save", function (next) { 109 | // password is change? 110 | if (!this.isModified("password")) { 111 | next() 112 | } 113 | 114 | // if password is not change, password is hashed 115 | bcrypt.genSalt(10, (err, salt) => { 116 | if (err) next(err) 117 | bcrypt.hash(this.password, salt, (err, hash) => { 118 | if (err) next(err) 119 | this.password = hash 120 | next() 121 | }) 122 | }) 123 | }) 124 | 125 | const User = mongoose.model("User", UserSchema) 126 | 127 | export default User -------------------------------------------------------------------------------- /question-answer-api/src/routes/admin.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute, getAdminAccess} from "../middlewares/auth.middleware.js" 3 | import { blockUser, deleteUser } from "../controllers/admin.contoller.js" 4 | import { checkUserExist } from "../helpers/db/db.error.helpers.js" 5 | 6 | const router = express.Router() 7 | 8 | router.use([getAccessToRoute, getAdminAccess]) 9 | 10 | router.get("/blockUser/:id", checkUserExist, blockUser) 11 | router.delete("/deleteUser/:id", checkUserExist, deleteUser) 12 | 13 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/answer.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { checkAnswerExist } from "../helpers/db/db.error.helpers.js" 4 | import { 5 | getAllAnswers, getAnswerById, 6 | addNewAnswerToQuestion, updateAnswer, 7 | deleteAnswer, favAnswer, 8 | unFavAnswer 9 | } from "../controllers/answer.controller.js" 10 | const router = express.Router({ mergeParams: true }) 11 | 12 | router.use(getAccessToRoute) 13 | 14 | router.get("/", getAllAnswers) 15 | router.post("/", addNewAnswerToQuestion) 16 | router.get("/:answerId", checkAnswerExist, getAnswerById), 17 | router.put("/:answerId", checkAnswerExist, updateAnswer) 18 | router.delete("/:answerId", checkAnswerExist, deleteAnswer) 19 | router.get("/:answerId/favAnswer", checkAnswerExist, favAnswer) 20 | router.get("/:answerId/unFavAnswer", checkAnswerExist, unFavAnswer) 21 | 22 | 23 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/auth.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { 4 | register, login, 5 | tokenControl, forgotPassword, 6 | resetPassword, imageUpload 7 | } from "../controllers/auth.controller.js" 8 | import profileImageUpload from "../middlewares/image.upload.js" 9 | const router = express.Router() 10 | 11 | router.post("/login", login) 12 | router.post("/register", register) 13 | router.get("/tokenControl", getAccessToRoute, tokenControl) 14 | router.post("/forgotPassword", forgotPassword) 15 | router.put("/resetPassword", resetPassword) 16 | router.post( 17 | "/imageUpload", 18 | [getAccessToRoute, profileImageUpload.single("profile_image")], 19 | imageUpload 20 | ) 21 | 22 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/index.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import auth from "./auth.js" 3 | import users from "./users.js" 4 | import admin from "./admin.js" 5 | import questions from "./questions.js" 6 | 7 | const router = express.Router() 8 | 9 | router.use("/auth", auth) 10 | router.use("/users", users) 11 | router.use("/admin", admin) 12 | router.use("/questions", questions) 13 | 14 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/questions.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute, getQuestionOwnerAccess } from "../middlewares/auth.middleware.js" 3 | import { checkQuesitonExist } from "../helpers/db/db.error.helpers.js" 4 | import { 5 | getAllQuestions, getQuestion, 6 | addQuestion, updateQuestion, 7 | deleteQuestion, favQuestion, 8 | unFavQuestion 9 | } from "../controllers/quesitons.controller.js" 10 | import answer from "../routes/answer.js" 11 | 12 | const router = express.Router() 13 | 14 | router.use(getAccessToRoute) 15 | router.get("/allQuestions", getAllQuestions) 16 | router.get("/getQuestion/:id", checkQuesitonExist, getQuestion) 17 | router.post("/ask", addQuestion) 18 | router.put( 19 | "/updateQuestion/:id", 20 | [checkQuesitonExist, 21 | getQuestionOwnerAccess], 22 | updateQuestion 23 | ) 24 | router.delete("/deleteQuestion/:id", 25 | [checkQuesitonExist, 26 | getQuestionOwnerAccess], 27 | deleteQuestion 28 | ) 29 | router.get("/favQuestion/:id", 30 | checkQuesitonExist, 31 | favQuestion 32 | ) 33 | router.get("/unFavQuestion/:id", 34 | checkQuesitonExist, 35 | unFavQuestion 36 | ) 37 | router.use("/:id/answers", checkQuesitonExist, answer) 38 | 39 | export default router -------------------------------------------------------------------------------- /question-answer-api/src/routes/users.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import { getAccessToRoute } from "../middlewares/auth.middleware.js" 3 | import { 4 | getAllUsers, 5 | getUserById, 6 | editProfile 7 | } from "../controllers/user.controller.js" 8 | import { checkUserExist } from "../helpers/db/db.error.helpers.js" 9 | 10 | const router = express.Router() 11 | 12 | router.use(getAccessToRoute) 13 | 14 | router.get("/getAllUsers", getAllUsers) 15 | router.get("/:id", checkUserExist, getUserById) 16 | router.put("/edit", editProfile) 17 | 18 | export default router -------------------------------------------------------------------------------- /todo-mysql/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akaanuzman/learn_node/97f7e1521d018ac9312ecee76bfc795627b6cb3f/todo-mysql/.DS_Store -------------------------------------------------------------------------------- /todo-mysql/README.MD: -------------------------------------------------------------------------------- 1 | ## 💻 Basic Todo App 2 | 3 | ### 🔎 Preview 4 | https://user-images.githubusercontent.com/55639112/195473254-c86797df-d656-4ed6-8e29-3c6b32720d47.mov 5 | 6 | ### 📁 Description 7 | Hello everyone! This is my second back-end project in software development. The project was written node.js programming langueage and with MySql Database. 8 | Project reads and writes data (read, write, delete, add) on mysql database with ejs template engine and nodejs. Also when I was coding of the design I used Bootstrap 5.2 version. In page all of the data and all of the operations (read, write, delete, add) on website is happened from database. You can create a todo list and management this list in this project. You can add and delete a todo or todos in your list otherwise you can delete all todos from your list. I am gonna show database scheme under chapter. 9 | 10 | ### 🚀 Database 11 | database_scheme 12 | data 13 | 14 | ### 🧑🏻‍💻 Coding 15 | I tried to write the code of this project as clean as possible and I learned too many thing. The first one i learned to use "get" and "post" methods. The second thing i learned to database operations in nodejs. That's all I was going to tell. Thank you if you are read this text at the moment. 16 | -------------------------------------------------------------------------------- /todo-mysql/db/db.js: -------------------------------------------------------------------------------- 1 | const mysql = require("mysql2") 2 | const config = require("../config") 3 | 4 | let dbConnection = mysql.createConnection(config.db) 5 | 6 | dbConnection.connect(function (err) { 7 | if (err) { 8 | console.log(err) 9 | } 10 | dbConnection.query("select * from Tasks", function (err, res) { 11 | console.log(res[0]) 12 | }) 13 | console.log("db connection was successful!") 14 | }) 15 | 16 | module.exports = dbConnection.promise() -------------------------------------------------------------------------------- /todo-mysql/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const app = express() 3 | const port = 5096 4 | const routes = require("./routes/route") 5 | app.set("view engine","ejs") 6 | app.set("views","./views") 7 | app.use(express.static("node_modules")) 8 | app.use(routes) 9 | 10 | 11 | app.listen(port,() => { 12 | console.log(`Example app listening on port ${port}`) 13 | }) -------------------------------------------------------------------------------- /todo-mysql/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-mysql", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "alert": "^5.1.1", 14 | "bootstrap": "^5.2.2", 15 | "ejs": "^3.1.8", 16 | "express": "^4.18.2", 17 | "mysql2": "^2.3.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /todo-mysql/routes/route.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const routes = express.Router() 3 | const db = require("../db/db") 4 | routes.use(express.json()) 5 | routes.use(express.urlencoded()) 6 | 7 | routes.get("/", (req, res) => { 8 | console.log(res.query) 9 | fetchData(res) 10 | }) 11 | 12 | routes.post("/", (req, res) => { 13 | const todoName = req.body.todoName 14 | addTodo(todoName, res) 15 | console.log(req.body) 16 | }) 17 | 18 | routes.get("/deleteAllTasks", (req, res) => { 19 | deleteAllTodos(res) 20 | }) 21 | 22 | routes.get("/deleteTask/:id", (req, res) => { 23 | deleteTodo(req, res) 24 | }) 25 | 26 | routes.get("/search",(req,res) => { 27 | 28 | }) 29 | 30 | async function fetchData(res) { 31 | try { 32 | const query = "select * from Tasks where isActive = 1" 33 | const [tasks,] = await db.execute(query) 34 | res.render("index", { 35 | tasks: tasks, 36 | }) 37 | console.log(tasks) 38 | } catch (error) { 39 | console.error(error) 40 | } 41 | } 42 | 43 | async function addTodo(todoName, res) { 44 | try { 45 | const query = "INSERT INTO `node_db`.`Tasks` (`todoName`, `createdTime`, `isActive`) VALUES (?, NOW(), '1')" 46 | await db.execute(query, [todoName]) 47 | fetchData(res) 48 | } catch (error) { 49 | console.error(error) 50 | } 51 | } 52 | 53 | async function deleteAllTodos(res) { 54 | try { 55 | const query = "select * from Tasks where isActive = 1" 56 | const [tasks,] = await db.execute(query) 57 | tasks.forEach(async task => { 58 | const query = "UPDATE `node_db`.`Tasks` SET `isActive` = '0' WHERE id=?" 59 | await db.execute(query, [task.id]) 60 | }); 61 | fetchData(res) 62 | } catch (error) { 63 | console.error(error) 64 | } 65 | } 66 | 67 | async function deleteTodo(req, res) { 68 | console.log("******* " + req.params.id) 69 | try { 70 | const query = "select * from Tasks where isActive = 1" 71 | const [tasks,] = await db.execute(query) 72 | const deleteQuery = "UPDATE `node_db`.`Tasks` SET `isActive` = '0' WHERE id=?" 73 | await db.execute(deleteQuery, [req.params.id]) 74 | fetchData(res) 75 | } catch (error) { 76 | console.error(error) 77 | } 78 | } 79 | 80 | 81 | function getDate(tasks) { 82 | var currentdate = new Date(); 83 | var dateTime = currentdate.getDay() + "/" + currentdate.getMonth() 84 | + "/" + currentdate.getFullYear() + " @ " 85 | + currentdate.getHours() + ":" 86 | + currentdate.getMinutes() + ":" + currentdate.getSeconds(); 87 | return currentdate 88 | } 89 | 90 | module.exports = routes -------------------------------------------------------------------------------- /todo-mysql/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Home 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 |
Todo List
24 |
25 |
26 |
27 |
28 | 30 |
31 |
32 | 33 |
34 |
35 |
36 |
37 |
Todos
38 |
39 |
    40 | <% tasks.forEach(task=> { %> 41 |
  • 42 | <%= task.todoName %> - <%= task.createdTime %> 43 | 44 | delete 45 | 46 |
  • 47 | <% }) %> 48 |
49 |
50 | Delete all tasks 51 |
52 |
53 |
54 | 55 | 56 | --------------------------------------------------------------------------------