diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..34b7366dcf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,17 @@ +{ + "name": "node-nodejs-basics", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "node-nodejs-basics", + "version": "1.0.0", + "license": "ISC", + "engines": { + "node": ">=24.10.0", + "npm": ">=10.9.2" + } + } + } +} diff --git a/src/cli/args.js b/src/cli/args.js index 9e3622f791..e6047166a4 100644 --- a/src/cli/args.js +++ b/src/cli/args.js @@ -1,5 +1,14 @@ const parseArgs = () => { - // Write your code here + const args = process.argv.slice(2); + + const result = []; + for (let i = 0; i < args.length; i += 2) { + const key = args[i].replace(/^--/, ''); + const value = args[i + 1]; + parts.push(`${key} is ${value}`); + } + + console.log(result.join(', ')); }; parseArgs(); diff --git a/src/cli/env.js b/src/cli/env.js index e3616dc8e7..499bcb5c8a 100644 --- a/src/cli/env.js +++ b/src/cli/env.js @@ -1,5 +1,11 @@ const parseEnv = () => { - // Write your code here + + const envVariables = Object.entries(process.env) + .filter(([key]) => key.startsWith('RSS_')) + .map(([key, value]) => `${key}=${value}`) + .join('; '); + + console.log(envVariables); }; parseEnv(); diff --git a/src/cp/cp.js b/src/cp/cp.js index 72c6addc9c..33844aff43 100644 --- a/src/cp/cp.js +++ b/src/cp/cp.js @@ -1,6 +1,26 @@ -const spawnChildProcess = async (args) => { - // Write your code here +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +export const spawnChildProcess = async (args = []) => { + const scriptPath = fileURLToPath(new URL('./files/script.js', import.meta.url)); + + const child = spawn(process.execPath, [scriptPath, ...args], { + stdio: ['pipe', 'pipe', 'inherit'], + }); + + process.stdin.pipe(child.stdin); + child.stdout.pipe(process.stdout); + + return new Promise((resolve, reject) => { + child.once('error', reject); + child.once('exit', (code) => { + process.stdin.unpipe(child.stdin); + child.stdout.unpipe(process.stdout); + if (code === 0) resolve(); + else reject(new Error(`Child exited with code ${code}`)); + }); + }); }; // Put your arguments in function call to test this functionality -spawnChildProcess( /* [someArgument1, someArgument2, ...] */); +spawnChildProcess( ["rs", "2025", "node.js"] ); diff --git a/src/fs/copy.js b/src/fs/copy.js index e226075b4c..8c3a3483f4 100644 --- a/src/fs/copy.js +++ b/src/fs/copy.js @@ -1,5 +1,14 @@ +import fs from 'fs/promises'; + const copy = async () => { - // Write your code here + const source = new URL('./files/', import.meta.url); + const destination = new URL('./files_copy/', import.meta.url); + + try { + await fs.cp(source, destination, { recursive: true, force: false, errorOnExist: true }); + } catch { + throw new Error('FS operation failed'); + } }; await copy(); diff --git a/src/fs/create.js b/src/fs/create.js index 6ede285599..545ed7b74b 100644 --- a/src/fs/create.js +++ b/src/fs/create.js @@ -1,5 +1,13 @@ +import fs from 'fs/promises'; + const create = async () => { - // Write your code here + const filePath = new URL('./fresh.txt', import.meta.url) + + try { + await fs.writeFile(filePath, 'I am fresh and young', { flag: 'wx'}) + } catch { + throw new Error('FS operation failed'); + } }; await create(); diff --git a/src/fs/delete.js b/src/fs/delete.js index a70b13766c..118dfd9056 100644 --- a/src/fs/delete.js +++ b/src/fs/delete.js @@ -1,5 +1,13 @@ +import fs from 'fs/promises'; + const remove = async () => { - // Write your code here + const fileToRemove = new URL('./files/fileToRemove.txt', import.meta.url); + + try { + await fs.unlink(fileToRemove); + } catch { + throw new Error('FS operation failed'); + } }; await remove(); diff --git a/src/fs/files/wrongFilename.txt b/src/fs/files/wrangFilename.txt similarity index 100% rename from src/fs/files/wrongFilename.txt rename to src/fs/files/wrangFilename.txt diff --git a/src/fs/list.js b/src/fs/list.js index 0c0fa21f7e..3ee7559bde 100644 --- a/src/fs/list.js +++ b/src/fs/list.js @@ -1,5 +1,14 @@ +import fs from 'fs/promises'; + const list = async () => { - // Write your code here + const folderToList = new URL('./files/', import.meta.url); + + try { + const files = await fs.readdir(folderToList); + console.log(files); + } catch { + throw new Error('FS operation failed'); + } }; await list(); diff --git a/src/fs/read.js b/src/fs/read.js index e3938be563..21094cf042 100644 --- a/src/fs/read.js +++ b/src/fs/read.js @@ -1,5 +1,14 @@ +import fs from 'fs/promises'; + const read = async () => { - // Write your code here + const fileToRead = new URL('./files/fileToRead.txt', import.meta.url); + + try { + const contentToRead = await fs.readFile(fileToRead, 'utf-8'); + console.log(contentToRead); + } catch { + throw new Error('FS operation failed'); + } }; await read(); diff --git a/src/fs/rename.js b/src/fs/rename.js index b1d65b0c86..414452efb2 100644 --- a/src/fs/rename.js +++ b/src/fs/rename.js @@ -1,5 +1,21 @@ +import fs from 'fs/promises'; + const rename = async () => { - // Write your code here + const source = new URL('./files/wrongFilename.txt', import.meta.url); + const destination = new URL('./files/properFilename.md', import.meta.url); + + try { + try { + await fs.stat(destination); + throw new Error('FS operation failled'); + } catch (e){ + if (!e || e.code !== 'ENOENT') + throw new Error('FS operation failled'); + } + await fs.rename(source, destination); + } catch { + throw new Error('FS operation failed'); + } }; await rename(); diff --git a/src/hash/calcHash.js b/src/hash/calcHash.js index e37c17ed62..3fc043eb50 100644 --- a/src/hash/calcHash.js +++ b/src/hash/calcHash.js @@ -1,5 +1,20 @@ -const calculateHash = async () => { - // Write your code here +import { createReadStream } from 'node:fs'; +import { createHash } from 'node:crypto'; +import { pipeline } from 'node:stream/promises'; + +const calcHash = async () => { + const filePath = new URL('./files/fileToCalculateHashFor.txt', import.meta.url); + + const hash = createHash('sha256'); + + try { + await pipeline(createReadStream(filePath), hash); + + console.log(hash.digest('hex')); + } catch { + throw new Error('FS operation failed'); + } }; -await calculateHash(); +await calcHash(); + diff --git a/src/modules/cjsToEsm.cjs b/src/modules/esm.mjs similarity index 52% rename from src/modules/cjsToEsm.cjs rename to src/modules/esm.mjs index 089bd2db13..339853f745 100644 --- a/src/modules/cjsToEsm.cjs +++ b/src/modules/esm.mjs @@ -1,12 +1,17 @@ -const path = require('node:path'); -const { release, version } = require('node:os'); -const { createServer: createServerHttp } = require('node:http'); +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { release, version } from 'node:os'; +import { createServer as createServerHttp } from 'node:http'; -require('./files/c.cjs'); +import './files/c.cjs'; -const random = Math.random(); +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -const unknownObject = random > 0.5 ? require('./files/a.json') : require('./files/b.json'); +const random = Math.random(); +const unknownObject = random > 0.5 + ? (await import('./files/a.json', { with: { type: 'json' } })).default + : (await import('./files/b.json', { with: { type: 'json' } })).default; console.log(`Release ${release()}`); console.log(`Version ${version()}`); @@ -28,7 +33,4 @@ myServer.listen(PORT, () => { console.log('To terminate it, use Ctrl+C combination'); }); -module.exports = { - unknownObject, - myServer, -}; +export { unknownObject, myServer }; diff --git a/src/streams/files/fileToWrite.txt b/src/streams/files/fileToWrite.txt index e69de29bb2..8b13789179 100644 --- a/src/streams/files/fileToWrite.txt +++ b/src/streams/files/fileToWrite.txt @@ -0,0 +1 @@ + diff --git a/src/streams/read.js b/src/streams/read.js index e3938be563..02a4ad7a43 100644 --- a/src/streams/read.js +++ b/src/streams/read.js @@ -1,5 +1,16 @@ +import fs from 'node:fs'; + const read = async () => { - // Write your code here + const filePath = new URL('./files/fileToRead.txt', import.meta.url); + + const readStream = fs.createReadStream(filePath, { encoding: 'utf-8' }); + + readStream.pipe(process.stdout); + + readStream.on('error', () => { + throw new Error('FS operation failed'); + }); }; await read(); + diff --git a/src/streams/transform.js b/src/streams/transform.js index 9e6c15fe84..1b49b880ae 100644 --- a/src/streams/transform.js +++ b/src/streams/transform.js @@ -1,5 +1,22 @@ +import { Transform } from 'node:stream'; +import { pipeline } from 'node:stream/promises'; +import { Readable } from 'node:stream'; + const transform = async () => { - // Write your code here + const mockData = process.stdin ? Readable.from('Hello world\n') : process.stdin; + + const reverseTransform = new Transform({ + transform(chunk, _enc, cb) { + const reversed = chunk.toString('utf8').split('').reverse().join(''); + cb(null, reversed); + } +}); + +try { + await pipeline(mockData, reverseTransform, process.stdout); + } catch { + console.error('Stream operation failed'); + } }; await transform(); diff --git a/src/streams/write.js b/src/streams/write.js index 84aa11e7cb..96cacf62ac 100644 --- a/src/streams/write.js +++ b/src/streams/write.js @@ -1,5 +1,18 @@ +import fs from 'node:fs'; +import { pipeline } from 'node:stream/promises'; +import { Readable } from 'node:stream'; + const write = async () => { - // Write your code here + const filePath = new URL('./files/fileToWrite.txt', import.meta.url); + const writeStream = fs.createWriteStream(filePath, { encoding: 'utf-8' }); + const mockData = process.stdin ? Readable.from('Hello world\n') : process.stdin; + + + try { + await pipeline(mockData, writeStream); + } catch { + throw new Error('FS operation failed'); + } }; await write(); diff --git a/src/wt/main.js b/src/wt/main.js index e2ef054d41..89b96de6c4 100644 --- a/src/wt/main.js +++ b/src/wt/main.js @@ -1,5 +1,39 @@ +import { cpus } from 'node:os'; +import { Worker } from 'node:worker_threads'; + const performCalculations = async () => { - // Write your code here + + const runWorker = (n) => + new Promise((resolve) => { + const worker = new Worker(new URL('./worker.js', import.meta.url), { + workerData: n, type: 'module' + }); + + worker.once('message', (value) => { + resolve({ status: 'resolved', data: value }); + }); + + worker.once('error', (err) => { + console.error('worker error:', err) + resolve({ status: 'error', data: null }); + }); + + worker.once('exit', (code) => { + if (code !== 0) { + resolve({ status: 'error', data: null }); + } + }); + }); + + const coreCount = cpus().length; + const start = 10; + + const workerPromises = Array.from({ length: coreCount }, (_, i) => + runWorker(start + i) + ); + + const results = await Promise.all(workerPromises); + console.log(results); }; await performCalculations(); diff --git a/src/wt/worker.js b/src/wt/worker.js index 405595394d..3fac1c199d 100644 --- a/src/wt/worker.js +++ b/src/wt/worker.js @@ -1,8 +1,17 @@ +import { parentPort, workerData } from 'node:worker_threads'; + // n should be received from main thread const nthFibonacci = (n) => n < 2 ? n : nthFibonacci(n - 1) + nthFibonacci(n - 2); -const sendResult = () => { +const sendResult = (n) => { // This function sends result of nthFibonacci computations to main thread + const result = nthFibonacci(Number(n)); + parentPort.postMessage(result); }; -sendResult(); +if (workerData !== undefined) { + sendResult(workerData); +} else { + parentPort.once('message', sendResult); +} + diff --git a/src/zip/compress.js b/src/zip/compress.js index d55209587e..7d0c1eeefc 100644 --- a/src/zip/compress.js +++ b/src/zip/compress.js @@ -1,5 +1,21 @@ +import fs from 'node:fs'; +import { pipeline } from 'node:stream/promises'; +import { createGzip } from 'node:zlib'; + const compress = async () => { - // Write your code here + const source = new URL('./files/fileToCompress.txt', import.meta.url); + const destination = new URL('./files/archive.gz', import.meta.url); + + try { + await pipeline( + fs.createReadStream(source), + createGzip(), + fs.createWriteStream(destination) + ); + } catch { + + throw new Error('FS operation failed'); + } }; await compress(); diff --git a/src/zip/decompress.js b/src/zip/decompress.js index 8aaf26c8a4..77e35735c8 100644 --- a/src/zip/decompress.js +++ b/src/zip/decompress.js @@ -1,5 +1,21 @@ +import fs from 'node:fs'; +import { pipeline } from 'node:stream/promises'; +import { createGunzip } from 'node:zlib'; + const decompress = async () => { - // Write your code here + const source = new URL('./files/archive.gz', import.meta.url); + const destination = new URL('./files/fileToCompress.txt', import.meta.url); + + try { + await pipeline( + fs.createReadStream(source), + createGunzip(), + fs.createWriteStream(destination) + ); + } catch { + throw new Error('FS operation failed'); + } }; await decompress(); +