├── .gitignore ├── ApplicationUI ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.tsx │ ├── components │ │ ├── AllChats.tsx │ │ ├── ChatBar.tsx │ │ ├── DisplayChat.tsx │ │ ├── LandingPage.tsx │ │ ├── NavBar.tsx │ │ ├── SearchUser.tsx │ │ ├── SignIn.tsx │ │ ├── SignUp.tsx │ │ └── TestNode.tsx │ ├── config │ │ └── SocketIns.ts │ ├── index.tsx │ └── styles │ │ ├── App.css │ │ ├── general.css │ │ └── index.css └── tsconfig.json ├── AuthServer ├── .gitignore ├── UserService.zip ├── UserService │ ├── .dockerignore │ ├── .gitignore │ ├── Dockerfile │ ├── index.ts │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── config │ │ │ └── connectDB.ts │ │ ├── controllers │ │ │ ├── signInController.ts │ │ │ └── signUpController.ts │ │ └── routes │ │ │ ├── GetUser.ts │ │ │ ├── userLogin.ts │ │ │ ├── userSignUp.ts │ │ │ └── validateUser.ts │ └── tsconfig.json └── package-lock.json ├── README.md ├── chatArch.png ├── chatserver ├── .gitignore ├── index.ts ├── package-lock.json ├── package.json ├── src │ ├── config │ │ ├── GetConnectedUser.ts │ │ └── SocketIns.ts │ └── routes │ │ ├── Group.ts │ │ └── OneToOne.ts └── tsconfig.json └── kafkaserver ├── .gitignore ├── config ├── ConnectDB.ts └── SchemaDB.ts ├── docker-compose.yml ├── index.ts ├── kafka ├── KafkaIns.ts ├── admin.ts ├── consumer.ts └── producer.ts ├── package-lock.json ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | helpers 2 | *.env -------------------------------------------------------------------------------- /ApplicationUI/.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /ApplicationUI/README.md: -------------------------------------------------------------------------------- 1 | # Distributed Chat application UI 2 | 3 | In the project directory, you can run: 4 | 5 | ### `npm start` 6 | 7 | 8 | -------------------------------------------------------------------------------- /ApplicationUI/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.17.0", 7 | "@testing-library/react": "^13.4.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "@types/dotenv": "^8.2.0", 10 | "@types/ioredis": "^5.0.0", 11 | "@types/jest": "^27.5.2", 12 | "@types/node": "^16.18.78", 13 | "@types/pg": "^8.11.0", 14 | "@types/react": "^18.2.51", 15 | "@types/react-dom": "^18.2.18", 16 | "@types/react-router-dom": "^5.3.3", 17 | "@types/socket.io-client": "^3.0.0", 18 | "dotenv": "^16.4.1", 19 | "ioredis": "^5.3.2", 20 | "jsonwebtoken": "^9.0.2", 21 | "pg": "^8.11.3", 22 | "react": "^18.2.0", 23 | "react-dom": "^18.2.0", 24 | "react-router-dom": "^6.21.3", 25 | "react-scripts": "5.0.1", 26 | "typescript": "^4.9.5", 27 | "util": "^0.12.5", 28 | "web-vitals": "^2.1.4" 29 | }, 30 | "scripts": { 31 | "start": "react-scripts start", 32 | "build": "react-scripts build", 33 | "test": "react-scripts test", 34 | "eject": "react-scripts eject" 35 | }, 36 | "eslintConfig": { 37 | "extends": [ 38 | "react-app", 39 | "react-app/jest" 40 | ] 41 | }, 42 | "browserslist": { 43 | "production": [ 44 | ">0.2%", 45 | "not dead", 46 | "not op_mini all" 47 | ], 48 | "development": [ 49 | "last 1 chrome version", 50 | "last 1 firefox version", 51 | "last 1 safari version" 52 | ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ApplicationUI/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/ApplicationUI/public/favicon.ico -------------------------------------------------------------------------------- /ApplicationUI/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ApplicationUI/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/ApplicationUI/public/logo192.png -------------------------------------------------------------------------------- /ApplicationUI/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/ApplicationUI/public/logo512.png -------------------------------------------------------------------------------- /ApplicationUI/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /ApplicationUI/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /ApplicationUI/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, Dispatch, SetStateAction, useEffect } from 'react'; 2 | import NavBar from './components/NavBar'; 3 | import LandingPage from './components/LandingPage'; 4 | import './styles/App.css'; 5 | import { ChatBar } from './components/ChatBar'; 6 | import { DisplayChat } from './components/DisplayChat'; 7 | import { Route,Routes } from 'react-router-dom'; 8 | import { SignIn } from './components/SignIn'; 9 | import { SignUp } from './components/SignUp'; 10 | import { AllChats } from './components/AllChats'; 11 | function App() { 12 | const [value, setValue]: [string, Dispatch>] = useState(""); 13 | const [displayVal, setDisplayVal]:any = useState([]); 14 | const [loginInfo, setLoginInfo] = useState({}); 15 | const [validated, setValidation ] = useState(false); 16 | const [token, setToken]:[string, Dispatch>] = useState(""); 17 | const [user, setUser]:[any,any] = useState(null); 18 | const [allChat, setAllChat] = useState({}); 19 | const [toUser, setToUser]:[any, any] = useState(null); 20 | const [emailMap , setEmailMap] = useState({}); 21 | useEffect(()=>{ 22 | let getUser = ()=>{ 23 | console.log("RAN"); 24 | fetch("http://localhost:4000/validateUser/",{ 25 | credentials:"include" // to send the httpOnly cookie to the server ; on the server end make sure Allow-credentials are true 26 | }).then((d)=>{ 27 | return d.json(); 28 | }) 29 | .then((d:any)=>{ 30 | console.log(d); 31 | if(d.user === undefined || d === null){ 32 | setToken(""); 33 | }else{ 34 | setUser(d.user); 35 | const currentUser = d.user; 36 | fetch("http://localhost:8000/findUser/",{ 37 | method: "POST", 38 | body: JSON.stringify({id:JSON.parse(d.user).id, email: JSON.parse(d.user).email}), 39 | credentials: "include", 40 | headers:{ 41 | 'content-type': 'application/json;charset=utf-8', 42 | } 43 | }).then((d)=>{ 44 | return d.json(); 45 | }) 46 | .then((d:any)=>{ 47 | let len = d.length; 48 | console.log("Data from mongo", d); 49 | const emailMaps:any = {}; 50 | const chatData:any = {} 51 | let tempDisplayChat = [] 52 | for(let i = 0;i{ 84 | console.error(ex); 85 | }); 86 | } 87 | }) 88 | .catch((ex)=>{ 89 | setToken(""); 90 | }); 91 | } 92 | if(user===null){ 93 | getUser(); 94 | } 95 | 96 | console.log("From useEffect ", displayVal, allChat, emailMap); 97 | },[toUser]); 98 | // var checkToken:()=>void = async ()=>{ 99 | // if(token === "") return false; 100 | // var data = await fetch("http://localhost:4000/protected",{ 101 | // method:"GET", 102 | // headers:{ 103 | // authorization : "Bearer-" + token, 104 | // content-type: 'application/json;charset=utf-8' 105 | // } 106 | // // }); 107 | // if(data.status === 200 || data.status === 201) setValidation(true); 108 | // else setValidation(false); 109 | // } 110 | // } 111 | 112 | return ( 113 | 114 | } /> 115 | 117 | 118 |
119 | 120 | 124 |
125 | 126 | } /> 127 | }/> 129 | }/> 130 | }/> 131 | 132 |
133 | ); 134 | } 135 | 136 | export default App; 137 | -------------------------------------------------------------------------------- /ApplicationUI/src/components/AllChats.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { SearchUser } from "./SearchUser"; 3 | import { useNavigate } from "react-router-dom"; 4 | import '../styles/general.css'; 5 | import NavBar from "./NavBar"; 6 | var AllChats = (props:any) => { 7 | const navigate = useNavigate(); 8 | useEffect(()=>{ 9 | if(props.user === null){ 10 | navigate("/signIn"); 11 | } 12 | return ()=>{ 13 | console.log("Allchat deloaded"); 14 | //props.setToUser(null); 15 | } 16 | },[]); 17 | const indexedObjs = props.allChat; 18 | let val = []; 19 | let handleSelectUser = (e:any) => { 20 | e.preventDefault(); 21 | //props.setToUser(null); 22 | console.warn(e.target.textContent); 23 | console.log(props.emailMap); 24 | const currEmail:string = props.emailMap[e.target.textContent]; 25 | props.setToUser({email: currEmail, username: e.target.textContent}); 26 | console.log(props.toUser); 27 | navigate("/easdasdasdasifnjsnfjkadsnkjasbdajskdbhasdhasdasd"); 28 | 29 | } 30 | console.log(indexedObjs); 31 | for(const [key, value ] of Object.entries(indexedObjs)){ 32 | const name:string = key; 33 | //console.log(key,value); 34 | val.push(name); 35 | } 36 | if(val.length>0){ 37 | return ( 38 | <> 39 | 40 | { val.map((value:string,index:number) => ( 41 | <> 42 |
43 |
44 |

{value}


45 |
46 |
47 | 48 | )) 49 | } 50 | 51 | ); 52 | }else{ 53 | return( 54 |
55 | ) 56 | } 57 | }; 58 | export {AllChats}; -------------------------------------------------------------------------------- /ApplicationUI/src/components/ChatBar.tsx: -------------------------------------------------------------------------------- 1 | import { socket } from "../config/SocketIns"; 2 | import React, { useEffect, Dispatch, SetStateAction, useState } from "react"; 3 | import '../styles/general.css'; 4 | import { useNavigate } from "react-router-dom"; 5 | import { SearchUser } from "./SearchUser"; 6 | type chatBarType = { 7 | value: string, 8 | setValue: Dispatch>, 9 | displayVal: any, // string [] 10 | setDisplayVal: any, 11 | validated:boolean, 12 | user: any, 13 | token:string, 14 | toUser:any, 15 | setToUser:any 16 | } 17 | const ChatBar = (props:chatBarType) => { 18 | //const [value, setValue]: [string, Dispatch>] = useState(""); 19 | const toUser = props.toUser; 20 | const setToUser = props.setToUser; 21 | const navigate = useNavigate(); 22 | useEffect(()=>{ 23 | console.log("Chat Use Effect Ran with to User: ", toUser); 24 | if(props.user===undefined || props.user === null){ 25 | navigate("/signIn"); 26 | }else if(JSON.parse(props.user).email!==undefined){ 27 | socket.auth = {email : JSON.parse(props.user).email} ; 28 | //if(socket.connected === true) socket.disconnect(); 29 | socket.connect(); 30 | const sockI:any = socket.id; 31 | //redisS.set(JSON.parse(props.user).email, sockI); 32 | socket.on("send-message-server",(msg:any)=>{ 33 | console.log("Sent from server, " ,msg); 34 | props.setDisplayVal((displayVal:any)=>{ 35 | return [...displayVal,{message:msg.message, email:msg.receiverId, fromemail: msg.email} ]; 36 | }); 37 | }); 38 | return ()=>{ 39 | socket.disconnect(); 40 | socket.off("send-message-server"); 41 | } 42 | } 43 | },[]); 44 | let onChangeHandler:(a:any)=> void = (e:any):void => { 45 | e.preventDefault(); 46 | props.setValue(e.target.value); 47 | } 48 | let onSubmitHandler:(e:any)=>Promise = async(e: any): Promise => { 49 | e.preventDefault(); 50 | // we have to add the sender and recover userID 51 | if((props.user!==null || props.user!==undefined) && toUser!==null ){ 52 | const sockId:any = "asd"; 53 | if(JSON.parse(props.user).email!== undefined){ 54 | console.log(toUser); 55 | socket.auth = JSON.parse(props.user).email; 56 | socket.emit("send-message",{senderId: JSON.parse(props.user).id, tousername: toUser.username, fromusername: JSON.parse(props.user).username, email: JSON.parse(props.user).email, receiverId: toUser.email, message:props.value}); 57 | }else{ 58 | //navigate("/errorRoute"); 59 | } 60 | } 61 | if (props.value === "" || toUser.email === undefined) return; 62 | props.setDisplayVal( (displayVal:any) => {return [...displayVal, {message: props.value,email:toUser.email, fromemail: JSON.parse(props.user).email}]}); 63 | 64 | console.log(props.displayVal); 65 | props.setValue(""); 66 | 67 | } 68 | if(toUser===null){ 69 | return (<> 70 | 71 | 72 | ); 73 | } 74 | return ( 75 |
76 |
77 | 78 | 79 | 80 | 81 |
82 |
83 | ) 84 | } 85 | export { ChatBar }; 86 | -------------------------------------------------------------------------------- /ApplicationUI/src/components/DisplayChat.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import '../styles/general.css'; 3 | import { TextNode } from "./TestNode"; 4 | type displayPropsType = { 5 | user:any, 6 | valueList: any, 7 | toUserName: string, 8 | toUser:any, 9 | setToUser: any 10 | } 11 | const DisplayChat = (props: displayPropsType) => { 12 | console.log(props.valueList); 13 | 14 |

{ props.toUserName}

15 | if(props.valueList === undefined || props.valueList.length === 0 || props.toUser===undefined || props.toUser === null || props.user === null) return (
); 16 | return ( 17 | <> 18 | { 19 | props.valueList.map((value:any, index:number) => { 20 | if(value.email === props.toUser.email && value.fromemail === JSON.parse(props.user).email){ 21 | return ( 22 |
23 | 24 |
25 | ); 26 | }else if(value.email === JSON.parse(props.user).email && value.fromemail === props.toUser.email ){ 27 | return ( 28 |
29 | 30 |
31 | ); 32 | }else{ 33 | return(
); 34 | } 35 | }) 36 | 37 | } 38 | 39 | ) 40 | } 41 | export { DisplayChat }; -------------------------------------------------------------------------------- /ApplicationUI/src/components/LandingPage.tsx: -------------------------------------------------------------------------------- 1 | import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | 4 | var LandingPage = (props:{validated:boolean, user:any}) => { 5 | const [time, setTime]: [string, Dispatch>] = useState(new Date().toLocaleTimeString()); 6 | const navigate = useNavigate(); 7 | useEffect(() => { 8 | if(props.user === null || props.user===undefined){ 9 | navigate("/signIn"); 10 | }else{ 11 | setInterval(() => { 12 | setTime(new Date().toLocaleTimeString()); 13 | }, 1000); 14 | } 15 | },[]); 16 | return ( 17 |
18 |
19 |

{time}

20 |
21 |
22 |
23 | Welcome to @AlgoChat 24 |

25 |
26 |
27 | ) 28 | } 29 | export default LandingPage -------------------------------------------------------------------------------- /ApplicationUI/src/components/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import '../styles/general.css'; 4 | var NavBar = (props:any) => { 5 | var comp = ""; 6 | if(props.user!==null && props.user!==undefined){ 7 | console.log(props.user); 8 | comp = JSON.parse(props.user).username; 9 | } 10 | return ( 11 |
12 |

Home

13 |

Chat

14 |

SignIn

15 |

SignUp

16 |

{comp}

17 |
18 | ) 19 | } 20 | export default NavBar; -------------------------------------------------------------------------------- /ApplicationUI/src/components/SearchUser.tsx: -------------------------------------------------------------------------------- 1 | // search bar calling user 2 | import React, { Dispatch, SetStateAction, useState } from "react"; 3 | import '../styles/general.css'; 4 | import { useNavigate } from "react-router-dom"; 5 | type userType = { 6 | toUser: Object, 7 | setToUser:Dispatch> 8 | } 9 | var SearchUser = (props:userType)=>{ 10 | const [text, setText]: [string, Dispatch>] = useState(""); 11 | const navigate = useNavigate(); 12 | function handleSearch(e:any){ 13 | e.preventDefault(); 14 | fetch("http://localhost:4000") 15 | .then((d)=>{ 16 | if(d.status === 201 || d.status === 200){ 17 | const firstName = text.split(" ")[0]; 18 | fetch("http://localhost:4000/getUser/",{ 19 | method: "POST", 20 | body:JSON.stringify({"firstName":firstName}), 21 | headers: { 22 | 'content-type': 'application/json;charset=utf-8', 23 | // if not added server doesn't catch the req.body 24 | } 25 | }).then((d:any)=>{ 26 | return d.json(); 27 | }) 28 | .then((d:any)=>{ 29 | const payload = JSON.parse(d.msg); 30 | props.setToUser(payload); 31 | console.log(payload); 32 | let link = "/easdasdasdasifnjsnfjkadsnkjasbdajskdbhasdhasdasd"; 33 | navigate(link); 34 | }) 35 | .catch((e)=>{ 36 | console.log(e); 37 | //navigate("/authError") 38 | }); 39 | } 40 | }) 41 | .catch((e)=>{ 42 | console.log("Error connecting to the auth server"); 43 | }) 44 | } 45 | return ( 46 |
47 | setText(e.target.value)}/> 48 | 49 |
50 | ) 51 | } 52 | export {SearchUser}; -------------------------------------------------------------------------------- /ApplicationUI/src/components/SignIn.tsx: -------------------------------------------------------------------------------- 1 | import React, { Dispatch, SetStateAction, useState, useEffect } from "react"; 2 | import '../styles/general.css'; 3 | import { useNavigate } from "react-router-dom"; 4 | const SignIn = (props:any) => { 5 | const [email, setEmail ]: [string, Dispatch>] = useState(""); 6 | const [password, setPassword]: [string, Dispatch>] = useState(""); 7 | useEffect(()=>{ 8 | if(props.user ===null || props.user === undefined){ 9 | navigate("/"); 10 | } 11 | },[]); 12 | const navigate = useNavigate(); 13 | let onSubmit = (e:any)=>{ 14 | e.preventDefault(); 15 | fetch("http://localhost:4000/validateUser/",{ 16 | credentials:"include" // to send the httpOnly cookie to the server ; on the server end make sure Allow-credentials are true 17 | }) 18 | .then((d)=>{ 19 | //console.log("Some data: ",d); 20 | return d.json(); 21 | }) 22 | .then((resp:any )=>{ 23 | console.log("Some data: ",resp); 24 | if(resp.user === undefined || resp.user === null){ 25 | fetch("http://localhost:4000/api/signIn/",{ 26 | method: "POST", 27 | body:JSON.stringify({"email":email, "password":password}), 28 | credentials: 'include', 29 | headers: { 30 | "content-type": 'application/json;charset=utf-8', 31 | // if not added server doesn't catch the req.body 32 | } 33 | }).then((d:any)=>{ 34 | return d.json(); 35 | }) 36 | .then((d:any)=>{ 37 | // props.setLoginInfo(d); 38 | // props.setToken(d.accesstoken); 39 | // blacklistServer.setex(email+"ACC",d.accesstoken,15,()=>{ 40 | // console.log("Access token Updated in database"); 41 | // }); 42 | // blacklistServer.setex(email+"REF",d.refreshtoken, 15,()=>{ 43 | // console.log("Refresh token updated"); 44 | // }); 45 | props.setToken(d.refreshtoken); 46 | navigate("/"); 47 | }) 48 | .catch((e)=>{ 49 | console.log(e); 50 | //navigate("/authError") 51 | }); 52 | }else{ 53 | props.setUser(resp.user); 54 | navigate("/"); 55 | } 56 | }) 57 | .catch((e)=>{ 58 | console.log("Error connecting to the auth server: ",e); 59 | }) 60 | } 61 | var redirectSignUp = (e:any)=>{ 62 | e.preventDefault(); 63 | navigate("/signUp"); 64 | } 65 | return ( 66 |
67 |
SignIn
68 |
69 | setEmail(e.target.value)} placeholder="Enter your email"/>
70 | setPassword(e.target.value)} placeholder="Enter your password"/>
71 | 72 | 73 | 74 | 75 |
76 |
77 | ) 78 | } 79 | export { SignIn }; -------------------------------------------------------------------------------- /ApplicationUI/src/components/SignUp.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import '../styles/general.css'; 3 | import { useNavigate } from "react-router-dom"; 4 | const SignUp = () => { 5 | const [firstName, setFirstName] = useState(""); 6 | const [lastName, setLastName] = useState(""); 7 | const [email, setEmail] = useState(""); 8 | const [password, setPassword] = useState(""); 9 | const [confirmPassword, setConfirm] = useState(""); 10 | const [phone, setPhone] = useState(""); 11 | const navigate = useNavigate(); 12 | let onSubmit = async(e:any)=>{ 13 | e.preventDefault(); 14 | let payload: string = JSON.stringify({ 15 | firstname : firstName, 16 | lastname: lastName, 17 | phone: phone, 18 | email : email, 19 | password : password, 20 | confirmpass : confirmPassword 21 | }); 22 | 23 | var data:any = await fetch("http://localhost:4000/api/signUp/",{ 24 | method: "POST", 25 | body:payload, 26 | headers: { 27 | 'content-type': 'application/json;charset=utf-8' 28 | } 29 | 30 | }); 31 | if(data.status === 200 || data.status === 201){ 32 | navigate("/signin"); 33 | } 34 | } 35 | return ( 36 |
37 |
SignUp
38 |
39 | setFirstName(e.target.value)} placeholder="Enter your FirstName"/>
40 | setLastName(e.target.value)} placeholder="Enter your LastName"/>
41 | setEmail(e.target.value)} placeholder="Enter your email"/>
42 | setPhone(e.target.value)} placeholder="Enter your Phone no"/>
43 | setPassword(e.target.value)} placeholder="Enter your password"/>
44 | setConfirm(e.target.value)} placeholder="Confirm Password"/>
45 | 46 |
47 |
48 | ) 49 | } 50 | export { SignUp }; -------------------------------------------------------------------------------- /ApplicationUI/src/components/TestNode.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import '../styles/general.css'; 3 | type stylePropType = { 4 | value: string 5 | } 6 | 7 | var TextNode = (props: stylePropType)=>{ 8 | var styleTag:string, outerShape:string; 9 | if(props.value!=="" && props.value[0] === '1'){ 10 | styleTag = "display-chat2"; 11 | outerShape = "outer-shape2"; 12 | }else{ 13 | styleTag = "display-chat1"; 14 | outerShape = "outer-shape1"; 15 | } 16 | return ( 17 |
18 |
19 |

{props.value.slice(1)}

20 |
21 |
22 | ) 23 | } 24 | export {TextNode}; -------------------------------------------------------------------------------- /ApplicationUI/src/config/SocketIns.ts: -------------------------------------------------------------------------------- 1 | import { io } from "socket.io-client"; 2 | 3 | export const socket = io('http://localhost:5000',{autoConnect:false}); -------------------------------------------------------------------------------- /ApplicationUI/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './styles/index.css'; 4 | import App from './App'; 5 | import { BrowserRouter } from 'react-router-dom'; 6 | const root = ReactDOM.createRoot( 7 | document.getElementById('root') as HTMLElement 8 | ); 9 | root.render( 10 | 11 | 12 | 13 | 14 | 15 | ); -------------------------------------------------------------------------------- /ApplicationUI/src/styles/App.css: -------------------------------------------------------------------------------- 1 | *{ 2 | text-decoration: none; 3 | } 4 | a:link{ 5 | text-decoration: none; 6 | color:none; 7 | } 8 | a:visited{ 9 | text-decoration: none; 10 | } -------------------------------------------------------------------------------- /ApplicationUI/src/styles/general.css: -------------------------------------------------------------------------------- 1 | .navbar{ 2 | display:flex; 3 | justify-content: left; 4 | margin:19px; 5 | padding:10px; 6 | border:3px; 7 | width:97%; 8 | align-items: center; 9 | background-color: rgb(239, 243, 218); 10 | height: 66px; 11 | border-radius: 210px; 12 | gap:70px; 13 | } 14 | .display-container{ 15 | display: flex; 16 | margin:10px,27px,10px,27px; 17 | padding:10px; 18 | } 19 | .main-text{ 20 | display:flex; 21 | justify-content: center; 22 | align-items: center; 23 | } 24 | .header{ 25 | display:block; 26 | margin:10%; 27 | font-family:'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 28 | font-size: 70px; 29 | font-weight:500 ; 30 | } 31 | .sec-header{ 32 | font-family: 'Times New Roman', Times, serif; 33 | font-size: 17px; 34 | font-weight: 500; 35 | } 36 | .time-data{ 37 | display:flex; 38 | margin-left: auto; 39 | margin:30px; 40 | padding:20px; 41 | border:10px; 42 | font-family: Arial, Helvetica, sans-serif; 43 | font-weight: 400; 44 | font-style: italic; 45 | } 46 | .display-chat1{ 47 | margin:3%; 48 | padding:1%; 49 | margin-right: auto; 50 | } 51 | .SignIn{ 52 | text-align: center; 53 | display: hidden; 54 | font-size: 45px; 55 | font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; 56 | padding:10px; 57 | margin:7px; 58 | } 59 | .display-chat2{ 60 | margin:3%; 61 | padding:1%; 62 | margin-left: auto; 63 | } 64 | .username{ 65 | display:block; 66 | font-size:23px; 67 | font-family: Arial, Helvetica, sans-serif; 68 | font-weight: 800; 69 | font-style: italic; 70 | justify-content: right; 71 | text-decoration: solid; 72 | margin-left: auto; 73 | } 74 | .search-comp{ 75 | position:relative; 76 | top:40%; 77 | display:flex; 78 | justify-content: center; 79 | } 80 | .search-bar{ 81 | height:20%; 82 | width:55%; 83 | display:block; 84 | justify-content: center; 85 | border-radius: 30px; 86 | margin:5px; 87 | padding:16px; 88 | } 89 | .search-btn{ 90 | height:40px; 91 | width:90px; 92 | background-color: rgba(3, 236, 34, 0.6); 93 | display: flex; 94 | align-items: center; 95 | justify-content: center; 96 | padding:15px; 97 | border-radius: 30px; 98 | margin:5px; 99 | font-size: large; 100 | font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 101 | font-weight: 700; 102 | } 103 | .signin-btn{ 104 | cursor: pointer; 105 | justify-content: center; 106 | position:relative; 107 | left:40%; 108 | border-radius: 15px; 109 | background-color: rgb(58, 235, 117); 110 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 111 | font-weight: 600; 112 | font-size: large; 113 | width:75px; 114 | height:45px; 115 | gap:10px; 116 | margin:5px; 117 | } 118 | .signup-btn{ 119 | cursor: pointer; 120 | justify-content: center; 121 | position:relative; 122 | left:40%; 123 | border-radius: 15px; 124 | background-color: rgb(235, 64, 64); 125 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 126 | font-weight: 600; 127 | font-size: large; 128 | width:75px; 129 | height:45px; 130 | } 131 | .singInForm{ 132 | position:absolute; 133 | top:23%; 134 | left:29%; 135 | justify-content: center; 136 | align-items: center; 137 | } 138 | .signin-inp{ 139 | width:720px; 140 | height:20px; 141 | padding:20px; 142 | margin:20px; 143 | border-width: 3px; 144 | border-radius: 100px; 145 | font-family: 'Times New Roman', Times, serif; 146 | font-size: 20px; 147 | } 148 | .chat-bar{ 149 | width: 100%; 150 | border-width: 3px; 151 | color:black; 152 | margin:10px,27px,10px,5px; 153 | } 154 | .ele-home{ 155 | display:flex; 156 | margin:10px; 157 | border: 10px; 158 | } 159 | .actual-text{ 160 | padding:20px; 161 | margin:30px; 162 | } 163 | .outer-shape1{ 164 | border-radius: 70px; 165 | margin:10px; 166 | padding:10px; 167 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 168 | font-size: 20px; 169 | background-color: rgb(13, 249, 92,0.8); 170 | color:black 171 | } 172 | .outer-shape2{ 173 | border-radius: 70px; 174 | margin:10px; 175 | padding:10px; 176 | font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; 177 | font-size: 20px; 178 | background-color: rgba(201, 226, 223, 0.863); 179 | color:black 180 | } 181 | .ChatNames{ 182 | margin:10px; 183 | font-size: 30px; 184 | font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; 185 | font-weight: 600; 186 | position:relative; 187 | display: block; 188 | justify-content: center; 189 | } 190 | .ChatName{ 191 | cursor: pointer; 192 | margin:10px; 193 | font-size: 30px; 194 | font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; 195 | font-weight: 600; 196 | position:relative; 197 | display: block; 198 | justify-content: center; 199 | } 200 | .ele-chat{ 201 | display:flex; 202 | gap:12px; 203 | border:10px; 204 | margin:10px; 205 | } 206 | .ele-signin{ 207 | display:flex; 208 | gap:12px; 209 | border:10px; 210 | margin:10px; 211 | } 212 | .ele-singup{ 213 | display:flex; 214 | gap:12px; 215 | border:10px; 216 | margin:10px; 217 | } 218 | .chat-comp{ 219 | position:fixed; 220 | top:93%; 221 | left:0.2%; 222 | margin-bottom: auto; 223 | margin: 10px; 224 | padding:10px; 225 | width:100%; 226 | justify-content: center; 227 | align-content: center; 228 | } 229 | .input-box{ 230 | border-radius: 220px; 231 | width: 91%; 232 | height:20px; 233 | border-width:4px; 234 | padding:10px; 235 | } 236 | .send-button{ 237 | padding:6px; 238 | margin:5px; 239 | border-radius: 6px; 240 | height:40px; 241 | width:80px; 242 | background-color:yellow; 243 | font-family: lobo,sans-serif; 244 | text-shadow: 1px; 245 | font-weight: 600; 246 | } 247 | -------------------------------------------------------------------------------- /ApplicationUI/src/styles/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /ApplicationUI/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /AuthServer/.gitignore: -------------------------------------------------------------------------------- 1 | UserService/node_modules/* 2 | -------------------------------------------------------------------------------- /AuthServer/UserService.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/AuthServer/UserService.zip -------------------------------------------------------------------------------- /AuthServer/UserService/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /AuthServer/UserService/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.env -------------------------------------------------------------------------------- /AuthServer/UserService/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | RUN npm install 5 | COPY . . 6 | EXPOSE 4000 7 | CMD ["npm","start"] 8 | 9 | 10 | -------------------------------------------------------------------------------- /AuthServer/UserService/index.ts: -------------------------------------------------------------------------------- 1 | import express, {Request, Response} from 'express'; 2 | 3 | import os from 'os'; 4 | import cluster from 'cluster'; 5 | import { signUpRoute } from './src/routes/userSignUp'; 6 | import { signInRoute } from './src/routes/userLogin'; 7 | import cors from 'cors'; 8 | import 'dotenv/config'; 9 | import helmet from 'helmet'; 10 | import cookieParser from "cookie-parser"; 11 | import { validateUser } from './src/helpers/helper'; 12 | const app = express(); 13 | app.use(express.json()); 14 | app.use(cors({ 15 | origin:'http://localhost:3000', 16 | credentials:true 17 | })); 18 | app.use(helmet()); 19 | app.use(cookieParser()); 20 | import "dotenv/config"; 21 | import jwt from 'jsonwebtoken'; 22 | import { getUser } from './src/routes/GetUser'; 23 | const accessSecretKey:any = process.env.ACCESS; 24 | const refreshSecretKey:any = process.env.REFRESH; 25 | const PORT = process.env.PORT || '3000'; 26 | app.get("/", (req: any, res: any) => { 27 | res.status(201).send({ 28 | 'message': `Welcome to User Service of the chat app ${process.pid}`, 29 | 'status': 201 30 | }); 31 | }); 32 | app.get("/validateUser/",(req:Request, res:Response)=>{ 33 | //console.log(req.headers); 34 | //const authToken:any = req.headers.authorization; // replace with cookies 35 | const cookies:any = req.headers.cookie; 36 | //console.log(cookies); 37 | if(cookies === undefined){ 38 | res.set("Access-Control-Allow-Credentials", 'true'); 39 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 40 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 41 | res.status(201).send({ 42 | 'msg':"Token not sent" 43 | }); 44 | return ; 45 | } 46 | const allCookies = cookies.split(";"); 47 | var accessT:any, refreshT:any; 48 | for(const a of allCookies){ 49 | if(a.split("=")[0]==='refreshtoken'){ 50 | refreshT = a.split("=")[1]; 51 | } 52 | } 53 | //console.log(refreshT); 54 | 55 | //console.log(refreshT); 56 | //console.log("AccessToken: ",accessT); 57 | //console.log("RefreshToken: ", refreshT); 58 | //console.log("Auth Token: ", authToken); 59 | //console.log(cookies.split(";").length); 60 | try{ 61 | if (refreshT!==undefined){ 62 | const data = jwt.verify(refreshT, refreshSecretKey); 63 | //console.log("JWt body: ", data); 64 | const accessToken = jwt.sign(data, accessSecretKey); 65 | res.cookie('accessToken', accessToken, {httpOnly: true}); 66 | res.set("Access-Control-Allow-Credentials", 'true'); 67 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 68 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 69 | res.status(201).send({ 70 | user : JSON.stringify(data) 71 | }); 72 | }else{ 73 | res.set("Access-Control-Allow-Credentials", 'true'); 74 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 75 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 76 | res.status(403).send({ 77 | 'msg':"Forbidden: Not Authorized" 78 | }); 79 | } 80 | }catch(ex){ 81 | console.log("JWT ERROR: ",ex) 82 | res.set("Access-Control-Allow-Credentials", 'true'); 83 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 84 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 85 | res.status(403).send({ 86 | 'msg':"Forbidden: Not Authorized" 87 | }); 88 | } 89 | return ; 90 | 91 | }); 92 | const cpuCounts = Math.min(os.cpus().length, 4); 93 | app.use(getUser); 94 | app.use(signInRoute); 95 | app.use(signUpRoute); 96 | if (cluster.isPrimary) { 97 | for (let i = 0; i < cpuCounts; i++) { 98 | cluster.fork(); 99 | } 100 | } else { 101 | app.listen(PORT, () => { 102 | console.log(`[+] Server Connected on PORT: ${PORT} and processID : ${process.pid}`); 103 | }); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /AuthServer/UserService/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "userservice", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "ts-node-dev index.ts" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@types/bcrypt": "^5.0.2", 15 | "@types/cookie-parser": "^1.4.6", 16 | "@types/cors": "^2.8.17", 17 | "@types/dotenv": "^8.2.0", 18 | "@types/express": "^4.17.21", 19 | "@types/helmet": "^4.0.0", 20 | "@types/jsonwebtoken": "^9.0.5", 21 | "@types/pg": "^8.10.9", 22 | "@types/randomstring": "^1.1.11", 23 | "bcrypt": "^5.1.1", 24 | "cookie-parser": "^1.4.6", 25 | "cors": "^2.8.5", 26 | "dot-env": "^0.0.1", 27 | "dotenv": "^16.3.2", 28 | "express": "^4.18.2", 29 | "helmet": "^7.1.0", 30 | "jsonwebtoken": "^9.0.2", 31 | "pg": "^8.11.3", 32 | "randomstring": "^1.3.0", 33 | "ts-node-dev": "^2.0.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /AuthServer/UserService/src/config/connectDB.ts: -------------------------------------------------------------------------------- 1 | import { Client } from 'pg'; 2 | import 'dotenv/config'; 3 | var connectionString: string | undefined = process.env.DB_URI; 4 | var client = new Client({ 5 | connectionString: connectionString, 6 | }); 7 | try { 8 | client.connect() 9 | .then(() => { 10 | console.log('[+] Postgres DB Connected'); 11 | }).catch((err: any) => { 12 | console.log(`Error : ${err}`); 13 | }); 14 | } catch(Ex) { 15 | 16 | } 17 | 18 | export default client; 19 | -------------------------------------------------------------------------------- /AuthServer/UserService/src/controllers/signInController.ts: -------------------------------------------------------------------------------- 1 | import client from "../config/connectDB"; 2 | import bcrypt from 'bcrypt'; 3 | import jwt from 'jsonwebtoken'; 4 | import 'dotenv/config'; 5 | import { Request, Response } from "express"; 6 | var signIn = (req: Request, res: Response) => { 7 | const accessSecretKey: any = process.env.ACCESS; 8 | const refreshSecretKey:any = process.env.REFRESH; 9 | const email = req.body.email; 10 | const password = req.body.password; 11 | if (res.locals.userExists === false) { 12 | res.status(401).send({ 13 | 'message': 'User doesn"t exists ', 14 | 'status': 401 15 | }); 16 | return; 17 | } 18 | client.query('SELECT Id, firstname, lastname, phone, email, password from users WHERE email = $1', [email]) 19 | .then((d) => { 20 | const userData = d.rows[0]; 21 | userData["username"] = userData.firstname + ' '+userData.lastname; 22 | //console.log(userData); 23 | bcrypt.compare(password, userData.password) 24 | .then((result) => { 25 | if (result == false) { 26 | res.status(403).send({ "msg": "Wrong Password" }); 27 | return; 28 | } else { 29 | const accesstoken = jwt.sign({ 30 | id: userData.id, 31 | email: userData.email, 32 | username : userData.username 33 | }, accessSecretKey, { expiresIn: '15m' }); // accessSecretJet is used for frequent accessTokens 34 | const refreshToken = jwt.sign({ 35 | id: userData.id, 36 | email:userData.email, 37 | username: userData.username 38 | }, refreshSecretKey, { expiresIn: '1d'}); // refreshtoken is used for regeneration of freq accessToken 39 | delete userData['password']; 40 | res.cookie("accesstoken",accesstoken,{ 41 | httpOnly:true, 42 | maxAge: 9000 43 | }); 44 | res.cookie("refreshtoken",refreshToken,{ 45 | httpOnly:true, 46 | maxAge: 1900000 47 | }); 48 | res.set("Access-Control-Allow-Credentials", 'true'); 49 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 50 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 51 | 52 | res.status(201).send({ 53 | 'refreshtoken': refreshToken, 54 | 'accesstoken': accesstoken, 55 | 'userId': userData.username, 56 | 'message': 'Successfully login', 57 | 'status': 201, 58 | 'data': userData 59 | }); 60 | } 61 | }).catch((ex) => { 62 | console.log(`Error in logging in ${ex}`); 63 | res.status(501).send({ 64 | 'message': 'Some Error occurred', 65 | 'status': 501 66 | }); 67 | }); 68 | }).catch((e) => { 69 | console.log(`Error: ${e}`); 70 | res.status(501).send({ 71 | 'message': 'Some Error occurred', 72 | 'status': 501 73 | }); 74 | }); 75 | } 76 | export { signIn }; -------------------------------------------------------------------------------- /AuthServer/UserService/src/controllers/signUpController.ts: -------------------------------------------------------------------------------- 1 | import client from "../config/connectDB"; 2 | import bcrypt from 'bcrypt'; 3 | var signUp = (req: any, res: any) => { 4 | const saltRounds = 10; 5 | const firstName: string = req.body.firstname; 6 | const lastName:string = req.body.lastname; 7 | const email:string = req.body.email; 8 | const password:string = req.body.password; 9 | const confirmPass:string = req.body.confirmpass; 10 | const phone: string = req.body.phone; 11 | if (res.locals.userExists == true) { 12 | res.status(404).send({ 13 | 'message': 'USER Already exists with the email', 14 | 'status':401 15 | }); 16 | return; 17 | } 18 | if (password != confirmPass) { 19 | res.status(404).send({ 20 | 'message': "Password didn't matched", 21 | 'status':401 22 | }); 23 | return; 24 | } 25 | bcrypt.hash(password, saltRounds) 26 | .then(( hashPass ) => { 27 | let listData = [firstName, lastName, email, hashPass, phone]; 28 | client.query('INSERT INTO users ( firstname , lastname , email, password, phone) VALUES($1, $2, $3, $4, $5)', listData) 29 | .then((d) => { 30 | console.log("Data Inserted Successfully "); 31 | res.status(201).send({ 'message': 'SUCCESS', 'status': 201 }); 32 | return ; 33 | }).catch((err) => { 34 | console.log(`Error in inserting data ${err}`); 35 | res.status(501).send({ 36 | 'message': 'Some Error occurred', 37 | 'status': 501 38 | }); 39 | return ; 40 | }); 41 | }).catch((err) => { 42 | console.log(`Error : ${err}`); 43 | res.status(501).send({ 44 | 'message': 'Some Error occurred', 45 | 'status': 501 46 | }); 47 | return ; 48 | }); 49 | } 50 | export { signUp }; -------------------------------------------------------------------------------- /AuthServer/UserService/src/routes/GetUser.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from 'express'; 2 | import { getUserInfoByFirstName, getUserInfoByEmail } from '../helpers/helper'; 3 | var getUser = express.Router(); 4 | getUser.post('/getUser', getUserInfoByFirstName ,(req:Request, res:Response)=>{ 5 | if(res.locals.user.length==0){ 6 | res.status(401).send({ 7 | 'msg':"No user found" 8 | }); 9 | }else{ 10 | res.status(200).send({ 11 | 'msg':JSON.stringify(res.locals.user[0]) 12 | }); 13 | } 14 | }); 15 | getUser.post('/getUserByEmail', getUserInfoByEmail ,(req:Request, res:Response)=>{ 16 | if(res.locals.userEmail.length==0){ 17 | res.status(401).send({ 18 | 'msg':"No user found" 19 | }); 20 | }else{ 21 | res.status(200).send({ 22 | 'msg':JSON.stringify(res.locals.userEmail[0]) 23 | }); 24 | } 25 | }); 26 | export {getUser}; -------------------------------------------------------------------------------- /AuthServer/UserService/src/routes/userLogin.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from 'express'; 2 | import { signIn} from '../controllers/signInController'; 3 | import { checkUser, validateUser } from '../helpers/helper'; 4 | var signInRoute = express.Router(); 5 | signInRoute.get("/protected",validateUser,(req:Request, res:Response)=>{ 6 | if(res.locals.validated === false){ 7 | res.status(403).send({ 8 | 'msg':'Not Validated' 9 | }); 10 | }else{ 11 | res.status(200).send({ 12 | 'msg':'Validated' 13 | }) 14 | } 15 | }); 16 | signInRoute.post('/api/signIn/',checkUser,signIn); 17 | export { signInRoute }; 18 | -------------------------------------------------------------------------------- /AuthServer/UserService/src/routes/userSignUp.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { checkUser, validateUser } from '../helpers/helper'; 3 | import { signUp } from '../controllers/signUpController'; 4 | var signUpRoute = express.Router(); 5 | signUpRoute.post('/api/signUp/', checkUser, signUp); 6 | export {signUpRoute}; -------------------------------------------------------------------------------- /AuthServer/UserService/src/routes/validateUser.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, Router } from "express"; 2 | import "dotenv/config"; 3 | import jwt from 'jsonwebtoken'; 4 | const accessSecretKey:any = process.env.ACCESS; 5 | const refreshSecretKey:any = process.env.REFRESH; 6 | const validationRoute = Router(); 7 | validationRoute.get("/validateUser/",(req:Request, res:Response)=>{ 8 | console.log(req.headers); 9 | const authToken:any = req.headers.authorization; 10 | //console.log("Auth Token: ", authToken); 11 | if(authToken === undefined || authToken === null){ 12 | res.status(403).send({ 13 | 'msg':"Token not sent" 14 | }); 15 | return ; 16 | } 17 | try{ 18 | const data = jwt.verify(authToken,accessSecretKey); 19 | //console.log("JWt body: ", data); 20 | res.status(201).send({ 21 | user : JSON.stringify(data) 22 | }); 23 | }catch{ 24 | res.status(403).send({ 25 | 'msg':"Forbidden: Not Authorized" 26 | }); 27 | } 28 | return ; 29 | 30 | }); 31 | export {validationRoute}; -------------------------------------------------------------------------------- /AuthServer/UserService/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": [], /* 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 legacy experimental 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": "node10", /* 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 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "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. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /AuthServer/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Distributed-Microservice-ChatApp", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algochat - Scalable Chat Microservice Application 2 | 3 | Algochat is a scalable chat microservice application designed to handle millions of users while ensuring stateless consistency, availability, and fault tolerance. It utilizes various technologies including TypeScript, Express.js, Node.js, React.js, Redis PUB/SUB model, Kafka streaming, MongoDB for chat persistence, and PostgreSQL for storing user data. 4 | ## Architecture Diagram: 5 | 6 | ![Algochat Logo](chatArch.png) 7 | 8 | ## Features 9 | 10 | - **Scalability**: Algochat has been tested to handle up to 2 million users, ensuring smooth performance even under high loads. 11 | - **Stateless Consistency**: The application maintains consistency across its stateless architecture, ensuring reliability and ease of maintenance. 12 | - **Availability**: With fault-tolerant design principles, Algochat ensures high availability, minimizing downtime and ensuring users can access the service when needed. 13 | - **Technologies Used**: Algochat leverages a stack of modern technologies including TypeScript, Express.js, Node.js, React.js, Redis PUB/SUB model, Kafka streaming, MongoDB, and PostgreSQL. 14 | 15 | ## Technologies Used 16 | 17 | - **TypeScript**: A statically typed superset of JavaScript that helps in writing scalable and maintainable code. 18 | - **Express.js**: A minimal and flexible Node.js web application framework that provides a robust set of features for building web and mobile applications. 19 | - **Node.js**: A JavaScript runtime built on Chrome's V8 JavaScript engine, which enables building scalable network applications. 20 | - **React.js**: A JavaScript library for building user interfaces, enabling the creation of interactive UIs with ease. 21 | - **Redis PUB/SUB Model**: Redis is used as a message broker with a publish/subscribe model for real-time communication between services. 22 | - **Kafka Streaming**: Kafka is used for building real-time streaming data pipelines and applications. 23 | - **MongoDB**: A NoSQL database used for chat persistence, providing flexibility and scalability for storing chat data. 24 | - **PostgreSQL**: A powerful, open-source relational database used for storing user data with robust features and reliability. 25 | 26 | ## OnGoing.. 27 | 28 | Working incrementally on the application UI and adding more functionalities to it. 29 | Containerizing the project and setting up the deployment pipeline to aws 30 | 31 | ## Contributing 32 | 33 | Contributions are welcome! If you find any bugs or have suggestions for improvements, please open an issue or submit a pull request. 34 | 35 | --- 36 | 37 | Feel free to reach out to us with any questions or feedback. Happy chatting with Algochat! 🚀 38 | -------------------------------------------------------------------------------- /chatArch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/chatArch.png -------------------------------------------------------------------------------- /chatserver/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.env -------------------------------------------------------------------------------- /chatserver/index.ts: -------------------------------------------------------------------------------- 1 | import express, {Express} from "express"; 2 | import http from 'http'; 3 | import { Server } from "socket.io"; 4 | import cluster from 'cluster'; 5 | import os from 'os'; 6 | import 'dotenv/config'; 7 | import cors from 'cors'; 8 | import { initSocketServer, getSocketIns } from "./src/config/SocketIns"; 9 | import { one2oneRouter, initConnect } from "./src/routes/OneToOne"; 10 | import mongoose from "mongoose"; 11 | const PORT: string = process.env.PORT || '3000'; 12 | const processes: number = os.cpus().length; 13 | // initialize express app 14 | var createExpressApp:()=>Express = ():Express => { 15 | var app = express(); 16 | app.use(cors()); 17 | app.use(express.json()); 18 | app.get("/", (req, res) => { 19 | res.status(200).send({ 20 | 'message': 'Server is running' 21 | }); 22 | }); 23 | return app; 24 | } 25 | // initialize create http server 26 | var createHttpServer:()=>[any,express.Express] = ():[any,express.Express] => { 27 | var app = createExpressApp(); 28 | let server = http.createServer(app); 29 | return [server,app]; 30 | } 31 | // initialize server and socket for each process 32 | var initServer: (a: any) => void = async (server: any): Promise => { 33 | initSocketServer(server); 34 | server.listen(PORT, () => { 35 | console.log(`[+] Server initialized' at PORT: ${PORT} PID ${process.pid}`); 36 | }); 37 | } 38 | if (cluster.isPrimary) { 39 | for (let i = 0; i < processes; i++) { 40 | cluster.fork(); 41 | } 42 | } else { 43 | var app: Express, server: any; 44 | [server, app] = createHttpServer(); 45 | initServer(server); 46 | initConnect(); 47 | } 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /chatserver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatapp-chatservice", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "ts-node-dev index.ts" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@types/cors": "^2.8.17", 15 | "@types/dotenv": "^8.2.0", 16 | "@types/express": "^4.17.21", 17 | "@types/ioredis": "^5.0.0", 18 | "@types/kafkajs": "^1.9.0", 19 | "@types/mongoose": "^5.11.97", 20 | "@types/socket.io": "^3.0.0", 21 | "cors": "^2.8.5", 22 | "dotenv": "^16.4.1", 23 | "express": "^4.18.2", 24 | "ioredis": "^5.3.2", 25 | "kafkajs": "^2.2.4", 26 | "mongoose": "^8.1.1", 27 | "socket.io": "^4.7.4", 28 | "ts-node-dev": "^2.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /chatserver/src/config/GetConnectedUser.ts: -------------------------------------------------------------------------------- 1 | // Persits all connected users in the server 2 | class ConnectedUser{ 3 | _userEmail:string 4 | _sockId:string 5 | static _allConnectedUsers: any = []; // enforce strict type 6 | static _indexedUsers:any = {id: 0}; // enforce strict type 7 | constructor(name:string, socketId:string){ 8 | this._userEmail = name; 9 | this._sockId = socketId; 10 | ConnectedUser.setConnectedUser(this._userEmail, this._sockId); 11 | } 12 | static setConnectedUser(usere: string, sckid:string):void{ 13 | if(ConnectedUser._indexedUsers[usere] === undefined){ 14 | ConnectedUser._allConnectedUsers.push({userEmail: usere, sockid:sckid }); 15 | let len = ConnectedUser._allConnectedUsers.length; 16 | ConnectedUser._indexedUsers[ConnectedUser._allConnectedUsers[len-1].userEmail] = ConnectedUser._allConnectedUsers.length - 1; 17 | } 18 | } 19 | static async checkUser(value: string):Promise{ 20 | let func = async ()=>{ 21 | // for(let i =0 ;i{ 34 | for(let i =0 ;ivoid = (server:any) => { 4 | io = new Server(server,{ 5 | cors: { 6 | origin: "*", 7 | methods:["GET","POST"] 8 | } 9 | }); 10 | } 11 | var getSocketIns = ()=>{ 12 | if(!io){ 13 | throw new Error("Socket server not initialized"); 14 | } 15 | return io; 16 | } 17 | export {initSocketServer,getSocketIns}; -------------------------------------------------------------------------------- /chatserver/src/routes/Group.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Astreak/DistributedChatApplication/4761acbc0271b9ea8767ad9f216072ab5e35a9c4/chatserver/src/routes/Group.ts -------------------------------------------------------------------------------- /chatserver/src/routes/OneToOne.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { getSocketIns } from "../config/SocketIns"; 3 | import Redis from "ioredis"; 4 | import 'dotenv/config'; 5 | import ConnectedUser from "../config/GetConnectedUser"; 6 | const redisPub = new Redis(6379,"127.0.0.1"); 7 | const redisSub = new Redis(6379,"127.0.0.1"); 8 | var initConnect: ()=>void = ()=>{ 9 | redisSub.subscribe("new-msg-streamv3"); 10 | const io = getSocketIns(); 11 | redisSub.on("message",async(channel,message)=>{ 12 | //console.log("Subscriber msg", message); 13 | const toEmail = JSON.parse(message).receiverId; 14 | console.log(toEmail); 15 | var data:any = await ConnectedUser.checkUser(toEmail); // revert to then-able formate later 16 | if( data===null || data===undefined ) return; 17 | // sockid is sender's socket id; 18 | io.to(data.sockid).emit("send-message-server",JSON.parse(message)); 19 | }); 20 | // io.use((socket:any,next:any)=>{ 21 | // const username = socket.handshake.auth; 22 | // console.log(username); 23 | // if(username === undefined || username === null){ 24 | // console.log("Not authorized"); 25 | // next(new Error("Not Authorized")); 26 | // }else next(); 27 | // }); 28 | io.on("connect",(socket:any)=>{ 29 | try{ 30 | if(socket.handshake.auth.email === undefined || socket.handshake.auth.email === null || socket.handshake.auth.email === "") return ; 31 | var currentConnection = new ConnectedUser(socket.handshake.auth.email, socket.id); 32 | // console.log("Auth key, ", socket.handshake.auth); 33 | //console.log("Index Users ", ConnectedUser._indexedUsers); 34 | }catch(ex){ 35 | console.log(ex); 36 | return ; 37 | } 38 | console.log("[+] Socket",socket.id,"Connected on process: ", process.pid); 39 | socket.on("disconnect",()=>{ 40 | ConnectedUser.disconnectUser(socket.handshake.auth.email) 41 | .then(()=>{ 42 | console.log(`${socket.id} is disconnected`); 43 | }) 44 | .catch(ex=>{console.log("disconnect, ", ex);}); 45 | }); 46 | socket.on("send-message", (msg:any)=>{ 47 | console.log(msg); 48 | const toBeCommited = {...msg}; // we should take care of the validity of the json 49 | //delete toBeCommited["sockId"]; 50 | console.log("Commited:", toBeCommited); 51 | redisPub.publish("new-msg-streamv3",JSON.stringify(msg)); 52 | fetch("http:localhost:8000/chatm",{ // post request to kafka server 53 | method: "POST", 54 | body: JSON.stringify(toBeCommited), 55 | headers: { 56 | 'content-type': 'application/json;charset=utf-8' // if not added server doesn't catch the req.body 57 | } 58 | }).then((d)=>{ 59 | return d.json(); 60 | }) 61 | .then((d)=> console.log(d)) 62 | .catch((ex) => console.log(ex)); 63 | //console.log(toBeCommited); 64 | }); 65 | }); 66 | return io ; 67 | } 68 | var one2oneRouter = Router(); 69 | one2oneRouter.get("/chat",(req:any, res:any)=>{ 70 | 71 | }); 72 | export {one2oneRouter, initConnect}; -------------------------------------------------------------------------------- /chatserver/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": [], /* 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 legacy experimental 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": "node10", /* 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 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "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. */ 58 | "outDir": "./dirs", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /kafkaserver/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.env -------------------------------------------------------------------------------- /kafkaserver/config/ConnectDB.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | let connectDB = ()=>{ 3 | return async(db_uri:any)=>{ 4 | await mongoose.connect(db_uri,{ 5 | } as any).then((d)=>{ 6 | console.log('[+] ChatDB connected'); 7 | }); 8 | } 9 | 10 | } 11 | export {connectDB}; -------------------------------------------------------------------------------- /kafkaserver/config/SchemaDB.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose"; 2 | // have to add sender and receiver validator 3 | const chatdb = new Schema({ 4 | senderId : { 5 | type: String, 6 | required: true 7 | 8 | }, 9 | 10 | email:{ 11 | type:String, 12 | required:true 13 | }, 14 | receiverId: { 15 | type: String, 16 | required: true, 17 | }, 18 | tousername:{ 19 | type:String, 20 | required:true 21 | }, 22 | fromusername:{ 23 | type:String, 24 | required:true 25 | }, 26 | message: { 27 | type: String, 28 | required : true 29 | } 30 | }, 31 | { 32 | timestamps:true 33 | } 34 | ); 35 | var db = mongoose.model("chatDB", chatdb); 36 | export { db }; -------------------------------------------------------------------------------- /kafkaserver/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | zookeeper: 4 | image: 'wurstmeister/zookeeper:latest' 5 | container_name: zookeeper 6 | ports: 7 | - "2181:2181" 8 | kafka: 9 | image: 'wurstmeister/kafka:latest' 10 | container_name: kafkaserver 11 | ports: 12 | - "9092:9092" 13 | environment: 14 | KAFKA_ADVERTISED_HOST_NAME: 192.168.29.168 15 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 16 | KAFKA_NO_PARTITIONER_WARNING: 1 17 | 18 | -------------------------------------------------------------------------------- /kafkaserver/index.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from 'express'; 2 | import 'dotenv/config'; 3 | import { connectDB } from './config/ConnectDB'; 4 | import { producerConnect } from './kafka/producer'; 5 | import { consumerConnect } from './kafka/consumer'; 6 | import { db } from './config/SchemaDB'; 7 | import cors from 'cors'; 8 | const DBURI = process.env.DBURI; 9 | var connectDBIns = connectDB(); 10 | connectDBIns(DBURI); 11 | const PORT = process.env.PORT || 3000; 12 | let initApp:()=>express.Express = ():express.Express=>{ 13 | const app = express(); 14 | app.use(express.json()); 15 | app.use(cors({ 16 | origin:"http://localhost:3000", 17 | credentials:true, 18 | })); 19 | app.get("/",(req:Request, res:Response)=>{ 20 | res.status(200).send({ 21 | "message":"Welcome to kafka server" 22 | }); 23 | }); 24 | app.post("/chatm",(req:Request, res:Response)=>{ 25 | var message:{ 26 | senderId: string, 27 | receiverId: string, 28 | message:string 29 | } = req.body; // a json 30 | producerConnect(message); // message is produced 31 | res.status(200).send({ 32 | 'message': 'Data is queued to be written in database' 33 | }); 34 | }); 35 | app.post("/findUser/",(req:Request, res:Response)=>{ 36 | const id: string = req.body.id; 37 | const email : string = req.body.email; 38 | res.set("Access-Control-Allow-Credentials", 'true'); 39 | res.set("Access-Control-Allow-Origin","http://localhost:3000"); 40 | res.set('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); 41 | //console.log(req.body); 42 | db.find({$or: [{"senderId":id}, {"receiverId":email}]}) 43 | .then((d)=>{ 44 | console.log(d); 45 | res.status(200).send(d); 46 | }); 47 | }); 48 | app.post("/findUser/",(req:Request, res:Response)=>{ 49 | 50 | }); 51 | return app; 52 | } 53 | 54 | var app = initApp(); 55 | app.listen(PORT,async()=>{ 56 | //await init(); 57 | consumerConnect("user0-1"); 58 | console.log(`[+] Kafka server started on ${PORT} `); 59 | }); 60 | 61 | 62 | -------------------------------------------------------------------------------- /kafkaserver/kafka/KafkaIns.ts: -------------------------------------------------------------------------------- 1 | import { Kafka } from "kafkajs"; 2 | const kafka = new Kafka({ 3 | clientId: "client_ID_app_new_v2", 4 | brokers:["192.168.29.168:9092"] 5 | }); 6 | export default kafka; -------------------------------------------------------------------------------- /kafkaserver/kafka/admin.ts: -------------------------------------------------------------------------------- 1 | import kafka from "./KafkaIns"; 2 | let init = async()=>{ 3 | const admin = kafka.admin(); 4 | await admin.connect(); // connecting admin 5 | console.log("[+] Admin Connected"); 6 | await admin.createTopics({ 7 | topics:[ 8 | { 9 | topic: "actual-stream_v3", 10 | numPartitions: 10 11 | } 12 | ] 13 | }); 14 | await admin.disconnect(); 15 | console.log("[-] Admin disconnected topics are created"); 16 | } 17 | init(); 18 | export {init}; -------------------------------------------------------------------------------- /kafkaserver/kafka/consumer.ts: -------------------------------------------------------------------------------- 1 | import kafka from "./KafkaIns"; 2 | import { db } from "../config/SchemaDB"; 3 | var consumerConnect = async (group:any)=>{ 4 | const consumer = kafka.consumer({groupId:group}); 5 | await consumer.connect(); 6 | await consumer.subscribe({topic: "actual-stream_v3", fromBeginning: true}); 7 | await consumer.run({ 8 | eachMessage:async({topic, partition,message,heartbeat,pause })=>{ 9 | // insert in db here 10 | const bufferS:any = message.value; 11 | db.create(JSON.parse(bufferS.toString())) 12 | .then((d)=>{ 13 | //console.log("returned data", d); 14 | console.log("[+] Data inserted successfully in database"); 15 | }) 16 | .catch((ex)=>{ 17 | console.log(`Erro: ${ex}`); 18 | }); 19 | console.log(`Topic: ${topic} -- Partition: ${partition} --- Message: ${message.value?.toString()}`); 20 | } 21 | }); 22 | } 23 | //consumerConnect(); 24 | export {consumerConnect}; -------------------------------------------------------------------------------- /kafkaserver/kafka/producer.ts: -------------------------------------------------------------------------------- 1 | import { init } from "./admin"; 2 | import kafka from "./KafkaIns"; 3 | let producerConnect = async(message:any)=>{ 4 | //await init(); 5 | let evaluatePartition = Math.floor(message.senderId/10) % 10; 6 | const producer = kafka.producer(); 7 | await producer.connect(); 8 | console.log("[+] Producer Connected"); 9 | console.log(evaluatePartition); 10 | await producer.send({ 11 | topic:"actual-stream_v3", 12 | messages:[ 13 | { 14 | partition: evaluatePartition, 15 | key: "some-data", 16 | value: JSON.stringify(message) 17 | }, 18 | 19 | ] 20 | }); 21 | await producer.disconnect(); 22 | } 23 | export {producerConnect}; -------------------------------------------------------------------------------- /kafkaserver/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kafkaserver", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "kafkaserver", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@types/cors": "^2.8.17", 13 | "@types/dotenv": "^8.2.0", 14 | "@types/express": "^4.17.21", 15 | "@types/kafkajs": "^1.9.0", 16 | "@types/mongoose": "^5.11.97", 17 | "cors": "^2.8.5", 18 | "dotenv": "^16.4.1", 19 | "express": "^4.18.2", 20 | "kafkajs": "^2.2.4", 21 | "mongoose": "^8.1.1", 22 | "ts-node-dev": "^2.0.0", 23 | "tsc": "^2.0.4" 24 | } 25 | }, 26 | "node_modules/@cspotcode/source-map-support": { 27 | "version": "0.8.1", 28 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 29 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 30 | "dependencies": { 31 | "@jridgewell/trace-mapping": "0.3.9" 32 | }, 33 | "engines": { 34 | "node": ">=12" 35 | } 36 | }, 37 | "node_modules/@jridgewell/resolve-uri": { 38 | "version": "3.1.1", 39 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", 40 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", 41 | "engines": { 42 | "node": ">=6.0.0" 43 | } 44 | }, 45 | "node_modules/@jridgewell/sourcemap-codec": { 46 | "version": "1.4.15", 47 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 48 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" 49 | }, 50 | "node_modules/@jridgewell/trace-mapping": { 51 | "version": "0.3.9", 52 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 53 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 54 | "dependencies": { 55 | "@jridgewell/resolve-uri": "^3.0.3", 56 | "@jridgewell/sourcemap-codec": "^1.4.10" 57 | } 58 | }, 59 | "node_modules/@mongodb-js/saslprep": { 60 | "version": "1.1.4", 61 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", 62 | "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", 63 | "dependencies": { 64 | "sparse-bitfield": "^3.0.3" 65 | } 66 | }, 67 | "node_modules/@tsconfig/node10": { 68 | "version": "1.0.9", 69 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", 70 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" 71 | }, 72 | "node_modules/@tsconfig/node12": { 73 | "version": "1.0.11", 74 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 75 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" 76 | }, 77 | "node_modules/@tsconfig/node14": { 78 | "version": "1.0.3", 79 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 80 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" 81 | }, 82 | "node_modules/@tsconfig/node16": { 83 | "version": "1.0.4", 84 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 85 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" 86 | }, 87 | "node_modules/@types/body-parser": { 88 | "version": "1.19.5", 89 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", 90 | "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", 91 | "dependencies": { 92 | "@types/connect": "*", 93 | "@types/node": "*" 94 | } 95 | }, 96 | "node_modules/@types/connect": { 97 | "version": "3.4.38", 98 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", 99 | "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", 100 | "dependencies": { 101 | "@types/node": "*" 102 | } 103 | }, 104 | "node_modules/@types/cors": { 105 | "version": "2.8.17", 106 | "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", 107 | "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", 108 | "dependencies": { 109 | "@types/node": "*" 110 | } 111 | }, 112 | "node_modules/@types/dotenv": { 113 | "version": "8.2.0", 114 | "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", 115 | "integrity": "sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==", 116 | "deprecated": "This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed.", 117 | "dependencies": { 118 | "dotenv": "*" 119 | } 120 | }, 121 | "node_modules/@types/express": { 122 | "version": "4.17.21", 123 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", 124 | "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", 125 | "dependencies": { 126 | "@types/body-parser": "*", 127 | "@types/express-serve-static-core": "^4.17.33", 128 | "@types/qs": "*", 129 | "@types/serve-static": "*" 130 | } 131 | }, 132 | "node_modules/@types/express-serve-static-core": { 133 | "version": "4.17.43", 134 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", 135 | "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", 136 | "dependencies": { 137 | "@types/node": "*", 138 | "@types/qs": "*", 139 | "@types/range-parser": "*", 140 | "@types/send": "*" 141 | } 142 | }, 143 | "node_modules/@types/http-errors": { 144 | "version": "2.0.4", 145 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", 146 | "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" 147 | }, 148 | "node_modules/@types/kafkajs": { 149 | "version": "1.9.0", 150 | "resolved": "https://registry.npmjs.org/@types/kafkajs/-/kafkajs-1.9.0.tgz", 151 | "integrity": "sha512-R9VDNbiw+vNfxWjjFHUrLMF/Dfc7asGXzKtYUwI4FaT24Chf5ZNkfvce54p4dkLMxPcsrEsVazAK0Jp2ib4Zxw==", 152 | "deprecated": "This is a stub types definition. kafkajs provides its own type definitions, so you do not need this installed.", 153 | "dependencies": { 154 | "kafkajs": "*" 155 | } 156 | }, 157 | "node_modules/@types/mime": { 158 | "version": "1.3.5", 159 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", 160 | "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" 161 | }, 162 | "node_modules/@types/mongoose": { 163 | "version": "5.11.97", 164 | "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.11.97.tgz", 165 | "integrity": "sha512-cqwOVYT3qXyLiGw7ueU2kX9noE8DPGRY6z8eUxudhXY8NZ7DMKYAxyZkLSevGfhCX3dO/AoX5/SO9lAzfjon0Q==", 166 | "deprecated": "Mongoose publishes its own types, so you do not need to install this package.", 167 | "dependencies": { 168 | "mongoose": "*" 169 | } 170 | }, 171 | "node_modules/@types/node": { 172 | "version": "20.11.16", 173 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", 174 | "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", 175 | "dependencies": { 176 | "undici-types": "~5.26.4" 177 | } 178 | }, 179 | "node_modules/@types/qs": { 180 | "version": "6.9.11", 181 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", 182 | "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" 183 | }, 184 | "node_modules/@types/range-parser": { 185 | "version": "1.2.7", 186 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", 187 | "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" 188 | }, 189 | "node_modules/@types/send": { 190 | "version": "0.17.4", 191 | "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", 192 | "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", 193 | "dependencies": { 194 | "@types/mime": "^1", 195 | "@types/node": "*" 196 | } 197 | }, 198 | "node_modules/@types/serve-static": { 199 | "version": "1.15.5", 200 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", 201 | "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", 202 | "dependencies": { 203 | "@types/http-errors": "*", 204 | "@types/mime": "*", 205 | "@types/node": "*" 206 | } 207 | }, 208 | "node_modules/@types/strip-bom": { 209 | "version": "3.0.0", 210 | "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", 211 | "integrity": "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==" 212 | }, 213 | "node_modules/@types/strip-json-comments": { 214 | "version": "0.0.30", 215 | "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", 216 | "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==" 217 | }, 218 | "node_modules/@types/webidl-conversions": { 219 | "version": "7.0.3", 220 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 221 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 222 | }, 223 | "node_modules/@types/whatwg-url": { 224 | "version": "11.0.4", 225 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", 226 | "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", 227 | "dependencies": { 228 | "@types/webidl-conversions": "*" 229 | } 230 | }, 231 | "node_modules/accepts": { 232 | "version": "1.3.8", 233 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 234 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 235 | "dependencies": { 236 | "mime-types": "~2.1.34", 237 | "negotiator": "0.6.3" 238 | }, 239 | "engines": { 240 | "node": ">= 0.6" 241 | } 242 | }, 243 | "node_modules/acorn": { 244 | "version": "8.11.3", 245 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 246 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 247 | "bin": { 248 | "acorn": "bin/acorn" 249 | }, 250 | "engines": { 251 | "node": ">=0.4.0" 252 | } 253 | }, 254 | "node_modules/acorn-walk": { 255 | "version": "8.3.2", 256 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 257 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 258 | "engines": { 259 | "node": ">=0.4.0" 260 | } 261 | }, 262 | "node_modules/anymatch": { 263 | "version": "3.1.3", 264 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 265 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 266 | "dependencies": { 267 | "normalize-path": "^3.0.0", 268 | "picomatch": "^2.0.4" 269 | }, 270 | "engines": { 271 | "node": ">= 8" 272 | } 273 | }, 274 | "node_modules/arg": { 275 | "version": "4.1.3", 276 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 277 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 278 | }, 279 | "node_modules/array-flatten": { 280 | "version": "1.1.1", 281 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 282 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 283 | }, 284 | "node_modules/balanced-match": { 285 | "version": "1.0.2", 286 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 287 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 288 | }, 289 | "node_modules/binary-extensions": { 290 | "version": "2.2.0", 291 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 292 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 293 | "engines": { 294 | "node": ">=8" 295 | } 296 | }, 297 | "node_modules/body-parser": { 298 | "version": "1.20.1", 299 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 300 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 301 | "dependencies": { 302 | "bytes": "3.1.2", 303 | "content-type": "~1.0.4", 304 | "debug": "2.6.9", 305 | "depd": "2.0.0", 306 | "destroy": "1.2.0", 307 | "http-errors": "2.0.0", 308 | "iconv-lite": "0.4.24", 309 | "on-finished": "2.4.1", 310 | "qs": "6.11.0", 311 | "raw-body": "2.5.1", 312 | "type-is": "~1.6.18", 313 | "unpipe": "1.0.0" 314 | }, 315 | "engines": { 316 | "node": ">= 0.8", 317 | "npm": "1.2.8000 || >= 1.4.16" 318 | } 319 | }, 320 | "node_modules/brace-expansion": { 321 | "version": "1.1.11", 322 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 323 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 324 | "dependencies": { 325 | "balanced-match": "^1.0.0", 326 | "concat-map": "0.0.1" 327 | } 328 | }, 329 | "node_modules/braces": { 330 | "version": "3.0.2", 331 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 332 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 333 | "dependencies": { 334 | "fill-range": "^7.0.1" 335 | }, 336 | "engines": { 337 | "node": ">=8" 338 | } 339 | }, 340 | "node_modules/bson": { 341 | "version": "6.3.0", 342 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", 343 | "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", 344 | "engines": { 345 | "node": ">=16.20.1" 346 | } 347 | }, 348 | "node_modules/buffer-from": { 349 | "version": "1.1.2", 350 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 351 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" 352 | }, 353 | "node_modules/bytes": { 354 | "version": "3.1.2", 355 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 356 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 357 | "engines": { 358 | "node": ">= 0.8" 359 | } 360 | }, 361 | "node_modules/call-bind": { 362 | "version": "1.0.6", 363 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", 364 | "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", 365 | "dependencies": { 366 | "es-errors": "^1.3.0", 367 | "function-bind": "^1.1.2", 368 | "get-intrinsic": "^1.2.3", 369 | "set-function-length": "^1.2.0" 370 | }, 371 | "engines": { 372 | "node": ">= 0.4" 373 | }, 374 | "funding": { 375 | "url": "https://github.com/sponsors/ljharb" 376 | } 377 | }, 378 | "node_modules/chokidar": { 379 | "version": "3.6.0", 380 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 381 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 382 | "dependencies": { 383 | "anymatch": "~3.1.2", 384 | "braces": "~3.0.2", 385 | "glob-parent": "~5.1.2", 386 | "is-binary-path": "~2.1.0", 387 | "is-glob": "~4.0.1", 388 | "normalize-path": "~3.0.0", 389 | "readdirp": "~3.6.0" 390 | }, 391 | "engines": { 392 | "node": ">= 8.10.0" 393 | }, 394 | "funding": { 395 | "url": "https://paulmillr.com/funding/" 396 | }, 397 | "optionalDependencies": { 398 | "fsevents": "~2.3.2" 399 | } 400 | }, 401 | "node_modules/concat-map": { 402 | "version": "0.0.1", 403 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 404 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 405 | }, 406 | "node_modules/content-disposition": { 407 | "version": "0.5.4", 408 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 409 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 410 | "dependencies": { 411 | "safe-buffer": "5.2.1" 412 | }, 413 | "engines": { 414 | "node": ">= 0.6" 415 | } 416 | }, 417 | "node_modules/content-type": { 418 | "version": "1.0.5", 419 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 420 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 421 | "engines": { 422 | "node": ">= 0.6" 423 | } 424 | }, 425 | "node_modules/cookie": { 426 | "version": "0.5.0", 427 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 428 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 429 | "engines": { 430 | "node": ">= 0.6" 431 | } 432 | }, 433 | "node_modules/cookie-signature": { 434 | "version": "1.0.6", 435 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 436 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 437 | }, 438 | "node_modules/cors": { 439 | "version": "2.8.5", 440 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 441 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 442 | "dependencies": { 443 | "object-assign": "^4", 444 | "vary": "^1" 445 | }, 446 | "engines": { 447 | "node": ">= 0.10" 448 | } 449 | }, 450 | "node_modules/create-require": { 451 | "version": "1.1.1", 452 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 453 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 454 | }, 455 | "node_modules/debug": { 456 | "version": "2.6.9", 457 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 458 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 459 | "dependencies": { 460 | "ms": "2.0.0" 461 | } 462 | }, 463 | "node_modules/define-data-property": { 464 | "version": "1.1.2", 465 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", 466 | "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", 467 | "dependencies": { 468 | "es-errors": "^1.3.0", 469 | "get-intrinsic": "^1.2.2", 470 | "gopd": "^1.0.1", 471 | "has-property-descriptors": "^1.0.1" 472 | }, 473 | "engines": { 474 | "node": ">= 0.4" 475 | } 476 | }, 477 | "node_modules/depd": { 478 | "version": "2.0.0", 479 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 480 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 481 | "engines": { 482 | "node": ">= 0.8" 483 | } 484 | }, 485 | "node_modules/destroy": { 486 | "version": "1.2.0", 487 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 488 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 489 | "engines": { 490 | "node": ">= 0.8", 491 | "npm": "1.2.8000 || >= 1.4.16" 492 | } 493 | }, 494 | "node_modules/diff": { 495 | "version": "4.0.2", 496 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 497 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 498 | "engines": { 499 | "node": ">=0.3.1" 500 | } 501 | }, 502 | "node_modules/dotenv": { 503 | "version": "16.4.1", 504 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", 505 | "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", 506 | "engines": { 507 | "node": ">=12" 508 | }, 509 | "funding": { 510 | "url": "https://github.com/motdotla/dotenv?sponsor=1" 511 | } 512 | }, 513 | "node_modules/dynamic-dedupe": { 514 | "version": "0.3.0", 515 | "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", 516 | "integrity": "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==", 517 | "dependencies": { 518 | "xtend": "^4.0.0" 519 | } 520 | }, 521 | "node_modules/ee-first": { 522 | "version": "1.1.1", 523 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 524 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 525 | }, 526 | "node_modules/encodeurl": { 527 | "version": "1.0.2", 528 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 529 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 530 | "engines": { 531 | "node": ">= 0.8" 532 | } 533 | }, 534 | "node_modules/es-errors": { 535 | "version": "1.3.0", 536 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 537 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 538 | "engines": { 539 | "node": ">= 0.4" 540 | } 541 | }, 542 | "node_modules/escape-html": { 543 | "version": "1.0.3", 544 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 545 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 546 | }, 547 | "node_modules/etag": { 548 | "version": "1.8.1", 549 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 550 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 551 | "engines": { 552 | "node": ">= 0.6" 553 | } 554 | }, 555 | "node_modules/express": { 556 | "version": "4.18.2", 557 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 558 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 559 | "dependencies": { 560 | "accepts": "~1.3.8", 561 | "array-flatten": "1.1.1", 562 | "body-parser": "1.20.1", 563 | "content-disposition": "0.5.4", 564 | "content-type": "~1.0.4", 565 | "cookie": "0.5.0", 566 | "cookie-signature": "1.0.6", 567 | "debug": "2.6.9", 568 | "depd": "2.0.0", 569 | "encodeurl": "~1.0.2", 570 | "escape-html": "~1.0.3", 571 | "etag": "~1.8.1", 572 | "finalhandler": "1.2.0", 573 | "fresh": "0.5.2", 574 | "http-errors": "2.0.0", 575 | "merge-descriptors": "1.0.1", 576 | "methods": "~1.1.2", 577 | "on-finished": "2.4.1", 578 | "parseurl": "~1.3.3", 579 | "path-to-regexp": "0.1.7", 580 | "proxy-addr": "~2.0.7", 581 | "qs": "6.11.0", 582 | "range-parser": "~1.2.1", 583 | "safe-buffer": "5.2.1", 584 | "send": "0.18.0", 585 | "serve-static": "1.15.0", 586 | "setprototypeof": "1.2.0", 587 | "statuses": "2.0.1", 588 | "type-is": "~1.6.18", 589 | "utils-merge": "1.0.1", 590 | "vary": "~1.1.2" 591 | }, 592 | "engines": { 593 | "node": ">= 0.10.0" 594 | } 595 | }, 596 | "node_modules/fill-range": { 597 | "version": "7.0.1", 598 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 599 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 600 | "dependencies": { 601 | "to-regex-range": "^5.0.1" 602 | }, 603 | "engines": { 604 | "node": ">=8" 605 | } 606 | }, 607 | "node_modules/finalhandler": { 608 | "version": "1.2.0", 609 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 610 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 611 | "dependencies": { 612 | "debug": "2.6.9", 613 | "encodeurl": "~1.0.2", 614 | "escape-html": "~1.0.3", 615 | "on-finished": "2.4.1", 616 | "parseurl": "~1.3.3", 617 | "statuses": "2.0.1", 618 | "unpipe": "~1.0.0" 619 | }, 620 | "engines": { 621 | "node": ">= 0.8" 622 | } 623 | }, 624 | "node_modules/forwarded": { 625 | "version": "0.2.0", 626 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 627 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 628 | "engines": { 629 | "node": ">= 0.6" 630 | } 631 | }, 632 | "node_modules/fresh": { 633 | "version": "0.5.2", 634 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 635 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 636 | "engines": { 637 | "node": ">= 0.6" 638 | } 639 | }, 640 | "node_modules/fs.realpath": { 641 | "version": "1.0.0", 642 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 643 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 644 | }, 645 | "node_modules/fsevents": { 646 | "version": "2.3.3", 647 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 648 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 649 | "hasInstallScript": true, 650 | "optional": true, 651 | "os": [ 652 | "darwin" 653 | ], 654 | "engines": { 655 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 656 | } 657 | }, 658 | "node_modules/function-bind": { 659 | "version": "1.1.2", 660 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 661 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 662 | "funding": { 663 | "url": "https://github.com/sponsors/ljharb" 664 | } 665 | }, 666 | "node_modules/get-intrinsic": { 667 | "version": "1.2.4", 668 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 669 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 670 | "dependencies": { 671 | "es-errors": "^1.3.0", 672 | "function-bind": "^1.1.2", 673 | "has-proto": "^1.0.1", 674 | "has-symbols": "^1.0.3", 675 | "hasown": "^2.0.0" 676 | }, 677 | "engines": { 678 | "node": ">= 0.4" 679 | }, 680 | "funding": { 681 | "url": "https://github.com/sponsors/ljharb" 682 | } 683 | }, 684 | "node_modules/glob": { 685 | "version": "7.2.3", 686 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 687 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 688 | "dependencies": { 689 | "fs.realpath": "^1.0.0", 690 | "inflight": "^1.0.4", 691 | "inherits": "2", 692 | "minimatch": "^3.1.1", 693 | "once": "^1.3.0", 694 | "path-is-absolute": "^1.0.0" 695 | }, 696 | "engines": { 697 | "node": "*" 698 | }, 699 | "funding": { 700 | "url": "https://github.com/sponsors/isaacs" 701 | } 702 | }, 703 | "node_modules/glob-parent": { 704 | "version": "5.1.2", 705 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 706 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 707 | "dependencies": { 708 | "is-glob": "^4.0.1" 709 | }, 710 | "engines": { 711 | "node": ">= 6" 712 | } 713 | }, 714 | "node_modules/gopd": { 715 | "version": "1.0.1", 716 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 717 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 718 | "dependencies": { 719 | "get-intrinsic": "^1.1.3" 720 | }, 721 | "funding": { 722 | "url": "https://github.com/sponsors/ljharb" 723 | } 724 | }, 725 | "node_modules/has-property-descriptors": { 726 | "version": "1.0.1", 727 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", 728 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", 729 | "dependencies": { 730 | "get-intrinsic": "^1.2.2" 731 | }, 732 | "funding": { 733 | "url": "https://github.com/sponsors/ljharb" 734 | } 735 | }, 736 | "node_modules/has-proto": { 737 | "version": "1.0.1", 738 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 739 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 740 | "engines": { 741 | "node": ">= 0.4" 742 | }, 743 | "funding": { 744 | "url": "https://github.com/sponsors/ljharb" 745 | } 746 | }, 747 | "node_modules/has-symbols": { 748 | "version": "1.0.3", 749 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 750 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 751 | "engines": { 752 | "node": ">= 0.4" 753 | }, 754 | "funding": { 755 | "url": "https://github.com/sponsors/ljharb" 756 | } 757 | }, 758 | "node_modules/hasown": { 759 | "version": "2.0.0", 760 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 761 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 762 | "dependencies": { 763 | "function-bind": "^1.1.2" 764 | }, 765 | "engines": { 766 | "node": ">= 0.4" 767 | } 768 | }, 769 | "node_modules/http-errors": { 770 | "version": "2.0.0", 771 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 772 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 773 | "dependencies": { 774 | "depd": "2.0.0", 775 | "inherits": "2.0.4", 776 | "setprototypeof": "1.2.0", 777 | "statuses": "2.0.1", 778 | "toidentifier": "1.0.1" 779 | }, 780 | "engines": { 781 | "node": ">= 0.8" 782 | } 783 | }, 784 | "node_modules/iconv-lite": { 785 | "version": "0.4.24", 786 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 787 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 788 | "dependencies": { 789 | "safer-buffer": ">= 2.1.2 < 3" 790 | }, 791 | "engines": { 792 | "node": ">=0.10.0" 793 | } 794 | }, 795 | "node_modules/inflight": { 796 | "version": "1.0.6", 797 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 798 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 799 | "dependencies": { 800 | "once": "^1.3.0", 801 | "wrappy": "1" 802 | } 803 | }, 804 | "node_modules/inherits": { 805 | "version": "2.0.4", 806 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 807 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 808 | }, 809 | "node_modules/ipaddr.js": { 810 | "version": "1.9.1", 811 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 812 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 813 | "engines": { 814 | "node": ">= 0.10" 815 | } 816 | }, 817 | "node_modules/is-binary-path": { 818 | "version": "2.1.0", 819 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 820 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 821 | "dependencies": { 822 | "binary-extensions": "^2.0.0" 823 | }, 824 | "engines": { 825 | "node": ">=8" 826 | } 827 | }, 828 | "node_modules/is-core-module": { 829 | "version": "2.13.1", 830 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", 831 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", 832 | "dependencies": { 833 | "hasown": "^2.0.0" 834 | }, 835 | "funding": { 836 | "url": "https://github.com/sponsors/ljharb" 837 | } 838 | }, 839 | "node_modules/is-extglob": { 840 | "version": "2.1.1", 841 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 842 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 843 | "engines": { 844 | "node": ">=0.10.0" 845 | } 846 | }, 847 | "node_modules/is-glob": { 848 | "version": "4.0.3", 849 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 850 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 851 | "dependencies": { 852 | "is-extglob": "^2.1.1" 853 | }, 854 | "engines": { 855 | "node": ">=0.10.0" 856 | } 857 | }, 858 | "node_modules/is-number": { 859 | "version": "7.0.0", 860 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 861 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 862 | "engines": { 863 | "node": ">=0.12.0" 864 | } 865 | }, 866 | "node_modules/kafkajs": { 867 | "version": "2.2.4", 868 | "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", 869 | "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==", 870 | "engines": { 871 | "node": ">=14.0.0" 872 | } 873 | }, 874 | "node_modules/kareem": { 875 | "version": "2.5.1", 876 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", 877 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", 878 | "engines": { 879 | "node": ">=12.0.0" 880 | } 881 | }, 882 | "node_modules/make-error": { 883 | "version": "1.3.6", 884 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 885 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 886 | }, 887 | "node_modules/media-typer": { 888 | "version": "0.3.0", 889 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 890 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 891 | "engines": { 892 | "node": ">= 0.6" 893 | } 894 | }, 895 | "node_modules/memory-pager": { 896 | "version": "1.5.0", 897 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 898 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 899 | }, 900 | "node_modules/merge-descriptors": { 901 | "version": "1.0.1", 902 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 903 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 904 | }, 905 | "node_modules/methods": { 906 | "version": "1.1.2", 907 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 908 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 909 | "engines": { 910 | "node": ">= 0.6" 911 | } 912 | }, 913 | "node_modules/mime": { 914 | "version": "1.6.0", 915 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 916 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 917 | "bin": { 918 | "mime": "cli.js" 919 | }, 920 | "engines": { 921 | "node": ">=4" 922 | } 923 | }, 924 | "node_modules/mime-db": { 925 | "version": "1.52.0", 926 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 927 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 928 | "engines": { 929 | "node": ">= 0.6" 930 | } 931 | }, 932 | "node_modules/mime-types": { 933 | "version": "2.1.35", 934 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 935 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 936 | "dependencies": { 937 | "mime-db": "1.52.0" 938 | }, 939 | "engines": { 940 | "node": ">= 0.6" 941 | } 942 | }, 943 | "node_modules/minimatch": { 944 | "version": "3.1.2", 945 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 946 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 947 | "dependencies": { 948 | "brace-expansion": "^1.1.7" 949 | }, 950 | "engines": { 951 | "node": "*" 952 | } 953 | }, 954 | "node_modules/minimist": { 955 | "version": "1.2.8", 956 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 957 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 958 | "funding": { 959 | "url": "https://github.com/sponsors/ljharb" 960 | } 961 | }, 962 | "node_modules/mkdirp": { 963 | "version": "1.0.4", 964 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 965 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 966 | "bin": { 967 | "mkdirp": "bin/cmd.js" 968 | }, 969 | "engines": { 970 | "node": ">=10" 971 | } 972 | }, 973 | "node_modules/mongodb": { 974 | "version": "6.3.0", 975 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", 976 | "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", 977 | "dependencies": { 978 | "@mongodb-js/saslprep": "^1.1.0", 979 | "bson": "^6.2.0", 980 | "mongodb-connection-string-url": "^3.0.0" 981 | }, 982 | "engines": { 983 | "node": ">=16.20.1" 984 | }, 985 | "peerDependencies": { 986 | "@aws-sdk/credential-providers": "^3.188.0", 987 | "@mongodb-js/zstd": "^1.1.0", 988 | "gcp-metadata": "^5.2.0", 989 | "kerberos": "^2.0.1", 990 | "mongodb-client-encryption": ">=6.0.0 <7", 991 | "snappy": "^7.2.2", 992 | "socks": "^2.7.1" 993 | }, 994 | "peerDependenciesMeta": { 995 | "@aws-sdk/credential-providers": { 996 | "optional": true 997 | }, 998 | "@mongodb-js/zstd": { 999 | "optional": true 1000 | }, 1001 | "gcp-metadata": { 1002 | "optional": true 1003 | }, 1004 | "kerberos": { 1005 | "optional": true 1006 | }, 1007 | "mongodb-client-encryption": { 1008 | "optional": true 1009 | }, 1010 | "snappy": { 1011 | "optional": true 1012 | }, 1013 | "socks": { 1014 | "optional": true 1015 | } 1016 | } 1017 | }, 1018 | "node_modules/mongodb-connection-string-url": { 1019 | "version": "3.0.0", 1020 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", 1021 | "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", 1022 | "dependencies": { 1023 | "@types/whatwg-url": "^11.0.2", 1024 | "whatwg-url": "^13.0.0" 1025 | } 1026 | }, 1027 | "node_modules/mongoose": { 1028 | "version": "8.1.1", 1029 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.1.1.tgz", 1030 | "integrity": "sha512-DbLb0NsiEXmaqLOpEz+AtAsgwhRw6f25gwa1dF5R7jj6lS1D8X6uTdhBSC8GDVtOwe5Tfw2EL7nTn6hiJT3Bgg==", 1031 | "dependencies": { 1032 | "bson": "^6.2.0", 1033 | "kareem": "2.5.1", 1034 | "mongodb": "6.3.0", 1035 | "mpath": "0.9.0", 1036 | "mquery": "5.0.0", 1037 | "ms": "2.1.3", 1038 | "sift": "16.0.1" 1039 | }, 1040 | "engines": { 1041 | "node": ">=16.20.1" 1042 | }, 1043 | "funding": { 1044 | "type": "opencollective", 1045 | "url": "https://opencollective.com/mongoose" 1046 | } 1047 | }, 1048 | "node_modules/mongoose/node_modules/ms": { 1049 | "version": "2.1.3", 1050 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1051 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1052 | }, 1053 | "node_modules/mpath": { 1054 | "version": "0.9.0", 1055 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", 1056 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", 1057 | "engines": { 1058 | "node": ">=4.0.0" 1059 | } 1060 | }, 1061 | "node_modules/mquery": { 1062 | "version": "5.0.0", 1063 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", 1064 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", 1065 | "dependencies": { 1066 | "debug": "4.x" 1067 | }, 1068 | "engines": { 1069 | "node": ">=14.0.0" 1070 | } 1071 | }, 1072 | "node_modules/mquery/node_modules/debug": { 1073 | "version": "4.3.4", 1074 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1075 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1076 | "dependencies": { 1077 | "ms": "2.1.2" 1078 | }, 1079 | "engines": { 1080 | "node": ">=6.0" 1081 | }, 1082 | "peerDependenciesMeta": { 1083 | "supports-color": { 1084 | "optional": true 1085 | } 1086 | } 1087 | }, 1088 | "node_modules/mquery/node_modules/ms": { 1089 | "version": "2.1.2", 1090 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1091 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1092 | }, 1093 | "node_modules/ms": { 1094 | "version": "2.0.0", 1095 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1096 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1097 | }, 1098 | "node_modules/negotiator": { 1099 | "version": "0.6.3", 1100 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1101 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1102 | "engines": { 1103 | "node": ">= 0.6" 1104 | } 1105 | }, 1106 | "node_modules/normalize-path": { 1107 | "version": "3.0.0", 1108 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1109 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1110 | "engines": { 1111 | "node": ">=0.10.0" 1112 | } 1113 | }, 1114 | "node_modules/object-assign": { 1115 | "version": "4.1.1", 1116 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1117 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1118 | "engines": { 1119 | "node": ">=0.10.0" 1120 | } 1121 | }, 1122 | "node_modules/object-inspect": { 1123 | "version": "1.13.1", 1124 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 1125 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 1126 | "funding": { 1127 | "url": "https://github.com/sponsors/ljharb" 1128 | } 1129 | }, 1130 | "node_modules/on-finished": { 1131 | "version": "2.4.1", 1132 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1133 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1134 | "dependencies": { 1135 | "ee-first": "1.1.1" 1136 | }, 1137 | "engines": { 1138 | "node": ">= 0.8" 1139 | } 1140 | }, 1141 | "node_modules/once": { 1142 | "version": "1.4.0", 1143 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1144 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1145 | "dependencies": { 1146 | "wrappy": "1" 1147 | } 1148 | }, 1149 | "node_modules/parseurl": { 1150 | "version": "1.3.3", 1151 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1152 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1153 | "engines": { 1154 | "node": ">= 0.8" 1155 | } 1156 | }, 1157 | "node_modules/path-is-absolute": { 1158 | "version": "1.0.1", 1159 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1160 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1161 | "engines": { 1162 | "node": ">=0.10.0" 1163 | } 1164 | }, 1165 | "node_modules/path-parse": { 1166 | "version": "1.0.7", 1167 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1168 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 1169 | }, 1170 | "node_modules/path-to-regexp": { 1171 | "version": "0.1.7", 1172 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1173 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1174 | }, 1175 | "node_modules/picomatch": { 1176 | "version": "2.3.1", 1177 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1178 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1179 | "engines": { 1180 | "node": ">=8.6" 1181 | }, 1182 | "funding": { 1183 | "url": "https://github.com/sponsors/jonschlinkert" 1184 | } 1185 | }, 1186 | "node_modules/proxy-addr": { 1187 | "version": "2.0.7", 1188 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1189 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1190 | "dependencies": { 1191 | "forwarded": "0.2.0", 1192 | "ipaddr.js": "1.9.1" 1193 | }, 1194 | "engines": { 1195 | "node": ">= 0.10" 1196 | } 1197 | }, 1198 | "node_modules/punycode": { 1199 | "version": "2.3.1", 1200 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1201 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1202 | "engines": { 1203 | "node": ">=6" 1204 | } 1205 | }, 1206 | "node_modules/qs": { 1207 | "version": "6.11.0", 1208 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1209 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1210 | "dependencies": { 1211 | "side-channel": "^1.0.4" 1212 | }, 1213 | "engines": { 1214 | "node": ">=0.6" 1215 | }, 1216 | "funding": { 1217 | "url": "https://github.com/sponsors/ljharb" 1218 | } 1219 | }, 1220 | "node_modules/range-parser": { 1221 | "version": "1.2.1", 1222 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1223 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1224 | "engines": { 1225 | "node": ">= 0.6" 1226 | } 1227 | }, 1228 | "node_modules/raw-body": { 1229 | "version": "2.5.1", 1230 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1231 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1232 | "dependencies": { 1233 | "bytes": "3.1.2", 1234 | "http-errors": "2.0.0", 1235 | "iconv-lite": "0.4.24", 1236 | "unpipe": "1.0.0" 1237 | }, 1238 | "engines": { 1239 | "node": ">= 0.8" 1240 | } 1241 | }, 1242 | "node_modules/readdirp": { 1243 | "version": "3.6.0", 1244 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1245 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1246 | "dependencies": { 1247 | "picomatch": "^2.2.1" 1248 | }, 1249 | "engines": { 1250 | "node": ">=8.10.0" 1251 | } 1252 | }, 1253 | "node_modules/resolve": { 1254 | "version": "1.22.8", 1255 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 1256 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 1257 | "dependencies": { 1258 | "is-core-module": "^2.13.0", 1259 | "path-parse": "^1.0.7", 1260 | "supports-preserve-symlinks-flag": "^1.0.0" 1261 | }, 1262 | "bin": { 1263 | "resolve": "bin/resolve" 1264 | }, 1265 | "funding": { 1266 | "url": "https://github.com/sponsors/ljharb" 1267 | } 1268 | }, 1269 | "node_modules/rimraf": { 1270 | "version": "2.7.1", 1271 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 1272 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 1273 | "dependencies": { 1274 | "glob": "^7.1.3" 1275 | }, 1276 | "bin": { 1277 | "rimraf": "bin.js" 1278 | } 1279 | }, 1280 | "node_modules/safe-buffer": { 1281 | "version": "5.2.1", 1282 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1283 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1284 | "funding": [ 1285 | { 1286 | "type": "github", 1287 | "url": "https://github.com/sponsors/feross" 1288 | }, 1289 | { 1290 | "type": "patreon", 1291 | "url": "https://www.patreon.com/feross" 1292 | }, 1293 | { 1294 | "type": "consulting", 1295 | "url": "https://feross.org/support" 1296 | } 1297 | ] 1298 | }, 1299 | "node_modules/safer-buffer": { 1300 | "version": "2.1.2", 1301 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1302 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1303 | }, 1304 | "node_modules/send": { 1305 | "version": "0.18.0", 1306 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1307 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1308 | "dependencies": { 1309 | "debug": "2.6.9", 1310 | "depd": "2.0.0", 1311 | "destroy": "1.2.0", 1312 | "encodeurl": "~1.0.2", 1313 | "escape-html": "~1.0.3", 1314 | "etag": "~1.8.1", 1315 | "fresh": "0.5.2", 1316 | "http-errors": "2.0.0", 1317 | "mime": "1.6.0", 1318 | "ms": "2.1.3", 1319 | "on-finished": "2.4.1", 1320 | "range-parser": "~1.2.1", 1321 | "statuses": "2.0.1" 1322 | }, 1323 | "engines": { 1324 | "node": ">= 0.8.0" 1325 | } 1326 | }, 1327 | "node_modules/send/node_modules/ms": { 1328 | "version": "2.1.3", 1329 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1330 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1331 | }, 1332 | "node_modules/serve-static": { 1333 | "version": "1.15.0", 1334 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1335 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1336 | "dependencies": { 1337 | "encodeurl": "~1.0.2", 1338 | "escape-html": "~1.0.3", 1339 | "parseurl": "~1.3.3", 1340 | "send": "0.18.0" 1341 | }, 1342 | "engines": { 1343 | "node": ">= 0.8.0" 1344 | } 1345 | }, 1346 | "node_modules/set-function-length": { 1347 | "version": "1.2.1", 1348 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", 1349 | "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", 1350 | "dependencies": { 1351 | "define-data-property": "^1.1.2", 1352 | "es-errors": "^1.3.0", 1353 | "function-bind": "^1.1.2", 1354 | "get-intrinsic": "^1.2.3", 1355 | "gopd": "^1.0.1", 1356 | "has-property-descriptors": "^1.0.1" 1357 | }, 1358 | "engines": { 1359 | "node": ">= 0.4" 1360 | } 1361 | }, 1362 | "node_modules/setprototypeof": { 1363 | "version": "1.2.0", 1364 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1365 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1366 | }, 1367 | "node_modules/side-channel": { 1368 | "version": "1.0.5", 1369 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", 1370 | "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", 1371 | "dependencies": { 1372 | "call-bind": "^1.0.6", 1373 | "es-errors": "^1.3.0", 1374 | "get-intrinsic": "^1.2.4", 1375 | "object-inspect": "^1.13.1" 1376 | }, 1377 | "engines": { 1378 | "node": ">= 0.4" 1379 | }, 1380 | "funding": { 1381 | "url": "https://github.com/sponsors/ljharb" 1382 | } 1383 | }, 1384 | "node_modules/sift": { 1385 | "version": "16.0.1", 1386 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", 1387 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" 1388 | }, 1389 | "node_modules/source-map": { 1390 | "version": "0.6.1", 1391 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1392 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1393 | "engines": { 1394 | "node": ">=0.10.0" 1395 | } 1396 | }, 1397 | "node_modules/source-map-support": { 1398 | "version": "0.5.21", 1399 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 1400 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 1401 | "dependencies": { 1402 | "buffer-from": "^1.0.0", 1403 | "source-map": "^0.6.0" 1404 | } 1405 | }, 1406 | "node_modules/sparse-bitfield": { 1407 | "version": "3.0.3", 1408 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 1409 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 1410 | "dependencies": { 1411 | "memory-pager": "^1.0.2" 1412 | } 1413 | }, 1414 | "node_modules/statuses": { 1415 | "version": "2.0.1", 1416 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1417 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1418 | "engines": { 1419 | "node": ">= 0.8" 1420 | } 1421 | }, 1422 | "node_modules/strip-bom": { 1423 | "version": "3.0.0", 1424 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1425 | "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", 1426 | "engines": { 1427 | "node": ">=4" 1428 | } 1429 | }, 1430 | "node_modules/strip-json-comments": { 1431 | "version": "2.0.1", 1432 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1433 | "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", 1434 | "engines": { 1435 | "node": ">=0.10.0" 1436 | } 1437 | }, 1438 | "node_modules/supports-preserve-symlinks-flag": { 1439 | "version": "1.0.0", 1440 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1441 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1442 | "engines": { 1443 | "node": ">= 0.4" 1444 | }, 1445 | "funding": { 1446 | "url": "https://github.com/sponsors/ljharb" 1447 | } 1448 | }, 1449 | "node_modules/to-regex-range": { 1450 | "version": "5.0.1", 1451 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1452 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1453 | "dependencies": { 1454 | "is-number": "^7.0.0" 1455 | }, 1456 | "engines": { 1457 | "node": ">=8.0" 1458 | } 1459 | }, 1460 | "node_modules/toidentifier": { 1461 | "version": "1.0.1", 1462 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1463 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1464 | "engines": { 1465 | "node": ">=0.6" 1466 | } 1467 | }, 1468 | "node_modules/tr46": { 1469 | "version": "4.1.1", 1470 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 1471 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 1472 | "dependencies": { 1473 | "punycode": "^2.3.0" 1474 | }, 1475 | "engines": { 1476 | "node": ">=14" 1477 | } 1478 | }, 1479 | "node_modules/tree-kill": { 1480 | "version": "1.2.2", 1481 | "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", 1482 | "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", 1483 | "bin": { 1484 | "tree-kill": "cli.js" 1485 | } 1486 | }, 1487 | "node_modules/ts-node": { 1488 | "version": "10.9.2", 1489 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", 1490 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", 1491 | "dependencies": { 1492 | "@cspotcode/source-map-support": "^0.8.0", 1493 | "@tsconfig/node10": "^1.0.7", 1494 | "@tsconfig/node12": "^1.0.7", 1495 | "@tsconfig/node14": "^1.0.0", 1496 | "@tsconfig/node16": "^1.0.2", 1497 | "acorn": "^8.4.1", 1498 | "acorn-walk": "^8.1.1", 1499 | "arg": "^4.1.0", 1500 | "create-require": "^1.1.0", 1501 | "diff": "^4.0.1", 1502 | "make-error": "^1.1.1", 1503 | "v8-compile-cache-lib": "^3.0.1", 1504 | "yn": "3.1.1" 1505 | }, 1506 | "bin": { 1507 | "ts-node": "dist/bin.js", 1508 | "ts-node-cwd": "dist/bin-cwd.js", 1509 | "ts-node-esm": "dist/bin-esm.js", 1510 | "ts-node-script": "dist/bin-script.js", 1511 | "ts-node-transpile-only": "dist/bin-transpile.js", 1512 | "ts-script": "dist/bin-script-deprecated.js" 1513 | }, 1514 | "peerDependencies": { 1515 | "@swc/core": ">=1.2.50", 1516 | "@swc/wasm": ">=1.2.50", 1517 | "@types/node": "*", 1518 | "typescript": ">=2.7" 1519 | }, 1520 | "peerDependenciesMeta": { 1521 | "@swc/core": { 1522 | "optional": true 1523 | }, 1524 | "@swc/wasm": { 1525 | "optional": true 1526 | } 1527 | } 1528 | }, 1529 | "node_modules/ts-node-dev": { 1530 | "version": "2.0.0", 1531 | "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-2.0.0.tgz", 1532 | "integrity": "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==", 1533 | "dependencies": { 1534 | "chokidar": "^3.5.1", 1535 | "dynamic-dedupe": "^0.3.0", 1536 | "minimist": "^1.2.6", 1537 | "mkdirp": "^1.0.4", 1538 | "resolve": "^1.0.0", 1539 | "rimraf": "^2.6.1", 1540 | "source-map-support": "^0.5.12", 1541 | "tree-kill": "^1.2.2", 1542 | "ts-node": "^10.4.0", 1543 | "tsconfig": "^7.0.0" 1544 | }, 1545 | "bin": { 1546 | "ts-node-dev": "lib/bin.js", 1547 | "tsnd": "lib/bin.js" 1548 | }, 1549 | "engines": { 1550 | "node": ">=0.8.0" 1551 | }, 1552 | "peerDependencies": { 1553 | "node-notifier": "*", 1554 | "typescript": "*" 1555 | }, 1556 | "peerDependenciesMeta": { 1557 | "node-notifier": { 1558 | "optional": true 1559 | } 1560 | } 1561 | }, 1562 | "node_modules/tsc": { 1563 | "version": "2.0.4", 1564 | "resolved": "https://registry.npmjs.org/tsc/-/tsc-2.0.4.tgz", 1565 | "integrity": "sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q==", 1566 | "bin": { 1567 | "tsc": "bin/tsc" 1568 | } 1569 | }, 1570 | "node_modules/tsconfig": { 1571 | "version": "7.0.0", 1572 | "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", 1573 | "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", 1574 | "dependencies": { 1575 | "@types/strip-bom": "^3.0.0", 1576 | "@types/strip-json-comments": "0.0.30", 1577 | "strip-bom": "^3.0.0", 1578 | "strip-json-comments": "^2.0.0" 1579 | } 1580 | }, 1581 | "node_modules/type-is": { 1582 | "version": "1.6.18", 1583 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1584 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1585 | "dependencies": { 1586 | "media-typer": "0.3.0", 1587 | "mime-types": "~2.1.24" 1588 | }, 1589 | "engines": { 1590 | "node": ">= 0.6" 1591 | } 1592 | }, 1593 | "node_modules/typescript": { 1594 | "version": "5.3.3", 1595 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", 1596 | "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", 1597 | "peer": true, 1598 | "bin": { 1599 | "tsc": "bin/tsc", 1600 | "tsserver": "bin/tsserver" 1601 | }, 1602 | "engines": { 1603 | "node": ">=14.17" 1604 | } 1605 | }, 1606 | "node_modules/undici-types": { 1607 | "version": "5.26.5", 1608 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1609 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 1610 | }, 1611 | "node_modules/unpipe": { 1612 | "version": "1.0.0", 1613 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1614 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1615 | "engines": { 1616 | "node": ">= 0.8" 1617 | } 1618 | }, 1619 | "node_modules/utils-merge": { 1620 | "version": "1.0.1", 1621 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1622 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1623 | "engines": { 1624 | "node": ">= 0.4.0" 1625 | } 1626 | }, 1627 | "node_modules/v8-compile-cache-lib": { 1628 | "version": "3.0.1", 1629 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 1630 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" 1631 | }, 1632 | "node_modules/vary": { 1633 | "version": "1.1.2", 1634 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1635 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1636 | "engines": { 1637 | "node": ">= 0.8" 1638 | } 1639 | }, 1640 | "node_modules/webidl-conversions": { 1641 | "version": "7.0.0", 1642 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 1643 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 1644 | "engines": { 1645 | "node": ">=12" 1646 | } 1647 | }, 1648 | "node_modules/whatwg-url": { 1649 | "version": "13.0.0", 1650 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 1651 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 1652 | "dependencies": { 1653 | "tr46": "^4.1.1", 1654 | "webidl-conversions": "^7.0.0" 1655 | }, 1656 | "engines": { 1657 | "node": ">=16" 1658 | } 1659 | }, 1660 | "node_modules/wrappy": { 1661 | "version": "1.0.2", 1662 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1663 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 1664 | }, 1665 | "node_modules/xtend": { 1666 | "version": "4.0.2", 1667 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1668 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 1669 | "engines": { 1670 | "node": ">=0.4" 1671 | } 1672 | }, 1673 | "node_modules/yn": { 1674 | "version": "3.1.1", 1675 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 1676 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 1677 | "engines": { 1678 | "node": ">=6" 1679 | } 1680 | } 1681 | } 1682 | } 1683 | -------------------------------------------------------------------------------- /kafkaserver/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kafkaserver", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "ts-node-dev index.ts", 9 | "dev": "ts-node-dev index2.ts", 10 | "producer": "ts-node-dev kafka/producer.ts", 11 | "admin": "ts-node-dev kafka/admin.ts" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "dependencies": { 17 | "@types/cors": "^2.8.17", 18 | "@types/dotenv": "^8.2.0", 19 | "@types/express": "^4.17.21", 20 | "@types/kafkajs": "^1.9.0", 21 | "@types/mongoose": "^5.11.97", 22 | "cors": "^2.8.5", 23 | "dotenv": "^16.4.1", 24 | "express": "^4.18.2", 25 | "kafkajs": "^2.2.4", 26 | "mongoose": "^8.1.1", 27 | "ts-node-dev": "^2.0.0", 28 | "tsc": "^2.0.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kafkaserver/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": [], /* 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 legacy experimental 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": "node10", /* 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 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "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. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | --------------------------------------------------------------------------------