This commit is contained in:
Philippe Torrel
2026-09-30 13:40:36 +02:00
parent 9dad0f06a2
commit 8c7380fde9
23 changed files with 4455 additions and 0 deletions
@@ -0,0 +1,9 @@
Code,Short Description,Tagline,Quantity,Price
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
1 Code Short Description Tagline Quantity Price
2 MUG0007 coffee mug with LCD level indicator never again reach for the empty mug 20 49.90
3 MUG0013 coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling put the smart into coffee reading 20 99.90
4 OFF3145 pen with pre-warmed ink (tested on the South Pole) the pen is mightier than the cold 50 29.90
5 COM1001 ambidextrous computer mouse end the dictate of left and right 10 19.90
6 COM0404 Easter egg themed webcam for your monitor put an Easter egg on hardware too 20 149.90
7 COM0001 Vulcan language vi cheatsheet learn vi and Vulcan at the same time 3 9.90
8 COM1536 Klingon language emacs cheatsheet learn emacs and Klingon at the same time 50 9.90
9 MOB0555 smartphone case with built-in screen never miss a message 20 39.90
@@ -0,0 +1,71 @@
// const fs = require('node:fs'); // commonjs
import fs from 'node:fs'; // module - esm
import color from 'chalk';
// VARS =========
const STOCK_WARN_AMOUNT = 5;
const data = fs.readFileSync('data/products.csv', 'utf-8');
const products = data.split('\n');
const headerAr = products.shift().split(/\s*,\s*/); // => [ 'Code', 'Short Description', 'Tagline', 'Quantity', 'Price' ]
// Functions ======
const recordToHtml = (row) => {
const fields = row.split(/\s*,\s*/); // ["MUG0007", "coffee mug with LCD level indicator", "never again reach for the empty mug","20","49.90" ]
// Destructuring von fields-Array
const [code, shortDescription, tagline, quantity, price] = fields;
let html = '<li class="list-group-item">';
html += `<h2>${shortDescription}</h2>`;
html += `<p>${tagline}</p>`;
html += `<p><strong>Price:</strong> ${Number(price).toFixed(2)}</p>`;
if (quantity < STOCK_WARN_AMOUNT) {
html += `<p class="alert alert-warning">Nur noch wenige Example verfügbar! (${quantity})</p>`;
}
html += '</li>';
return html;
};
const writeHtmlDocument = (content = '') => {
const headerStr = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5">`;
const footerStr = `</div>
</main>
</body>
</html>`;
const htmlDocument = `${headerStr}${content}${footerStr}`;
fs.writeFile('products.html', htmlDocument, 'utf-8', (err) => {
if (err) console.log(color.red(err));
console.log(color.green('File created!'));
});
};
const listItems = products
.filter((row) => row !== '') // leere String Einträge rausfiltern
.map((row) => {
return recordToHtml(row);
});
const htmlList = `<ul class="list-group">${listItems.join('')}</ul>`;
// Output ===========
writeHtmlDocument(htmlList);
@@ -0,0 +1,27 @@
{
"name": "01_csv-to-html",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "01_csv-to-html",
"version": "1.0.0",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "01_csv-to-html",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module",
"dependencies": {
"chalk": "^6.0.1"
}
}
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
</main>
</body>
</html>
@@ -0,0 +1 @@
Code,Short Description,Tagline,Quantity,Price
1 Code Short Description Tagline Quantity Price
@@ -0,0 +1,13 @@
import fs from 'node:fs';
import color from 'chalk';
// async process
fs.readFile('data/products.csv', 'UTF8', (error, data) => {
console.log(color.yellow(data)); // 2 output
});
for (let i = 0; i < 2000000000; i++) {
// be busy for a few seconds
}
console.log(color.green('ready')); // 1 output
@@ -0,0 +1,27 @@
{
"name": "02_async-vs-multithread",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "02_async-vs-multithread",
"version": "1.0.0",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "02_async-vs-multithread",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module",
"dependencies": {
"chalk": "^6.0.1"
}
}
@@ -0,0 +1 @@
hello World
@@ -0,0 +1,54 @@
import fs from 'fs'; // Modul aus der Standardbibliothek
let data;
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
// fs.readFileSync(…)
// liest eine Datei ein (blockierende Variante)
data = fs.readFileSync('hello.txt', 'utf8');
console.log(data);
// fs.readFile(…)
// liest eine Datei ein (asynchrone Variante)
fs.readFile('hello.txt', 'utf8', (error, data) => {
console.log(data);
});
// fs.writeFileSync(…)
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (blockierende Variante)
fs.writeFileSync('hello.txt', data, 'utf8');
console.log(data);
// fs.writeFile(…)
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (asynchrone Variante)
fs.writeFile('hello.txt', data, 'UTF8', (error) => {
if (error) console.log('Error: ' + error);
});
// fs.statSync(…)
// ermittelt Infos zur Datei (blockierende Variante)
const stats = fs.statSync('hello.txt');
// console.log('File Stats: ', stats);
console.log('File size: ', stats.size); // => size in bytes
console.log('File birthdate: ', stats.birthtime); // => enstehungsdatum der Datei
// fs.stat(…)
// ermittelt Infos zur Datei (asynchrone Variante)
fs.stat('hello.txt', (error, stats) => console.log(stats.size)); // => size in bytes
// fs.unlinkSync(…)
// löscht eine Datei (blockierende Variante)
fs.unlinkSync('hello.txt');
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
// fs.unlink(…)
// löscht eine Datei (asynchrone Variante)
// fs.unlink('hello.txt', 'utf-8', (error) => {
// if (error) console.log('Error: ' + error);
// });
@@ -0,0 +1,13 @@
{
"name": "01_fs-methoden",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module"
}
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
</main>
</body>
</html>
@@ -0,0 +1,15 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
const data = fs.readFileSync('data/products.html', 'utf-8');
const compressedData = zlib.gzipSync(data); // => <Buffer 1f 8b 08 00 00 00 00 00 00 13 9d 95 c1 8e dc 36 0c 86 ef 79 0a c6 a7 04 a8 c7 c9 6e 03 64 03 8d 51 20 d9 5e 5a b4 0b 34 2d 90 23 47 e2 58 6c 25 ca 90 ... 688 more bytes>
console.log(compressedData);
try {
fs.writeFileSync('data/products.html.gz', compressedData);
console.log('compressed file!');
} catch (error) {
console.log(error);
}
@@ -0,0 +1,11 @@
{
"name": "04_zlib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
const data = fs.readFileSync('data/products.html', 'utf-8');
const gzipCompressor = zlib.createGzip();
const inputStream = fs.createReadStream('data/products.html');
const outputStream = fs.createWriteStream('data/products.html.gz');
inputStream.on('data', (data) => {
console.log('Pakete (data chunks) werden geladen:', data.length);
});
inputStream.pipe(gzipCompressor).pipe(outputStream);
@@ -0,0 +1,11 @@
{
"name": "04_zlib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
@@ -0,0 +1,6 @@
import crypto from 'node:crypto';
const data = 'Ich werde verschüsselt!';
const hash = crypto.createHash('sha256').update(data).digest('hex'); // 256-bit SHA-2 hash algorithm
console.log(hash); // 59e9f3b7c10a8c5c9e099d60bebb142eaa7560b375bb41e3def6bc34708ce6ae
@@ -0,0 +1,11 @@
{
"name": "06_crypto",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}