├── .gitignore ├── README.md ├── backend ├── .gitignore ├── controllers │ └── task.ts ├── package.json ├── pnpm-lock.yaml ├── prisma │ ├── dev.db │ ├── migrations │ │ ├── 20221124145832_init │ │ │ └── migration.sql │ │ └── migration_lock.toml │ └── schema.prisma ├── protos │ ├── task_grpc_pb.d.ts │ ├── task_grpc_pb.js │ ├── task_pb.d.ts │ └── task_pb.js ├── server.ts └── tsconfig.json ├── envoy.yaml ├── frontend ├── .gitignore ├── README.md ├── next.config.js ├── package.json ├── pages │ ├── _app.tsx │ ├── index.tsx │ ├── task │ │ ├── add.tsx │ │ └── update │ │ │ └── [id].tsx │ └── tasks.tsx ├── pnpm-lock.yaml ├── postcss.config.js ├── protos │ ├── task_grpc_web_pb.d.ts │ ├── task_grpc_web_pb.js │ ├── task_pb.d.ts │ └── task_pb.js ├── public │ ├── favicon.ico │ └── vercel.svg ├── styles │ └── globals.css ├── tailwind.config.js ├── tsconfig.json └── util │ ├── grpc-connection.ts │ └── useOnceCall.ts ├── generate_proto.sh ├── package.json ├── pnpm-lock.yaml ├── protos └── task.proto └── rundoc.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .idea -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RealTime Task Management App 2 | 3 | ## Intro 4 | `Simpe task management app built in NextJs and GRPC-Node.` 5 |
6 | `Used GRPC for API calls and Prisma ORM for database to store tasks.` 7 | 8 | ## Technalogies used 9 | 1: Node(GRPC) : Backend 10 |
11 | 2: NextJS : Frontend 12 |
13 | 3: Envoy : Proxy for GRPC 14 | 15 | ## 1: Run in Dev Mode 16 | 1: Install grpc-tools globally using bellow command or else grpc_tools_node_protoc will not work 17 |
18 |
19 | npm i -g grpc-tools 20 |
21 |
22 | 2: Install npm dependencies in these 3 directories 23 |
24 |
25 | npm i 26 | cd backend && npm i backend 27 | cd frontend && npm i frontend 28 |
29 |
30 | 3: Generate protos (optional) 31 |
32 |
33 | npm run gen-proto 34 |
35 |
36 | 4: Run both backend and frondend 37 |
38 |
39 | npm run dev 40 |
41 |
42 | 5: Run docker command for backend GRPC in DEV mode 43 |
44 |
45 | 46 | docker run -ti -p 8080:8080 -p 9901:9901 -v /$(pwd)/envoy.yaml:/etc/envoy/envoy.yaml --rm envoyproxy/envoy-dev:04dd76b051c99f82abda081e1d04cac38667ef88 47 | 48 |
49 | 50 | #### Note: For git-bash i have used /$(pwd) and for bash in linux or mac use $(pwd) and for win use "%cd%". -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | # Keep environment variables out of version control 3 | .env 4 | -------------------------------------------------------------------------------- /backend/controllers/task.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AddTaskRequest, 3 | AddTaskResponse, 4 | DeleteTaskRequest, 5 | DeleteTaskResponse, 6 | EmptyRequest, 7 | EmptyResponse, 8 | Task, 9 | TaskRequest, 10 | TaskResponse, 11 | TasksRequest, 12 | TasksResponse, 13 | UpdateTaskRequest, 14 | UpdateTaskResponse, 15 | } from "../protos/task_pb"; 16 | import { 17 | sendUnaryData, 18 | ServerUnaryCall, 19 | ServerWritableStream, 20 | } from "@grpc/grpc-js"; 21 | import { prisma } from "../server"; 22 | import { Status } from "@grpc/grpc-js/build/src/constants"; 23 | 24 | let connectedClientsForTasks: any[] = []; 25 | 26 | function setTask(task: any) { 27 | const realtask = new Task(); 28 | realtask.setId(task.id); 29 | realtask.setTitle(task.title); 30 | realtask.setBody(task.body); 31 | realtask.setStatus(task.status); 32 | return realtask; 33 | } 34 | 35 | async function addTask( 36 | call: ServerUnaryCall, 37 | callback: sendUnaryData 38 | ) { 39 | try { 40 | console.log(call.request.getTitle()); 41 | const task = await prisma.task.create({ 42 | data: { 43 | title: call.request.getTitle(), 44 | body: call.request.getBody(), 45 | status: call.request.getStatus(), 46 | }, 47 | }); 48 | if (task) { 49 | const requestResponse = new AddTaskResponse(); 50 | requestResponse.setTask(setTask(task)); 51 | const taskRequestResponse = new TasksResponse(); 52 | taskRequestResponse.setTasksList([setTask(task)]); 53 | connectedClientsForTasks.map((item) => { 54 | item.write(taskRequestResponse); 55 | }); 56 | callback(null, requestResponse); 57 | } else { 58 | callback({ 59 | code: Status.INVALID_ARGUMENT, 60 | message: "Unable to add task data into database!", 61 | }); 62 | } 63 | } catch (e: any) { 64 | if (e.code == "P2003") { 65 | callback({ 66 | code: Status.UNKNOWN, 67 | message: "foreign key violation!", 68 | }); 69 | } else { 70 | callback({ 71 | code: Status.UNKNOWN, 72 | message: e.message.toString(), 73 | }); 74 | } 75 | } 76 | } 77 | async function getTask( 78 | call: ServerUnaryCall, 79 | callback: sendUnaryData 80 | ) { 81 | const task = await prisma.task.findUnique({ 82 | where: { 83 | id: call.request.getId(), 84 | }, 85 | }); 86 | if (task) { 87 | const requestResponse = new TaskResponse(); 88 | requestResponse.setTask(setTask(task)); 89 | callback(null, requestResponse); 90 | } else { 91 | callback({ 92 | code: Status.INVALID_ARGUMENT, 93 | message: "task with given ID is not found!", 94 | }); 95 | } 96 | } 97 | 98 | async function updateTask( 99 | call: ServerUnaryCall, 100 | callback: sendUnaryData 101 | ) { 102 | try { 103 | const task = await prisma.task.findUnique({ 104 | where: { 105 | id: call.request.getTask()?.getId(), 106 | }, 107 | }); 108 | if (task) { 109 | const updateTask = await prisma.task.update({ 110 | where: { 111 | id: call.request.getTask()?.getId(), 112 | }, 113 | data: { 114 | title: call.request.getTask()?.getTitle(), 115 | body: call.request.getTask()?.getBody(), 116 | status: call.request.getTask()?.getStatus(), 117 | }, 118 | }); 119 | const requestResponse = new UpdateTaskResponse(); 120 | requestResponse.setTask(setTask(updateTask)); 121 | callback(null, requestResponse); 122 | } else { 123 | callback({ 124 | code: Status.UNAVAILABLE, 125 | message: "Failed to update, task with given ID is not found!", 126 | }); 127 | } 128 | } catch (e: any) { 129 | if (e.code == "P2003") { 130 | callback({ 131 | code: Status.UNKNOWN, 132 | message: "foreign key violation!", 133 | }); 134 | } else { 135 | callback({ 136 | code: Status.UNKNOWN, 137 | message: e.message.toString(), 138 | }); 139 | } 140 | } 141 | } 142 | async function deleteTask( 143 | call: ServerUnaryCall, 144 | callback: sendUnaryData 145 | ) { 146 | try { 147 | const deleteTask = await prisma.task.delete({ 148 | where: { 149 | id: call.request.getId(), 150 | }, 151 | }); 152 | if (deleteTask) { 153 | const requestResponse = new DeleteTaskResponse(); 154 | requestResponse.setMessage( 155 | "Task with ID: " + call.request.getId() + " delete successfully!" 156 | ); 157 | callback(null, requestResponse); 158 | } else { 159 | callback({ 160 | code: Status.UNAVAILABLE, 161 | message: "Unable to delete task with the given ID!", 162 | }); 163 | } 164 | } catch (e: any) { 165 | if (e.code == "P2003") { 166 | callback({ 167 | code: Status.UNKNOWN, 168 | message: "foreign key violation!", 169 | }); 170 | } else if (e.code == "P2025") { 171 | callback({ 172 | code: Status.UNKNOWN, 173 | message: "Record to delete does not exist", 174 | }); 175 | } else { 176 | callback({ 177 | code: Status.UNKNOWN, 178 | message: e.message.toString(), 179 | }); 180 | } 181 | } 182 | } 183 | async function getAllTasks( 184 | call: ServerWritableStream 185 | ) { 186 | connectedClientsForTasks.push(call); 187 | const tasks = await prisma.task.findMany({ 188 | orderBy: [ 189 | { 190 | id: "desc", 191 | }, 192 | ], 193 | }); 194 | const requestResponse = new TasksResponse(); 195 | tasks.map((item) => { 196 | requestResponse.addTasks(setTask(item)); 197 | }); 198 | call.write(requestResponse); 199 | } 200 | 201 | async function deleteUnUsedConnections( 202 | call: ServerUnaryCall, 203 | callback: sendUnaryData 204 | ) { 205 | let connectedClientsCancelled = 0; 206 | connectedClientsForTasks = connectedClientsForTasks.filter((item) => { 207 | if (item.cancelled) connectedClientsCancelled++; 208 | return !item.cancelled; 209 | }); 210 | const empty = new EmptyResponse(); 211 | empty.setMessage( 212 | "Total unused clients connections cancelled: " + connectedClientsCancelled 213 | ); 214 | callback(null, empty); 215 | } 216 | 217 | export { 218 | addTask, 219 | getTask, 220 | updateTask, 221 | deleteTask, 222 | getAllTasks, 223 | deleteUnUsedConnections, 224 | }; 225 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "ts-node-dev server.ts", 8 | "start": "ts-node server.ts" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@tsconfig/node18": "^1.0.1", 15 | "@types/bcrypt": "^5.0.0", 16 | "@types/jsonwebtoken": "^8.5.9", 17 | "@types/node": "^18.11.9", 18 | "bcrypt": "^5.1.0", 19 | "dotenv": "^16.0.3", 20 | "google-protobuf": "^3.21.2", 21 | "jsonwebtoken": "^8.5.1", 22 | "prisma": "^4.6.1", 23 | "ts-node": "^10.9.1", 24 | "ts-node-dev": "^2.0.0", 25 | "tslib": "^2.4.1", 26 | "typescript": "^4.9.3" 27 | }, 28 | "dependencies": { 29 | "@grpc/grpc-js": "^1.7.3", 30 | "@prisma/client": "^4.6.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /backend/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@grpc/grpc-js': ^1.7.3 5 | '@prisma/client': ^4.6.1 6 | '@tsconfig/node18': ^1.0.1 7 | '@types/bcrypt': ^5.0.0 8 | '@types/jsonwebtoken': ^8.5.9 9 | '@types/node': ^18.11.9 10 | bcrypt: ^5.1.0 11 | dotenv: ^16.0.3 12 | google-protobuf: ^3.21.2 13 | jsonwebtoken: ^8.5.1 14 | prisma: ^4.6.1 15 | ts-node: ^10.9.1 16 | ts-node-dev: ^2.0.0 17 | tslib: ^2.4.1 18 | typescript: ^4.9.3 19 | 20 | dependencies: 21 | '@grpc/grpc-js': 1.7.3 22 | '@prisma/client': 4.6.1_prisma@4.6.1 23 | 24 | devDependencies: 25 | '@tsconfig/node18': 1.0.1 26 | '@types/bcrypt': 5.0.0 27 | '@types/jsonwebtoken': 8.5.9 28 | '@types/node': 18.11.9 29 | bcrypt: 5.1.0 30 | dotenv: 16.0.3 31 | google-protobuf: 3.21.2 32 | jsonwebtoken: 8.5.1 33 | prisma: 4.6.1 34 | ts-node: 10.9.1_wup25etrarvlqkprac7h35hj7u 35 | ts-node-dev: 2.0.0_wup25etrarvlqkprac7h35hj7u 36 | tslib: 2.4.1 37 | typescript: 4.9.3 38 | 39 | packages: 40 | 41 | /@cspotcode/source-map-support/0.8.1: 42 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 43 | engines: {node: '>=12'} 44 | dependencies: 45 | '@jridgewell/trace-mapping': 0.3.9 46 | dev: true 47 | 48 | /@grpc/grpc-js/1.7.3: 49 | resolution: {integrity: sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==} 50 | engines: {node: ^8.13.0 || >=10.10.0} 51 | dependencies: 52 | '@grpc/proto-loader': 0.7.3 53 | '@types/node': 18.11.9 54 | dev: false 55 | 56 | /@grpc/proto-loader/0.7.3: 57 | resolution: {integrity: sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==} 58 | engines: {node: '>=6'} 59 | hasBin: true 60 | dependencies: 61 | '@types/long': 4.0.2 62 | lodash.camelcase: 4.3.0 63 | long: 4.0.0 64 | protobufjs: 7.1.2 65 | yargs: 16.2.0 66 | dev: false 67 | 68 | /@jridgewell/resolve-uri/3.1.0: 69 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 70 | engines: {node: '>=6.0.0'} 71 | dev: true 72 | 73 | /@jridgewell/sourcemap-codec/1.4.14: 74 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 75 | dev: true 76 | 77 | /@jridgewell/trace-mapping/0.3.9: 78 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 79 | dependencies: 80 | '@jridgewell/resolve-uri': 3.1.0 81 | '@jridgewell/sourcemap-codec': 1.4.14 82 | dev: true 83 | 84 | /@mapbox/node-pre-gyp/1.0.10: 85 | resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==} 86 | hasBin: true 87 | dependencies: 88 | detect-libc: 2.0.1 89 | https-proxy-agent: 5.0.1 90 | make-dir: 3.1.0 91 | node-fetch: 2.6.7 92 | nopt: 5.0.0 93 | npmlog: 5.0.1 94 | rimraf: 3.0.2 95 | semver: 7.3.8 96 | tar: 6.1.12 97 | transitivePeerDependencies: 98 | - encoding 99 | - supports-color 100 | dev: true 101 | 102 | /@prisma/client/4.6.1_prisma@4.6.1: 103 | resolution: {integrity: sha512-M1+NNrMzqaOIxT7PBGcTs3IZo7d1EW/+gVQd4C4gUgWBDGgD9AcIeZnUSidgWClmpMSgVUdnVORjsWWGUameYA==} 104 | engines: {node: '>=14.17'} 105 | requiresBuild: true 106 | peerDependencies: 107 | prisma: '*' 108 | peerDependenciesMeta: 109 | prisma: 110 | optional: true 111 | dependencies: 112 | '@prisma/engines-version': 4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32 113 | prisma: 4.6.1 114 | dev: false 115 | 116 | /@prisma/engines-version/4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32: 117 | resolution: {integrity: sha512-HUCmkXAU2jqp2O1RvNtbE+seLGLyJGEABZS/R38rZjSAafAy0WzBuHq+tbZMnD+b5OSCsTVtIPVcuvx1ySxcWQ==} 118 | dev: false 119 | 120 | /@prisma/engines/4.6.1: 121 | resolution: {integrity: sha512-3u2/XxvxB+Q7cMXHnKU0CpBiUK1QWqpgiBv28YDo1zOIJE3FCF8DI2vrp6vuwjGt5h0JGXDSvmSf4D4maVjJdw==} 122 | requiresBuild: true 123 | 124 | /@protobufjs/aspromise/1.1.2: 125 | resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} 126 | dev: false 127 | 128 | /@protobufjs/base64/1.1.2: 129 | resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} 130 | dev: false 131 | 132 | /@protobufjs/codegen/2.0.4: 133 | resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} 134 | dev: false 135 | 136 | /@protobufjs/eventemitter/1.1.0: 137 | resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} 138 | dev: false 139 | 140 | /@protobufjs/fetch/1.1.0: 141 | resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} 142 | dependencies: 143 | '@protobufjs/aspromise': 1.1.2 144 | '@protobufjs/inquire': 1.1.0 145 | dev: false 146 | 147 | /@protobufjs/float/1.0.2: 148 | resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} 149 | dev: false 150 | 151 | /@protobufjs/inquire/1.1.0: 152 | resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} 153 | dev: false 154 | 155 | /@protobufjs/path/1.1.2: 156 | resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} 157 | dev: false 158 | 159 | /@protobufjs/pool/1.1.0: 160 | resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} 161 | dev: false 162 | 163 | /@protobufjs/utf8/1.1.0: 164 | resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} 165 | dev: false 166 | 167 | /@tsconfig/node10/1.0.9: 168 | resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} 169 | dev: true 170 | 171 | /@tsconfig/node12/1.0.11: 172 | resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} 173 | dev: true 174 | 175 | /@tsconfig/node14/1.0.3: 176 | resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} 177 | dev: true 178 | 179 | /@tsconfig/node16/1.0.3: 180 | resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} 181 | dev: true 182 | 183 | /@tsconfig/node18/1.0.1: 184 | resolution: {integrity: sha512-sNFeK6X2ATlhlvzyH4kKYQlfHXE2f2/wxtB9ClvYXevWpmwkUT7VaSrjIN9E76Qebz8qP5JOJJ9jD3QoD/Z9TA==} 185 | dev: true 186 | 187 | /@types/bcrypt/5.0.0: 188 | resolution: {integrity: sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==} 189 | dependencies: 190 | '@types/node': 18.11.9 191 | dev: true 192 | 193 | /@types/jsonwebtoken/8.5.9: 194 | resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==} 195 | dependencies: 196 | '@types/node': 18.11.9 197 | dev: true 198 | 199 | /@types/long/4.0.2: 200 | resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} 201 | dev: false 202 | 203 | /@types/node/18.11.9: 204 | resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} 205 | 206 | /@types/strip-bom/3.0.0: 207 | resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} 208 | dev: true 209 | 210 | /@types/strip-json-comments/0.0.30: 211 | resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} 212 | dev: true 213 | 214 | /abbrev/1.1.1: 215 | resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} 216 | dev: true 217 | 218 | /acorn-walk/8.2.0: 219 | resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} 220 | engines: {node: '>=0.4.0'} 221 | dev: true 222 | 223 | /acorn/8.8.1: 224 | resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} 225 | engines: {node: '>=0.4.0'} 226 | hasBin: true 227 | dev: true 228 | 229 | /agent-base/6.0.2: 230 | resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} 231 | engines: {node: '>= 6.0.0'} 232 | dependencies: 233 | debug: 4.3.4 234 | transitivePeerDependencies: 235 | - supports-color 236 | dev: true 237 | 238 | /ansi-regex/5.0.1: 239 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 240 | engines: {node: '>=8'} 241 | 242 | /ansi-styles/4.3.0: 243 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 244 | engines: {node: '>=8'} 245 | dependencies: 246 | color-convert: 2.0.1 247 | dev: false 248 | 249 | /anymatch/3.1.2: 250 | resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} 251 | engines: {node: '>= 8'} 252 | dependencies: 253 | normalize-path: 3.0.0 254 | picomatch: 2.3.1 255 | dev: true 256 | 257 | /aproba/2.0.0: 258 | resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} 259 | dev: true 260 | 261 | /are-we-there-yet/2.0.0: 262 | resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} 263 | engines: {node: '>=10'} 264 | dependencies: 265 | delegates: 1.0.0 266 | readable-stream: 3.6.0 267 | dev: true 268 | 269 | /arg/4.1.3: 270 | resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 271 | dev: true 272 | 273 | /balanced-match/1.0.2: 274 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 275 | dev: true 276 | 277 | /bcrypt/5.1.0: 278 | resolution: {integrity: sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==} 279 | engines: {node: '>= 10.0.0'} 280 | requiresBuild: true 281 | dependencies: 282 | '@mapbox/node-pre-gyp': 1.0.10 283 | node-addon-api: 5.0.0 284 | transitivePeerDependencies: 285 | - encoding 286 | - supports-color 287 | dev: true 288 | 289 | /binary-extensions/2.2.0: 290 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 291 | engines: {node: '>=8'} 292 | dev: true 293 | 294 | /brace-expansion/1.1.11: 295 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 296 | dependencies: 297 | balanced-match: 1.0.2 298 | concat-map: 0.0.1 299 | dev: true 300 | 301 | /braces/3.0.2: 302 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 303 | engines: {node: '>=8'} 304 | dependencies: 305 | fill-range: 7.0.1 306 | dev: true 307 | 308 | /buffer-equal-constant-time/1.0.1: 309 | resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} 310 | dev: true 311 | 312 | /buffer-from/1.1.2: 313 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 314 | dev: true 315 | 316 | /chokidar/3.5.3: 317 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 318 | engines: {node: '>= 8.10.0'} 319 | dependencies: 320 | anymatch: 3.1.2 321 | braces: 3.0.2 322 | glob-parent: 5.1.2 323 | is-binary-path: 2.1.0 324 | is-glob: 4.0.3 325 | normalize-path: 3.0.0 326 | readdirp: 3.6.0 327 | optionalDependencies: 328 | fsevents: 2.3.2 329 | dev: true 330 | 331 | /chownr/2.0.0: 332 | resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} 333 | engines: {node: '>=10'} 334 | dev: true 335 | 336 | /cliui/7.0.4: 337 | resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} 338 | dependencies: 339 | string-width: 4.2.3 340 | strip-ansi: 6.0.1 341 | wrap-ansi: 7.0.0 342 | dev: false 343 | 344 | /color-convert/2.0.1: 345 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 346 | engines: {node: '>=7.0.0'} 347 | dependencies: 348 | color-name: 1.1.4 349 | dev: false 350 | 351 | /color-name/1.1.4: 352 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 353 | dev: false 354 | 355 | /color-support/1.1.3: 356 | resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} 357 | hasBin: true 358 | dev: true 359 | 360 | /concat-map/0.0.1: 361 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 362 | dev: true 363 | 364 | /console-control-strings/1.1.0: 365 | resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} 366 | dev: true 367 | 368 | /create-require/1.1.1: 369 | resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} 370 | dev: true 371 | 372 | /debug/4.3.4: 373 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 374 | engines: {node: '>=6.0'} 375 | peerDependencies: 376 | supports-color: '*' 377 | peerDependenciesMeta: 378 | supports-color: 379 | optional: true 380 | dependencies: 381 | ms: 2.1.2 382 | dev: true 383 | 384 | /delegates/1.0.0: 385 | resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} 386 | dev: true 387 | 388 | /detect-libc/2.0.1: 389 | resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} 390 | engines: {node: '>=8'} 391 | dev: true 392 | 393 | /diff/4.0.2: 394 | resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} 395 | engines: {node: '>=0.3.1'} 396 | dev: true 397 | 398 | /dotenv/16.0.3: 399 | resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} 400 | engines: {node: '>=12'} 401 | dev: true 402 | 403 | /dynamic-dedupe/0.3.0: 404 | resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} 405 | dependencies: 406 | xtend: 4.0.2 407 | dev: true 408 | 409 | /ecdsa-sig-formatter/1.0.11: 410 | resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} 411 | dependencies: 412 | safe-buffer: 5.2.1 413 | dev: true 414 | 415 | /emoji-regex/8.0.0: 416 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 417 | 418 | /escalade/3.1.1: 419 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 420 | engines: {node: '>=6'} 421 | dev: false 422 | 423 | /fill-range/7.0.1: 424 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 425 | engines: {node: '>=8'} 426 | dependencies: 427 | to-regex-range: 5.0.1 428 | dev: true 429 | 430 | /fs-minipass/2.1.0: 431 | resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} 432 | engines: {node: '>= 8'} 433 | dependencies: 434 | minipass: 3.3.4 435 | dev: true 436 | 437 | /fs.realpath/1.0.0: 438 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 439 | dev: true 440 | 441 | /fsevents/2.3.2: 442 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 443 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 444 | os: [darwin] 445 | requiresBuild: true 446 | dev: true 447 | optional: true 448 | 449 | /function-bind/1.1.1: 450 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 451 | dev: true 452 | 453 | /gauge/3.0.2: 454 | resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} 455 | engines: {node: '>=10'} 456 | dependencies: 457 | aproba: 2.0.0 458 | color-support: 1.1.3 459 | console-control-strings: 1.1.0 460 | has-unicode: 2.0.1 461 | object-assign: 4.1.1 462 | signal-exit: 3.0.7 463 | string-width: 4.2.3 464 | strip-ansi: 6.0.1 465 | wide-align: 1.1.5 466 | dev: true 467 | 468 | /get-caller-file/2.0.5: 469 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 470 | engines: {node: 6.* || 8.* || >= 10.*} 471 | dev: false 472 | 473 | /glob-parent/5.1.2: 474 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 475 | engines: {node: '>= 6'} 476 | dependencies: 477 | is-glob: 4.0.3 478 | dev: true 479 | 480 | /glob/7.2.3: 481 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 482 | dependencies: 483 | fs.realpath: 1.0.0 484 | inflight: 1.0.6 485 | inherits: 2.0.4 486 | minimatch: 3.1.2 487 | once: 1.4.0 488 | path-is-absolute: 1.0.1 489 | dev: true 490 | 491 | /google-protobuf/3.21.2: 492 | resolution: {integrity: sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==} 493 | dev: true 494 | 495 | /has-unicode/2.0.1: 496 | resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} 497 | dev: true 498 | 499 | /has/1.0.3: 500 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 501 | engines: {node: '>= 0.4.0'} 502 | dependencies: 503 | function-bind: 1.1.1 504 | dev: true 505 | 506 | /https-proxy-agent/5.0.1: 507 | resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} 508 | engines: {node: '>= 6'} 509 | dependencies: 510 | agent-base: 6.0.2 511 | debug: 4.3.4 512 | transitivePeerDependencies: 513 | - supports-color 514 | dev: true 515 | 516 | /inflight/1.0.6: 517 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 518 | dependencies: 519 | once: 1.4.0 520 | wrappy: 1.0.2 521 | dev: true 522 | 523 | /inherits/2.0.4: 524 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 525 | dev: true 526 | 527 | /is-binary-path/2.1.0: 528 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 529 | engines: {node: '>=8'} 530 | dependencies: 531 | binary-extensions: 2.2.0 532 | dev: true 533 | 534 | /is-core-module/2.11.0: 535 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 536 | dependencies: 537 | has: 1.0.3 538 | dev: true 539 | 540 | /is-extglob/2.1.1: 541 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 542 | engines: {node: '>=0.10.0'} 543 | dev: true 544 | 545 | /is-fullwidth-code-point/3.0.0: 546 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 547 | engines: {node: '>=8'} 548 | 549 | /is-glob/4.0.3: 550 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 551 | engines: {node: '>=0.10.0'} 552 | dependencies: 553 | is-extglob: 2.1.1 554 | dev: true 555 | 556 | /is-number/7.0.0: 557 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 558 | engines: {node: '>=0.12.0'} 559 | dev: true 560 | 561 | /jsonwebtoken/8.5.1: 562 | resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} 563 | engines: {node: '>=4', npm: '>=1.4.28'} 564 | dependencies: 565 | jws: 3.2.2 566 | lodash.includes: 4.3.0 567 | lodash.isboolean: 3.0.3 568 | lodash.isinteger: 4.0.4 569 | lodash.isnumber: 3.0.3 570 | lodash.isplainobject: 4.0.6 571 | lodash.isstring: 4.0.1 572 | lodash.once: 4.1.1 573 | ms: 2.1.3 574 | semver: 5.7.1 575 | dev: true 576 | 577 | /jwa/1.4.1: 578 | resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} 579 | dependencies: 580 | buffer-equal-constant-time: 1.0.1 581 | ecdsa-sig-formatter: 1.0.11 582 | safe-buffer: 5.2.1 583 | dev: true 584 | 585 | /jws/3.2.2: 586 | resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} 587 | dependencies: 588 | jwa: 1.4.1 589 | safe-buffer: 5.2.1 590 | dev: true 591 | 592 | /lodash.camelcase/4.3.0: 593 | resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} 594 | dev: false 595 | 596 | /lodash.includes/4.3.0: 597 | resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} 598 | dev: true 599 | 600 | /lodash.isboolean/3.0.3: 601 | resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} 602 | dev: true 603 | 604 | /lodash.isinteger/4.0.4: 605 | resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} 606 | dev: true 607 | 608 | /lodash.isnumber/3.0.3: 609 | resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} 610 | dev: true 611 | 612 | /lodash.isplainobject/4.0.6: 613 | resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} 614 | dev: true 615 | 616 | /lodash.isstring/4.0.1: 617 | resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} 618 | dev: true 619 | 620 | /lodash.once/4.1.1: 621 | resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} 622 | dev: true 623 | 624 | /long/4.0.0: 625 | resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} 626 | dev: false 627 | 628 | /long/5.2.1: 629 | resolution: {integrity: sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==} 630 | dev: false 631 | 632 | /lru-cache/6.0.0: 633 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 634 | engines: {node: '>=10'} 635 | dependencies: 636 | yallist: 4.0.0 637 | dev: true 638 | 639 | /make-dir/3.1.0: 640 | resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} 641 | engines: {node: '>=8'} 642 | dependencies: 643 | semver: 6.3.0 644 | dev: true 645 | 646 | /make-error/1.3.6: 647 | resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} 648 | dev: true 649 | 650 | /minimatch/3.1.2: 651 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 652 | dependencies: 653 | brace-expansion: 1.1.11 654 | dev: true 655 | 656 | /minimist/1.2.7: 657 | resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} 658 | dev: true 659 | 660 | /minipass/3.3.4: 661 | resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} 662 | engines: {node: '>=8'} 663 | dependencies: 664 | yallist: 4.0.0 665 | dev: true 666 | 667 | /minizlib/2.1.2: 668 | resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} 669 | engines: {node: '>= 8'} 670 | dependencies: 671 | minipass: 3.3.4 672 | yallist: 4.0.0 673 | dev: true 674 | 675 | /mkdirp/1.0.4: 676 | resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} 677 | engines: {node: '>=10'} 678 | hasBin: true 679 | dev: true 680 | 681 | /ms/2.1.2: 682 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 683 | dev: true 684 | 685 | /ms/2.1.3: 686 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 687 | dev: true 688 | 689 | /node-addon-api/5.0.0: 690 | resolution: {integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==} 691 | dev: true 692 | 693 | /node-fetch/2.6.7: 694 | resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} 695 | engines: {node: 4.x || >=6.0.0} 696 | peerDependencies: 697 | encoding: ^0.1.0 698 | peerDependenciesMeta: 699 | encoding: 700 | optional: true 701 | dependencies: 702 | whatwg-url: 5.0.0 703 | dev: true 704 | 705 | /nopt/5.0.0: 706 | resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} 707 | engines: {node: '>=6'} 708 | hasBin: true 709 | dependencies: 710 | abbrev: 1.1.1 711 | dev: true 712 | 713 | /normalize-path/3.0.0: 714 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 715 | engines: {node: '>=0.10.0'} 716 | dev: true 717 | 718 | /npmlog/5.0.1: 719 | resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} 720 | dependencies: 721 | are-we-there-yet: 2.0.0 722 | console-control-strings: 1.1.0 723 | gauge: 3.0.2 724 | set-blocking: 2.0.0 725 | dev: true 726 | 727 | /object-assign/4.1.1: 728 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 729 | engines: {node: '>=0.10.0'} 730 | dev: true 731 | 732 | /once/1.4.0: 733 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 734 | dependencies: 735 | wrappy: 1.0.2 736 | dev: true 737 | 738 | /path-is-absolute/1.0.1: 739 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 740 | engines: {node: '>=0.10.0'} 741 | dev: true 742 | 743 | /path-parse/1.0.7: 744 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 745 | dev: true 746 | 747 | /picomatch/2.3.1: 748 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 749 | engines: {node: '>=8.6'} 750 | dev: true 751 | 752 | /prisma/4.6.1: 753 | resolution: {integrity: sha512-BR4itMCuzrDV4tn3e2TF+nh1zIX/RVU0isKtKoN28ADeoJ9nYaMhiuRRkFd2TZN8+l/XfYzoRKyHzUFXLQhmBQ==} 754 | engines: {node: '>=14.17'} 755 | hasBin: true 756 | requiresBuild: true 757 | dependencies: 758 | '@prisma/engines': 4.6.1 759 | 760 | /protobufjs/7.1.2: 761 | resolution: {integrity: sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==} 762 | engines: {node: '>=12.0.0'} 763 | requiresBuild: true 764 | dependencies: 765 | '@protobufjs/aspromise': 1.1.2 766 | '@protobufjs/base64': 1.1.2 767 | '@protobufjs/codegen': 2.0.4 768 | '@protobufjs/eventemitter': 1.1.0 769 | '@protobufjs/fetch': 1.1.0 770 | '@protobufjs/float': 1.0.2 771 | '@protobufjs/inquire': 1.1.0 772 | '@protobufjs/path': 1.1.2 773 | '@protobufjs/pool': 1.1.0 774 | '@protobufjs/utf8': 1.1.0 775 | '@types/node': 18.11.9 776 | long: 5.2.1 777 | dev: false 778 | 779 | /readable-stream/3.6.0: 780 | resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} 781 | engines: {node: '>= 6'} 782 | dependencies: 783 | inherits: 2.0.4 784 | string_decoder: 1.3.0 785 | util-deprecate: 1.0.2 786 | dev: true 787 | 788 | /readdirp/3.6.0: 789 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 790 | engines: {node: '>=8.10.0'} 791 | dependencies: 792 | picomatch: 2.3.1 793 | dev: true 794 | 795 | /require-directory/2.1.1: 796 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 797 | engines: {node: '>=0.10.0'} 798 | dev: false 799 | 800 | /resolve/1.22.1: 801 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 802 | hasBin: true 803 | dependencies: 804 | is-core-module: 2.11.0 805 | path-parse: 1.0.7 806 | supports-preserve-symlinks-flag: 1.0.0 807 | dev: true 808 | 809 | /rimraf/2.7.1: 810 | resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} 811 | hasBin: true 812 | dependencies: 813 | glob: 7.2.3 814 | dev: true 815 | 816 | /rimraf/3.0.2: 817 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 818 | hasBin: true 819 | dependencies: 820 | glob: 7.2.3 821 | dev: true 822 | 823 | /safe-buffer/5.2.1: 824 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 825 | dev: true 826 | 827 | /semver/5.7.1: 828 | resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} 829 | hasBin: true 830 | dev: true 831 | 832 | /semver/6.3.0: 833 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 834 | hasBin: true 835 | dev: true 836 | 837 | /semver/7.3.8: 838 | resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} 839 | engines: {node: '>=10'} 840 | hasBin: true 841 | dependencies: 842 | lru-cache: 6.0.0 843 | dev: true 844 | 845 | /set-blocking/2.0.0: 846 | resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} 847 | dev: true 848 | 849 | /signal-exit/3.0.7: 850 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 851 | dev: true 852 | 853 | /source-map-support/0.5.21: 854 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 855 | dependencies: 856 | buffer-from: 1.1.2 857 | source-map: 0.6.1 858 | dev: true 859 | 860 | /source-map/0.6.1: 861 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 862 | engines: {node: '>=0.10.0'} 863 | dev: true 864 | 865 | /string-width/4.2.3: 866 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 867 | engines: {node: '>=8'} 868 | dependencies: 869 | emoji-regex: 8.0.0 870 | is-fullwidth-code-point: 3.0.0 871 | strip-ansi: 6.0.1 872 | 873 | /string_decoder/1.3.0: 874 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 875 | dependencies: 876 | safe-buffer: 5.2.1 877 | dev: true 878 | 879 | /strip-ansi/6.0.1: 880 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 881 | engines: {node: '>=8'} 882 | dependencies: 883 | ansi-regex: 5.0.1 884 | 885 | /strip-bom/3.0.0: 886 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 887 | engines: {node: '>=4'} 888 | dev: true 889 | 890 | /strip-json-comments/2.0.1: 891 | resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} 892 | engines: {node: '>=0.10.0'} 893 | dev: true 894 | 895 | /supports-preserve-symlinks-flag/1.0.0: 896 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 897 | engines: {node: '>= 0.4'} 898 | dev: true 899 | 900 | /tar/6.1.12: 901 | resolution: {integrity: sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==} 902 | engines: {node: '>=10'} 903 | dependencies: 904 | chownr: 2.0.0 905 | fs-minipass: 2.1.0 906 | minipass: 3.3.4 907 | minizlib: 2.1.2 908 | mkdirp: 1.0.4 909 | yallist: 4.0.0 910 | dev: true 911 | 912 | /to-regex-range/5.0.1: 913 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 914 | engines: {node: '>=8.0'} 915 | dependencies: 916 | is-number: 7.0.0 917 | dev: true 918 | 919 | /tr46/0.0.3: 920 | resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 921 | dev: true 922 | 923 | /tree-kill/1.2.2: 924 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 925 | hasBin: true 926 | dev: true 927 | 928 | /ts-node-dev/2.0.0_wup25etrarvlqkprac7h35hj7u: 929 | resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} 930 | engines: {node: '>=0.8.0'} 931 | hasBin: true 932 | peerDependencies: 933 | node-notifier: '*' 934 | typescript: '*' 935 | peerDependenciesMeta: 936 | node-notifier: 937 | optional: true 938 | dependencies: 939 | chokidar: 3.5.3 940 | dynamic-dedupe: 0.3.0 941 | minimist: 1.2.7 942 | mkdirp: 1.0.4 943 | resolve: 1.22.1 944 | rimraf: 2.7.1 945 | source-map-support: 0.5.21 946 | tree-kill: 1.2.2 947 | ts-node: 10.9.1_wup25etrarvlqkprac7h35hj7u 948 | tsconfig: 7.0.0 949 | typescript: 4.9.3 950 | transitivePeerDependencies: 951 | - '@swc/core' 952 | - '@swc/wasm' 953 | - '@types/node' 954 | dev: true 955 | 956 | /ts-node/10.9.1_wup25etrarvlqkprac7h35hj7u: 957 | resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} 958 | hasBin: true 959 | peerDependencies: 960 | '@swc/core': '>=1.2.50' 961 | '@swc/wasm': '>=1.2.50' 962 | '@types/node': '*' 963 | typescript: '>=2.7' 964 | peerDependenciesMeta: 965 | '@swc/core': 966 | optional: true 967 | '@swc/wasm': 968 | optional: true 969 | dependencies: 970 | '@cspotcode/source-map-support': 0.8.1 971 | '@tsconfig/node10': 1.0.9 972 | '@tsconfig/node12': 1.0.11 973 | '@tsconfig/node14': 1.0.3 974 | '@tsconfig/node16': 1.0.3 975 | '@types/node': 18.11.9 976 | acorn: 8.8.1 977 | acorn-walk: 8.2.0 978 | arg: 4.1.3 979 | create-require: 1.1.1 980 | diff: 4.0.2 981 | make-error: 1.3.6 982 | typescript: 4.9.3 983 | v8-compile-cache-lib: 3.0.1 984 | yn: 3.1.1 985 | dev: true 986 | 987 | /tsconfig/7.0.0: 988 | resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} 989 | dependencies: 990 | '@types/strip-bom': 3.0.0 991 | '@types/strip-json-comments': 0.0.30 992 | strip-bom: 3.0.0 993 | strip-json-comments: 2.0.1 994 | dev: true 995 | 996 | /tslib/2.4.1: 997 | resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} 998 | dev: true 999 | 1000 | /typescript/4.9.3: 1001 | resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} 1002 | engines: {node: '>=4.2.0'} 1003 | hasBin: true 1004 | dev: true 1005 | 1006 | /util-deprecate/1.0.2: 1007 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1008 | dev: true 1009 | 1010 | /v8-compile-cache-lib/3.0.1: 1011 | resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} 1012 | dev: true 1013 | 1014 | /webidl-conversions/3.0.1: 1015 | resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 1016 | dev: true 1017 | 1018 | /whatwg-url/5.0.0: 1019 | resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} 1020 | dependencies: 1021 | tr46: 0.0.3 1022 | webidl-conversions: 3.0.1 1023 | dev: true 1024 | 1025 | /wide-align/1.1.5: 1026 | resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} 1027 | dependencies: 1028 | string-width: 4.2.3 1029 | dev: true 1030 | 1031 | /wrap-ansi/7.0.0: 1032 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1033 | engines: {node: '>=10'} 1034 | dependencies: 1035 | ansi-styles: 4.3.0 1036 | string-width: 4.2.3 1037 | strip-ansi: 6.0.1 1038 | dev: false 1039 | 1040 | /wrappy/1.0.2: 1041 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1042 | dev: true 1043 | 1044 | /xtend/4.0.2: 1045 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 1046 | engines: {node: '>=0.4'} 1047 | dev: true 1048 | 1049 | /y18n/5.0.8: 1050 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 1051 | engines: {node: '>=10'} 1052 | dev: false 1053 | 1054 | /yallist/4.0.0: 1055 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1056 | dev: true 1057 | 1058 | /yargs-parser/20.2.9: 1059 | resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} 1060 | engines: {node: '>=10'} 1061 | dev: false 1062 | 1063 | /yargs/16.2.0: 1064 | resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} 1065 | engines: {node: '>=10'} 1066 | dependencies: 1067 | cliui: 7.0.4 1068 | escalade: 3.1.1 1069 | get-caller-file: 2.0.5 1070 | require-directory: 2.1.1 1071 | string-width: 4.2.3 1072 | y18n: 5.0.8 1073 | yargs-parser: 20.2.9 1074 | dev: false 1075 | 1076 | /yn/3.1.1: 1077 | resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} 1078 | engines: {node: '>=6'} 1079 | dev: true 1080 | -------------------------------------------------------------------------------- /backend/prisma/dev.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ozair0/RealTime-Task-Management-App/6bf75b57b21d146f2d0182ab6d6b7aff10a44eb7/backend/prisma/dev.db -------------------------------------------------------------------------------- /backend/prisma/migrations/20221124145832_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "Task" ( 3 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 4 | "title" TEXT NOT NULL, 5 | "body" TEXT NOT NULL, 6 | "status" TEXT NOT NULL 7 | ); 8 | -------------------------------------------------------------------------------- /backend/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "sqlite" -------------------------------------------------------------------------------- /backend/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | generator client { 5 | provider = "prisma-client-js" 6 | } 7 | 8 | datasource db { 9 | provider = "sqlite" 10 | url = "file:./dev.db" 11 | } 12 | 13 | model Task { 14 | id Int @id @default(autoincrement()) 15 | title String 16 | body String 17 | status String 18 | } 19 | -------------------------------------------------------------------------------- /backend/protos/task_grpc_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: task 2 | // file: protos/task.proto 3 | 4 | /* tslint:disable */ 5 | /* eslint-disable */ 6 | 7 | import * as grpc from "@grpc/grpc-js"; 8 | import * as protos_task_pb from "../protos/task_pb"; 9 | 10 | interface ITaskServiceService extends grpc.ServiceDefinition { 11 | getTask: ITaskServiceService_IGetTask; 12 | addTask: ITaskServiceService_IAddTask; 13 | deleteTask: ITaskServiceService_IDeleteTask; 14 | updateTask: ITaskServiceService_IUpdateTask; 15 | deleteUnUsedConnections: ITaskServiceService_IDeleteUnUsedConnections; 16 | getAllTasks: ITaskServiceService_IGetAllTasks; 17 | } 18 | 19 | interface ITaskServiceService_IGetTask extends grpc.MethodDefinition { 20 | path: "/task.TaskService/GetTask"; 21 | requestStream: false; 22 | responseStream: false; 23 | requestSerialize: grpc.serialize; 24 | requestDeserialize: grpc.deserialize; 25 | responseSerialize: grpc.serialize; 26 | responseDeserialize: grpc.deserialize; 27 | } 28 | interface ITaskServiceService_IAddTask extends grpc.MethodDefinition { 29 | path: "/task.TaskService/AddTask"; 30 | requestStream: false; 31 | responseStream: false; 32 | requestSerialize: grpc.serialize; 33 | requestDeserialize: grpc.deserialize; 34 | responseSerialize: grpc.serialize; 35 | responseDeserialize: grpc.deserialize; 36 | } 37 | interface ITaskServiceService_IDeleteTask extends grpc.MethodDefinition { 38 | path: "/task.TaskService/DeleteTask"; 39 | requestStream: false; 40 | responseStream: false; 41 | requestSerialize: grpc.serialize; 42 | requestDeserialize: grpc.deserialize; 43 | responseSerialize: grpc.serialize; 44 | responseDeserialize: grpc.deserialize; 45 | } 46 | interface ITaskServiceService_IUpdateTask extends grpc.MethodDefinition { 47 | path: "/task.TaskService/UpdateTask"; 48 | requestStream: false; 49 | responseStream: false; 50 | requestSerialize: grpc.serialize; 51 | requestDeserialize: grpc.deserialize; 52 | responseSerialize: grpc.serialize; 53 | responseDeserialize: grpc.deserialize; 54 | } 55 | interface ITaskServiceService_IDeleteUnUsedConnections extends grpc.MethodDefinition { 56 | path: "/task.TaskService/DeleteUnUsedConnections"; 57 | requestStream: false; 58 | responseStream: false; 59 | requestSerialize: grpc.serialize; 60 | requestDeserialize: grpc.deserialize; 61 | responseSerialize: grpc.serialize; 62 | responseDeserialize: grpc.deserialize; 63 | } 64 | interface ITaskServiceService_IGetAllTasks extends grpc.MethodDefinition { 65 | path: "/task.TaskService/GetAllTasks"; 66 | requestStream: false; 67 | responseStream: true; 68 | requestSerialize: grpc.serialize; 69 | requestDeserialize: grpc.deserialize; 70 | responseSerialize: grpc.serialize; 71 | responseDeserialize: grpc.deserialize; 72 | } 73 | 74 | export const TaskServiceService: ITaskServiceService; 75 | 76 | export interface ITaskServiceServer extends grpc.UntypedServiceImplementation { 77 | getTask: grpc.handleUnaryCall; 78 | addTask: grpc.handleUnaryCall; 79 | deleteTask: grpc.handleUnaryCall; 80 | updateTask: grpc.handleUnaryCall; 81 | deleteUnUsedConnections: grpc.handleUnaryCall; 82 | getAllTasks: grpc.handleServerStreamingCall; 83 | } 84 | 85 | export interface ITaskServiceClient { 86 | getTask(request: protos_task_pb.TaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 87 | getTask(request: protos_task_pb.TaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 88 | getTask(request: protos_task_pb.TaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 89 | addTask(request: protos_task_pb.AddTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 90 | addTask(request: protos_task_pb.AddTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 91 | addTask(request: protos_task_pb.AddTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 92 | deleteTask(request: protos_task_pb.DeleteTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 93 | deleteTask(request: protos_task_pb.DeleteTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 94 | deleteTask(request: protos_task_pb.DeleteTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 95 | updateTask(request: protos_task_pb.UpdateTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 96 | updateTask(request: protos_task_pb.UpdateTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 97 | updateTask(request: protos_task_pb.UpdateTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 98 | deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 99 | deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 100 | deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 101 | getAllTasks(request: protos_task_pb.TasksRequest, options?: Partial): grpc.ClientReadableStream; 102 | getAllTasks(request: protos_task_pb.TasksRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 103 | } 104 | 105 | export class TaskServiceClient extends grpc.Client implements ITaskServiceClient { 106 | constructor(address: string, credentials: grpc.ChannelCredentials, options?: Partial); 107 | public getTask(request: protos_task_pb.TaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 108 | public getTask(request: protos_task_pb.TaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 109 | public getTask(request: protos_task_pb.TaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.TaskResponse) => void): grpc.ClientUnaryCall; 110 | public addTask(request: protos_task_pb.AddTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 111 | public addTask(request: protos_task_pb.AddTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 112 | public addTask(request: protos_task_pb.AddTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.AddTaskResponse) => void): grpc.ClientUnaryCall; 113 | public deleteTask(request: protos_task_pb.DeleteTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 114 | public deleteTask(request: protos_task_pb.DeleteTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 115 | public deleteTask(request: protos_task_pb.DeleteTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.DeleteTaskResponse) => void): grpc.ClientUnaryCall; 116 | public updateTask(request: protos_task_pb.UpdateTaskRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 117 | public updateTask(request: protos_task_pb.UpdateTaskRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 118 | public updateTask(request: protos_task_pb.UpdateTaskRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.UpdateTaskResponse) => void): grpc.ClientUnaryCall; 119 | public deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 120 | public deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 121 | public deleteUnUsedConnections(request: protos_task_pb.EmptyRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: protos_task_pb.EmptyResponse) => void): grpc.ClientUnaryCall; 122 | public getAllTasks(request: protos_task_pb.TasksRequest, options?: Partial): grpc.ClientReadableStream; 123 | public getAllTasks(request: protos_task_pb.TasksRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; 124 | } 125 | -------------------------------------------------------------------------------- /backend/protos/task_grpc_pb.js: -------------------------------------------------------------------------------- 1 | // GENERATED CODE -- DO NOT EDIT! 2 | 3 | 'use strict'; 4 | var grpc = require('@grpc/grpc-js'); 5 | var protos_task_pb = require('../protos/task_pb.js'); 6 | 7 | function serialize_task_AddTaskRequest(arg) { 8 | if (!(arg instanceof protos_task_pb.AddTaskRequest)) { 9 | throw new Error('Expected argument of type task.AddTaskRequest'); 10 | } 11 | return Buffer.from(arg.serializeBinary()); 12 | } 13 | 14 | function deserialize_task_AddTaskRequest(buffer_arg) { 15 | return protos_task_pb.AddTaskRequest.deserializeBinary(new Uint8Array(buffer_arg)); 16 | } 17 | 18 | function serialize_task_AddTaskResponse(arg) { 19 | if (!(arg instanceof protos_task_pb.AddTaskResponse)) { 20 | throw new Error('Expected argument of type task.AddTaskResponse'); 21 | } 22 | return Buffer.from(arg.serializeBinary()); 23 | } 24 | 25 | function deserialize_task_AddTaskResponse(buffer_arg) { 26 | return protos_task_pb.AddTaskResponse.deserializeBinary(new Uint8Array(buffer_arg)); 27 | } 28 | 29 | function serialize_task_DeleteTaskRequest(arg) { 30 | if (!(arg instanceof protos_task_pb.DeleteTaskRequest)) { 31 | throw new Error('Expected argument of type task.DeleteTaskRequest'); 32 | } 33 | return Buffer.from(arg.serializeBinary()); 34 | } 35 | 36 | function deserialize_task_DeleteTaskRequest(buffer_arg) { 37 | return protos_task_pb.DeleteTaskRequest.deserializeBinary(new Uint8Array(buffer_arg)); 38 | } 39 | 40 | function serialize_task_DeleteTaskResponse(arg) { 41 | if (!(arg instanceof protos_task_pb.DeleteTaskResponse)) { 42 | throw new Error('Expected argument of type task.DeleteTaskResponse'); 43 | } 44 | return Buffer.from(arg.serializeBinary()); 45 | } 46 | 47 | function deserialize_task_DeleteTaskResponse(buffer_arg) { 48 | return protos_task_pb.DeleteTaskResponse.deserializeBinary(new Uint8Array(buffer_arg)); 49 | } 50 | 51 | function serialize_task_EmptyRequest(arg) { 52 | if (!(arg instanceof protos_task_pb.EmptyRequest)) { 53 | throw new Error('Expected argument of type task.EmptyRequest'); 54 | } 55 | return Buffer.from(arg.serializeBinary()); 56 | } 57 | 58 | function deserialize_task_EmptyRequest(buffer_arg) { 59 | return protos_task_pb.EmptyRequest.deserializeBinary(new Uint8Array(buffer_arg)); 60 | } 61 | 62 | function serialize_task_EmptyResponse(arg) { 63 | if (!(arg instanceof protos_task_pb.EmptyResponse)) { 64 | throw new Error('Expected argument of type task.EmptyResponse'); 65 | } 66 | return Buffer.from(arg.serializeBinary()); 67 | } 68 | 69 | function deserialize_task_EmptyResponse(buffer_arg) { 70 | return protos_task_pb.EmptyResponse.deserializeBinary(new Uint8Array(buffer_arg)); 71 | } 72 | 73 | function serialize_task_TaskRequest(arg) { 74 | if (!(arg instanceof protos_task_pb.TaskRequest)) { 75 | throw new Error('Expected argument of type task.TaskRequest'); 76 | } 77 | return Buffer.from(arg.serializeBinary()); 78 | } 79 | 80 | function deserialize_task_TaskRequest(buffer_arg) { 81 | return protos_task_pb.TaskRequest.deserializeBinary(new Uint8Array(buffer_arg)); 82 | } 83 | 84 | function serialize_task_TaskResponse(arg) { 85 | if (!(arg instanceof protos_task_pb.TaskResponse)) { 86 | throw new Error('Expected argument of type task.TaskResponse'); 87 | } 88 | return Buffer.from(arg.serializeBinary()); 89 | } 90 | 91 | function deserialize_task_TaskResponse(buffer_arg) { 92 | return protos_task_pb.TaskResponse.deserializeBinary(new Uint8Array(buffer_arg)); 93 | } 94 | 95 | function serialize_task_TasksRequest(arg) { 96 | if (!(arg instanceof protos_task_pb.TasksRequest)) { 97 | throw new Error('Expected argument of type task.TasksRequest'); 98 | } 99 | return Buffer.from(arg.serializeBinary()); 100 | } 101 | 102 | function deserialize_task_TasksRequest(buffer_arg) { 103 | return protos_task_pb.TasksRequest.deserializeBinary(new Uint8Array(buffer_arg)); 104 | } 105 | 106 | function serialize_task_TasksResponse(arg) { 107 | if (!(arg instanceof protos_task_pb.TasksResponse)) { 108 | throw new Error('Expected argument of type task.TasksResponse'); 109 | } 110 | return Buffer.from(arg.serializeBinary()); 111 | } 112 | 113 | function deserialize_task_TasksResponse(buffer_arg) { 114 | return protos_task_pb.TasksResponse.deserializeBinary(new Uint8Array(buffer_arg)); 115 | } 116 | 117 | function serialize_task_UpdateTaskRequest(arg) { 118 | if (!(arg instanceof protos_task_pb.UpdateTaskRequest)) { 119 | throw new Error('Expected argument of type task.UpdateTaskRequest'); 120 | } 121 | return Buffer.from(arg.serializeBinary()); 122 | } 123 | 124 | function deserialize_task_UpdateTaskRequest(buffer_arg) { 125 | return protos_task_pb.UpdateTaskRequest.deserializeBinary(new Uint8Array(buffer_arg)); 126 | } 127 | 128 | function serialize_task_UpdateTaskResponse(arg) { 129 | if (!(arg instanceof protos_task_pb.UpdateTaskResponse)) { 130 | throw new Error('Expected argument of type task.UpdateTaskResponse'); 131 | } 132 | return Buffer.from(arg.serializeBinary()); 133 | } 134 | 135 | function deserialize_task_UpdateTaskResponse(buffer_arg) { 136 | return protos_task_pb.UpdateTaskResponse.deserializeBinary(new Uint8Array(buffer_arg)); 137 | } 138 | 139 | 140 | var TaskServiceService = exports.TaskServiceService = { 141 | getTask: { 142 | path: '/task.TaskService/GetTask', 143 | requestStream: false, 144 | responseStream: false, 145 | requestType: protos_task_pb.TaskRequest, 146 | responseType: protos_task_pb.TaskResponse, 147 | requestSerialize: serialize_task_TaskRequest, 148 | requestDeserialize: deserialize_task_TaskRequest, 149 | responseSerialize: serialize_task_TaskResponse, 150 | responseDeserialize: deserialize_task_TaskResponse, 151 | }, 152 | addTask: { 153 | path: '/task.TaskService/AddTask', 154 | requestStream: false, 155 | responseStream: false, 156 | requestType: protos_task_pb.AddTaskRequest, 157 | responseType: protos_task_pb.AddTaskResponse, 158 | requestSerialize: serialize_task_AddTaskRequest, 159 | requestDeserialize: deserialize_task_AddTaskRequest, 160 | responseSerialize: serialize_task_AddTaskResponse, 161 | responseDeserialize: deserialize_task_AddTaskResponse, 162 | }, 163 | deleteTask: { 164 | path: '/task.TaskService/DeleteTask', 165 | requestStream: false, 166 | responseStream: false, 167 | requestType: protos_task_pb.DeleteTaskRequest, 168 | responseType: protos_task_pb.DeleteTaskResponse, 169 | requestSerialize: serialize_task_DeleteTaskRequest, 170 | requestDeserialize: deserialize_task_DeleteTaskRequest, 171 | responseSerialize: serialize_task_DeleteTaskResponse, 172 | responseDeserialize: deserialize_task_DeleteTaskResponse, 173 | }, 174 | updateTask: { 175 | path: '/task.TaskService/UpdateTask', 176 | requestStream: false, 177 | responseStream: false, 178 | requestType: protos_task_pb.UpdateTaskRequest, 179 | responseType: protos_task_pb.UpdateTaskResponse, 180 | requestSerialize: serialize_task_UpdateTaskRequest, 181 | requestDeserialize: deserialize_task_UpdateTaskRequest, 182 | responseSerialize: serialize_task_UpdateTaskResponse, 183 | responseDeserialize: deserialize_task_UpdateTaskResponse, 184 | }, 185 | deleteUnUsedConnections: { 186 | path: '/task.TaskService/DeleteUnUsedConnections', 187 | requestStream: false, 188 | responseStream: false, 189 | requestType: protos_task_pb.EmptyRequest, 190 | responseType: protos_task_pb.EmptyResponse, 191 | requestSerialize: serialize_task_EmptyRequest, 192 | requestDeserialize: deserialize_task_EmptyRequest, 193 | responseSerialize: serialize_task_EmptyResponse, 194 | responseDeserialize: deserialize_task_EmptyResponse, 195 | }, 196 | getAllTasks: { 197 | path: '/task.TaskService/GetAllTasks', 198 | requestStream: false, 199 | responseStream: true, 200 | requestType: protos_task_pb.TasksRequest, 201 | responseType: protos_task_pb.TasksResponse, 202 | requestSerialize: serialize_task_TasksRequest, 203 | requestDeserialize: deserialize_task_TasksRequest, 204 | responseSerialize: serialize_task_TasksResponse, 205 | responseDeserialize: deserialize_task_TasksResponse, 206 | }, 207 | }; 208 | 209 | exports.TaskServiceClient = grpc.makeGenericClientConstructor(TaskServiceService); 210 | -------------------------------------------------------------------------------- /backend/protos/task_pb.d.ts: -------------------------------------------------------------------------------- 1 | // package: task 2 | // file: protos/task.proto 3 | 4 | /* tslint:disable */ 5 | /* eslint-disable */ 6 | 7 | import * as jspb from "google-protobuf"; 8 | 9 | export class Task extends jspb.Message { 10 | getId(): number; 11 | setId(value: number): Task; 12 | getTitle(): string; 13 | setTitle(value: string): Task; 14 | getBody(): string; 15 | setBody(value: string): Task; 16 | getStatus(): string; 17 | setStatus(value: string): Task; 18 | 19 | serializeBinary(): Uint8Array; 20 | toObject(includeInstance?: boolean): Task.AsObject; 21 | static toObject(includeInstance: boolean, msg: Task): Task.AsObject; 22 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 23 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 24 | static serializeBinaryToWriter(message: Task, writer: jspb.BinaryWriter): void; 25 | static deserializeBinary(bytes: Uint8Array): Task; 26 | static deserializeBinaryFromReader(message: Task, reader: jspb.BinaryReader): Task; 27 | } 28 | 29 | export namespace Task { 30 | export type AsObject = { 31 | id: number, 32 | title: string, 33 | body: string, 34 | status: string, 35 | } 36 | } 37 | 38 | export class TaskRequest extends jspb.Message { 39 | getId(): number; 40 | setId(value: number): TaskRequest; 41 | 42 | serializeBinary(): Uint8Array; 43 | toObject(includeInstance?: boolean): TaskRequest.AsObject; 44 | static toObject(includeInstance: boolean, msg: TaskRequest): TaskRequest.AsObject; 45 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 46 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 47 | static serializeBinaryToWriter(message: TaskRequest, writer: jspb.BinaryWriter): void; 48 | static deserializeBinary(bytes: Uint8Array): TaskRequest; 49 | static deserializeBinaryFromReader(message: TaskRequest, reader: jspb.BinaryReader): TaskRequest; 50 | } 51 | 52 | export namespace TaskRequest { 53 | export type AsObject = { 54 | id: number, 55 | } 56 | } 57 | 58 | export class TaskResponse extends jspb.Message { 59 | 60 | hasTask(): boolean; 61 | clearTask(): void; 62 | getTask(): Task | undefined; 63 | setTask(value?: Task): TaskResponse; 64 | 65 | serializeBinary(): Uint8Array; 66 | toObject(includeInstance?: boolean): TaskResponse.AsObject; 67 | static toObject(includeInstance: boolean, msg: TaskResponse): TaskResponse.AsObject; 68 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 69 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 70 | static serializeBinaryToWriter(message: TaskResponse, writer: jspb.BinaryWriter): void; 71 | static deserializeBinary(bytes: Uint8Array): TaskResponse; 72 | static deserializeBinaryFromReader(message: TaskResponse, reader: jspb.BinaryReader): TaskResponse; 73 | } 74 | 75 | export namespace TaskResponse { 76 | export type AsObject = { 77 | task?: Task.AsObject, 78 | } 79 | } 80 | 81 | export class EmptyRequest extends jspb.Message { 82 | 83 | serializeBinary(): Uint8Array; 84 | toObject(includeInstance?: boolean): EmptyRequest.AsObject; 85 | static toObject(includeInstance: boolean, msg: EmptyRequest): EmptyRequest.AsObject; 86 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 87 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 88 | static serializeBinaryToWriter(message: EmptyRequest, writer: jspb.BinaryWriter): void; 89 | static deserializeBinary(bytes: Uint8Array): EmptyRequest; 90 | static deserializeBinaryFromReader(message: EmptyRequest, reader: jspb.BinaryReader): EmptyRequest; 91 | } 92 | 93 | export namespace EmptyRequest { 94 | export type AsObject = { 95 | } 96 | } 97 | 98 | export class EmptyResponse extends jspb.Message { 99 | getMessage(): string; 100 | setMessage(value: string): EmptyResponse; 101 | 102 | serializeBinary(): Uint8Array; 103 | toObject(includeInstance?: boolean): EmptyResponse.AsObject; 104 | static toObject(includeInstance: boolean, msg: EmptyResponse): EmptyResponse.AsObject; 105 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 106 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 107 | static serializeBinaryToWriter(message: EmptyResponse, writer: jspb.BinaryWriter): void; 108 | static deserializeBinary(bytes: Uint8Array): EmptyResponse; 109 | static deserializeBinaryFromReader(message: EmptyResponse, reader: jspb.BinaryReader): EmptyResponse; 110 | } 111 | 112 | export namespace EmptyResponse { 113 | export type AsObject = { 114 | message: string, 115 | } 116 | } 117 | 118 | export class TasksRequest extends jspb.Message { 119 | 120 | serializeBinary(): Uint8Array; 121 | toObject(includeInstance?: boolean): TasksRequest.AsObject; 122 | static toObject(includeInstance: boolean, msg: TasksRequest): TasksRequest.AsObject; 123 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 124 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 125 | static serializeBinaryToWriter(message: TasksRequest, writer: jspb.BinaryWriter): void; 126 | static deserializeBinary(bytes: Uint8Array): TasksRequest; 127 | static deserializeBinaryFromReader(message: TasksRequest, reader: jspb.BinaryReader): TasksRequest; 128 | } 129 | 130 | export namespace TasksRequest { 131 | export type AsObject = { 132 | } 133 | } 134 | 135 | export class TasksResponse extends jspb.Message { 136 | clearTasksList(): void; 137 | getTasksList(): Array; 138 | setTasksList(value: Array): TasksResponse; 139 | addTasks(value?: Task, index?: number): Task; 140 | 141 | serializeBinary(): Uint8Array; 142 | toObject(includeInstance?: boolean): TasksResponse.AsObject; 143 | static toObject(includeInstance: boolean, msg: TasksResponse): TasksResponse.AsObject; 144 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 145 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 146 | static serializeBinaryToWriter(message: TasksResponse, writer: jspb.BinaryWriter): void; 147 | static deserializeBinary(bytes: Uint8Array): TasksResponse; 148 | static deserializeBinaryFromReader(message: TasksResponse, reader: jspb.BinaryReader): TasksResponse; 149 | } 150 | 151 | export namespace TasksResponse { 152 | export type AsObject = { 153 | tasksList: Array, 154 | } 155 | } 156 | 157 | export class AddTaskRequest extends jspb.Message { 158 | getTitle(): string; 159 | setTitle(value: string): AddTaskRequest; 160 | getBody(): string; 161 | setBody(value: string): AddTaskRequest; 162 | getStatus(): string; 163 | setStatus(value: string): AddTaskRequest; 164 | 165 | serializeBinary(): Uint8Array; 166 | toObject(includeInstance?: boolean): AddTaskRequest.AsObject; 167 | static toObject(includeInstance: boolean, msg: AddTaskRequest): AddTaskRequest.AsObject; 168 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 169 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 170 | static serializeBinaryToWriter(message: AddTaskRequest, writer: jspb.BinaryWriter): void; 171 | static deserializeBinary(bytes: Uint8Array): AddTaskRequest; 172 | static deserializeBinaryFromReader(message: AddTaskRequest, reader: jspb.BinaryReader): AddTaskRequest; 173 | } 174 | 175 | export namespace AddTaskRequest { 176 | export type AsObject = { 177 | title: string, 178 | body: string, 179 | status: string, 180 | } 181 | } 182 | 183 | export class AddTaskResponse extends jspb.Message { 184 | 185 | hasTask(): boolean; 186 | clearTask(): void; 187 | getTask(): Task | undefined; 188 | setTask(value?: Task): AddTaskResponse; 189 | 190 | serializeBinary(): Uint8Array; 191 | toObject(includeInstance?: boolean): AddTaskResponse.AsObject; 192 | static toObject(includeInstance: boolean, msg: AddTaskResponse): AddTaskResponse.AsObject; 193 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 194 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 195 | static serializeBinaryToWriter(message: AddTaskResponse, writer: jspb.BinaryWriter): void; 196 | static deserializeBinary(bytes: Uint8Array): AddTaskResponse; 197 | static deserializeBinaryFromReader(message: AddTaskResponse, reader: jspb.BinaryReader): AddTaskResponse; 198 | } 199 | 200 | export namespace AddTaskResponse { 201 | export type AsObject = { 202 | task?: Task.AsObject, 203 | } 204 | } 205 | 206 | export class DeleteTaskRequest extends jspb.Message { 207 | getId(): number; 208 | setId(value: number): DeleteTaskRequest; 209 | 210 | serializeBinary(): Uint8Array; 211 | toObject(includeInstance?: boolean): DeleteTaskRequest.AsObject; 212 | static toObject(includeInstance: boolean, msg: DeleteTaskRequest): DeleteTaskRequest.AsObject; 213 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 214 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 215 | static serializeBinaryToWriter(message: DeleteTaskRequest, writer: jspb.BinaryWriter): void; 216 | static deserializeBinary(bytes: Uint8Array): DeleteTaskRequest; 217 | static deserializeBinaryFromReader(message: DeleteTaskRequest, reader: jspb.BinaryReader): DeleteTaskRequest; 218 | } 219 | 220 | export namespace DeleteTaskRequest { 221 | export type AsObject = { 222 | id: number, 223 | } 224 | } 225 | 226 | export class DeleteTaskResponse extends jspb.Message { 227 | getMessage(): string; 228 | setMessage(value: string): DeleteTaskResponse; 229 | 230 | serializeBinary(): Uint8Array; 231 | toObject(includeInstance?: boolean): DeleteTaskResponse.AsObject; 232 | static toObject(includeInstance: boolean, msg: DeleteTaskResponse): DeleteTaskResponse.AsObject; 233 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 234 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 235 | static serializeBinaryToWriter(message: DeleteTaskResponse, writer: jspb.BinaryWriter): void; 236 | static deserializeBinary(bytes: Uint8Array): DeleteTaskResponse; 237 | static deserializeBinaryFromReader(message: DeleteTaskResponse, reader: jspb.BinaryReader): DeleteTaskResponse; 238 | } 239 | 240 | export namespace DeleteTaskResponse { 241 | export type AsObject = { 242 | message: string, 243 | } 244 | } 245 | 246 | export class UpdateTaskRequest extends jspb.Message { 247 | 248 | hasTask(): boolean; 249 | clearTask(): void; 250 | getTask(): Task | undefined; 251 | setTask(value?: Task): UpdateTaskRequest; 252 | 253 | serializeBinary(): Uint8Array; 254 | toObject(includeInstance?: boolean): UpdateTaskRequest.AsObject; 255 | static toObject(includeInstance: boolean, msg: UpdateTaskRequest): UpdateTaskRequest.AsObject; 256 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 257 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 258 | static serializeBinaryToWriter(message: UpdateTaskRequest, writer: jspb.BinaryWriter): void; 259 | static deserializeBinary(bytes: Uint8Array): UpdateTaskRequest; 260 | static deserializeBinaryFromReader(message: UpdateTaskRequest, reader: jspb.BinaryReader): UpdateTaskRequest; 261 | } 262 | 263 | export namespace UpdateTaskRequest { 264 | export type AsObject = { 265 | task?: Task.AsObject, 266 | } 267 | } 268 | 269 | export class UpdateTaskResponse extends jspb.Message { 270 | 271 | hasTask(): boolean; 272 | clearTask(): void; 273 | getTask(): Task | undefined; 274 | setTask(value?: Task): UpdateTaskResponse; 275 | 276 | serializeBinary(): Uint8Array; 277 | toObject(includeInstance?: boolean): UpdateTaskResponse.AsObject; 278 | static toObject(includeInstance: boolean, msg: UpdateTaskResponse): UpdateTaskResponse.AsObject; 279 | static extensions: {[key: number]: jspb.ExtensionFieldInfo}; 280 | static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; 281 | static serializeBinaryToWriter(message: UpdateTaskResponse, writer: jspb.BinaryWriter): void; 282 | static deserializeBinary(bytes: Uint8Array): UpdateTaskResponse; 283 | static deserializeBinaryFromReader(message: UpdateTaskResponse, reader: jspb.BinaryReader): UpdateTaskResponse; 284 | } 285 | 286 | export namespace UpdateTaskResponse { 287 | export type AsObject = { 288 | task?: Task.AsObject, 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /backend/server.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | import { Server, ServerCredentials } from "@grpc/grpc-js"; 3 | import { PrismaClient } from "@prisma/client"; 4 | import { TaskServiceService } from "./protos/task_grpc_pb"; 5 | import { 6 | addTask, 7 | deleteTask, 8 | deleteUnUsedConnections, 9 | getAllTasks, 10 | getTask, 11 | updateTask, 12 | } from "./controllers/task"; 13 | 14 | dotenv.config(); 15 | 16 | export const prisma = new PrismaClient(); 17 | const port = 9090; 18 | 19 | async function main() { 20 | const server = new Server(); 21 | server.addService(TaskServiceService, { 22 | addTask: addTask, 23 | getTask: getTask, 24 | updateTask: updateTask, 25 | deleteTask: deleteTask, 26 | getAllTasks: getAllTasks, 27 | deleteUnUsedConnections: deleteUnUsedConnections, 28 | }); 29 | server.bindAsync( 30 | "0.0.0.0:" + 9090, 31 | ServerCredentials.createInsecure(), 32 | () => { 33 | console.log("server running on port 127.0.0.1:" + 9090); 34 | server.start(); 35 | } 36 | ); 37 | } 38 | 39 | main() 40 | .then(async () => { 41 | await prisma.$disconnect(); 42 | }) 43 | 44 | .catch(async (e) => { 45 | console.error(e); 46 | 47 | await prisma.$disconnect(); 48 | 49 | process.exit(1); 50 | }); 51 | -------------------------------------------------------------------------------- /backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | "lib": ["esnext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 52 | "outDir": "./", /* Specify an output folder for all emitted files. */ 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 74 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 77 | 78 | /* Type Checking */ 79 | "strict": true, /* Enable all strict type-checking options. */ 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 81 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /envoy.yaml: -------------------------------------------------------------------------------- 1 | admin: 2 | access_log_path: /tmp/admin_access.log 3 | address: 4 | socket_address: { address: 0.0.0.0, port_value: 9901 } 5 | static_resources: 6 | listeners: 7 | - name: listener_0 8 | address: 9 | socket_address: { address: 0.0.0.0, port_value: 8080 } 10 | filter_chains: 11 | - filters: 12 | - name: envoy.filters.network.http_connection_manager 13 | typed_config: 14 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 15 | codec_type: auto 16 | stat_prefix: ingress_http 17 | route_config: 18 | name: local_route 19 | virtual_hosts: 20 | - name: local_service 21 | domains: ["*"] 22 | routes: 23 | - match: { prefix: "/" } 24 | route: 25 | cluster: backend_service 26 | timeout: 0s 27 | max_stream_duration: 28 | grpc_timeout_header_max: 0s 29 | cors: 30 | allow_origin_string_match: 31 | - prefix: "*" 32 | allow_methods: GET, PUT, DELETE, POST, OPTIONS 33 | allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout 34 | max_age: "1728000" 35 | expose_headers: custom-header-1,grpc-status,grpc-message 36 | http_filters: 37 | - name: envoy.filters.http.grpc_web 38 | typed_config: 39 | "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb 40 | - name: envoy.filters.http.cors 41 | typed_config: 42 | "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors 43 | - name: envoy.filters.http.router 44 | typed_config: 45 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router 46 | clusters: 47 | - name: backend_service 48 | connect_timeout: 0.25s 49 | type: logical_dns 50 | http2_protocol_options: {} 51 | lb_policy: round_robin 52 | load_assignment: 53 | cluster_name: cluster_0 54 | endpoints: 55 | - lb_endpoints: 56 | - endpoint: 57 | address: 58 | socket_address: 59 | address: host.docker.internal 60 | port_value: 9090 -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /frontend/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | swcMinify: true, 5 | }; 6 | 7 | module.exports = nextConfig; 8 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@types/node": "18.11.9", 13 | "@types/react": "18.0.25", 14 | "@types/react-dom": "18.0.9", 15 | "grpc-web": "^1.4.2", 16 | "next": "13.0.4", 17 | "react": "18.2.0", 18 | "react-dom": "18.2.0", 19 | "typescript": "4.9.3" 20 | }, 21 | "devDependencies": { 22 | "autoprefixer": "^10.4.13", 23 | "cookies-next": "^2.1.1", 24 | "google-protobuf": "^3.21.2", 25 | "postcss": "^8.4.19", 26 | "tailwindcss": "^3.2.4" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css' 2 | import type { AppProps } from 'next/app' 3 | 4 | export default function App({ Component, pageProps }: AppProps) { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /frontend/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import Link from "next/link"; 3 | 4 | export default function Home() { 5 | return ( 6 |
7 | 8 | Task Management 9 | 10 | 11 | 12 | 13 |
14 | 15 | View All Tasks 16 | 17 | 21 | Add A Task 22 | 23 |
24 |
25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /frontend/pages/task/add.tsx: -------------------------------------------------------------------------------- 1 | import { FormEvent, useState } from "react"; 2 | import { AddTaskRequest, AddTaskResponse } from "../../protos/task_pb"; 3 | import { grpcTaskClient } from "../../util/grpc-connection"; 4 | import * as grpc_web from "grpc-web"; 5 | import { useRouter } from "next/router"; 6 | 7 | export default function Add() { 8 | const [title, setTitle] = useState(""); 9 | const [body, setBody] = useState(""); 10 | const [status, setStatus] = useState(""); 11 | const router = useRouter(); 12 | const addTask = () => { 13 | const task = new AddTaskRequest(); 14 | task.setTitle(title.trim()); 15 | task.setBody(body.trim()); 16 | task.setStatus(status.trim()); 17 | grpcTaskClient.addTask( 18 | task, 19 | undefined, 20 | (err: grpc_web.RpcError, response: AddTaskResponse) => { 21 | if (!err) { 22 | router.push("/tasks"); 23 | } else { 24 | console.log(err); 25 | } 26 | } 27 | ); 28 | }; 29 | 30 | return ( 31 |
32 |
33 |
34 | 40 | ) => 47 | setTitle(e.currentTarget.value) 48 | } 49 | /> 50 |
51 |
52 | 58 | ) => 65 | setBody(e.currentTarget.value) 66 | } 67 | /> 68 |
69 |
70 | 76 | ) => 83 | setStatus(e.currentTarget.value) 84 | } 85 | /> 86 |
87 |
88 |
89 | 96 |
97 |
98 | ); 99 | } 100 | -------------------------------------------------------------------------------- /frontend/pages/task/update/[id].tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import { FormEvent, useEffect, useState } from "react"; 3 | import { grpcTaskClient } from "../../../util/grpc-connection"; 4 | import { 5 | Task, 6 | TaskRequest, 7 | TaskResponse, 8 | UpdateTaskRequest, 9 | UpdateTaskResponse, 10 | } from "../../../protos/task_pb"; 11 | import * as grpc_web from "grpc-web"; 12 | 13 | export default function Id() { 14 | const router = useRouter(); 15 | const { id } = router.query; 16 | const [title, setTitle] = useState(""); 17 | const [body, setBody] = useState(""); 18 | const [status, setStatus] = useState(""); 19 | useEffect(() => { 20 | if (id) { 21 | const task = new TaskRequest(); 22 | task.setId(parseInt(id.toString().trim())); 23 | grpcTaskClient.getTask( 24 | task, 25 | undefined, 26 | (err: grpc_web.RpcError, response: TaskResponse) => { 27 | if (!err) { 28 | // @ts-ignore 29 | setTitle(response.getTask()?.getTitle()); 30 | // @ts-ignore 31 | setBody(response.getTask()?.getBody()); 32 | // @ts-ignore 33 | setStatus(response.getTask()?.getStatus()); 34 | } else { 35 | console.log(err); 36 | } 37 | } 38 | ); 39 | } 40 | }, [id]); 41 | 42 | const updateTask = (event: FormEvent) => { 43 | event.preventDefault(); 44 | const taskRequest = new UpdateTaskRequest(); 45 | const task = new Task(); 46 | // @ts-ignore 47 | task.setId(parseInt(id.toString().trim())); 48 | task.setTitle(title.trim()); 49 | task.setBody(body.trim()); 50 | task.setStatus(status.trim()); 51 | taskRequest.setTask(task); 52 | grpcTaskClient.updateTask( 53 | taskRequest, 54 | undefined, 55 | (err: grpc_web.RpcError, response: UpdateTaskResponse) => { 56 | if (!err) { 57 | router.push("/tasks"); 58 | } else { 59 | console.log(err); 60 | } 61 | } 62 | ); 63 | }; 64 | 65 | return ( 66 |
67 |
68 |
69 | 75 | ) => 82 | setTitle(e.currentTarget.value) 83 | } 84 | required 85 | /> 86 |
87 |
88 | 94 | ) => 101 | setBody(e.currentTarget.value) 102 | } 103 | required 104 | /> 105 |
106 |
107 | 113 | ) => 120 | setStatus(e.currentTarget.value) 121 | } 122 | required 123 | /> 124 |
125 |
126 |
127 | 134 |
135 |
136 | ); 137 | } 138 | -------------------------------------------------------------------------------- /frontend/pages/tasks.tsx: -------------------------------------------------------------------------------- 1 | import { FormEvent, useState } from "react"; 2 | import { 3 | DeleteTaskRequest, 4 | DeleteTaskResponse, 5 | Task, 6 | TasksRequest, 7 | TasksResponse, 8 | } from "../protos/task_pb"; 9 | import Link from "next/link"; 10 | import { useOnceCall } from "../util/useOnceCall"; 11 | import { grpcTaskClient } from "../util/grpc-connection"; 12 | import * as grpc_web from "grpc-web"; 13 | 14 | export default function Home() { 15 | const [tasks, setTasks] = useState([]); 16 | useOnceCall(() => { 17 | const emptyRequest = new TasksRequest(); 18 | const req = grpcTaskClient.getAllTasks(emptyRequest, undefined); 19 | req.on("data", function (callback: TasksResponse) { 20 | setTasks((prev) => [...callback.getTasksList(), ...prev]); 21 | }); 22 | }); 23 | 24 | const deleteTask = (id: number, event: FormEvent) => { 25 | event.preventDefault(); 26 | const task = new DeleteTaskRequest(); 27 | task.setId(id); 28 | grpcTaskClient.deleteTask( 29 | task, 30 | undefined, 31 | (err: grpc_web.RpcError, response: DeleteTaskResponse) => { 32 | if (!err) { 33 | setTasks((prevState) => [ 34 | ...prevState.filter((item) => item.getId() !== id), 35 | ]); 36 | console.log(response.toObject().message); 37 | } else { 38 | console.log(err); 39 | } 40 | } 41 | ); 42 | }; 43 | 44 | return ( 45 |
46 |
47 |
48 | 49 | Go to home page 50 | 51 |
52 |
53 |

54 | All Tasks 55 |

56 |
57 |
58 | {tasks.length > 0 ? ( 59 | tasks.map((item: Task, index: number) => ( 60 |
64 | 85 | 86 | 90 | 98 | 103 | 104 | 105 |

106 | {index + 1} 107 |

108 |
109 |
110 |

{item.getTitle()}

111 |
112 |
113 |

{item.getBody()}

114 |
115 |
116 |
117 | )) 118 | ) : ( 119 |
120 |

121 | No tasks available 122 |

123 |
124 | )} 125 |
126 |
127 |
128 | ); 129 | } 130 | -------------------------------------------------------------------------------- /frontend/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@types/node': 18.11.9 5 | '@types/react': 18.0.25 6 | '@types/react-dom': 18.0.9 7 | autoprefixer: ^10.4.13 8 | cookies-next: ^2.1.1 9 | google-protobuf: ^3.21.2 10 | grpc-web: ^1.4.2 11 | next: 13.0.4 12 | postcss: ^8.4.19 13 | react: 18.2.0 14 | react-dom: 18.2.0 15 | tailwindcss: ^3.2.4 16 | typescript: 4.9.3 17 | 18 | dependencies: 19 | '@types/node': 18.11.9 20 | '@types/react': 18.0.25 21 | '@types/react-dom': 18.0.9 22 | grpc-web: 1.4.2 23 | next: 13.0.4_biqbaboplfbrettd7655fr4n2y 24 | react: 18.2.0 25 | react-dom: 18.2.0_react@18.2.0 26 | typescript: 4.9.3 27 | 28 | devDependencies: 29 | autoprefixer: 10.4.13_postcss@8.4.19 30 | cookies-next: 2.1.1 31 | google-protobuf: 3.21.2 32 | postcss: 8.4.19 33 | tailwindcss: 3.2.4_postcss@8.4.19 34 | 35 | packages: 36 | 37 | /@next/env/13.0.4: 38 | resolution: {integrity: sha512-N5Z3bdxBzoxrC5bwykDFITzdWuwDteOdZ+7nxixY+I1XpRX8/iQYbw2wuXMdqdfBGm2NNUpAqg8YF2e4oAC2UQ==} 39 | dev: false 40 | 41 | /@next/swc-android-arm-eabi/13.0.4: 42 | resolution: {integrity: sha512-SD9H+/zuV3L0oHIhsDdFkDqFtg6pIHtqRUPlsrNdOsmWXgMlSzxBmwt2ta4kyrazS62BQu7XRUG++ZyODS7AWg==} 43 | engines: {node: '>= 10'} 44 | cpu: [arm] 45 | os: [android] 46 | requiresBuild: true 47 | dev: false 48 | optional: true 49 | 50 | /@next/swc-android-arm64/13.0.4: 51 | resolution: {integrity: sha512-F8W5WcBbdn/zBoy32/mQiefs9DNsT12CTSSVCsO8GvQR7GjJU+uduQ4drKcSDoDLuAFULc2jDN06Circq4vuQg==} 52 | engines: {node: '>= 10'} 53 | cpu: [arm64] 54 | os: [android] 55 | requiresBuild: true 56 | dev: false 57 | optional: true 58 | 59 | /@next/swc-darwin-arm64/13.0.4: 60 | resolution: {integrity: sha512-/lajev+9GSie+rRTl5z8skW9RJwZ+TwMKLzzM24TbDk8lUjqPTyJZ/cU0NDj8J7VQAZ6EehACSh9rcJeBRtLuA==} 61 | engines: {node: '>= 10'} 62 | cpu: [arm64] 63 | os: [darwin] 64 | requiresBuild: true 65 | dev: false 66 | optional: true 67 | 68 | /@next/swc-darwin-x64/13.0.4: 69 | resolution: {integrity: sha512-HK4b2rFiju8d40GTL/jH9U6OQ7BYA2MeEHs7Dm7Rp7kwQtLzP3z6osdQS8er20tIFHDE4b+oVBy03ZUQkHf0Pg==} 70 | engines: {node: '>= 10'} 71 | cpu: [x64] 72 | os: [darwin] 73 | requiresBuild: true 74 | dev: false 75 | optional: true 76 | 77 | /@next/swc-freebsd-x64/13.0.4: 78 | resolution: {integrity: sha512-xBvIGLaGzZtgJfRRJ2DBN82DQCJ/O7jkXyBp8X/vHefPWyVXVqF6C68Rv8ADp11thPpf8WpjkvDDLb9AuWHQUA==} 79 | engines: {node: '>= 10'} 80 | cpu: [x64] 81 | os: [freebsd] 82 | requiresBuild: true 83 | dev: false 84 | optional: true 85 | 86 | /@next/swc-linux-arm-gnueabihf/13.0.4: 87 | resolution: {integrity: sha512-s13pxNp9deKmmxEGTp1MoL1e4nf4wbEymEaHgFxUlhoR1OD9tK8oTNrQphQePJgVjzcWmRGH/dX7O9mVkHbU/g==} 88 | engines: {node: '>= 10'} 89 | cpu: [arm] 90 | os: [linux] 91 | requiresBuild: true 92 | dev: false 93 | optional: true 94 | 95 | /@next/swc-linux-arm64-gnu/13.0.4: 96 | resolution: {integrity: sha512-Lklo65usNzoYwjX51CpDKOepWVZBdwO49/Jz3djxiYUr2lRtpDVnlfwCvzN+47j3BMVMWtC2ndIi8Q4s3J0v4g==} 97 | engines: {node: '>= 10'} 98 | cpu: [arm64] 99 | os: [linux] 100 | requiresBuild: true 101 | dev: false 102 | optional: true 103 | 104 | /@next/swc-linux-arm64-musl/13.0.4: 105 | resolution: {integrity: sha512-+3BXtXBwjVhd5lahDe5nKZ7EwD6hE/oLFQkITCvgxymU5qYHGlLFyF52/lyw8qhyxoCr7mMVsUFhlCzVwCfNjg==} 106 | engines: {node: '>= 10'} 107 | cpu: [arm64] 108 | os: [linux] 109 | requiresBuild: true 110 | dev: false 111 | optional: true 112 | 113 | /@next/swc-linux-x64-gnu/13.0.4: 114 | resolution: {integrity: sha512-QB8qoZrvHhZsz62nUrTKlp5IiZ8I7KZsaa6437H/W/NOZHLGJjCxROnhUjLvKVe/T5P86pjya2SUOUqWAjz4Pg==} 115 | engines: {node: '>= 10'} 116 | cpu: [x64] 117 | os: [linux] 118 | requiresBuild: true 119 | dev: false 120 | optional: true 121 | 122 | /@next/swc-linux-x64-musl/13.0.4: 123 | resolution: {integrity: sha512-WaahF6DYUQRg1QqIMcuOu2ZsFhS3aC5iWeQyeptMHklP9wb4FfTNmBArKHknX/GXD8P9gI38WTAHJ25cc0zVwg==} 124 | engines: {node: '>= 10'} 125 | cpu: [x64] 126 | os: [linux] 127 | requiresBuild: true 128 | dev: false 129 | optional: true 130 | 131 | /@next/swc-win32-arm64-msvc/13.0.4: 132 | resolution: {integrity: sha512-FD+k1j2jeY0aKcqcpzFKfTsv55PPmIZ5GKDyPjjV5AO6XvQ4nALwWl4JwizjH2426TfLXObb+C3MH0bl9Ok1Kw==} 133 | engines: {node: '>= 10'} 134 | cpu: [arm64] 135 | os: [win32] 136 | requiresBuild: true 137 | dev: false 138 | optional: true 139 | 140 | /@next/swc-win32-ia32-msvc/13.0.4: 141 | resolution: {integrity: sha512-+Q/Q8Ydvz3X3U84CyZdNv1HC7fE43k+xB8C6b3IFmWGa5Tu2tfskQ2FsUNBrYreZjhFC/894J3rVQ6Vj6Auugg==} 142 | engines: {node: '>= 10'} 143 | cpu: [ia32] 144 | os: [win32] 145 | requiresBuild: true 146 | dev: false 147 | optional: true 148 | 149 | /@next/swc-win32-x64-msvc/13.0.4: 150 | resolution: {integrity: sha512-vXtbo9N1FdtZZRcv4BliU28tTYrkb1EnVpUiiFFe88I6kS9aZVTMY9Z/OtDR52rl1JF1hgs9sL/59D/TQqSATQ==} 151 | engines: {node: '>= 10'} 152 | cpu: [x64] 153 | os: [win32] 154 | requiresBuild: true 155 | dev: false 156 | optional: true 157 | 158 | /@nodelib/fs.scandir/2.1.5: 159 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 160 | engines: {node: '>= 8'} 161 | dependencies: 162 | '@nodelib/fs.stat': 2.0.5 163 | run-parallel: 1.2.0 164 | dev: true 165 | 166 | /@nodelib/fs.stat/2.0.5: 167 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 168 | engines: {node: '>= 8'} 169 | dev: true 170 | 171 | /@nodelib/fs.walk/1.2.8: 172 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 173 | engines: {node: '>= 8'} 174 | dependencies: 175 | '@nodelib/fs.scandir': 2.1.5 176 | fastq: 1.13.0 177 | dev: true 178 | 179 | /@swc/helpers/0.4.11: 180 | resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} 181 | dependencies: 182 | tslib: 2.4.1 183 | dev: false 184 | 185 | /@types/cookie/0.4.1: 186 | resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} 187 | dev: true 188 | 189 | /@types/node/16.18.3: 190 | resolution: {integrity: sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==} 191 | dev: true 192 | 193 | /@types/node/18.11.9: 194 | resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} 195 | dev: false 196 | 197 | /@types/prop-types/15.7.5: 198 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 199 | dev: false 200 | 201 | /@types/react-dom/18.0.9: 202 | resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} 203 | dependencies: 204 | '@types/react': 18.0.25 205 | dev: false 206 | 207 | /@types/react/18.0.25: 208 | resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} 209 | dependencies: 210 | '@types/prop-types': 15.7.5 211 | '@types/scheduler': 0.16.2 212 | csstype: 3.1.1 213 | dev: false 214 | 215 | /@types/scheduler/0.16.2: 216 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 217 | dev: false 218 | 219 | /acorn-node/1.8.2: 220 | resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} 221 | dependencies: 222 | acorn: 7.4.1 223 | acorn-walk: 7.2.0 224 | xtend: 4.0.2 225 | dev: true 226 | 227 | /acorn-walk/7.2.0: 228 | resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} 229 | engines: {node: '>=0.4.0'} 230 | dev: true 231 | 232 | /acorn/7.4.1: 233 | resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} 234 | engines: {node: '>=0.4.0'} 235 | hasBin: true 236 | dev: true 237 | 238 | /anymatch/3.1.2: 239 | resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} 240 | engines: {node: '>= 8'} 241 | dependencies: 242 | normalize-path: 3.0.0 243 | picomatch: 2.3.1 244 | dev: true 245 | 246 | /arg/5.0.2: 247 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} 248 | dev: true 249 | 250 | /autoprefixer/10.4.13_postcss@8.4.19: 251 | resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} 252 | engines: {node: ^10 || ^12 || >=14} 253 | hasBin: true 254 | peerDependencies: 255 | postcss: ^8.1.0 256 | dependencies: 257 | browserslist: 4.21.4 258 | caniuse-lite: 1.0.30001431 259 | fraction.js: 4.2.0 260 | normalize-range: 0.1.2 261 | picocolors: 1.0.0 262 | postcss: 8.4.19 263 | postcss-value-parser: 4.2.0 264 | dev: true 265 | 266 | /binary-extensions/2.2.0: 267 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 268 | engines: {node: '>=8'} 269 | dev: true 270 | 271 | /braces/3.0.2: 272 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 273 | engines: {node: '>=8'} 274 | dependencies: 275 | fill-range: 7.0.1 276 | dev: true 277 | 278 | /browserslist/4.21.4: 279 | resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} 280 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 281 | hasBin: true 282 | dependencies: 283 | caniuse-lite: 1.0.30001431 284 | electron-to-chromium: 1.4.284 285 | node-releases: 2.0.6 286 | update-browserslist-db: 1.0.10_browserslist@4.21.4 287 | dev: true 288 | 289 | /camelcase-css/2.0.1: 290 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 291 | engines: {node: '>= 6'} 292 | dev: true 293 | 294 | /caniuse-lite/1.0.30001431: 295 | resolution: {integrity: sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==} 296 | 297 | /chokidar/3.5.3: 298 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 299 | engines: {node: '>= 8.10.0'} 300 | dependencies: 301 | anymatch: 3.1.2 302 | braces: 3.0.2 303 | glob-parent: 5.1.2 304 | is-binary-path: 2.1.0 305 | is-glob: 4.0.3 306 | normalize-path: 3.0.0 307 | readdirp: 3.6.0 308 | optionalDependencies: 309 | fsevents: 2.3.2 310 | dev: true 311 | 312 | /client-only/0.0.1: 313 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} 314 | dev: false 315 | 316 | /color-name/1.1.4: 317 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 318 | dev: true 319 | 320 | /cookie/0.4.2: 321 | resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} 322 | engines: {node: '>= 0.6'} 323 | dev: true 324 | 325 | /cookies-next/2.1.1: 326 | resolution: {integrity: sha512-AZGZPdL1hU3jCjN2UMJTGhLOYzNUN9Gm+v8BdptYIHUdwz397Et1p+sZRfvAl8pKnnmMdX2Pk9xDRKCGBum6GA==} 327 | dependencies: 328 | '@types/cookie': 0.4.1 329 | '@types/node': 16.18.3 330 | cookie: 0.4.2 331 | dev: true 332 | 333 | /cssesc/3.0.0: 334 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 335 | engines: {node: '>=4'} 336 | hasBin: true 337 | dev: true 338 | 339 | /csstype/3.1.1: 340 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 341 | dev: false 342 | 343 | /defined/1.0.1: 344 | resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} 345 | dev: true 346 | 347 | /detective/5.2.1: 348 | resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} 349 | engines: {node: '>=0.8.0'} 350 | hasBin: true 351 | dependencies: 352 | acorn-node: 1.8.2 353 | defined: 1.0.1 354 | minimist: 1.2.7 355 | dev: true 356 | 357 | /didyoumean/1.2.2: 358 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} 359 | dev: true 360 | 361 | /dlv/1.1.3: 362 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 363 | dev: true 364 | 365 | /electron-to-chromium/1.4.284: 366 | resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} 367 | dev: true 368 | 369 | /escalade/3.1.1: 370 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 371 | engines: {node: '>=6'} 372 | dev: true 373 | 374 | /fast-glob/3.2.12: 375 | resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} 376 | engines: {node: '>=8.6.0'} 377 | dependencies: 378 | '@nodelib/fs.stat': 2.0.5 379 | '@nodelib/fs.walk': 1.2.8 380 | glob-parent: 5.1.2 381 | merge2: 1.4.1 382 | micromatch: 4.0.5 383 | dev: true 384 | 385 | /fastq/1.13.0: 386 | resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} 387 | dependencies: 388 | reusify: 1.0.4 389 | dev: true 390 | 391 | /fill-range/7.0.1: 392 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 393 | engines: {node: '>=8'} 394 | dependencies: 395 | to-regex-range: 5.0.1 396 | dev: true 397 | 398 | /fraction.js/4.2.0: 399 | resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} 400 | dev: true 401 | 402 | /fsevents/2.3.2: 403 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 404 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 405 | os: [darwin] 406 | requiresBuild: true 407 | dev: true 408 | optional: true 409 | 410 | /function-bind/1.1.1: 411 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 412 | dev: true 413 | 414 | /glob-parent/5.1.2: 415 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 416 | engines: {node: '>= 6'} 417 | dependencies: 418 | is-glob: 4.0.3 419 | dev: true 420 | 421 | /glob-parent/6.0.2: 422 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 423 | engines: {node: '>=10.13.0'} 424 | dependencies: 425 | is-glob: 4.0.3 426 | dev: true 427 | 428 | /google-protobuf/3.21.2: 429 | resolution: {integrity: sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==} 430 | dev: true 431 | 432 | /grpc-web/1.4.2: 433 | resolution: {integrity: sha512-gUxWq42l5ldaRplcKb4Pw5O4XBONWZgz3vxIIXnfIeJj8Jc3wYiq2O4c9xzx/NGbbPEej4rhI62C9eTENwLGNw==} 434 | dev: false 435 | 436 | /has/1.0.3: 437 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 438 | engines: {node: '>= 0.4.0'} 439 | dependencies: 440 | function-bind: 1.1.1 441 | dev: true 442 | 443 | /is-binary-path/2.1.0: 444 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 445 | engines: {node: '>=8'} 446 | dependencies: 447 | binary-extensions: 2.2.0 448 | dev: true 449 | 450 | /is-core-module/2.11.0: 451 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 452 | dependencies: 453 | has: 1.0.3 454 | dev: true 455 | 456 | /is-extglob/2.1.1: 457 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 458 | engines: {node: '>=0.10.0'} 459 | dev: true 460 | 461 | /is-glob/4.0.3: 462 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 463 | engines: {node: '>=0.10.0'} 464 | dependencies: 465 | is-extglob: 2.1.1 466 | dev: true 467 | 468 | /is-number/7.0.0: 469 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 470 | engines: {node: '>=0.12.0'} 471 | dev: true 472 | 473 | /js-tokens/4.0.0: 474 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 475 | dev: false 476 | 477 | /lilconfig/2.0.6: 478 | resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} 479 | engines: {node: '>=10'} 480 | dev: true 481 | 482 | /loose-envify/1.4.0: 483 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 484 | hasBin: true 485 | dependencies: 486 | js-tokens: 4.0.0 487 | dev: false 488 | 489 | /merge2/1.4.1: 490 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 491 | engines: {node: '>= 8'} 492 | dev: true 493 | 494 | /micromatch/4.0.5: 495 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 496 | engines: {node: '>=8.6'} 497 | dependencies: 498 | braces: 3.0.2 499 | picomatch: 2.3.1 500 | dev: true 501 | 502 | /minimist/1.2.7: 503 | resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} 504 | dev: true 505 | 506 | /nanoid/3.3.4: 507 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 508 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 509 | hasBin: true 510 | 511 | /next/13.0.4_biqbaboplfbrettd7655fr4n2y: 512 | resolution: {integrity: sha512-4P0MvbjPCI1E/UPL1GrTXtYlgFnbBbY3JQ+AMY8jYE2SwyvCWctEJySoRjveznAHjrl6TIjuAJeB8u1c2StYUQ==} 513 | engines: {node: '>=14.6.0'} 514 | hasBin: true 515 | peerDependencies: 516 | fibers: '>= 3.1.0' 517 | node-sass: ^6.0.0 || ^7.0.0 518 | react: ^18.2.0 519 | react-dom: ^18.2.0 520 | sass: ^1.3.0 521 | peerDependenciesMeta: 522 | fibers: 523 | optional: true 524 | node-sass: 525 | optional: true 526 | sass: 527 | optional: true 528 | dependencies: 529 | '@next/env': 13.0.4 530 | '@swc/helpers': 0.4.11 531 | caniuse-lite: 1.0.30001431 532 | postcss: 8.4.14 533 | react: 18.2.0 534 | react-dom: 18.2.0_react@18.2.0 535 | styled-jsx: 5.1.0_react@18.2.0 536 | use-sync-external-store: 1.2.0_react@18.2.0 537 | optionalDependencies: 538 | '@next/swc-android-arm-eabi': 13.0.4 539 | '@next/swc-android-arm64': 13.0.4 540 | '@next/swc-darwin-arm64': 13.0.4 541 | '@next/swc-darwin-x64': 13.0.4 542 | '@next/swc-freebsd-x64': 13.0.4 543 | '@next/swc-linux-arm-gnueabihf': 13.0.4 544 | '@next/swc-linux-arm64-gnu': 13.0.4 545 | '@next/swc-linux-arm64-musl': 13.0.4 546 | '@next/swc-linux-x64-gnu': 13.0.4 547 | '@next/swc-linux-x64-musl': 13.0.4 548 | '@next/swc-win32-arm64-msvc': 13.0.4 549 | '@next/swc-win32-ia32-msvc': 13.0.4 550 | '@next/swc-win32-x64-msvc': 13.0.4 551 | transitivePeerDependencies: 552 | - '@babel/core' 553 | - babel-plugin-macros 554 | dev: false 555 | 556 | /node-releases/2.0.6: 557 | resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} 558 | dev: true 559 | 560 | /normalize-path/3.0.0: 561 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 562 | engines: {node: '>=0.10.0'} 563 | dev: true 564 | 565 | /normalize-range/0.1.2: 566 | resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} 567 | engines: {node: '>=0.10.0'} 568 | dev: true 569 | 570 | /object-hash/3.0.0: 571 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} 572 | engines: {node: '>= 6'} 573 | dev: true 574 | 575 | /path-parse/1.0.7: 576 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 577 | dev: true 578 | 579 | /picocolors/1.0.0: 580 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 581 | 582 | /picomatch/2.3.1: 583 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 584 | engines: {node: '>=8.6'} 585 | dev: true 586 | 587 | /pify/2.3.0: 588 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} 589 | engines: {node: '>=0.10.0'} 590 | dev: true 591 | 592 | /postcss-import/14.1.0_postcss@8.4.19: 593 | resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} 594 | engines: {node: '>=10.0.0'} 595 | peerDependencies: 596 | postcss: ^8.0.0 597 | dependencies: 598 | postcss: 8.4.19 599 | postcss-value-parser: 4.2.0 600 | read-cache: 1.0.0 601 | resolve: 1.22.1 602 | dev: true 603 | 604 | /postcss-js/4.0.0_postcss@8.4.19: 605 | resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} 606 | engines: {node: ^12 || ^14 || >= 16} 607 | peerDependencies: 608 | postcss: ^8.3.3 609 | dependencies: 610 | camelcase-css: 2.0.1 611 | postcss: 8.4.19 612 | dev: true 613 | 614 | /postcss-load-config/3.1.4_postcss@8.4.19: 615 | resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 616 | engines: {node: '>= 10'} 617 | peerDependencies: 618 | postcss: '>=8.0.9' 619 | ts-node: '>=9.0.0' 620 | peerDependenciesMeta: 621 | postcss: 622 | optional: true 623 | ts-node: 624 | optional: true 625 | dependencies: 626 | lilconfig: 2.0.6 627 | postcss: 8.4.19 628 | yaml: 1.10.2 629 | dev: true 630 | 631 | /postcss-nested/6.0.0_postcss@8.4.19: 632 | resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} 633 | engines: {node: '>=12.0'} 634 | peerDependencies: 635 | postcss: ^8.2.14 636 | dependencies: 637 | postcss: 8.4.19 638 | postcss-selector-parser: 6.0.11 639 | dev: true 640 | 641 | /postcss-selector-parser/6.0.11: 642 | resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} 643 | engines: {node: '>=4'} 644 | dependencies: 645 | cssesc: 3.0.0 646 | util-deprecate: 1.0.2 647 | dev: true 648 | 649 | /postcss-value-parser/4.2.0: 650 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 651 | dev: true 652 | 653 | /postcss/8.4.14: 654 | resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} 655 | engines: {node: ^10 || ^12 || >=14} 656 | dependencies: 657 | nanoid: 3.3.4 658 | picocolors: 1.0.0 659 | source-map-js: 1.0.2 660 | dev: false 661 | 662 | /postcss/8.4.19: 663 | resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} 664 | engines: {node: ^10 || ^12 || >=14} 665 | dependencies: 666 | nanoid: 3.3.4 667 | picocolors: 1.0.0 668 | source-map-js: 1.0.2 669 | dev: true 670 | 671 | /queue-microtask/1.2.3: 672 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 673 | dev: true 674 | 675 | /quick-lru/5.1.1: 676 | resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} 677 | engines: {node: '>=10'} 678 | dev: true 679 | 680 | /react-dom/18.2.0_react@18.2.0: 681 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 682 | peerDependencies: 683 | react: ^18.2.0 684 | dependencies: 685 | loose-envify: 1.4.0 686 | react: 18.2.0 687 | scheduler: 0.23.0 688 | dev: false 689 | 690 | /react/18.2.0: 691 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 692 | engines: {node: '>=0.10.0'} 693 | dependencies: 694 | loose-envify: 1.4.0 695 | dev: false 696 | 697 | /read-cache/1.0.0: 698 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} 699 | dependencies: 700 | pify: 2.3.0 701 | dev: true 702 | 703 | /readdirp/3.6.0: 704 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 705 | engines: {node: '>=8.10.0'} 706 | dependencies: 707 | picomatch: 2.3.1 708 | dev: true 709 | 710 | /resolve/1.22.1: 711 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 712 | hasBin: true 713 | dependencies: 714 | is-core-module: 2.11.0 715 | path-parse: 1.0.7 716 | supports-preserve-symlinks-flag: 1.0.0 717 | dev: true 718 | 719 | /reusify/1.0.4: 720 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 721 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 722 | dev: true 723 | 724 | /run-parallel/1.2.0: 725 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 726 | dependencies: 727 | queue-microtask: 1.2.3 728 | dev: true 729 | 730 | /scheduler/0.23.0: 731 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 732 | dependencies: 733 | loose-envify: 1.4.0 734 | dev: false 735 | 736 | /source-map-js/1.0.2: 737 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 738 | engines: {node: '>=0.10.0'} 739 | 740 | /styled-jsx/5.1.0_react@18.2.0: 741 | resolution: {integrity: sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==} 742 | engines: {node: '>= 12.0.0'} 743 | peerDependencies: 744 | '@babel/core': '*' 745 | babel-plugin-macros: '*' 746 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' 747 | peerDependenciesMeta: 748 | '@babel/core': 749 | optional: true 750 | babel-plugin-macros: 751 | optional: true 752 | dependencies: 753 | client-only: 0.0.1 754 | react: 18.2.0 755 | dev: false 756 | 757 | /supports-preserve-symlinks-flag/1.0.0: 758 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 759 | engines: {node: '>= 0.4'} 760 | dev: true 761 | 762 | /tailwindcss/3.2.4_postcss@8.4.19: 763 | resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} 764 | engines: {node: '>=12.13.0'} 765 | hasBin: true 766 | peerDependencies: 767 | postcss: ^8.0.9 768 | dependencies: 769 | arg: 5.0.2 770 | chokidar: 3.5.3 771 | color-name: 1.1.4 772 | detective: 5.2.1 773 | didyoumean: 1.2.2 774 | dlv: 1.1.3 775 | fast-glob: 3.2.12 776 | glob-parent: 6.0.2 777 | is-glob: 4.0.3 778 | lilconfig: 2.0.6 779 | micromatch: 4.0.5 780 | normalize-path: 3.0.0 781 | object-hash: 3.0.0 782 | picocolors: 1.0.0 783 | postcss: 8.4.19 784 | postcss-import: 14.1.0_postcss@8.4.19 785 | postcss-js: 4.0.0_postcss@8.4.19 786 | postcss-load-config: 3.1.4_postcss@8.4.19 787 | postcss-nested: 6.0.0_postcss@8.4.19 788 | postcss-selector-parser: 6.0.11 789 | postcss-value-parser: 4.2.0 790 | quick-lru: 5.1.1 791 | resolve: 1.22.1 792 | transitivePeerDependencies: 793 | - ts-node 794 | dev: true 795 | 796 | /to-regex-range/5.0.1: 797 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 798 | engines: {node: '>=8.0'} 799 | dependencies: 800 | is-number: 7.0.0 801 | dev: true 802 | 803 | /tslib/2.4.1: 804 | resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} 805 | dev: false 806 | 807 | /typescript/4.9.3: 808 | resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} 809 | engines: {node: '>=4.2.0'} 810 | hasBin: true 811 | dev: false 812 | 813 | /update-browserslist-db/1.0.10_browserslist@4.21.4: 814 | resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} 815 | hasBin: true 816 | peerDependencies: 817 | browserslist: '>= 4.21.0' 818 | dependencies: 819 | browserslist: 4.21.4 820 | escalade: 3.1.1 821 | picocolors: 1.0.0 822 | dev: true 823 | 824 | /use-sync-external-store/1.2.0_react@18.2.0: 825 | resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} 826 | peerDependencies: 827 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 828 | dependencies: 829 | react: 18.2.0 830 | dev: false 831 | 832 | /util-deprecate/1.0.2: 833 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 834 | dev: true 835 | 836 | /xtend/4.0.2: 837 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 838 | engines: {node: '>=0.4'} 839 | dev: true 840 | 841 | /yaml/1.10.2: 842 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 843 | engines: {node: '>= 6'} 844 | dev: true 845 | -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /frontend/protos/task_grpc_web_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as grpcWeb from 'grpc-web'; 2 | 3 | import * as protos_task_pb from '../protos/task_pb'; 4 | 5 | 6 | export class TaskServiceClient { 7 | constructor (hostname: string, 8 | credentials?: null | { [index: string]: string; }, 9 | options?: null | { [index: string]: any; }); 10 | 11 | getTask( 12 | request: protos_task_pb.TaskRequest, 13 | metadata: grpcWeb.Metadata | undefined, 14 | callback: (err: grpcWeb.RpcError, 15 | response: protos_task_pb.TaskResponse) => void 16 | ): grpcWeb.ClientReadableStream; 17 | 18 | addTask( 19 | request: protos_task_pb.AddTaskRequest, 20 | metadata: grpcWeb.Metadata | undefined, 21 | callback: (err: grpcWeb.RpcError, 22 | response: protos_task_pb.AddTaskResponse) => void 23 | ): grpcWeb.ClientReadableStream; 24 | 25 | deleteTask( 26 | request: protos_task_pb.DeleteTaskRequest, 27 | metadata: grpcWeb.Metadata | undefined, 28 | callback: (err: grpcWeb.RpcError, 29 | response: protos_task_pb.DeleteTaskResponse) => void 30 | ): grpcWeb.ClientReadableStream; 31 | 32 | updateTask( 33 | request: protos_task_pb.UpdateTaskRequest, 34 | metadata: grpcWeb.Metadata | undefined, 35 | callback: (err: grpcWeb.RpcError, 36 | response: protos_task_pb.UpdateTaskResponse) => void 37 | ): grpcWeb.ClientReadableStream; 38 | 39 | deleteUnUsedConnections( 40 | request: protos_task_pb.EmptyRequest, 41 | metadata: grpcWeb.Metadata | undefined, 42 | callback: (err: grpcWeb.RpcError, 43 | response: protos_task_pb.EmptyResponse) => void 44 | ): grpcWeb.ClientReadableStream; 45 | 46 | getAllTasks( 47 | request: protos_task_pb.TasksRequest, 48 | metadata?: grpcWeb.Metadata 49 | ): grpcWeb.ClientReadableStream; 50 | 51 | } 52 | 53 | export class TaskServicePromiseClient { 54 | constructor (hostname: string, 55 | credentials?: null | { [index: string]: string; }, 56 | options?: null | { [index: string]: any; }); 57 | 58 | getTask( 59 | request: protos_task_pb.TaskRequest, 60 | metadata?: grpcWeb.Metadata 61 | ): Promise; 62 | 63 | addTask( 64 | request: protos_task_pb.AddTaskRequest, 65 | metadata?: grpcWeb.Metadata 66 | ): Promise; 67 | 68 | deleteTask( 69 | request: protos_task_pb.DeleteTaskRequest, 70 | metadata?: grpcWeb.Metadata 71 | ): Promise; 72 | 73 | updateTask( 74 | request: protos_task_pb.UpdateTaskRequest, 75 | metadata?: grpcWeb.Metadata 76 | ): Promise; 77 | 78 | deleteUnUsedConnections( 79 | request: protos_task_pb.EmptyRequest, 80 | metadata?: grpcWeb.Metadata 81 | ): Promise; 82 | 83 | getAllTasks( 84 | request: protos_task_pb.TasksRequest, 85 | metadata?: grpcWeb.Metadata 86 | ): grpcWeb.ClientReadableStream; 87 | 88 | } 89 | 90 | -------------------------------------------------------------------------------- /frontend/protos/task_grpc_web_pb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview gRPC-Web generated client stub for task 3 | * @enhanceable 4 | * @public 5 | */ 6 | 7 | // Code generated by protoc-gen-grpc-web. DO NOT EDIT. 8 | // versions: 9 | // protoc-gen-grpc-web v1.4.2 10 | // protoc v3.15.6 11 | // source: protos/task.proto 12 | 13 | 14 | /* eslint-disable */ 15 | // @ts-nocheck 16 | 17 | 18 | 19 | const grpc = {}; 20 | grpc.web = require('grpc-web'); 21 | 22 | const proto = {}; 23 | proto.task = require('./task_pb.js'); 24 | 25 | /** 26 | * @param {string} hostname 27 | * @param {?Object} credentials 28 | * @param {?grpc.web.ClientOptions} options 29 | * @constructor 30 | * @struct 31 | * @final 32 | */ 33 | proto.task.TaskServiceClient = 34 | function(hostname, credentials, options) { 35 | if (!options) options = {}; 36 | options.format = 'text'; 37 | 38 | /** 39 | * @private @const {!grpc.web.GrpcWebClientBase} The client 40 | */ 41 | this.client_ = new grpc.web.GrpcWebClientBase(options); 42 | 43 | /** 44 | * @private @const {string} The hostname 45 | */ 46 | this.hostname_ = hostname.replace(/\/+$/, ''); 47 | 48 | }; 49 | 50 | 51 | /** 52 | * @param {string} hostname 53 | * @param {?Object} credentials 54 | * @param {?grpc.web.ClientOptions} options 55 | * @constructor 56 | * @struct 57 | * @final 58 | */ 59 | proto.task.TaskServicePromiseClient = 60 | function(hostname, credentials, options) { 61 | if (!options) options = {}; 62 | options.format = 'text'; 63 | 64 | /** 65 | * @private @const {!grpc.web.GrpcWebClientBase} The client 66 | */ 67 | this.client_ = new grpc.web.GrpcWebClientBase(options); 68 | 69 | /** 70 | * @private @const {string} The hostname 71 | */ 72 | this.hostname_ = hostname.replace(/\/+$/, ''); 73 | 74 | }; 75 | 76 | 77 | /** 78 | * @const 79 | * @type {!grpc.web.MethodDescriptor< 80 | * !proto.task.TaskRequest, 81 | * !proto.task.TaskResponse>} 82 | */ 83 | const methodDescriptor_TaskService_GetTask = new grpc.web.MethodDescriptor( 84 | '/task.TaskService/GetTask', 85 | grpc.web.MethodType.UNARY, 86 | proto.task.TaskRequest, 87 | proto.task.TaskResponse, 88 | /** 89 | * @param {!proto.task.TaskRequest} request 90 | * @return {!Uint8Array} 91 | */ 92 | function(request) { 93 | return request.serializeBinary(); 94 | }, 95 | proto.task.TaskResponse.deserializeBinary 96 | ); 97 | 98 | 99 | /** 100 | * @param {!proto.task.TaskRequest} request The 101 | * request proto 102 | * @param {?Object} metadata User defined 103 | * call metadata 104 | * @param {function(?grpc.web.RpcError, ?proto.task.TaskResponse)} 105 | * callback The callback function(error, response) 106 | * @return {!grpc.web.ClientReadableStream|undefined} 107 | * The XHR Node Readable Stream 108 | */ 109 | proto.task.TaskServiceClient.prototype.getTask = 110 | function(request, metadata, callback) { 111 | return this.client_.rpcCall(this.hostname_ + 112 | '/task.TaskService/GetTask', 113 | request, 114 | metadata || {}, 115 | methodDescriptor_TaskService_GetTask, 116 | callback); 117 | }; 118 | 119 | 120 | /** 121 | * @param {!proto.task.TaskRequest} request The 122 | * request proto 123 | * @param {?Object=} metadata User defined 124 | * call metadata 125 | * @return {!Promise} 126 | * Promise that resolves to the response 127 | */ 128 | proto.task.TaskServicePromiseClient.prototype.getTask = 129 | function(request, metadata) { 130 | return this.client_.unaryCall(this.hostname_ + 131 | '/task.TaskService/GetTask', 132 | request, 133 | metadata || {}, 134 | methodDescriptor_TaskService_GetTask); 135 | }; 136 | 137 | 138 | /** 139 | * @const 140 | * @type {!grpc.web.MethodDescriptor< 141 | * !proto.task.AddTaskRequest, 142 | * !proto.task.AddTaskResponse>} 143 | */ 144 | const methodDescriptor_TaskService_AddTask = new grpc.web.MethodDescriptor( 145 | '/task.TaskService/AddTask', 146 | grpc.web.MethodType.UNARY, 147 | proto.task.AddTaskRequest, 148 | proto.task.AddTaskResponse, 149 | /** 150 | * @param {!proto.task.AddTaskRequest} request 151 | * @return {!Uint8Array} 152 | */ 153 | function(request) { 154 | return request.serializeBinary(); 155 | }, 156 | proto.task.AddTaskResponse.deserializeBinary 157 | ); 158 | 159 | 160 | /** 161 | * @param {!proto.task.AddTaskRequest} request The 162 | * request proto 163 | * @param {?Object} metadata User defined 164 | * call metadata 165 | * @param {function(?grpc.web.RpcError, ?proto.task.AddTaskResponse)} 166 | * callback The callback function(error, response) 167 | * @return {!grpc.web.ClientReadableStream|undefined} 168 | * The XHR Node Readable Stream 169 | */ 170 | proto.task.TaskServiceClient.prototype.addTask = 171 | function(request, metadata, callback) { 172 | return this.client_.rpcCall(this.hostname_ + 173 | '/task.TaskService/AddTask', 174 | request, 175 | metadata || {}, 176 | methodDescriptor_TaskService_AddTask, 177 | callback); 178 | }; 179 | 180 | 181 | /** 182 | * @param {!proto.task.AddTaskRequest} request The 183 | * request proto 184 | * @param {?Object=} metadata User defined 185 | * call metadata 186 | * @return {!Promise} 187 | * Promise that resolves to the response 188 | */ 189 | proto.task.TaskServicePromiseClient.prototype.addTask = 190 | function(request, metadata) { 191 | return this.client_.unaryCall(this.hostname_ + 192 | '/task.TaskService/AddTask', 193 | request, 194 | metadata || {}, 195 | methodDescriptor_TaskService_AddTask); 196 | }; 197 | 198 | 199 | /** 200 | * @const 201 | * @type {!grpc.web.MethodDescriptor< 202 | * !proto.task.DeleteTaskRequest, 203 | * !proto.task.DeleteTaskResponse>} 204 | */ 205 | const methodDescriptor_TaskService_DeleteTask = new grpc.web.MethodDescriptor( 206 | '/task.TaskService/DeleteTask', 207 | grpc.web.MethodType.UNARY, 208 | proto.task.DeleteTaskRequest, 209 | proto.task.DeleteTaskResponse, 210 | /** 211 | * @param {!proto.task.DeleteTaskRequest} request 212 | * @return {!Uint8Array} 213 | */ 214 | function(request) { 215 | return request.serializeBinary(); 216 | }, 217 | proto.task.DeleteTaskResponse.deserializeBinary 218 | ); 219 | 220 | 221 | /** 222 | * @param {!proto.task.DeleteTaskRequest} request The 223 | * request proto 224 | * @param {?Object} metadata User defined 225 | * call metadata 226 | * @param {function(?grpc.web.RpcError, ?proto.task.DeleteTaskResponse)} 227 | * callback The callback function(error, response) 228 | * @return {!grpc.web.ClientReadableStream|undefined} 229 | * The XHR Node Readable Stream 230 | */ 231 | proto.task.TaskServiceClient.prototype.deleteTask = 232 | function(request, metadata, callback) { 233 | return this.client_.rpcCall(this.hostname_ + 234 | '/task.TaskService/DeleteTask', 235 | request, 236 | metadata || {}, 237 | methodDescriptor_TaskService_DeleteTask, 238 | callback); 239 | }; 240 | 241 | 242 | /** 243 | * @param {!proto.task.DeleteTaskRequest} request The 244 | * request proto 245 | * @param {?Object=} metadata User defined 246 | * call metadata 247 | * @return {!Promise} 248 | * Promise that resolves to the response 249 | */ 250 | proto.task.TaskServicePromiseClient.prototype.deleteTask = 251 | function(request, metadata) { 252 | return this.client_.unaryCall(this.hostname_ + 253 | '/task.TaskService/DeleteTask', 254 | request, 255 | metadata || {}, 256 | methodDescriptor_TaskService_DeleteTask); 257 | }; 258 | 259 | 260 | /** 261 | * @const 262 | * @type {!grpc.web.MethodDescriptor< 263 | * !proto.task.UpdateTaskRequest, 264 | * !proto.task.UpdateTaskResponse>} 265 | */ 266 | const methodDescriptor_TaskService_UpdateTask = new grpc.web.MethodDescriptor( 267 | '/task.TaskService/UpdateTask', 268 | grpc.web.MethodType.UNARY, 269 | proto.task.UpdateTaskRequest, 270 | proto.task.UpdateTaskResponse, 271 | /** 272 | * @param {!proto.task.UpdateTaskRequest} request 273 | * @return {!Uint8Array} 274 | */ 275 | function(request) { 276 | return request.serializeBinary(); 277 | }, 278 | proto.task.UpdateTaskResponse.deserializeBinary 279 | ); 280 | 281 | 282 | /** 283 | * @param {!proto.task.UpdateTaskRequest} request The 284 | * request proto 285 | * @param {?Object} metadata User defined 286 | * call metadata 287 | * @param {function(?grpc.web.RpcError, ?proto.task.UpdateTaskResponse)} 288 | * callback The callback function(error, response) 289 | * @return {!grpc.web.ClientReadableStream|undefined} 290 | * The XHR Node Readable Stream 291 | */ 292 | proto.task.TaskServiceClient.prototype.updateTask = 293 | function(request, metadata, callback) { 294 | return this.client_.rpcCall(this.hostname_ + 295 | '/task.TaskService/UpdateTask', 296 | request, 297 | metadata || {}, 298 | methodDescriptor_TaskService_UpdateTask, 299 | callback); 300 | }; 301 | 302 | 303 | /** 304 | * @param {!proto.task.UpdateTaskRequest} request The 305 | * request proto 306 | * @param {?Object=} metadata User defined 307 | * call metadata 308 | * @return {!Promise} 309 | * Promise that resolves to the response 310 | */ 311 | proto.task.TaskServicePromiseClient.prototype.updateTask = 312 | function(request, metadata) { 313 | return this.client_.unaryCall(this.hostname_ + 314 | '/task.TaskService/UpdateTask', 315 | request, 316 | metadata || {}, 317 | methodDescriptor_TaskService_UpdateTask); 318 | }; 319 | 320 | 321 | /** 322 | * @const 323 | * @type {!grpc.web.MethodDescriptor< 324 | * !proto.task.EmptyRequest, 325 | * !proto.task.EmptyResponse>} 326 | */ 327 | const methodDescriptor_TaskService_DeleteUnUsedConnections = new grpc.web.MethodDescriptor( 328 | '/task.TaskService/DeleteUnUsedConnections', 329 | grpc.web.MethodType.UNARY, 330 | proto.task.EmptyRequest, 331 | proto.task.EmptyResponse, 332 | /** 333 | * @param {!proto.task.EmptyRequest} request 334 | * @return {!Uint8Array} 335 | */ 336 | function(request) { 337 | return request.serializeBinary(); 338 | }, 339 | proto.task.EmptyResponse.deserializeBinary 340 | ); 341 | 342 | 343 | /** 344 | * @param {!proto.task.EmptyRequest} request The 345 | * request proto 346 | * @param {?Object} metadata User defined 347 | * call metadata 348 | * @param {function(?grpc.web.RpcError, ?proto.task.EmptyResponse)} 349 | * callback The callback function(error, response) 350 | * @return {!grpc.web.ClientReadableStream|undefined} 351 | * The XHR Node Readable Stream 352 | */ 353 | proto.task.TaskServiceClient.prototype.deleteUnUsedConnections = 354 | function(request, metadata, callback) { 355 | return this.client_.rpcCall(this.hostname_ + 356 | '/task.TaskService/DeleteUnUsedConnections', 357 | request, 358 | metadata || {}, 359 | methodDescriptor_TaskService_DeleteUnUsedConnections, 360 | callback); 361 | }; 362 | 363 | 364 | /** 365 | * @param {!proto.task.EmptyRequest} request The 366 | * request proto 367 | * @param {?Object=} metadata User defined 368 | * call metadata 369 | * @return {!Promise} 370 | * Promise that resolves to the response 371 | */ 372 | proto.task.TaskServicePromiseClient.prototype.deleteUnUsedConnections = 373 | function(request, metadata) { 374 | return this.client_.unaryCall(this.hostname_ + 375 | '/task.TaskService/DeleteUnUsedConnections', 376 | request, 377 | metadata || {}, 378 | methodDescriptor_TaskService_DeleteUnUsedConnections); 379 | }; 380 | 381 | 382 | /** 383 | * @const 384 | * @type {!grpc.web.MethodDescriptor< 385 | * !proto.task.TasksRequest, 386 | * !proto.task.TasksResponse>} 387 | */ 388 | const methodDescriptor_TaskService_GetAllTasks = new grpc.web.MethodDescriptor( 389 | '/task.TaskService/GetAllTasks', 390 | grpc.web.MethodType.SERVER_STREAMING, 391 | proto.task.TasksRequest, 392 | proto.task.TasksResponse, 393 | /** 394 | * @param {!proto.task.TasksRequest} request 395 | * @return {!Uint8Array} 396 | */ 397 | function(request) { 398 | return request.serializeBinary(); 399 | }, 400 | proto.task.TasksResponse.deserializeBinary 401 | ); 402 | 403 | 404 | /** 405 | * @param {!proto.task.TasksRequest} request The request proto 406 | * @param {?Object=} metadata User defined 407 | * call metadata 408 | * @return {!grpc.web.ClientReadableStream} 409 | * The XHR Node Readable Stream 410 | */ 411 | proto.task.TaskServiceClient.prototype.getAllTasks = 412 | function(request, metadata) { 413 | return this.client_.serverStreaming(this.hostname_ + 414 | '/task.TaskService/GetAllTasks', 415 | request, 416 | metadata || {}, 417 | methodDescriptor_TaskService_GetAllTasks); 418 | }; 419 | 420 | 421 | /** 422 | * @param {!proto.task.TasksRequest} request The request proto 423 | * @param {?Object=} metadata User defined 424 | * call metadata 425 | * @return {!grpc.web.ClientReadableStream} 426 | * The XHR Node Readable Stream 427 | */ 428 | proto.task.TaskServicePromiseClient.prototype.getAllTasks = 429 | function(request, metadata) { 430 | return this.client_.serverStreaming(this.hostname_ + 431 | '/task.TaskService/GetAllTasks', 432 | request, 433 | metadata || {}, 434 | methodDescriptor_TaskService_GetAllTasks); 435 | }; 436 | 437 | 438 | module.exports = proto.task; 439 | 440 | -------------------------------------------------------------------------------- /frontend/protos/task_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as jspb from 'google-protobuf' 2 | 3 | 4 | 5 | export class Task extends jspb.Message { 6 | getId(): number; 7 | setId(value: number): Task; 8 | 9 | getTitle(): string; 10 | setTitle(value: string): Task; 11 | 12 | getBody(): string; 13 | setBody(value: string): Task; 14 | 15 | getStatus(): string; 16 | setStatus(value: string): Task; 17 | 18 | serializeBinary(): Uint8Array; 19 | toObject(includeInstance?: boolean): Task.AsObject; 20 | static toObject(includeInstance: boolean, msg: Task): Task.AsObject; 21 | static serializeBinaryToWriter(message: Task, writer: jspb.BinaryWriter): void; 22 | static deserializeBinary(bytes: Uint8Array): Task; 23 | static deserializeBinaryFromReader(message: Task, reader: jspb.BinaryReader): Task; 24 | } 25 | 26 | export namespace Task { 27 | export type AsObject = { 28 | id: number, 29 | title: string, 30 | body: string, 31 | status: string, 32 | } 33 | } 34 | 35 | export class TaskRequest extends jspb.Message { 36 | getId(): number; 37 | setId(value: number): TaskRequest; 38 | 39 | serializeBinary(): Uint8Array; 40 | toObject(includeInstance?: boolean): TaskRequest.AsObject; 41 | static toObject(includeInstance: boolean, msg: TaskRequest): TaskRequest.AsObject; 42 | static serializeBinaryToWriter(message: TaskRequest, writer: jspb.BinaryWriter): void; 43 | static deserializeBinary(bytes: Uint8Array): TaskRequest; 44 | static deserializeBinaryFromReader(message: TaskRequest, reader: jspb.BinaryReader): TaskRequest; 45 | } 46 | 47 | export namespace TaskRequest { 48 | export type AsObject = { 49 | id: number, 50 | } 51 | } 52 | 53 | export class TaskResponse extends jspb.Message { 54 | getTask(): Task | undefined; 55 | setTask(value?: Task): TaskResponse; 56 | hasTask(): boolean; 57 | clearTask(): TaskResponse; 58 | 59 | serializeBinary(): Uint8Array; 60 | toObject(includeInstance?: boolean): TaskResponse.AsObject; 61 | static toObject(includeInstance: boolean, msg: TaskResponse): TaskResponse.AsObject; 62 | static serializeBinaryToWriter(message: TaskResponse, writer: jspb.BinaryWriter): void; 63 | static deserializeBinary(bytes: Uint8Array): TaskResponse; 64 | static deserializeBinaryFromReader(message: TaskResponse, reader: jspb.BinaryReader): TaskResponse; 65 | } 66 | 67 | export namespace TaskResponse { 68 | export type AsObject = { 69 | task?: Task.AsObject, 70 | } 71 | } 72 | 73 | export class EmptyRequest extends jspb.Message { 74 | serializeBinary(): Uint8Array; 75 | toObject(includeInstance?: boolean): EmptyRequest.AsObject; 76 | static toObject(includeInstance: boolean, msg: EmptyRequest): EmptyRequest.AsObject; 77 | static serializeBinaryToWriter(message: EmptyRequest, writer: jspb.BinaryWriter): void; 78 | static deserializeBinary(bytes: Uint8Array): EmptyRequest; 79 | static deserializeBinaryFromReader(message: EmptyRequest, reader: jspb.BinaryReader): EmptyRequest; 80 | } 81 | 82 | export namespace EmptyRequest { 83 | export type AsObject = { 84 | } 85 | } 86 | 87 | export class EmptyResponse extends jspb.Message { 88 | getMessage(): string; 89 | setMessage(value: string): EmptyResponse; 90 | 91 | serializeBinary(): Uint8Array; 92 | toObject(includeInstance?: boolean): EmptyResponse.AsObject; 93 | static toObject(includeInstance: boolean, msg: EmptyResponse): EmptyResponse.AsObject; 94 | static serializeBinaryToWriter(message: EmptyResponse, writer: jspb.BinaryWriter): void; 95 | static deserializeBinary(bytes: Uint8Array): EmptyResponse; 96 | static deserializeBinaryFromReader(message: EmptyResponse, reader: jspb.BinaryReader): EmptyResponse; 97 | } 98 | 99 | export namespace EmptyResponse { 100 | export type AsObject = { 101 | message: string, 102 | } 103 | } 104 | 105 | export class TasksRequest extends jspb.Message { 106 | serializeBinary(): Uint8Array; 107 | toObject(includeInstance?: boolean): TasksRequest.AsObject; 108 | static toObject(includeInstance: boolean, msg: TasksRequest): TasksRequest.AsObject; 109 | static serializeBinaryToWriter(message: TasksRequest, writer: jspb.BinaryWriter): void; 110 | static deserializeBinary(bytes: Uint8Array): TasksRequest; 111 | static deserializeBinaryFromReader(message: TasksRequest, reader: jspb.BinaryReader): TasksRequest; 112 | } 113 | 114 | export namespace TasksRequest { 115 | export type AsObject = { 116 | } 117 | } 118 | 119 | export class TasksResponse extends jspb.Message { 120 | getTasksList(): Array; 121 | setTasksList(value: Array): TasksResponse; 122 | clearTasksList(): TasksResponse; 123 | addTasks(value?: Task, index?: number): Task; 124 | 125 | serializeBinary(): Uint8Array; 126 | toObject(includeInstance?: boolean): TasksResponse.AsObject; 127 | static toObject(includeInstance: boolean, msg: TasksResponse): TasksResponse.AsObject; 128 | static serializeBinaryToWriter(message: TasksResponse, writer: jspb.BinaryWriter): void; 129 | static deserializeBinary(bytes: Uint8Array): TasksResponse; 130 | static deserializeBinaryFromReader(message: TasksResponse, reader: jspb.BinaryReader): TasksResponse; 131 | } 132 | 133 | export namespace TasksResponse { 134 | export type AsObject = { 135 | tasksList: Array, 136 | } 137 | } 138 | 139 | export class AddTaskRequest extends jspb.Message { 140 | getTitle(): string; 141 | setTitle(value: string): AddTaskRequest; 142 | 143 | getBody(): string; 144 | setBody(value: string): AddTaskRequest; 145 | 146 | getStatus(): string; 147 | setStatus(value: string): AddTaskRequest; 148 | 149 | serializeBinary(): Uint8Array; 150 | toObject(includeInstance?: boolean): AddTaskRequest.AsObject; 151 | static toObject(includeInstance: boolean, msg: AddTaskRequest): AddTaskRequest.AsObject; 152 | static serializeBinaryToWriter(message: AddTaskRequest, writer: jspb.BinaryWriter): void; 153 | static deserializeBinary(bytes: Uint8Array): AddTaskRequest; 154 | static deserializeBinaryFromReader(message: AddTaskRequest, reader: jspb.BinaryReader): AddTaskRequest; 155 | } 156 | 157 | export namespace AddTaskRequest { 158 | export type AsObject = { 159 | title: string, 160 | body: string, 161 | status: string, 162 | } 163 | } 164 | 165 | export class AddTaskResponse extends jspb.Message { 166 | getTask(): Task | undefined; 167 | setTask(value?: Task): AddTaskResponse; 168 | hasTask(): boolean; 169 | clearTask(): AddTaskResponse; 170 | 171 | serializeBinary(): Uint8Array; 172 | toObject(includeInstance?: boolean): AddTaskResponse.AsObject; 173 | static toObject(includeInstance: boolean, msg: AddTaskResponse): AddTaskResponse.AsObject; 174 | static serializeBinaryToWriter(message: AddTaskResponse, writer: jspb.BinaryWriter): void; 175 | static deserializeBinary(bytes: Uint8Array): AddTaskResponse; 176 | static deserializeBinaryFromReader(message: AddTaskResponse, reader: jspb.BinaryReader): AddTaskResponse; 177 | } 178 | 179 | export namespace AddTaskResponse { 180 | export type AsObject = { 181 | task?: Task.AsObject, 182 | } 183 | } 184 | 185 | export class DeleteTaskRequest extends jspb.Message { 186 | getId(): number; 187 | setId(value: number): DeleteTaskRequest; 188 | 189 | serializeBinary(): Uint8Array; 190 | toObject(includeInstance?: boolean): DeleteTaskRequest.AsObject; 191 | static toObject(includeInstance: boolean, msg: DeleteTaskRequest): DeleteTaskRequest.AsObject; 192 | static serializeBinaryToWriter(message: DeleteTaskRequest, writer: jspb.BinaryWriter): void; 193 | static deserializeBinary(bytes: Uint8Array): DeleteTaskRequest; 194 | static deserializeBinaryFromReader(message: DeleteTaskRequest, reader: jspb.BinaryReader): DeleteTaskRequest; 195 | } 196 | 197 | export namespace DeleteTaskRequest { 198 | export type AsObject = { 199 | id: number, 200 | } 201 | } 202 | 203 | export class DeleteTaskResponse extends jspb.Message { 204 | getMessage(): string; 205 | setMessage(value: string): DeleteTaskResponse; 206 | 207 | serializeBinary(): Uint8Array; 208 | toObject(includeInstance?: boolean): DeleteTaskResponse.AsObject; 209 | static toObject(includeInstance: boolean, msg: DeleteTaskResponse): DeleteTaskResponse.AsObject; 210 | static serializeBinaryToWriter(message: DeleteTaskResponse, writer: jspb.BinaryWriter): void; 211 | static deserializeBinary(bytes: Uint8Array): DeleteTaskResponse; 212 | static deserializeBinaryFromReader(message: DeleteTaskResponse, reader: jspb.BinaryReader): DeleteTaskResponse; 213 | } 214 | 215 | export namespace DeleteTaskResponse { 216 | export type AsObject = { 217 | message: string, 218 | } 219 | } 220 | 221 | export class UpdateTaskRequest extends jspb.Message { 222 | getTask(): Task | undefined; 223 | setTask(value?: Task): UpdateTaskRequest; 224 | hasTask(): boolean; 225 | clearTask(): UpdateTaskRequest; 226 | 227 | serializeBinary(): Uint8Array; 228 | toObject(includeInstance?: boolean): UpdateTaskRequest.AsObject; 229 | static toObject(includeInstance: boolean, msg: UpdateTaskRequest): UpdateTaskRequest.AsObject; 230 | static serializeBinaryToWriter(message: UpdateTaskRequest, writer: jspb.BinaryWriter): void; 231 | static deserializeBinary(bytes: Uint8Array): UpdateTaskRequest; 232 | static deserializeBinaryFromReader(message: UpdateTaskRequest, reader: jspb.BinaryReader): UpdateTaskRequest; 233 | } 234 | 235 | export namespace UpdateTaskRequest { 236 | export type AsObject = { 237 | task?: Task.AsObject, 238 | } 239 | } 240 | 241 | export class UpdateTaskResponse extends jspb.Message { 242 | getTask(): Task | undefined; 243 | setTask(value?: Task): UpdateTaskResponse; 244 | hasTask(): boolean; 245 | clearTask(): UpdateTaskResponse; 246 | 247 | serializeBinary(): Uint8Array; 248 | toObject(includeInstance?: boolean): UpdateTaskResponse.AsObject; 249 | static toObject(includeInstance: boolean, msg: UpdateTaskResponse): UpdateTaskResponse.AsObject; 250 | static serializeBinaryToWriter(message: UpdateTaskResponse, writer: jspb.BinaryWriter): void; 251 | static deserializeBinary(bytes: Uint8Array): UpdateTaskResponse; 252 | static deserializeBinaryFromReader(message: UpdateTaskResponse, reader: jspb.BinaryReader): UpdateTaskResponse; 253 | } 254 | 255 | export namespace UpdateTaskResponse { 256 | export type AsObject = { 257 | task?: Task.AsObject, 258 | } 259 | } 260 | 261 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ozair0/RealTime-Task-Management-App/6bf75b57b21d146f2d0182ab6d6b7aff10a44eb7/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /frontend/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx}", 5 | "./components/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | }; 12 | -------------------------------------------------------------------------------- /frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /frontend/util/grpc-connection.ts: -------------------------------------------------------------------------------- 1 | import { TaskServiceClient } from "../protos/task_grpc_web_pb"; 2 | 3 | const grpcTaskClient = new TaskServiceClient("http://127.0.0.1:8080"); 4 | 5 | export { grpcTaskClient }; 6 | -------------------------------------------------------------------------------- /frontend/util/useOnceCall.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | function useOnceCall(cb: any, condition = true) { 4 | const isCalledRef = useRef(false); 5 | 6 | useEffect(() => { 7 | if (condition && !isCalledRef.current) { 8 | isCalledRef.current = true; 9 | cb(); 10 | } 11 | }, [cb, condition]); 12 | } 13 | 14 | export { useOnceCall }; 15 | -------------------------------------------------------------------------------- /generate_proto.sh: -------------------------------------------------------------------------------- 1 | # for backend 2 | grpc_tools_node_protoc --js_out=import_style=commonjs,binary:./backend --grpc_out=grpc_js:./backend ./protos/*.proto 3 | grpc_tools_node_protoc --ts_out=grpc_js:./backend ./protos/*.proto 4 | 5 | # for frontend 6 | grpc_tools_node_protoc -I=. ./protos/*.proto --js_out=import_style=commonjs:./frontend --grpc-web_out=import_style=commonjs+dts,mode=grpcwebtext:./frontend -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "realtime-task-management", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "backend": "cd backend && pnpm dev", 8 | "frontend": "cd frontend && pnpm dev", 9 | "gen-proto": "bash generate_proto.sh", 10 | "dev": "concurrently \"pnpm backend\" \"pnpm frontend\" " 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "concurrently": "^7.6.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | concurrently: ^7.6.0 5 | 6 | devDependencies: 7 | concurrently: 7.6.0 8 | 9 | packages: 10 | 11 | /ansi-regex/5.0.1: 12 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 13 | engines: {node: '>=8'} 14 | dev: true 15 | 16 | /ansi-styles/4.3.0: 17 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 18 | engines: {node: '>=8'} 19 | dependencies: 20 | color-convert: 2.0.1 21 | dev: true 22 | 23 | /chalk/4.1.2: 24 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 25 | engines: {node: '>=10'} 26 | dependencies: 27 | ansi-styles: 4.3.0 28 | supports-color: 7.2.0 29 | dev: true 30 | 31 | /cliui/8.0.1: 32 | resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} 33 | engines: {node: '>=12'} 34 | dependencies: 35 | string-width: 4.2.3 36 | strip-ansi: 6.0.1 37 | wrap-ansi: 7.0.0 38 | dev: true 39 | 40 | /color-convert/2.0.1: 41 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 42 | engines: {node: '>=7.0.0'} 43 | dependencies: 44 | color-name: 1.1.4 45 | dev: true 46 | 47 | /color-name/1.1.4: 48 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 49 | dev: true 50 | 51 | /concurrently/7.6.0: 52 | resolution: {integrity: sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw==} 53 | engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} 54 | hasBin: true 55 | dependencies: 56 | chalk: 4.1.2 57 | date-fns: 2.29.3 58 | lodash: 4.17.21 59 | rxjs: 7.5.7 60 | shell-quote: 1.7.4 61 | spawn-command: 0.0.2-1 62 | supports-color: 8.1.1 63 | tree-kill: 1.2.2 64 | yargs: 17.6.2 65 | dev: true 66 | 67 | /date-fns/2.29.3: 68 | resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} 69 | engines: {node: '>=0.11'} 70 | dev: true 71 | 72 | /emoji-regex/8.0.0: 73 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 74 | dev: true 75 | 76 | /escalade/3.1.1: 77 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 78 | engines: {node: '>=6'} 79 | dev: true 80 | 81 | /get-caller-file/2.0.5: 82 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 83 | engines: {node: 6.* || 8.* || >= 10.*} 84 | dev: true 85 | 86 | /has-flag/4.0.0: 87 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 88 | engines: {node: '>=8'} 89 | dev: true 90 | 91 | /is-fullwidth-code-point/3.0.0: 92 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 93 | engines: {node: '>=8'} 94 | dev: true 95 | 96 | /lodash/4.17.21: 97 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 98 | dev: true 99 | 100 | /require-directory/2.1.1: 101 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 102 | engines: {node: '>=0.10.0'} 103 | dev: true 104 | 105 | /rxjs/7.5.7: 106 | resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} 107 | dependencies: 108 | tslib: 2.4.1 109 | dev: true 110 | 111 | /shell-quote/1.7.4: 112 | resolution: {integrity: sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==} 113 | dev: true 114 | 115 | /spawn-command/0.0.2-1: 116 | resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} 117 | dev: true 118 | 119 | /string-width/4.2.3: 120 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 121 | engines: {node: '>=8'} 122 | dependencies: 123 | emoji-regex: 8.0.0 124 | is-fullwidth-code-point: 3.0.0 125 | strip-ansi: 6.0.1 126 | dev: true 127 | 128 | /strip-ansi/6.0.1: 129 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 130 | engines: {node: '>=8'} 131 | dependencies: 132 | ansi-regex: 5.0.1 133 | dev: true 134 | 135 | /supports-color/7.2.0: 136 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 137 | engines: {node: '>=8'} 138 | dependencies: 139 | has-flag: 4.0.0 140 | dev: true 141 | 142 | /supports-color/8.1.1: 143 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 144 | engines: {node: '>=10'} 145 | dependencies: 146 | has-flag: 4.0.0 147 | dev: true 148 | 149 | /tree-kill/1.2.2: 150 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 151 | hasBin: true 152 | dev: true 153 | 154 | /tslib/2.4.1: 155 | resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} 156 | dev: true 157 | 158 | /wrap-ansi/7.0.0: 159 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 160 | engines: {node: '>=10'} 161 | dependencies: 162 | ansi-styles: 4.3.0 163 | string-width: 4.2.3 164 | strip-ansi: 6.0.1 165 | dev: true 166 | 167 | /y18n/5.0.8: 168 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 169 | engines: {node: '>=10'} 170 | dev: true 171 | 172 | /yargs-parser/21.1.1: 173 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 174 | engines: {node: '>=12'} 175 | dev: true 176 | 177 | /yargs/17.6.2: 178 | resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} 179 | engines: {node: '>=12'} 180 | dependencies: 181 | cliui: 8.0.1 182 | escalade: 3.1.1 183 | get-caller-file: 2.0.5 184 | require-directory: 2.1.1 185 | string-width: 4.2.3 186 | y18n: 5.0.8 187 | yargs-parser: 21.1.1 188 | dev: true 189 | -------------------------------------------------------------------------------- /protos/task.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package task; 4 | 5 | message Task { 6 | int32 id = 1; 7 | string title = 2; 8 | string body = 3; 9 | string status = 4; 10 | } 11 | 12 | message TaskRequest { 13 | int32 id = 1; 14 | } 15 | 16 | message TaskResponse { 17 | Task task = 1; 18 | } 19 | 20 | message EmptyRequest{} 21 | message EmptyResponse{ 22 | string message = 1; 23 | } 24 | 25 | message TasksRequest {} 26 | 27 | message TasksResponse { 28 | repeated Task tasks = 1; 29 | } 30 | 31 | message AddTaskRequest { 32 | string title = 1; 33 | string body = 2; 34 | string status = 3; 35 | } 36 | 37 | message AddTaskResponse { 38 | Task task = 1; 39 | } 40 | 41 | message DeleteTaskRequest { 42 | int32 id = 1; 43 | } 44 | 45 | message DeleteTaskResponse { 46 | string message = 1; 47 | } 48 | 49 | message UpdateTaskRequest { 50 | Task task = 1; 51 | } 52 | 53 | message UpdateTaskResponse { 54 | Task task = 1; 55 | } 56 | 57 | 58 | 59 | service TaskService { 60 | rpc GetTask(TaskRequest) returns (TaskResponse) {}; 61 | rpc AddTask(AddTaskRequest) returns (AddTaskResponse) {}; 62 | rpc DeleteTask(DeleteTaskRequest) returns (DeleteTaskResponse) {}; 63 | rpc UpdateTask(UpdateTaskRequest) returns (UpdateTaskResponse) {}; 64 | rpc DeleteUnUsedConnections(EmptyRequest) returns (EmptyResponse) {}; 65 | 66 | rpc GetAllTasks(TasksRequest) returns (stream TasksResponse) {}; 67 | } -------------------------------------------------------------------------------- /rundoc.sh: -------------------------------------------------------------------------------- 1 | docker run -ti -p 8080:8080 -p 9901:9901 -v /$(pwd)/envoy.yaml:/etc/envoy/envoy.yaml --rm envoyproxy/envoy-alpine:v1.21-latest --------------------------------------------------------------------------------