├── README.md ├── backend ├── .gitignore ├── db.js ├── index.js ├── package-lock.json ├── package.json └── types.js └── frontend ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public └── vite.svg ├── src ├── App.css ├── App.jsx ├── assets │ └── react.svg ├── components │ ├── CreateTodo.jsx │ └── Todos.jsx ├── index.css └── main.jsx └── vite.config.js /README.md: -------------------------------------------------------------------------------- 1 | ## Todo app 2 | 3 | This project contains a simple TODO application 4 | It has the following features - 5 | 6 | - Anyone can create a todo 7 | - Anyone can see their existing todos 8 | - Anyone can mark a todo as done -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /backend/db.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | // mongodb+srv://kirags123:8qPEa8KTKBEh2bss@cluster0.f3qlbuo.mongodb.net/todos 4 | // .env 5 | mongoose.connect("mongodb+srv://kirags123:8qPEa8KTKBEh2bss@cluster0.f3qlbuo.mongodb.net/todos") 6 | const todoSchema = mongoose.Schema({ 7 | title: String, 8 | description: String, 9 | completed: Boolean 10 | }) 11 | 12 | const todo = mongoose.model('todos', todoSchema); 13 | 14 | module.exports = { 15 | todo 16 | } -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { createTodo, updateTodo } = require("./types"); 3 | const { todo } = require("./db"); 4 | const cors = require("cors"); 5 | const app = express(); 6 | 7 | app.use(express.json()); 8 | app.use(cors()); 9 | 10 | app.post("/todo", async function(req, res) { 11 | const createPayload = req.body; 12 | const parsedPayload = createTodo.safeParse(createPayload); 13 | 14 | if (!parsedPayload.success) { 15 | res.status(411).json({ 16 | msg: "You sent the wrong inputs", 17 | }) 18 | return; 19 | } 20 | // put it in mongodb 21 | await todo.create({ 22 | title: createPayload.title, 23 | description: createPayload.description, 24 | completed: false 25 | }) 26 | 27 | res.json({ 28 | msg: "Todo created" 29 | }) 30 | }) 31 | 32 | app.get("/todos", async function(req, res) { 33 | // const todos = await todo.find({}); 34 | 35 | res.json({ 36 | todos: [] 37 | }) 38 | 39 | }) 40 | 41 | app.put("/completed", async function(req, res) { 42 | const updatePayload = req.body; 43 | const parsedPayload = updateTodo.safeParse(updatePayload); 44 | if (!parsedPayload.success) { 45 | res.status(411).json({ 46 | msg: "You sent the wrong inputs", 47 | }) 48 | return; 49 | } 50 | 51 | await todo.update({ 52 | _id: req.body.id 53 | }, { 54 | completed: true 55 | }) 56 | 57 | res.json({ 58 | msg: "Todo marked as completed" 59 | }) 60 | }) 61 | 62 | app.listen(3000); -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-backend", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "todo-backend", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "express": "^4.18.2", 14 | "jsonwebtoken": "^9.0.2", 15 | "zod": "^3.22.4" 16 | } 17 | }, 18 | "node_modules/accepts": { 19 | "version": "1.3.8", 20 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 21 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 22 | "dependencies": { 23 | "mime-types": "~2.1.34", 24 | "negotiator": "0.6.3" 25 | }, 26 | "engines": { 27 | "node": ">= 0.6" 28 | } 29 | }, 30 | "node_modules/array-flatten": { 31 | "version": "1.1.1", 32 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 33 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 34 | }, 35 | "node_modules/body-parser": { 36 | "version": "1.20.1", 37 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 38 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 39 | "dependencies": { 40 | "bytes": "3.1.2", 41 | "content-type": "~1.0.4", 42 | "debug": "2.6.9", 43 | "depd": "2.0.0", 44 | "destroy": "1.2.0", 45 | "http-errors": "2.0.0", 46 | "iconv-lite": "0.4.24", 47 | "on-finished": "2.4.1", 48 | "qs": "6.11.0", 49 | "raw-body": "2.5.1", 50 | "type-is": "~1.6.18", 51 | "unpipe": "1.0.0" 52 | }, 53 | "engines": { 54 | "node": ">= 0.8", 55 | "npm": "1.2.8000 || >= 1.4.16" 56 | } 57 | }, 58 | "node_modules/buffer-equal-constant-time": { 59 | "version": "1.0.1", 60 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 61 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 62 | }, 63 | "node_modules/bytes": { 64 | "version": "3.1.2", 65 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 66 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 67 | "engines": { 68 | "node": ">= 0.8" 69 | } 70 | }, 71 | "node_modules/call-bind": { 72 | "version": "1.0.5", 73 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", 74 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", 75 | "dependencies": { 76 | "function-bind": "^1.1.2", 77 | "get-intrinsic": "^1.2.1", 78 | "set-function-length": "^1.1.1" 79 | }, 80 | "funding": { 81 | "url": "https://github.com/sponsors/ljharb" 82 | } 83 | }, 84 | "node_modules/content-disposition": { 85 | "version": "0.5.4", 86 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 87 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 88 | "dependencies": { 89 | "safe-buffer": "5.2.1" 90 | }, 91 | "engines": { 92 | "node": ">= 0.6" 93 | } 94 | }, 95 | "node_modules/content-type": { 96 | "version": "1.0.5", 97 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 98 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 99 | "engines": { 100 | "node": ">= 0.6" 101 | } 102 | }, 103 | "node_modules/cookie": { 104 | "version": "0.5.0", 105 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 106 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 107 | "engines": { 108 | "node": ">= 0.6" 109 | } 110 | }, 111 | "node_modules/cookie-signature": { 112 | "version": "1.0.6", 113 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 114 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 115 | }, 116 | "node_modules/cors": { 117 | "version": "2.8.5", 118 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 119 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 120 | "dependencies": { 121 | "object-assign": "^4", 122 | "vary": "^1" 123 | }, 124 | "engines": { 125 | "node": ">= 0.10" 126 | } 127 | }, 128 | "node_modules/debug": { 129 | "version": "2.6.9", 130 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 131 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 132 | "dependencies": { 133 | "ms": "2.0.0" 134 | } 135 | }, 136 | "node_modules/define-data-property": { 137 | "version": "1.1.1", 138 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", 139 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", 140 | "dependencies": { 141 | "get-intrinsic": "^1.2.1", 142 | "gopd": "^1.0.1", 143 | "has-property-descriptors": "^1.0.0" 144 | }, 145 | "engines": { 146 | "node": ">= 0.4" 147 | } 148 | }, 149 | "node_modules/depd": { 150 | "version": "2.0.0", 151 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 152 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 153 | "engines": { 154 | "node": ">= 0.8" 155 | } 156 | }, 157 | "node_modules/destroy": { 158 | "version": "1.2.0", 159 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 160 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 161 | "engines": { 162 | "node": ">= 0.8", 163 | "npm": "1.2.8000 || >= 1.4.16" 164 | } 165 | }, 166 | "node_modules/ecdsa-sig-formatter": { 167 | "version": "1.0.11", 168 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 169 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 170 | "dependencies": { 171 | "safe-buffer": "^5.0.1" 172 | } 173 | }, 174 | "node_modules/ee-first": { 175 | "version": "1.1.1", 176 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 177 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 178 | }, 179 | "node_modules/encodeurl": { 180 | "version": "1.0.2", 181 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 182 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 183 | "engines": { 184 | "node": ">= 0.8" 185 | } 186 | }, 187 | "node_modules/escape-html": { 188 | "version": "1.0.3", 189 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 190 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 191 | }, 192 | "node_modules/etag": { 193 | "version": "1.8.1", 194 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 195 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 196 | "engines": { 197 | "node": ">= 0.6" 198 | } 199 | }, 200 | "node_modules/express": { 201 | "version": "4.18.2", 202 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 203 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 204 | "dependencies": { 205 | "accepts": "~1.3.8", 206 | "array-flatten": "1.1.1", 207 | "body-parser": "1.20.1", 208 | "content-disposition": "0.5.4", 209 | "content-type": "~1.0.4", 210 | "cookie": "0.5.0", 211 | "cookie-signature": "1.0.6", 212 | "debug": "2.6.9", 213 | "depd": "2.0.0", 214 | "encodeurl": "~1.0.2", 215 | "escape-html": "~1.0.3", 216 | "etag": "~1.8.1", 217 | "finalhandler": "1.2.0", 218 | "fresh": "0.5.2", 219 | "http-errors": "2.0.0", 220 | "merge-descriptors": "1.0.1", 221 | "methods": "~1.1.2", 222 | "on-finished": "2.4.1", 223 | "parseurl": "~1.3.3", 224 | "path-to-regexp": "0.1.7", 225 | "proxy-addr": "~2.0.7", 226 | "qs": "6.11.0", 227 | "range-parser": "~1.2.1", 228 | "safe-buffer": "5.2.1", 229 | "send": "0.18.0", 230 | "serve-static": "1.15.0", 231 | "setprototypeof": "1.2.0", 232 | "statuses": "2.0.1", 233 | "type-is": "~1.6.18", 234 | "utils-merge": "1.0.1", 235 | "vary": "~1.1.2" 236 | }, 237 | "engines": { 238 | "node": ">= 0.10.0" 239 | } 240 | }, 241 | "node_modules/finalhandler": { 242 | "version": "1.2.0", 243 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 244 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 245 | "dependencies": { 246 | "debug": "2.6.9", 247 | "encodeurl": "~1.0.2", 248 | "escape-html": "~1.0.3", 249 | "on-finished": "2.4.1", 250 | "parseurl": "~1.3.3", 251 | "statuses": "2.0.1", 252 | "unpipe": "~1.0.0" 253 | }, 254 | "engines": { 255 | "node": ">= 0.8" 256 | } 257 | }, 258 | "node_modules/forwarded": { 259 | "version": "0.2.0", 260 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 261 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 262 | "engines": { 263 | "node": ">= 0.6" 264 | } 265 | }, 266 | "node_modules/fresh": { 267 | "version": "0.5.2", 268 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 269 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 270 | "engines": { 271 | "node": ">= 0.6" 272 | } 273 | }, 274 | "node_modules/function-bind": { 275 | "version": "1.1.2", 276 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 277 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 278 | "funding": { 279 | "url": "https://github.com/sponsors/ljharb" 280 | } 281 | }, 282 | "node_modules/get-intrinsic": { 283 | "version": "1.2.2", 284 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", 285 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", 286 | "dependencies": { 287 | "function-bind": "^1.1.2", 288 | "has-proto": "^1.0.1", 289 | "has-symbols": "^1.0.3", 290 | "hasown": "^2.0.0" 291 | }, 292 | "funding": { 293 | "url": "https://github.com/sponsors/ljharb" 294 | } 295 | }, 296 | "node_modules/gopd": { 297 | "version": "1.0.1", 298 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 299 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 300 | "dependencies": { 301 | "get-intrinsic": "^1.1.3" 302 | }, 303 | "funding": { 304 | "url": "https://github.com/sponsors/ljharb" 305 | } 306 | }, 307 | "node_modules/has-property-descriptors": { 308 | "version": "1.0.1", 309 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", 310 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", 311 | "dependencies": { 312 | "get-intrinsic": "^1.2.2" 313 | }, 314 | "funding": { 315 | "url": "https://github.com/sponsors/ljharb" 316 | } 317 | }, 318 | "node_modules/has-proto": { 319 | "version": "1.0.1", 320 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 321 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 322 | "engines": { 323 | "node": ">= 0.4" 324 | }, 325 | "funding": { 326 | "url": "https://github.com/sponsors/ljharb" 327 | } 328 | }, 329 | "node_modules/has-symbols": { 330 | "version": "1.0.3", 331 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 332 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 333 | "engines": { 334 | "node": ">= 0.4" 335 | }, 336 | "funding": { 337 | "url": "https://github.com/sponsors/ljharb" 338 | } 339 | }, 340 | "node_modules/hasown": { 341 | "version": "2.0.0", 342 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 343 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 344 | "dependencies": { 345 | "function-bind": "^1.1.2" 346 | }, 347 | "engines": { 348 | "node": ">= 0.4" 349 | } 350 | }, 351 | "node_modules/http-errors": { 352 | "version": "2.0.0", 353 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 354 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 355 | "dependencies": { 356 | "depd": "2.0.0", 357 | "inherits": "2.0.4", 358 | "setprototypeof": "1.2.0", 359 | "statuses": "2.0.1", 360 | "toidentifier": "1.0.1" 361 | }, 362 | "engines": { 363 | "node": ">= 0.8" 364 | } 365 | }, 366 | "node_modules/iconv-lite": { 367 | "version": "0.4.24", 368 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 369 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 370 | "dependencies": { 371 | "safer-buffer": ">= 2.1.2 < 3" 372 | }, 373 | "engines": { 374 | "node": ">=0.10.0" 375 | } 376 | }, 377 | "node_modules/inherits": { 378 | "version": "2.0.4", 379 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 380 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 381 | }, 382 | "node_modules/ipaddr.js": { 383 | "version": "1.9.1", 384 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 385 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 386 | "engines": { 387 | "node": ">= 0.10" 388 | } 389 | }, 390 | "node_modules/jsonwebtoken": { 391 | "version": "9.0.2", 392 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 393 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 394 | "dependencies": { 395 | "jws": "^3.2.2", 396 | "lodash.includes": "^4.3.0", 397 | "lodash.isboolean": "^3.0.3", 398 | "lodash.isinteger": "^4.0.4", 399 | "lodash.isnumber": "^3.0.3", 400 | "lodash.isplainobject": "^4.0.6", 401 | "lodash.isstring": "^4.0.1", 402 | "lodash.once": "^4.0.0", 403 | "ms": "^2.1.1", 404 | "semver": "^7.5.4" 405 | }, 406 | "engines": { 407 | "node": ">=12", 408 | "npm": ">=6" 409 | } 410 | }, 411 | "node_modules/jsonwebtoken/node_modules/ms": { 412 | "version": "2.1.3", 413 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 414 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 415 | }, 416 | "node_modules/jwa": { 417 | "version": "1.4.1", 418 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 419 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 420 | "dependencies": { 421 | "buffer-equal-constant-time": "1.0.1", 422 | "ecdsa-sig-formatter": "1.0.11", 423 | "safe-buffer": "^5.0.1" 424 | } 425 | }, 426 | "node_modules/jws": { 427 | "version": "3.2.2", 428 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 429 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 430 | "dependencies": { 431 | "jwa": "^1.4.1", 432 | "safe-buffer": "^5.0.1" 433 | } 434 | }, 435 | "node_modules/lodash.includes": { 436 | "version": "4.3.0", 437 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 438 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 439 | }, 440 | "node_modules/lodash.isboolean": { 441 | "version": "3.0.3", 442 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 443 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 444 | }, 445 | "node_modules/lodash.isinteger": { 446 | "version": "4.0.4", 447 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 448 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 449 | }, 450 | "node_modules/lodash.isnumber": { 451 | "version": "3.0.3", 452 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 453 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 454 | }, 455 | "node_modules/lodash.isplainobject": { 456 | "version": "4.0.6", 457 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 458 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 459 | }, 460 | "node_modules/lodash.isstring": { 461 | "version": "4.0.1", 462 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 463 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 464 | }, 465 | "node_modules/lodash.once": { 466 | "version": "4.1.1", 467 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 468 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 469 | }, 470 | "node_modules/lru-cache": { 471 | "version": "6.0.0", 472 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 473 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 474 | "dependencies": { 475 | "yallist": "^4.0.0" 476 | }, 477 | "engines": { 478 | "node": ">=10" 479 | } 480 | }, 481 | "node_modules/media-typer": { 482 | "version": "0.3.0", 483 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 484 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 485 | "engines": { 486 | "node": ">= 0.6" 487 | } 488 | }, 489 | "node_modules/merge-descriptors": { 490 | "version": "1.0.1", 491 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 492 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 493 | }, 494 | "node_modules/methods": { 495 | "version": "1.1.2", 496 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 497 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 498 | "engines": { 499 | "node": ">= 0.6" 500 | } 501 | }, 502 | "node_modules/mime": { 503 | "version": "1.6.0", 504 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 505 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 506 | "bin": { 507 | "mime": "cli.js" 508 | }, 509 | "engines": { 510 | "node": ">=4" 511 | } 512 | }, 513 | "node_modules/mime-db": { 514 | "version": "1.52.0", 515 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 516 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 517 | "engines": { 518 | "node": ">= 0.6" 519 | } 520 | }, 521 | "node_modules/mime-types": { 522 | "version": "2.1.35", 523 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 524 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 525 | "dependencies": { 526 | "mime-db": "1.52.0" 527 | }, 528 | "engines": { 529 | "node": ">= 0.6" 530 | } 531 | }, 532 | "node_modules/ms": { 533 | "version": "2.0.0", 534 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 535 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 536 | }, 537 | "node_modules/negotiator": { 538 | "version": "0.6.3", 539 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 540 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 541 | "engines": { 542 | "node": ">= 0.6" 543 | } 544 | }, 545 | "node_modules/object-assign": { 546 | "version": "4.1.1", 547 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 548 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 549 | "engines": { 550 | "node": ">=0.10.0" 551 | } 552 | }, 553 | "node_modules/object-inspect": { 554 | "version": "1.13.1", 555 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 556 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 557 | "funding": { 558 | "url": "https://github.com/sponsors/ljharb" 559 | } 560 | }, 561 | "node_modules/on-finished": { 562 | "version": "2.4.1", 563 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 564 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 565 | "dependencies": { 566 | "ee-first": "1.1.1" 567 | }, 568 | "engines": { 569 | "node": ">= 0.8" 570 | } 571 | }, 572 | "node_modules/parseurl": { 573 | "version": "1.3.3", 574 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 575 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 576 | "engines": { 577 | "node": ">= 0.8" 578 | } 579 | }, 580 | "node_modules/path-to-regexp": { 581 | "version": "0.1.7", 582 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 583 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 584 | }, 585 | "node_modules/proxy-addr": { 586 | "version": "2.0.7", 587 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 588 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 589 | "dependencies": { 590 | "forwarded": "0.2.0", 591 | "ipaddr.js": "1.9.1" 592 | }, 593 | "engines": { 594 | "node": ">= 0.10" 595 | } 596 | }, 597 | "node_modules/qs": { 598 | "version": "6.11.0", 599 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 600 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 601 | "dependencies": { 602 | "side-channel": "^1.0.4" 603 | }, 604 | "engines": { 605 | "node": ">=0.6" 606 | }, 607 | "funding": { 608 | "url": "https://github.com/sponsors/ljharb" 609 | } 610 | }, 611 | "node_modules/range-parser": { 612 | "version": "1.2.1", 613 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 614 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 615 | "engines": { 616 | "node": ">= 0.6" 617 | } 618 | }, 619 | "node_modules/raw-body": { 620 | "version": "2.5.1", 621 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 622 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 623 | "dependencies": { 624 | "bytes": "3.1.2", 625 | "http-errors": "2.0.0", 626 | "iconv-lite": "0.4.24", 627 | "unpipe": "1.0.0" 628 | }, 629 | "engines": { 630 | "node": ">= 0.8" 631 | } 632 | }, 633 | "node_modules/safe-buffer": { 634 | "version": "5.2.1", 635 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 636 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 637 | "funding": [ 638 | { 639 | "type": "github", 640 | "url": "https://github.com/sponsors/feross" 641 | }, 642 | { 643 | "type": "patreon", 644 | "url": "https://www.patreon.com/feross" 645 | }, 646 | { 647 | "type": "consulting", 648 | "url": "https://feross.org/support" 649 | } 650 | ] 651 | }, 652 | "node_modules/safer-buffer": { 653 | "version": "2.1.2", 654 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 655 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 656 | }, 657 | "node_modules/semver": { 658 | "version": "7.5.4", 659 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 660 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 661 | "dependencies": { 662 | "lru-cache": "^6.0.0" 663 | }, 664 | "bin": { 665 | "semver": "bin/semver.js" 666 | }, 667 | "engines": { 668 | "node": ">=10" 669 | } 670 | }, 671 | "node_modules/send": { 672 | "version": "0.18.0", 673 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 674 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 675 | "dependencies": { 676 | "debug": "2.6.9", 677 | "depd": "2.0.0", 678 | "destroy": "1.2.0", 679 | "encodeurl": "~1.0.2", 680 | "escape-html": "~1.0.3", 681 | "etag": "~1.8.1", 682 | "fresh": "0.5.2", 683 | "http-errors": "2.0.0", 684 | "mime": "1.6.0", 685 | "ms": "2.1.3", 686 | "on-finished": "2.4.1", 687 | "range-parser": "~1.2.1", 688 | "statuses": "2.0.1" 689 | }, 690 | "engines": { 691 | "node": ">= 0.8.0" 692 | } 693 | }, 694 | "node_modules/send/node_modules/ms": { 695 | "version": "2.1.3", 696 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 697 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 698 | }, 699 | "node_modules/serve-static": { 700 | "version": "1.15.0", 701 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 702 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 703 | "dependencies": { 704 | "encodeurl": "~1.0.2", 705 | "escape-html": "~1.0.3", 706 | "parseurl": "~1.3.3", 707 | "send": "0.18.0" 708 | }, 709 | "engines": { 710 | "node": ">= 0.8.0" 711 | } 712 | }, 713 | "node_modules/set-function-length": { 714 | "version": "1.1.1", 715 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", 716 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", 717 | "dependencies": { 718 | "define-data-property": "^1.1.1", 719 | "get-intrinsic": "^1.2.1", 720 | "gopd": "^1.0.1", 721 | "has-property-descriptors": "^1.0.0" 722 | }, 723 | "engines": { 724 | "node": ">= 0.4" 725 | } 726 | }, 727 | "node_modules/setprototypeof": { 728 | "version": "1.2.0", 729 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 730 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 731 | }, 732 | "node_modules/side-channel": { 733 | "version": "1.0.4", 734 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 735 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 736 | "dependencies": { 737 | "call-bind": "^1.0.0", 738 | "get-intrinsic": "^1.0.2", 739 | "object-inspect": "^1.9.0" 740 | }, 741 | "funding": { 742 | "url": "https://github.com/sponsors/ljharb" 743 | } 744 | }, 745 | "node_modules/statuses": { 746 | "version": "2.0.1", 747 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 748 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 749 | "engines": { 750 | "node": ">= 0.8" 751 | } 752 | }, 753 | "node_modules/toidentifier": { 754 | "version": "1.0.1", 755 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 756 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 757 | "engines": { 758 | "node": ">=0.6" 759 | } 760 | }, 761 | "node_modules/type-is": { 762 | "version": "1.6.18", 763 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 764 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 765 | "dependencies": { 766 | "media-typer": "0.3.0", 767 | "mime-types": "~2.1.24" 768 | }, 769 | "engines": { 770 | "node": ">= 0.6" 771 | } 772 | }, 773 | "node_modules/unpipe": { 774 | "version": "1.0.0", 775 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 776 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 777 | "engines": { 778 | "node": ">= 0.8" 779 | } 780 | }, 781 | "node_modules/utils-merge": { 782 | "version": "1.0.1", 783 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 784 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 785 | "engines": { 786 | "node": ">= 0.4.0" 787 | } 788 | }, 789 | "node_modules/vary": { 790 | "version": "1.1.2", 791 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 792 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 793 | "engines": { 794 | "node": ">= 0.8" 795 | } 796 | }, 797 | "node_modules/yallist": { 798 | "version": "4.0.0", 799 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 800 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 801 | }, 802 | "node_modules/zod": { 803 | "version": "3.22.4", 804 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 805 | "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", 806 | "funding": { 807 | "url": "https://github.com/sponsors/colinhacks" 808 | } 809 | } 810 | }, 811 | "dependencies": { 812 | "accepts": { 813 | "version": "1.3.8", 814 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 815 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 816 | "requires": { 817 | "mime-types": "~2.1.34", 818 | "negotiator": "0.6.3" 819 | } 820 | }, 821 | "array-flatten": { 822 | "version": "1.1.1", 823 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 824 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 825 | }, 826 | "body-parser": { 827 | "version": "1.20.1", 828 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 829 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 830 | "requires": { 831 | "bytes": "3.1.2", 832 | "content-type": "~1.0.4", 833 | "debug": "2.6.9", 834 | "depd": "2.0.0", 835 | "destroy": "1.2.0", 836 | "http-errors": "2.0.0", 837 | "iconv-lite": "0.4.24", 838 | "on-finished": "2.4.1", 839 | "qs": "6.11.0", 840 | "raw-body": "2.5.1", 841 | "type-is": "~1.6.18", 842 | "unpipe": "1.0.0" 843 | } 844 | }, 845 | "buffer-equal-constant-time": { 846 | "version": "1.0.1", 847 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 848 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 849 | }, 850 | "bytes": { 851 | "version": "3.1.2", 852 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 853 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 854 | }, 855 | "call-bind": { 856 | "version": "1.0.5", 857 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", 858 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", 859 | "requires": { 860 | "function-bind": "^1.1.2", 861 | "get-intrinsic": "^1.2.1", 862 | "set-function-length": "^1.1.1" 863 | } 864 | }, 865 | "content-disposition": { 866 | "version": "0.5.4", 867 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 868 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 869 | "requires": { 870 | "safe-buffer": "5.2.1" 871 | } 872 | }, 873 | "content-type": { 874 | "version": "1.0.5", 875 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 876 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" 877 | }, 878 | "cookie": { 879 | "version": "0.5.0", 880 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 881 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" 882 | }, 883 | "cookie-signature": { 884 | "version": "1.0.6", 885 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 886 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 887 | }, 888 | "cors": { 889 | "version": "2.8.5", 890 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 891 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 892 | "requires": { 893 | "object-assign": "^4", 894 | "vary": "^1" 895 | } 896 | }, 897 | "debug": { 898 | "version": "2.6.9", 899 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 900 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 901 | "requires": { 902 | "ms": "2.0.0" 903 | } 904 | }, 905 | "define-data-property": { 906 | "version": "1.1.1", 907 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", 908 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", 909 | "requires": { 910 | "get-intrinsic": "^1.2.1", 911 | "gopd": "^1.0.1", 912 | "has-property-descriptors": "^1.0.0" 913 | } 914 | }, 915 | "depd": { 916 | "version": "2.0.0", 917 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 918 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 919 | }, 920 | "destroy": { 921 | "version": "1.2.0", 922 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 923 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 924 | }, 925 | "ecdsa-sig-formatter": { 926 | "version": "1.0.11", 927 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 928 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 929 | "requires": { 930 | "safe-buffer": "^5.0.1" 931 | } 932 | }, 933 | "ee-first": { 934 | "version": "1.1.1", 935 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 936 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 937 | }, 938 | "encodeurl": { 939 | "version": "1.0.2", 940 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 941 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 942 | }, 943 | "escape-html": { 944 | "version": "1.0.3", 945 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 946 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 947 | }, 948 | "etag": { 949 | "version": "1.8.1", 950 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 951 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 952 | }, 953 | "express": { 954 | "version": "4.18.2", 955 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 956 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 957 | "requires": { 958 | "accepts": "~1.3.8", 959 | "array-flatten": "1.1.1", 960 | "body-parser": "1.20.1", 961 | "content-disposition": "0.5.4", 962 | "content-type": "~1.0.4", 963 | "cookie": "0.5.0", 964 | "cookie-signature": "1.0.6", 965 | "debug": "2.6.9", 966 | "depd": "2.0.0", 967 | "encodeurl": "~1.0.2", 968 | "escape-html": "~1.0.3", 969 | "etag": "~1.8.1", 970 | "finalhandler": "1.2.0", 971 | "fresh": "0.5.2", 972 | "http-errors": "2.0.0", 973 | "merge-descriptors": "1.0.1", 974 | "methods": "~1.1.2", 975 | "on-finished": "2.4.1", 976 | "parseurl": "~1.3.3", 977 | "path-to-regexp": "0.1.7", 978 | "proxy-addr": "~2.0.7", 979 | "qs": "6.11.0", 980 | "range-parser": "~1.2.1", 981 | "safe-buffer": "5.2.1", 982 | "send": "0.18.0", 983 | "serve-static": "1.15.0", 984 | "setprototypeof": "1.2.0", 985 | "statuses": "2.0.1", 986 | "type-is": "~1.6.18", 987 | "utils-merge": "1.0.1", 988 | "vary": "~1.1.2" 989 | } 990 | }, 991 | "finalhandler": { 992 | "version": "1.2.0", 993 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 994 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 995 | "requires": { 996 | "debug": "2.6.9", 997 | "encodeurl": "~1.0.2", 998 | "escape-html": "~1.0.3", 999 | "on-finished": "2.4.1", 1000 | "parseurl": "~1.3.3", 1001 | "statuses": "2.0.1", 1002 | "unpipe": "~1.0.0" 1003 | } 1004 | }, 1005 | "forwarded": { 1006 | "version": "0.2.0", 1007 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1008 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 1009 | }, 1010 | "fresh": { 1011 | "version": "0.5.2", 1012 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1013 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 1014 | }, 1015 | "function-bind": { 1016 | "version": "1.1.2", 1017 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1018 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" 1019 | }, 1020 | "get-intrinsic": { 1021 | "version": "1.2.2", 1022 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", 1023 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", 1024 | "requires": { 1025 | "function-bind": "^1.1.2", 1026 | "has-proto": "^1.0.1", 1027 | "has-symbols": "^1.0.3", 1028 | "hasown": "^2.0.0" 1029 | } 1030 | }, 1031 | "gopd": { 1032 | "version": "1.0.1", 1033 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 1034 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 1035 | "requires": { 1036 | "get-intrinsic": "^1.1.3" 1037 | } 1038 | }, 1039 | "has-property-descriptors": { 1040 | "version": "1.0.1", 1041 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", 1042 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", 1043 | "requires": { 1044 | "get-intrinsic": "^1.2.2" 1045 | } 1046 | }, 1047 | "has-proto": { 1048 | "version": "1.0.1", 1049 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 1050 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" 1051 | }, 1052 | "has-symbols": { 1053 | "version": "1.0.3", 1054 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1055 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" 1056 | }, 1057 | "hasown": { 1058 | "version": "2.0.0", 1059 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 1060 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 1061 | "requires": { 1062 | "function-bind": "^1.1.2" 1063 | } 1064 | }, 1065 | "http-errors": { 1066 | "version": "2.0.0", 1067 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1068 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1069 | "requires": { 1070 | "depd": "2.0.0", 1071 | "inherits": "2.0.4", 1072 | "setprototypeof": "1.2.0", 1073 | "statuses": "2.0.1", 1074 | "toidentifier": "1.0.1" 1075 | } 1076 | }, 1077 | "iconv-lite": { 1078 | "version": "0.4.24", 1079 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1080 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1081 | "requires": { 1082 | "safer-buffer": ">= 2.1.2 < 3" 1083 | } 1084 | }, 1085 | "inherits": { 1086 | "version": "2.0.4", 1087 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1088 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1089 | }, 1090 | "ipaddr.js": { 1091 | "version": "1.9.1", 1092 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1093 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 1094 | }, 1095 | "jsonwebtoken": { 1096 | "version": "9.0.2", 1097 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 1098 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 1099 | "requires": { 1100 | "jws": "^3.2.2", 1101 | "lodash.includes": "^4.3.0", 1102 | "lodash.isboolean": "^3.0.3", 1103 | "lodash.isinteger": "^4.0.4", 1104 | "lodash.isnumber": "^3.0.3", 1105 | "lodash.isplainobject": "^4.0.6", 1106 | "lodash.isstring": "^4.0.1", 1107 | "lodash.once": "^4.0.0", 1108 | "ms": "^2.1.1", 1109 | "semver": "^7.5.4" 1110 | }, 1111 | "dependencies": { 1112 | "ms": { 1113 | "version": "2.1.3", 1114 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1115 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1116 | } 1117 | } 1118 | }, 1119 | "jwa": { 1120 | "version": "1.4.1", 1121 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 1122 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 1123 | "requires": { 1124 | "buffer-equal-constant-time": "1.0.1", 1125 | "ecdsa-sig-formatter": "1.0.11", 1126 | "safe-buffer": "^5.0.1" 1127 | } 1128 | }, 1129 | "jws": { 1130 | "version": "3.2.2", 1131 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 1132 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 1133 | "requires": { 1134 | "jwa": "^1.4.1", 1135 | "safe-buffer": "^5.0.1" 1136 | } 1137 | }, 1138 | "lodash.includes": { 1139 | "version": "4.3.0", 1140 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 1141 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 1142 | }, 1143 | "lodash.isboolean": { 1144 | "version": "3.0.3", 1145 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 1146 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 1147 | }, 1148 | "lodash.isinteger": { 1149 | "version": "4.0.4", 1150 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 1151 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 1152 | }, 1153 | "lodash.isnumber": { 1154 | "version": "3.0.3", 1155 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 1156 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 1157 | }, 1158 | "lodash.isplainobject": { 1159 | "version": "4.0.6", 1160 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 1161 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 1162 | }, 1163 | "lodash.isstring": { 1164 | "version": "4.0.1", 1165 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 1166 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 1167 | }, 1168 | "lodash.once": { 1169 | "version": "4.1.1", 1170 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 1171 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 1172 | }, 1173 | "lru-cache": { 1174 | "version": "6.0.0", 1175 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1176 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1177 | "requires": { 1178 | "yallist": "^4.0.0" 1179 | } 1180 | }, 1181 | "media-typer": { 1182 | "version": "0.3.0", 1183 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1184 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 1185 | }, 1186 | "merge-descriptors": { 1187 | "version": "1.0.1", 1188 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1189 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1190 | }, 1191 | "methods": { 1192 | "version": "1.1.2", 1193 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1194 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 1195 | }, 1196 | "mime": { 1197 | "version": "1.6.0", 1198 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1199 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1200 | }, 1201 | "mime-db": { 1202 | "version": "1.52.0", 1203 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1204 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 1205 | }, 1206 | "mime-types": { 1207 | "version": "2.1.35", 1208 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1209 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1210 | "requires": { 1211 | "mime-db": "1.52.0" 1212 | } 1213 | }, 1214 | "ms": { 1215 | "version": "2.0.0", 1216 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1217 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1218 | }, 1219 | "negotiator": { 1220 | "version": "0.6.3", 1221 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1222 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 1223 | }, 1224 | "object-assign": { 1225 | "version": "4.1.1", 1226 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1227 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" 1228 | }, 1229 | "object-inspect": { 1230 | "version": "1.13.1", 1231 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 1232 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" 1233 | }, 1234 | "on-finished": { 1235 | "version": "2.4.1", 1236 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1237 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1238 | "requires": { 1239 | "ee-first": "1.1.1" 1240 | } 1241 | }, 1242 | "parseurl": { 1243 | "version": "1.3.3", 1244 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1245 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1246 | }, 1247 | "path-to-regexp": { 1248 | "version": "0.1.7", 1249 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1250 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1251 | }, 1252 | "proxy-addr": { 1253 | "version": "2.0.7", 1254 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1255 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1256 | "requires": { 1257 | "forwarded": "0.2.0", 1258 | "ipaddr.js": "1.9.1" 1259 | } 1260 | }, 1261 | "qs": { 1262 | "version": "6.11.0", 1263 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1264 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1265 | "requires": { 1266 | "side-channel": "^1.0.4" 1267 | } 1268 | }, 1269 | "range-parser": { 1270 | "version": "1.2.1", 1271 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1272 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1273 | }, 1274 | "raw-body": { 1275 | "version": "2.5.1", 1276 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1277 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1278 | "requires": { 1279 | "bytes": "3.1.2", 1280 | "http-errors": "2.0.0", 1281 | "iconv-lite": "0.4.24", 1282 | "unpipe": "1.0.0" 1283 | } 1284 | }, 1285 | "safe-buffer": { 1286 | "version": "5.2.1", 1287 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1288 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1289 | }, 1290 | "safer-buffer": { 1291 | "version": "2.1.2", 1292 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1293 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1294 | }, 1295 | "semver": { 1296 | "version": "7.5.4", 1297 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1298 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1299 | "requires": { 1300 | "lru-cache": "^6.0.0" 1301 | } 1302 | }, 1303 | "send": { 1304 | "version": "0.18.0", 1305 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1306 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1307 | "requires": { 1308 | "debug": "2.6.9", 1309 | "depd": "2.0.0", 1310 | "destroy": "1.2.0", 1311 | "encodeurl": "~1.0.2", 1312 | "escape-html": "~1.0.3", 1313 | "etag": "~1.8.1", 1314 | "fresh": "0.5.2", 1315 | "http-errors": "2.0.0", 1316 | "mime": "1.6.0", 1317 | "ms": "2.1.3", 1318 | "on-finished": "2.4.1", 1319 | "range-parser": "~1.2.1", 1320 | "statuses": "2.0.1" 1321 | }, 1322 | "dependencies": { 1323 | "ms": { 1324 | "version": "2.1.3", 1325 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1326 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1327 | } 1328 | } 1329 | }, 1330 | "serve-static": { 1331 | "version": "1.15.0", 1332 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1333 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1334 | "requires": { 1335 | "encodeurl": "~1.0.2", 1336 | "escape-html": "~1.0.3", 1337 | "parseurl": "~1.3.3", 1338 | "send": "0.18.0" 1339 | } 1340 | }, 1341 | "set-function-length": { 1342 | "version": "1.1.1", 1343 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", 1344 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", 1345 | "requires": { 1346 | "define-data-property": "^1.1.1", 1347 | "get-intrinsic": "^1.2.1", 1348 | "gopd": "^1.0.1", 1349 | "has-property-descriptors": "^1.0.0" 1350 | } 1351 | }, 1352 | "setprototypeof": { 1353 | "version": "1.2.0", 1354 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1355 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1356 | }, 1357 | "side-channel": { 1358 | "version": "1.0.4", 1359 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1360 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1361 | "requires": { 1362 | "call-bind": "^1.0.0", 1363 | "get-intrinsic": "^1.0.2", 1364 | "object-inspect": "^1.9.0" 1365 | } 1366 | }, 1367 | "statuses": { 1368 | "version": "2.0.1", 1369 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1370 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 1371 | }, 1372 | "toidentifier": { 1373 | "version": "1.0.1", 1374 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1375 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1376 | }, 1377 | "type-is": { 1378 | "version": "1.6.18", 1379 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1380 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1381 | "requires": { 1382 | "media-typer": "0.3.0", 1383 | "mime-types": "~2.1.24" 1384 | } 1385 | }, 1386 | "unpipe": { 1387 | "version": "1.0.0", 1388 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1389 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1390 | }, 1391 | "utils-merge": { 1392 | "version": "1.0.1", 1393 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1394 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1395 | }, 1396 | "vary": { 1397 | "version": "1.1.2", 1398 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1399 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1400 | }, 1401 | "yallist": { 1402 | "version": "4.0.0", 1403 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1404 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 1405 | }, 1406 | "zod": { 1407 | "version": "3.22.4", 1408 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", 1409 | "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==" 1410 | } 1411 | } 1412 | } 1413 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-backend", 3 | "version": "1.0.0", 4 | "description": "This is a simple todo application backend", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "harkirat singh", 10 | "license": "ISC", 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "express": "^4.18.2", 14 | "jsonwebtoken": "^9.0.2", 15 | "zod": "^3.22.4" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /backend/types.js: -------------------------------------------------------------------------------- 1 | const zod = require("zod"); 2 | 3 | const createTodo = zod.object({ 4 | title: zod.string(), 5 | description: zod.string() 6 | }) 7 | 8 | const updateTodo = zod.object({ 9 | id: zod.string(), 10 | }) 11 | 12 | module.exports = { 13 | createTodo: createTodo, 14 | updateTodo: updateTodo 15 | } 16 | -------------------------------------------------------------------------------- /frontend/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "react": "^18.2.0", 14 | "react-dom": "^18.2.0" 15 | }, 16 | "devDependencies": { 17 | "@types/react": "^18.2.43", 18 | "@types/react-dom": "^18.2.17", 19 | "@vitejs/plugin-react": "^4.2.1", 20 | "eslint": "^8.55.0", 21 | "eslint-plugin-react": "^7.33.2", 22 | "eslint-plugin-react-hooks": "^4.6.0", 23 | "eslint-plugin-react-refresh": "^0.4.5", 24 | "vite": "^5.0.8" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkirat/todo-app/bd4d0b8edcdf98b956874d2262f5b24e2b9939aa/frontend/src/App.css -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import reactLogo from './assets/react.svg' 3 | import viteLogo from '/vite.svg' 4 | import './App.css' 5 | import { CreateTodo } from './components/CreateTodo' 6 | import { Todos } from './components/Todos' 7 | 8 | // useEffect hook 9 | function App() { 10 | const [todos, setTodos] = useState([]); 11 | 12 | // fetch("http://localhost:3000/todos") 13 | // .then(async function(res) { 14 | // const json = await res.json(); 15 | // setTodos(json.todos); 16 | // }) 17 | 18 | return ( 19 |
20 | 21 | 22 |
23 | ) 24 | } 25 | 26 | export default App 27 | -------------------------------------------------------------------------------- /frontend/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/components/CreateTodo.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | export function CreateTodo(props) { 4 | // react-query 5 | const [title, setTitle] = useState(""); 6 | const [description, setDescription] = useState(""); 7 | 8 | return
9 |
16 | 17 |
24 | 25 | 45 |
46 | } 47 | 48 | -------------------------------------------------------------------------------- /frontend/src/components/Todos.jsx: -------------------------------------------------------------------------------- 1 | 2 | /* todos = [ 3 | { 4 | title: "go to gym", 5 | description: "go to gym", 6 | } 7 | ] 8 | */ 9 | export function Todos({todos}) { 10 | 11 | return
12 | {todos.map(function(todo) { 13 | return
14 |

{todo.title}

15 |

{todo.description}

16 | 17 |
18 | })} 19 |
20 | } -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hkirat/todo-app/bd4d0b8edcdf98b956874d2262f5b24e2b9939aa/frontend/src/index.css -------------------------------------------------------------------------------- /frontend/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------