diff --git a/01-js/easy/anagram.js b/01-js/easy/anagram.js index 8184c83083..7ac1ec3885 100644 --- a/01-js/easy/anagram.js +++ b/01-js/easy/anagram.js @@ -6,6 +6,15 @@ function isAnagram(str1, str2) { -} + let newStr1= str1.toLowerCase().split("").sort().join(""); + let newStr2= str2.toLowerCase().split("").sort().join(""); + if(newStr1===newStr2){ + return true; + } + else{ + return false; + } +} +isAnagram("showkat", "akwohst") module.exports = isAnagram; diff --git a/01-js/easy/expenditure-analysis.js b/01-js/easy/expenditure-analysis.js index 09c4013040..74ef344622 100644 --- a/01-js/easy/expenditure-analysis.js +++ b/01-js/easy/expenditure-analysis.js @@ -14,7 +14,8 @@ */ function calculateTotalSpentByCategory(transactions) { - return []; + const categoryTotals = {}; + } module.exports = calculateTotalSpentByCategory; diff --git a/01-js/easy/findLargestElement.js b/01-js/easy/findLargestElement.js index 33278de43a..103af7a3de 100644 --- a/01-js/easy/findLargestElement.js +++ b/01-js/easy/findLargestElement.js @@ -5,8 +5,13 @@   - Output: 9 */ + function findLargestElement(numbers) { - + if(numbers.length==0){ + return undefined; + } + let highest = Math.max(...numbers); + return highest; } module.exports = findLargestElement; \ No newline at end of file diff --git a/01-js/hard/calculator.js b/01-js/hard/calculator.js index fb60142b79..b026d7a129 100644 --- a/01-js/hard/calculator.js +++ b/01-js/hard/calculator.js @@ -15,7 +15,40 @@ Once you've implemented the logic, test your code by running */ +const math = require("mathjs") -class Calculator {} +class Calculator { + constructor (){ + this.result =0; + } + add(n){ + this.result = this.result + n + } + subtract (n){ + this.result = this.result - n + } + multiply (n){ + this.result = this.result * n + } + divide(n){ + if (n == 0){ + throw new Error("its undefined") + } else { + this.result = this.result / parseFloat(n) + } + } + clear (){ + this.result = 0 + } + getResult (){ + return this.result + } + calculate (str){ + this.result= math.evaluate(str) + if (this.result== Infinity){ + throw new Error("invalid expression") + } + } +} module.exports = Calculator; diff --git a/01-js/hard/todo-list.js b/01-js/hard/todo-list.js index 381d6d0754..37eab8e571 100644 --- a/01-js/hard/todo-list.js +++ b/01-js/hard/todo-list.js @@ -11,7 +11,41 @@ */ class Todo { + constructor(todos){ + this.todos = []; + } + add(todo){ + this.todos.push(todo) + } + + remove(index){ + if(index>= 0 && index= 0 && index= 0 && index=6.9.0" + } + }, + "node_modules/complex.js": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.2.5.tgz", + "integrity": "sha512-U3pSYTZz5Af/xvHgKQkJYHBMGmae7Ms51qqJougCR05YWF1Fihef4LRfOpBFONH2gvPFHMZq2rhx0I44DG23xw==", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + }, + "node_modules/mathjs": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.2.0.tgz", + "integrity": "sha512-P5PZoiUX2Tkghkv3tsSqlK0B9My/ErKapv1j6wdxd0MOrYQ30cnGE4LH/kzYB2gA5rN46Njqc4cFgJjaxgijoQ==", + "dependencies": { + "@babel/runtime": "^7.25.6", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^4.3.7", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "node_modules/typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "engines": { + "node": ">= 18" + } + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "complex.js": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.2.5.tgz", + "integrity": "sha512-U3pSYTZz5Af/xvHgKQkJYHBMGmae7Ms51qqJougCR05YWF1Fihef4LRfOpBFONH2gvPFHMZq2rhx0I44DG23xw==" + }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, + "fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" + }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + }, + "mathjs": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-13.2.0.tgz", + "integrity": "sha512-P5PZoiUX2Tkghkv3tsSqlK0B9My/ErKapv1j6wdxd0MOrYQ30cnGE4LH/kzYB2gA5rN46Njqc4cFgJjaxgijoQ==", + "requires": { + "@babel/runtime": "^7.25.6", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^4.3.7", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" + } + }, + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==" } } } diff --git a/01-js/package.json b/01-js/package.json index 57a256da87..ca0393a859 100644 --- a/01-js/package.json +++ b/01-js/package.json @@ -8,5 +8,8 @@ }, "keywords": [], "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "mathjs": "^13.2.0" + } } diff --git a/week-2/01-async-js/.gitignore b/week-2/01-async-js/.gitignore deleted file mode 100644 index 836bcdebaf..0000000000 --- a/week-2/01-async-js/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -solutions \ No newline at end of file diff --git a/week-2/01-async-js/easy/1-counter.md b/week-2/01-async-js/easy/1-counter.md index 54483eabc4..ae2171d235 100644 --- a/week-2/01-async-js/easy/1-counter.md +++ b/week-2/01-async-js/easy/1-counter.md @@ -1,4 +1,21 @@ ## Create a counter in JavaScript We have already covered this in the second lesson, but as an easy recap try to code a counter in Javascript -It should go up as time goes by in intervals of 1 second \ No newline at end of file +It should go up as time goes by in intervals of 1 second. + + +let count = 0 + +console.log(count) + +function counter() { + let countt = setInterval(() => { + console.log(++count) + if (count >= 10) { + clearInterval(countt) + } + }, 1000) +} + + +counter() diff --git a/week-2/01-async-js/easy/2-counter.md b/week-2/01-async-js/easy/2-counter.md index db5f2fffa1..4a338205e2 100644 --- a/week-2/01-async-js/easy/2-counter.md +++ b/week-2/01-async-js/easy/2-counter.md @@ -3,7 +3,20 @@ Without using setInterval, try to code a counter in Javascript. There is a hint at the bottom of the file if you get stuck. +let count = 0; +function counter(){ + if(count>=21){ + clearInterval(wetinterval) + } + console.log(count++) + let wetinterval= setTimeout(()=> { + counter() + }, 1000) + +} + +counter() diff --git a/week-2/01-async-js/easy/3-read-from-file.md b/week-2/01-async-js/easy/3-read-from-file.md index f619d71aed..598c4f2fcd 100644 --- a/week-2/01-async-js/easy/3-read-from-file.md +++ b/week-2/01-async-js/easy/3-read-from-file.md @@ -5,3 +5,17 @@ You can use the fs library to as a black box, the goal is to understand async ta Try to do an expensive operation below the file read and see how it affects the output. Make the expensive operation more and more expensive and see how it affects the output. + +const fs = require("fs") + +function read (){ +fs.readFile("abx.txt", "utf-8", (err, data)=>{ + if(err){ + console.log(err) + return + } + console.log(data) +}) +} + +read() diff --git a/week-2/01-async-js/easy/4-write-to-file.md b/week-2/01-async-js/easy/4-write-to-file.md index f1c151f98f..28758d0984 100644 --- a/week-2/01-async-js/easy/4-write-to-file.md +++ b/week-2/01-async-js/easy/4-write-to-file.md @@ -1,3 +1,18 @@ ## Write to a file Using the fs library again, try to write to the contents of a file. -You can use the fs library to as a black box, the goal is to understand async tasks. \ No newline at end of file +You can use the fs library to as a black box, the goal is to understand async tasks. + + +const fs = require("fs") + +function write (){ +fs.writeFile("abx.txt", "hello hadi","utf-8", (err) =>{ + if(err){ + console.log(err) + return + } + console.log("wrote successfully") +}) +} + +write() diff --git a/week-2/01-async-js/hard (promises)/1-promisify-setTimeout.js b/week-2/01-async-js/hard (promises)/1-promisify-setTimeout.js index 32a99c83fc..d745e0f7f2 100644 --- a/week-2/01-async-js/hard (promises)/1-promisify-setTimeout.js +++ b/week-2/01-async-js/hard (promises)/1-promisify-setTimeout.js @@ -3,6 +3,9 @@ */ function wait(n) { -} + return new Promise((resolve,reject) =>{ + setTimeout(resolve, n*1000); + }) +} module.exports = wait; diff --git a/week-2/01-async-js/hard (promises)/2-sleep-completely.js b/week-2/01-async-js/hard (promises)/2-sleep-completely.js index a171170b09..4c242cfcec 100644 --- a/week-2/01-async-js/hard (promises)/2-sleep-completely.js +++ b/week-2/01-async-js/hard (promises)/2-sleep-completely.js @@ -4,7 +4,21 @@ * the function should return a promise just like before */ +console.log("before halting"); function sleep(milliseconds) { + let startTime = Date.now(); + while (Date.now() - startTime < milliseconds) {} + return new Promise((resolve, reject) => { + resolve(); + }); } +async function relieved() { + await sleep(10000); + console.log("äfter halting"); +} + +relieved() + + module.exports = sleep; diff --git a/week-2/01-async-js/hard (promises)/3-promise-all.js b/week-2/01-async-js/hard (promises)/3-promise-all.js index a57838ade0..ac001874f3 100644 --- a/week-2/01-async-js/hard (promises)/3-promise-all.js +++ b/week-2/01-async-js/hard (promises)/3-promise-all.js @@ -4,20 +4,34 @@ * Return a promise.all which return the time in milliseconds it takes to complete the entire operation. */ -function wait1(t) { - +function wait1(t1) { + return new Promise ((resolve, reject)=> { + setTimeout(resolve, t1*1000) + }) } -function wait2(t) { - +function wait2(t2) { + return new Promise ((resolve, reject)=> { + setTimeout(resolve, t2*1000) + }) } -function wait3(t) { - +function wait3(t3) { + return new Promise ((resolve, reject)=> { + setTimeout(resolve, t3*1000) + }) } function calculateTime(t1, t2, t3) { - + const start = Date.now() + return Promise.all([wait1(t1), wait2(t2), wait3(t3)]).then(()=>{ + const end = Date.now() + totalTime = end - start + return totalTime + }) } + +// console.log(calculateTime) + module.exports = calculateTime; diff --git a/week-2/01-async-js/hard (promises)/4-promise-chain.js b/week-2/01-async-js/hard (promises)/4-promise-chain.js index 6044e241f7..0644b5ab62 100644 --- a/week-2/01-async-js/hard (promises)/4-promise-chain.js +++ b/week-2/01-async-js/hard (promises)/4-promise-chain.js @@ -5,20 +5,48 @@ * Compare it with the results from 3-promise-all.js */ -function wait1(t) { - +function wait1(t1) { + return new Promise ((resolve, reject )=>{ + setTimeout(resolve, t1*1000) + }) } -function wait2(t) { - +function wait2(t2){ + return new Promise ((resolve, reject )=>{ + setTimeout(resolve, t2*1000) + }) } -function wait3(t) { +function wait3(t3) { + return new Promise ((resolve, reject )=>{ + setTimeout(resolve, t3*1000) + }) +} +// function calculateTime(t1, t2, t3) { +// let startTime = Date.now() +// wait1(t1).then (()=>{ +// return wait2(t2) +// }).then(()=>{ +// return wait3(t3) +// }).then(() => { +// timeTaken = Date.now() - startTime +// return timeTaken +// }) +// } + +async function calculateTime(t1, t2, t3) { + let startTime = Date.now() + wait1(t1) + wait2(t2) + wait3(t3) + await( () => { + timeTaken = Date.now() - startTime + return timeTaken + }) } -function calculateTime(t1, t2, t3) { -} + module.exports = calculateTime; diff --git a/week-2/01-async-js/medium/1-file-cleaner.md b/week-2/01-async-js/medium/1-file-cleaner.md index 2be6e450b2..5322da2a69 100644 --- a/week-2/01-async-js/medium/1-file-cleaner.md +++ b/week-2/01-async-js/medium/1-file-cleaner.md @@ -10,4 +10,27 @@ After the program runs, the output should be ``` hello world my name is raman -``` \ No newline at end of file +``` + + + +const fs = require("fs") + + +fs.readFile("abx.txt", "utf-8", (err,data) =>{ + if(err){ + console.log(err) + return + } + let newData = data.replace(/\s+/g, ' ') + + + +fs.writeFile("abx.txt", newData ,"utf-8", (err) =>{ + if(err){ + console.log(err) + return + } + console.log("wrote successfully") +}) +}) \ No newline at end of file diff --git a/week-2/01-async-js/medium/2-clock.md b/week-2/01-async-js/medium/2-clock.md index 4a034c671b..1a978a5b2e 100644 --- a/week-2/01-async-js/medium/2-clock.md +++ b/week-2/01-async-js/medium/2-clock.md @@ -1,4 +1,7 @@ -Using `1-counter.md` or `2-counter.md` from the easy section, can you create a + + + +using `1-counter.md` or `2-counter.md` from the easy section, can you create a clock that shows you the current machine time? Can you make it so that it updates every second, and shows time in the following formats - @@ -6,3 +9,37 @@ Can you make it so that it updates every second, and shows time in the following - HH:MM::SS (Eg. 13:45:23) - HH:MM::SS AM/PM (Eg 01:45:23 PM) + +setInterval(() => { + let hour = new Date().getHours(); + let min = new Date().getMinutes(); + let sec = new Date().getSeconds(); + console.log(hour + ":" + min + ":" + sec) + let am_pm = "am"; + if(hour>12){ + am_pm = "pm" + console.log(hour + ":" + min + ":" + sec+ am_pm) + }else{ + console.log(hour + ":" + min + ":" + sec+am_pm) + } +}, 1000) + + + + + + + + + + + + + + + + + + + + diff --git a/week-2/02-nodejs/fileServer.js b/week-2/02-nodejs/fileServer.js index f1329bd001..95a54d6d39 100644 --- a/week-2/02-nodejs/fileServer.js +++ b/week-2/02-nodejs/fileServer.js @@ -5,6 +5,7 @@ 1. GET /files - Returns a list of files present in `./files/` directory Response: 200 OK with an array of file names in JSON format. Example: GET http://localhost:3000/files + 2. GET /file/:filename - Returns content of given file by name Description: Use the filename from the request path parameter to read the file from `./files/` directory Response: 200 OK with the file content as the response body if found, or 404 Not Found if not found. Should return `File not found` as text if file is not found @@ -17,5 +18,38 @@ const fs = require('fs'); const path = require('path'); const app = express(); +app.get("/files", (req, res) => { + const fileAddress= path.join(__dirname, "./files") + fs.readdir(fileAddress, (err, data) => { + if (err) { + console.log(error) + res.status(500).json({ "error": "error reading data" }) + } else { + res.status(200).json(data); + + } + } + ) +}) + + +app.get("/file/:filename", (req,res)=>{ + + const filename = req.params.filename + const filePath = path.join(__dirname, "./files", filename) + fs.readFile(filePath, utf-8, (err,data) =>{ + if(err){ + console.log(err) + res.status(404).json({"message": "not found"}) + } else{ + res.status(200).json(data) + } + }) +}) + +app.use((req,res) => { + res.status(404).send("route not found ") +}) + module.exports = app; \ No newline at end of file diff --git a/week-2/02-nodejs/todoServer.js b/week-2/02-nodejs/todoServer.js index 4b55de9f9e..445eb56e62 100644 --- a/week-2/02-nodejs/todoServer.js +++ b/week-2/02-nodejs/todoServer.js @@ -1,49 +1,111 @@ -/** - You need to create an express HTTP server in Node.js which will handle the logic of a todo list app. - - Don't use any database, just store all the data in an array to store the todo list data (in-memory) - - Hard todo: Try to save responses in files, so that even if u exit the app and run it again, the data remains (similar to databases) - - Each todo has a title and a description. The title is a string and the description is a string. - Each todo should also get an unique autogenerated id every time it is created - The expected API endpoints are defined below, - 1.GET /todos - Retrieve all todo items - Description: Returns a list of all todo items. - Response: 200 OK with an array of todo items in JSON format. - Example: GET http://localhost:3000/todos - - 2.GET /todos/:id - Retrieve a specific todo item by ID - Description: Returns a specific todo item identified by its ID. - Response: 200 OK with the todo item in JSON format if found, or 404 Not Found if not found. - Example: GET http://localhost:3000/todos/123 - - 3. POST /todos - Create a new todo item - Description: Creates a new todo item. - Request Body: JSON object representing the todo item. - Response: 201 Created with the ID of the created todo item in JSON format. eg: {id: 1} - Example: POST http://localhost:3000/todos - Request Body: { "title": "Buy groceries", "completed": false, description: "I should buy groceries" } - - 4. PUT /todos/:id - Update an existing todo item by ID - Description: Updates an existing todo item identified by its ID. - Request Body: JSON object representing the updated todo item. - Response: 200 OK if the todo item was found and updated, or 404 Not Found if not found. - Example: PUT http://localhost:3000/todos/123 - Request Body: { "title": "Buy groceries", "completed": true } - - 5. DELETE /todos/:id - Delete a todo item by ID - Description: Deletes a todo item identified by its ID. - Response: 200 OK if the todo item was found and deleted, or 404 Not Found if not found. - Example: DELETE http://localhost:3000/todos/123 - - - For any other route not defined in the server return 404 - - Testing the server - run `npm run test-todoServer` command in terminal - */ - const express = require('express'); - const bodyParser = require('body-parser'); - - const app = express(); - - app.use(bodyParser.json()); - - module.exports = app; \ No newline at end of file +// // /** +// // You need to create an express HTTP server in Node.js which will handle the logic of a todo list app. +// - Don't use any database, just store all the data in an array to store the todo list data (in-memory) +// - Hard todo: Try to save responses in files, so that even if u exit the app and run it again, the data remains(similar to databases) + +// Each todo has a title and a description.The title is a string an d the description is a string. +// Each todo should also get an unique autogenerated id every time it is created +// The expected API endpoints are defined below, +// 1.GET / todos - Retrieve all todo items +// Description: Returns a list of all todo items. +// Response: 200 OK with an array of todo items in JSON format. +// Example: GET http://localhost:3000/todos + +// 2.GET / todos /: id - Retrieve a specific todo item by ID +// Description: Returns a specific todo item identified by its ID. +// Response: 200 OK with the todo item in JSON format if found, or 404 Not Found if not found. +// Example: GET http://localhost:3000/todos/123 + +// 3. POST / todos - Create a new todo item +// Description: Creates a new todo item. +// Request Body: JSON object representing the todo item. +// Response: 201 Created with the ID of the created todo item in JSON format.eg: { id: 1 } +// Example: POST http://localhost:3000/todos +// Request Body: { "title": "Buy groceries", "completed": false, description: "I should buy groceries" } + +// 4. PUT / todos /: id - Update an existing todo item by ID +// Description: Updates an existing todo item identified by its ID. +// Request Body: JSON object representing the updated todo item. +// Response: 200 OK if the todo item was found and updated, or 404 Not Found if not found. +// Example: PUT http://localhost:3000/todos/123 +// Request Body: { "title": "Buy groceries", "completed": true } + +// 5. DELETE / todos /: id - Delete a todo item by ID +// Description: Deletes a todo item identified by its ID. +// Response: 200 OK if the todo item was found and deleted, or 404 Not Found if not found. +// Example: DELETE http://localhost:3000/todos/123 + +// - For any other route not defined in the server return 404 + +// Testing the server - run`npm run test-todoServer` command in terminal +// */ + +const express = require("express") + +const app = express() + +app.use(express.json()) + +let todos = [] + +app.get("/todos", (req, res) => { + res.status(200).json(todos) +}) + +app.get("/todos/:id", (req, res) => { + let todoId = req.params.todoId + for (let i = 0; i < todos.length; i++) { + if (todos[i].id == todoId) { + res.status(200).json(todos[i]) + } else { + res.status(404).send("not found") + } + } +}) + + +app.post("/todos", (req, res) => { + let newTodo = { + todo: req.body.todo, + id: Math.round(Math.random()) * 1000, + description: req.body.description + } + todos.push(newTodo) + res.status(201).json(newTodo) +}) + + +app.put("/todos/:id", (req, res) => { + let changeId = req.params.changeId + let newTodo = req.body.newTodo + for (let i = 0; i < todos.length; i++) { + if (todos[i].id == changeId) { + todos[i].todo = newTodo + res.status(200).json(todos[i]) + } else { + res.status(404).send("cant find") + } + } +}) + + +app.delete("/todos/:id", (req, res) => { + let deleteId = req.params.deleteId + for (let i = 0; i < todos.length; i++) { + if (todos[i].id == deleteId) { + todos.splice(todos[i], 1) + res.status(200).send("found and deleted") + } else { + res.status(404).send("not found") + } + } +}) + +app.use((req, res) => { + res.status(404).send("error") +}) + +app.listen(3000) + + +module.exports = app \ No newline at end of file diff --git a/week-3/01-middlewares/01-requestcount.js b/week-3/01-middlewares/01-requestcount.js index aced495488..98cc72bdeb 100644 --- a/week-3/01-middlewares/01-requestcount.js +++ b/week-3/01-middlewares/01-requestcount.js @@ -5,11 +5,18 @@ const express = require('express'); const app = express(); let requestCount = 0; +function requestCounter(req,res,next) { + requestCount = requestCount+1 + next() +} + // You have been given an express server which has a few endpoints. // Your task is to create a global middleware (app.use) which will // maintain a count of the number of requests made to the server in the global // requestCount variable +app.use(requestCounter) + app.get('/user', function(req, res) { res.status(200).json({ name: 'john' }); }); @@ -18,6 +25,9 @@ app.post('/user', function(req, res) { res.status(200).json({ msg: 'created dummy user' }); }); + + + app.get('/requestCount', function(req, res) { res.status(200).json({ requestCount }); }); diff --git a/week-3/01-middlewares/02-ratelimitter.js b/week-3/01-middlewares/02-ratelimitter.js index 3329bb9497..8f98e02736 100644 --- a/week-3/01-middlewares/02-ratelimitter.js +++ b/week-3/01-middlewares/02-ratelimitter.js @@ -12,10 +12,33 @@ const app = express(); // clears every one second let numberOfRequestsForUser = {}; + setInterval(() => { - numberOfRequestsForUser = {}; + numberOfRequestsForUser = {}; }, 1000) + + +function rateLimitter(req,res,next){ + let userid = req.headers["user-id"] + if(numberOfRequestsForUser.userid){ + numberOfRequestsForUser.userid += 1 + } + else { + numberOfRequestsForUser.userid =1 + next() + } + if(numberOfRequestsForUser.userid>5){ + res.status(404).json({msg: "limit exceeded"}) + }else{ + next() + } +} + +app.use(rateLimitter) + + + app.get('/user', function(req, res) { res.status(200).json({ name: 'john' }); }); diff --git a/week-3/01-middlewares/03-errorcount.js b/week-3/01-middlewares/03-errorcount.js index c5374ae6ef..ecdad5533a 100644 --- a/week-3/01-middlewares/03-errorcount.js +++ b/week-3/01-middlewares/03-errorcount.js @@ -5,6 +5,14 @@ const express = require('express'); const app = express(); let errorCount = 0; +// function errorCounter(){ +// if(Error){ +// errorCount = errorCount+1 +// } +// } + +// app.use(errorCounter) + // You have been given an express server which has a few endpoints. // Your task is to // 1. Ensure that if there is ever an exception, the end user sees a status code of 404 @@ -23,4 +31,9 @@ app.get('/errorCount', function(req, res) { res.status(200).json({ errorCount }); }); +app.use((err,req,res,next)=>{ + errorCount = errorCount +1; + res.status(404).json({msg: "we fucked up"}) +}) + module.exports = app; \ No newline at end of file diff --git a/week-3/01-middlewares/coverage/clover.xml b/week-3/01-middlewares/coverage/clover.xml new file mode 100644 index 0000000000..499314e26f --- /dev/null +++ b/week-3/01-middlewares/coverage/clover.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/week-3/01-middlewares/coverage/coverage-final.json b/week-3/01-middlewares/coverage/coverage-final.json new file mode 100644 index 0000000000..6b8ae4c90b --- /dev/null +++ b/week-3/01-middlewares/coverage/coverage-final.json @@ -0,0 +1,2 @@ +{"/home/hadeerasool/assignmentsxkirat/week-3/01-middlewares/02-ratelimitter.js": {"path":"/home/hadeerasool/assignmentsxkirat/week-3/01-middlewares/02-ratelimitter.js","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":33}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":35}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":22}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":67}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":66}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":67}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":70}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":32}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":67}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":79}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":26}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":0}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":33}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":19}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":31}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":8}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":0}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":0}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":36}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":37}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":37}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":39}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":5}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":10}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":39}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":12}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":5}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":41}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":51}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":10}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":12}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":5}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":1}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":0}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":21}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":0}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":0}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":0}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":37}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":41}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":38}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":54}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":3}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":0}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":21}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":2,"17":1,"18":1,"19":1,"20":1,"21":13,"22":13,"23":13,"24":11,"25":11,"26":2,"27":2,"28":2,"29":2,"30":13,"31":7,"32":13,"33":6,"34":6,"35":13,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":6,"43":1,"44":1,"45":1,"46":0,"47":1,"48":1,"49":1},"branchMap":{"0":{"type":"branch","line":16,"loc":{"start":{"line":16,"column":12},"end":{"line":18,"column":3}},"locations":[{"start":{"line":16,"column":12},"end":{"line":18,"column":3}}]},"1":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":0},"end":{"line":36,"column":1}},"locations":[{"start":{"line":22,"column":0},"end":{"line":36,"column":1}}]},"2":{"type":"branch","line":24,"loc":{"start":{"line":24,"column":36},"end":{"line":26,"column":5}},"locations":[{"start":{"line":24,"column":36},"end":{"line":26,"column":5}}]},"3":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":-1},"end":{"line":30,"column":5}},"locations":[{"start":{"line":27,"column":-1},"end":{"line":30,"column":5}}]},"4":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":40},"end":{"line":33,"column":5}},"locations":[{"start":{"line":31,"column":40},"end":{"line":33,"column":5}}]},"5":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":5},"end":{"line":35,"column":5}},"locations":[{"start":{"line":33,"column":5},"end":{"line":35,"column":5}}]},"6":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":17},"end":{"line":44,"column":2}},"locations":[{"start":{"line":42,"column":17},"end":{"line":44,"column":2}}]}},"b":{"0":[2],"1":[13],"2":[11],"3":[2],"4":[7],"5":[6],"6":[6]},"fnMap":{"0":{"name":"rateLimitter","decl":{"start":{"line":22,"column":0},"end":{"line":36,"column":1}},"loc":{"start":{"line":22,"column":0},"end":{"line":36,"column":1}},"line":22}},"f":{"0":13}} +} diff --git a/week-3/01-middlewares/coverage/lcov-report/01-requestcount.js.html b/week-3/01-middlewares/coverage/lcov-report/01-requestcount.js.html new file mode 100644 index 0000000000..f54b86c963 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/01-requestcount.js.html @@ -0,0 +1,187 @@ + + + + + + Code coverage report for 01-requestcount.js + + + + + + + + + +
+
+

All files 01-requestcount.js

+
+ +
+ 97.14% + Statements + 34/35 +
+ + +
+ 100% + Branches + 3/3 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 97.14% + Lines + 34/35 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +351x +1x +1x +1x +1x +1x +1x +12x +12x +12x +12x +1x +1x +1x +1x +1x +1x +1x +1x +1x +10x +1x +1x +1x +  +1x +1x +1x +1x +1x +1x +2x +1x +1x +1x
const request = require('supertest');
+const assert = require('assert');
+const express = require('express');
+ 
+const app = express();
+let requestCount = 0;
+ 
+function requestCounter(req,res,next) {
+  requestCount = requestCount+1
+  next()
+}
+ 
+// You have been given an express server which has a few endpoints.
+// Your task is to create a global middleware (app.use) which will
+// maintain a count of the number of requests made to the server in the global
+// requestCount variable
+ 
+app.use(requestCounter)  
+ 
+app.get('/user', function(req, res) {
+  res.status(200).json({ name: 'john' });
+});
+ 
+app.post('/user', function(req, res) {
+  res.status(200).json({ msg: 'created dummy user' });
+});
+ 
+ 
+ 
+ 
+app.get('/requestCount', function(req, res) {
+  res.status(200).json({ requestCount });
+});
+ 
+module.exports = app;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/week-3/01-middlewares/coverage/lcov-report/02-ratelimitter.js.html b/week-3/01-middlewares/coverage/lcov-report/02-ratelimitter.js.html new file mode 100644 index 0000000000..2055188354 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/02-ratelimitter.js.html @@ -0,0 +1,232 @@ + + + + + + Code coverage report for 02-ratelimitter.js + + + + + + + + + +
+
+

All files 02-ratelimitter.js

+
+ +
+ 98% + Statements + 49/50 +
+ + +
+ 100% + Branches + 7/7 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 98% + Lines + 49/50 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +501x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +2x +1x +1x +1x +1x +13x +13x +13x +11x +11x +2x +2x +2x +2x +13x +7x +13x +6x +6x +13x +1x +1x +1x +1x +1x +1x +6x +1x +1x +1x +  +1x +1x +1x
const request = require('supertest');
+const assert = require('assert');
+const express = require('express');
+const app = express();
+// You have been given an express server which has a few endpoints.
+// Your task is to create a global middleware (app.use) which will
+// rate limit the requests from a user to only 5 request per second
+// If a user sends more than 5 requests in a single second, the server
+// should block them with a 404.
+// User will be sending in their user id in the header as 'user-id'
+// You have been given a numberOfRequestsForUser object to start off with which
+// clears every one second
+ 
+let numberOfRequestsForUser = {};
+ 
+setInterval(() => {
+  numberOfRequestsForUser = {};
+}, 1000)
+ 
+ 
+ 
+function rateLimitter(req,res,next){
+  let userid = req.headers["user-id"]
+  if(numberOfRequestsForUser.userid){
+    numberOfRequestsForUser.userid += 1
+    }
+    else {
+      numberOfRequestsForUser.userid =1
+      next()
+    }
+    if(numberOfRequestsForUser.userid>5){
+      res.status(404).json({msg: "limit exceeded"})
+    }else{
+      next()
+    }
+}
+ 
+app.use(rateLimitter)
+ 
+ 
+ 
+app.get('/user', function(req, res) {
+  res.status(200).json({ name: 'john' });
+});
+ 
+app.post('/user', function(req, res) {
+  res.status(200).json({ msg: 'created dummy user' });
+});
+ 
+module.exports = app;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/week-3/01-middlewares/coverage/lcov-report/03-errorcount.js.html b/week-3/01-middlewares/coverage/lcov-report/03-errorcount.js.html new file mode 100644 index 0000000000..7454f109b1 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/03-errorcount.js.html @@ -0,0 +1,199 @@ + + + + + + Code coverage report for 03-errorcount.js + + + + + + + + + +
+
+

All files 03-errorcount.js

+
+ +
+ 94.87% + Statements + 37/39 +
+ + +
+ 75% + Branches + 3/4 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 94.87% + Lines + 37/39 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +391x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +11x +  +1x +1x +1x +  +1x +1x +1x +2x +1x +1x +1x +11x +11x +11x +1x +1x
const request = require('supertest');
+const assert = require('assert');
+const express = require('express');
+ 
+const app = express();
+let errorCount = 0;
+ 
+// function errorCounter(){
+//   if(Error){
+//     errorCount = errorCount+1
+//   }
+// }
+ 
+// app.use(errorCounter)
+ 
+// You have been given an express server which has a few endpoints.
+// Your task is to
+// 1. Ensure that if there is ever an exception, the end user sees a status code of 404
+// 2. Maintain the errorCount variable whose value should go up every time there is an exception in any endpoint
+ 
+app.get('/user', function(req, res) {
+  throw new Error("User not found");
+  res.status(200).json({ name: 'john' });
+});
+ 
+app.post('/user', function(req, res) {
+  res.status(200).json({ msg: 'created dummy user' });
+});
+ 
+app.get('/errorCount', function(req, res) {
+  res.status(200).json({ errorCount });
+});
+ 
+app.use((err,req,res,next)=>{
+  errorCount = errorCount +1;
+  res.status(404).json({msg: "we fucked up"})
+})
+ 
+module.exports = app;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/week-3/01-middlewares/coverage/lcov-report/base.css b/week-3/01-middlewares/coverage/lcov-report/base.css new file mode 100644 index 0000000000..f418035b46 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/week-3/01-middlewares/coverage/lcov-report/block-navigation.js b/week-3/01-middlewares/coverage/lcov-report/block-navigation.js new file mode 100644 index 0000000000..cc12130231 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/week-3/01-middlewares/coverage/lcov-report/favicon.png b/week-3/01-middlewares/coverage/lcov-report/favicon.png new file mode 100644 index 0000000000..c1525b811a Binary files /dev/null and b/week-3/01-middlewares/coverage/lcov-report/favicon.png differ diff --git a/week-3/01-middlewares/coverage/lcov-report/index.html b/week-3/01-middlewares/coverage/lcov-report/index.html new file mode 100644 index 0000000000..527b73c43c --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 98% + Statements + 49/50 +
+ + +
+ 100% + Branches + 7/7 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 98% + Lines + 49/50 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
02-ratelimitter.js +
+
98%49/50100%7/7100%1/198%49/50
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/week-3/01-middlewares/coverage/lcov-report/prettify.css b/week-3/01-middlewares/coverage/lcov-report/prettify.css new file mode 100644 index 0000000000..b317a7cda3 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/week-3/01-middlewares/coverage/lcov-report/prettify.js b/week-3/01-middlewares/coverage/lcov-report/prettify.js new file mode 100644 index 0000000000..b3225238f2 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/week-3/01-middlewares/coverage/lcov-report/sort-arrow-sprite.png b/week-3/01-middlewares/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000..6ed68316eb Binary files /dev/null and b/week-3/01-middlewares/coverage/lcov-report/sort-arrow-sprite.png differ diff --git a/week-3/01-middlewares/coverage/lcov-report/sorter.js b/week-3/01-middlewares/coverage/lcov-report/sorter.js new file mode 100644 index 0000000000..2bb296a8ca --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov-report/sorter.js @@ -0,0 +1,196 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if ( + row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/week-3/01-middlewares/coverage/lcov.info b/week-3/01-middlewares/coverage/lcov.info new file mode 100644 index 0000000000..7d50280d38 --- /dev/null +++ b/week-3/01-middlewares/coverage/lcov.info @@ -0,0 +1,68 @@ +TN: +SF:02-ratelimitter.js +FN:22,rateLimitter +FNF:1 +FNH:1 +FNDA:13,rateLimitter +DA:1,1 +DA:2,1 +DA:3,1 +DA:4,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:9,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +DA:17,2 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,13 +DA:23,13 +DA:24,13 +DA:25,11 +DA:26,11 +DA:27,2 +DA:28,2 +DA:29,2 +DA:30,2 +DA:31,13 +DA:32,7 +DA:33,13 +DA:34,6 +DA:35,6 +DA:36,13 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:43,6 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,0 +DA:48,1 +DA:49,1 +DA:50,1 +LF:50 +LH:49 +BRDA:16,0,0,2 +BRDA:22,1,0,13 +BRDA:24,2,0,11 +BRDA:27,3,0,2 +BRDA:31,4,0,7 +BRDA:33,5,0,6 +BRDA:42,6,0,6 +BRF:7 +BRH:7 +end_of_record diff --git a/week-3/02-jwt/index.js b/week-3/02-jwt/index.js index fb7c604c81..ed6db83ff6 100644 --- a/week-3/02-jwt/index.js +++ b/week-3/02-jwt/index.js @@ -1,6 +1,9 @@ const jwt = require('jsonwebtoken'); const jwtPassword = 'secret'; +const zod = require("zod") +const schemaUsername = zod.string().email() +const schemaPassword = zod.string().min(6) /** * Generates a JWT for a given username and password. @@ -14,7 +17,13 @@ const jwtPassword = 'secret'; * the password does not meet the length requirement. */ function signJwt(username, password) { - // Your code here + const user = schemaUsername.safeParse(username) + const pass = schemaPassword.safeParse(password) + if( !user.success || !pass.success){ + return null + } + const token = jwt.sign({username}, jwtPassword) + return token } /** @@ -26,7 +35,17 @@ function signJwt(username, password) { * using the secret key. */ function verifyJwt(token) { - // Your code here + let verification = true + try{ + const verified= jwt.verify(token, jwtPassword) + if(verified){ + verification = true + } + } catch(e){ + verification = false + } + return verification + } /** @@ -37,7 +56,12 @@ function verifyJwt(token) { * Returns false if the token is not a valid JWT format. */ function decodeJwt(token) { - // Your code here + const decode = jwt.decode(token) + if(decode){ + return true + }else { + return false + } }