# NodeJS - Executable for nodejs app [https://www.youtube.com/watch?v=50f6y-npKAY](https://www.youtube.com/watch?v=50f6y-npKAY) `npm i -g pkg` `pkg app.js` [https://www.youtube.com/watch?v=crnaBzztX44](https://www.youtube.com/watch?v=crnaBzztX44) [https://www.npmjs.com/package/pkg](https://www.npmjs.com/package/pkg) in package.json add: ```json "pkg": { "scripts": "build/**/*.js", "assets": ["views/**/*","public/**","build/**"], "targets": [ "node14-win-x64" ] } ``` Now type: `pkg app.js -c package.json` this will create the exe file. In assets resources is assigned like build/** so that all build folder is included as its front end in smart brain app. if we have images folder then include that too. - converting callback to async/await ```jsx const promiseSetTimeOut = (time) => { return new Promise((resolve) => { setTimeout(() => { resolve(); }, time); }); }; // or // delay.js export function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } ``` - apk version fo nodejs app [Apache Cordova app development setup guide - Andrés Zsögön (andreszsogon.com)](https://www.andreszsogon.com/setting-up-your-environment-for-apache-cordova-apps/) [https://cordova.apache.org/docs/en/3.5.0/guide/cli/index.html](https://cordova.apache.org/docs/en/3.5.0/guide/cli/index.html) expressjs in mobile: [https://www.sitepoint.com/how-to-run-node-js-with-express-on-mobile-devices/](https://www.sitepoint.com/how-to-run-node-js-with-express-on-mobile-devices/) [https://github.com/node-on-mobile/node-on-android](https://github.com/node-on-mobile/node-on-android) - Exposing localhost to internet for testing ```jsx const localtunnel = require('localtunnel'); (async () => { const tunnel = await localtunnel({ port: 80 }); // the assigned public url for your tunnel // i.e. https://abcdefgjhij.localtunnel.me // tunnel.url; console.log('url: ',tunnel.url) tunnel.on('close', () => { // tunnels are closed }); })(); ``` Ngrok: Install ngrok or add ngrok.exe file in environment path from [https://ngrok.com/download](https://ngrok.com/download) If local nodejs app is started in port number say 3000 then type `ngrok http 3000` public url wil be printed in terminal or access by [http://localhost:4040](http://localhost:4040/) [NodeGUI](../../Export-9fad9947-5bd5-4195-952b-6512c5a4beb1/Web%20development%2083dd4e6675f04ba782a6865a434a0598/NodeJS%206d499253059041d699e2e6fa36ded013/NodeGUI%20ac8ad0b3e1a74e0ca752c60add16e6ce.md) - Extract metadata [https://www.npmjs.com/package/metadata-scraper?activeTab=readme](https://www.npmjs.com/package/metadata-scraper?activeTab=readme) [](https://www.npmjs.com/package/metadata-scraper?activeTab=readme) [https://www.npmjs.com/package/page-metadata-parser](https://www.npmjs.com/package/page-metadata-parser) [https://www.scrapingbee.com/blog/node-fetch/](https://www.scrapingbee.com/blog/node-fetch/) - Page scrapper browser as service : [https://www.browserless.io/blog/2022/05/31/youtube-scraper/](https://www.browserless.io/blog/2022/05/31/youtube-scraper/) [https://www.demo2s.com/node.js/node-js-url-project-playlist-scraper-takes-a-youtube-playlist-url-gi.html](https://www.demo2s.com/node.js/node-js-url-project-playlist-scraper-takes-a-youtube-playlist-url-gi.html) - for lazy loading content(which render when we scroll down to that): [https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore](https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore) ```jsx const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.yoursite.com'); await page.setViewport({ width: 1200, height: 800 }); await autoScroll(page); await page.screenshot({ path: 'yoursite.png', fullPage: true }); await browser.close(); })(); async function autoScroll(page){ await page.evaluate(async () => { await new Promise((resolve) => { var totalHeight = 0; var distance = 100; var timer = setInterval(() => { var scrollHeight = document.body.scrollHeight; window.scrollBy(0, distance); totalHeight += distance; // scrollheight is subtracted as innerheight is portion // only rendered so remaining portion to be scrolled down if(totalHeight >= scrollHeight - window.innerHeight){ clearInterval(timer); resolve(); } }, 100); }); }); } ``` - Download any file from web server [https://www.npmjs.com/package/nodejs-file-downloader](https://www.npmjs.com/package/nodejs-file-downloader) - Alternative of axios [https://stackoverflow.com/questions/13864983/how-to-post-multipart-form-data-with-node-js-superagent](https://stackoverflow.com/questions/13864983/how-to-post-multipart-form-data-with-node-js-superagent) ```jsx const superagent = require('superagent'); superagent .post('https://www.y2mate.com/mates/en423/analyze/ajax') // .send(formData) // sends a JSON post body .set('accept', 'application/json') .field('url',url) .field('q_auto',0) .field('ajax',2) .end(async (err, res) => { // same as finally means both then and catch } ``` or for json: ```jsx superagent .post('/api/pet') .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body .set('X-API-Key', 'foobar') .set('accept', 'json') .end((err, res) => { // Calling the end function will send the request }); // promise with then/catch superagent.post('/api/pet').then(console.log).catch(console.error); ``` - Inspect nodejs app to Chrome `node inspect app.js` In browser type `chrome://inspect` and open dedicated DevTools for Node - Update nodejs and npm [https://www.geeksforgeeks.org/how-to-update-node-js-and-npm-to-next-version/](https://www.geeksforgeeks.org/how-to-update-node-js-and-npm-to-next-version/) - Taking input in synchronous way ```jsx // to take input from user const readlineSync = require('readline-sync'); // Wait for user's response. const phrase = readlineSync.question('Type a phrase (or quit to exit program): '); ``` - async fs without callback hell [https://www.youtube.com/watch?v=msnTtrx2C4s](https://www.youtube.com/watch?v=msnTtrx2C4s) - file system cache in nodejs [https://www.npmjs.com/package/file-system-cache](https://www.npmjs.com/package/file-system-cache) Example: ```jsx // const NodeCache=require('node-cache') // const myCache=new NodeCache(); const FileSystemCache_1 =require('file-system-cache') const options={basePath: "./.cache", // Optional. Path where cache files are stored (default). ns: "my-namespace" // Optional. A grouping namespace for items. } const cache=new FileSystemCache_1.FileSystemCache(options) const heavyComputation=()=>{ let temp = 0; for(let i=0; i<100000; i++) temp = (Math.random()*5342)%i; return 123; } const main=async()=>{ if(await cache.fileExists('key')) { console.log('res: ',await cache.get('key')) } else{ let res= heavyComputation() cache.set('key',res) console.log('Value not present performing calculation') console.log('res2: ',res) } } main() ``` some changes in `./node_modules/file-system-cache/lib/index.js` : ```jsx "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileSystemCache = void 0; const FileSystemCache_1 = require("./FileSystemCache"); Object.defineProperty(exports, "FileSystemCache", { enumerable: true, get: function () { return FileSystemCache_1.FileSystemCache; } }); const Cache= (options) => new FileSystemCache_1.FileSystemCache(options); exports.default = FileSystemCache_1 ``` - Mockable.io used by front end developers to create rest api - read only file system When working on read only file system use the /tmp to perform write functions. `fs.writeFileSync("/tmp/users.json", JSON.stringify(users))` - state management in nodejs ```jsx //state.js file class State { constructor() { this.currentState = false; this.data = null; this.setState = (st) => { this.currentState=st; }; this.setData = (da) => { this.data = da; } } } const appState = new State(); module.exports = appState; ``` ```jsx const appState = require("./state"); const PORT = 3000; const promiseSetTimeOut = (time) => { return new Promise((resolve) => { setTimeout(() => { resolve(); }, time); }); }; const app = express(); app.use(express.static(__dirname + "/public")); app.get("/getData", (req, res) => { res.json(appState.currentState); }); app.put("/updateData/:st", (req, res) => { const { st } = req.params; let stBool = false; let actualValue; if (st == "1") { stBool = true; actualValue=st } res.json("updating"); const promiseID = promiseSetTimeOut(5000); promiseID.then(() => { // console.log("updated ",stBool); appState.setState(stBool); appState.setData(actualValue); console.log(appState); }); }); app.listen(PORT, () => { console.log("listening"); }); ``` - Polling for limited timeout problem [https://www.npmjs.com/package/http-delayed-response](https://www.npmjs.com/package/http-delayed-response) [https://spin.atomicobject.com/2018/05/15/extending-heroku-timeout-node/](https://spin.atomicobject.com/2018/05/15/extending-heroku-timeout-node/) - Deta [https://deta.space/docs/en/quickstart-guides/node](https://deta.space/docs/en/quickstart-guides/node) https://deta.space/docs/en/build/quick-starts/node https://deta.space/builder : to go to builder page **Uninstalling deta**: It makes a hidden directory named as ".detaspace" in home directory just delete it . to open setting: [https://deta.space/?tty_open=settings](https://deta.space/?tty_open=settings) - Installing from github instead of npm library `"ytdl-core": "git+https://github.com/khlevon/node-ytdl-core.git#v4.11.4-patch.2”` `npm -i [https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2](https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2) —no-audit` - Socket backend ```jsx const WebSocket = require("ws"); // creating a websocket connection at port 8080 const server = new WebSocket.Server({ port: 8080 }); // this callback function will respond once client connect to ws://localhost:8080 server.on("connection", (socket) => { console.log("connected"); // this one respond once client send back a message here socket.on("message", (message, isString) => { // by default message is in buffer si convert it to string let msg = isString ? message : message.toString(); console.log("message: ", msg); // sending back the same message which was sent here by client socket.send(msg); }); }); ``` frontend ```jsx // ws protocol is used instead of http const socket = new WebSocket("ws://localhost:8080"); // this callback function will respond once server send back a message here socket.onmessage = (e) => { console.log("Message: ", e.data); }; document.querySelector("button").onclick = () => { // send method to send the message to server socket.send("helo"); }; ``` - socket.io high level library which uses ws to provide support for multiple clients and broadcasting backend ```jsx const PORT = process.env.PORT || 8080; const httpServer = require("http").createServer(); const socketIO = require("socket.io"); // linking with httpserver const io = socketIO(httpServer, { cors: { origin: "*" }, }); // when client connects to the server io.on("connection", (socket) => { console.log(`user connected ${socket.id}`); // when listening to custom event named 'message' socket.on("message", (message) => { // here using socket.boradcast.emit will send message to all client except the one who originally sent to server socket.broadcast.emit( "message", `${socket.id.substr(0, 2)} said ${message}` ); // to send to all including OP, use io.emit // and for particular client use // io.to(socket.id). emit("event", data); }); }); httpServer.listen(PORT, () => { console.log("listening"); }); ``` frontend ```jsx const socket = io("ws://localhost:8080"); const list = document.querySelector("#msgList"); const inputEle = document.querySelector("#chatInput"); // when listening to custom event named 'message' socket.on("message", (msg) => { const li = document.createElement("li"); li.innerText = msg; list.appendChild(li); }); document.querySelector("#sendBtn").onclick = () => { const text = inputEle.value; // emitting custom event named 'message' and passing the paramter $text socket.emit("message", text); const li = document.createElement("li"); li.innerText = `you said ${text}`; list.appendChild(li); inputEle.value = ""; }; ``` - AES file encryption [https://github.com/AKASHAorg/easy-web-crypto](https://github.com/AKASHAorg/easy-web-crypto) ```jsx function processFile(evt) { var file = evt.target.files[0], reader = new FileReader(); reader.onload = function(e) { var data = e.target.result, iv = crypto.getRandomValues(new Uint8Array(16)); crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt']) .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data) ) .then(encrypted => { console.log(encrypted); alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer }) .catch(console.error); } reader.readAsArrayBuffer(file); ``` `` - more [https://stackoverflow.com/questions/60520526/aes-encryption-and-decryption-of-files-using-crypto-js](https://stackoverflow.com/questions/60520526/aes-encryption-and-decryption-of-files-using-crypto-js) Slicing files to chunks [https://stackoverflow.com/questions/29731329/cryptojs-sha256-large-file-progressive-checksum/62824083#62824083](https://stackoverflow.com/questions/29731329/cryptojs-sha256-large-file-progressive-checksum/62824083#62824083) ```jsx function encrypt(input) { var file = input.files[0]; var reader = new FileReader(); reader.onload = () => { var key = "1234567887654321"; var wordArray = CryptoJS.lib.WordArray.create(reader.result); // Convert: ArrayBuffer -> WordArray var encrypted = CryptoJS.AES.encrypt(wordArray, key).toString(); // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format) var fileEnc = new Blob([encrypted]); // Create blob from string var a = document.createElement("a"); var url = window.URL.createObjectURL(fileEnc); var filename = file.name + ".enc"; a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url); }; reader.readAsArrayBuffer(file); } function convertWordArrayToUint8Array(wordArray) { var arrayOfWords = wordArray.hasOwnProperty("words") ? wordArray.words : []; var length = wordArray.hasOwnProperty("sigBytes") ? wordArray.sigBytes : arrayOfWords.length * 4; var uInt8Array = new Uint8Array(length), index=0, word, i; for (i=0; i> 24; uInt8Array[index++] = (word >> 16) & 0xff; uInt8Array[index++] = (word >> 8) & 0xff; uInt8Array[index++] = word & 0xff; } return uInt8Array; } function decrypt(input) { var file = input.files[0]; var reader = new FileReader(); reader.onload = () => { var key = "1234567887654321"; var decrypted = CryptoJS.AES.decrypt(reader.result, key); // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray var typedArray = convertWordArrayToUint8Array(decrypted); // Convert: WordArray -> typed array var fileDec = new Blob([typedArray]); // Create blob from typed array var a = document.createElement("a"); var url = window.URL.createObjectURL(fileDec); var filename = file.name.substr(0, file.name.length - 4) + ".dec"; a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url); }; reader.readAsText(file); } ``` Slicing ```jsx import CryptoJS from 'crypto-js'; class ChecksumService { async sha256(file: File): Promise { let sha256 = CryptoJS.algo.SHA256.create(); const sliceSize = 10_485_760; // 10 MiB let start = 0; while (start < file.size) { const slice: Uint8Array = await this.readSlice(file, start, sliceSize); const wordArray = CryptoJS.lib.WordArray.create(slice); sha256 = sha256.update(wordArray); start += sliceSize; } sha256.finalize(); return sha256._hash.toString(); } private async readSlice(file: File, start: number, size: number): Promise { return new Promise((resolve, reject) => { const fileReader = new FileReader(); const slice = file.slice(start, start + size); fileReader.onload = () => resolve(new Uint8Array(fileReader.result as any)); fileReader.onerror = reject; fileReader.readAsArrayBuffer(slice); }); } } ``` - Tauri [Download first_tauri.zip-423.8 MB](https://www.mediafire.com/file/m2jld5bq1adnxil/first_tauri.zip/file) [Download linux_tauri.zip-574.9 MB](https://www.mediafire.com/file/q16pyty2nqkb9do/linux_tauri.zip/file)