diff --git a/src/cli/args.js b/src/cli/args.js index 8283f7f7aa..972db14cdd 100644 --- a/src/cli/args.js +++ b/src/cli/args.js @@ -1,5 +1,18 @@ +// args.js - implement function that parses command line arguments +// (given in format --propName value --prop2Name value2, you don't need to validate it) +// and prints them to the console in the format propName is value, prop2Name is value2 const parseArgs = () => { - // Write your code here + const re = /^--.+/; + const res = []; + const args = process.argv; + for (let i = 0; i < args.length; i++) { + if (i + 1 < args.length && re.test(args[i]) && !re.test(args[i + 1])) { + const name = args[i].substring(2); + const val = args[i + 1]; + res.push(name + ' is ' + val); + } + } + console.log(res.join(', ')); }; -parseArgs(); \ No newline at end of file +parseArgs(); diff --git a/src/cli/env.js b/src/cli/env.js index fe4aa4a8df..a104732fbb 100644 --- a/src/cli/env.js +++ b/src/cli/env.js @@ -1,5 +1,15 @@ +// env.js - implement function that parses environment variables with prefix RSS_ +// and prints them to the console in the format "RSS_name1=value1; RSS_name2=value2" + const parseEnv = () => { - // Write your code here + const re = /^RSS_/; + const rssvars = []; + Object.keys(process.env).forEach((key) => { + if (re.test(key)) { + rssvars.push(`${key}=${process.env[key]}`); + } + }); + console.log(rssvars.join('; ')); }; -parseEnv(); \ No newline at end of file +parseEnv(); diff --git a/src/cp/cp.js b/src/cp/cp.js index 4a87b98c55..54d1aa4811 100644 --- a/src/cp/cp.js +++ b/src/cp/cp.js @@ -1,6 +1,22 @@ +// implement function spawnChildProcess that receives array of arguments args and creates child process from file +import { spawn } from 'child_process'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const spawnChildProcess = async (args) => { - // Write your code here + const nodejs = process.argv[0]; + const scriptFile = path.join(__dirname, 'files', 'script.js'); + args.unshift(scriptFile); + + const childProcess = spawn(nodejs, args); + process.stdin.pipe(childProcess.stdin); + childProcess.stdout.pipe(process.stdout); }; // Put your arguments in function call to test this functionality -spawnChildProcess( /* [someArgument1, someArgument2, ...] */); +spawnChildProcess(['--opt1', 'val1', '--opt2', 'val2']); diff --git a/src/fs/copy.js b/src/fs/copy.js index bd17fe3991..d0b50f907a 100644 --- a/src/fs/copy.js +++ b/src/fs/copy.js @@ -1,5 +1,45 @@ +// copy.js - implement function that copies folder files files with all its content into folder files_copy +// at the same level (if files folder doesn't exists or files_copy has already been created Error with +// message FS operation failed must be thrown) +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const copy = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + const filesCopyDir = path.join(__dirname, 'files_copy'); + fs.stat(filesDir, (err, stats) => { + if (err && err.code === 'ENOENT') { + throw new Error("FS operation failed"); + } + fs.access(filesCopyDir, fs.constants.F_OK, (err) => { + if (err === null) { + throw new Error("FS operation failed"); + } + fs.mkdir(filesCopyDir, { recursive: true }, (err) => { + if (err) throw err; + fs.readdir(filesDir, (err, files) => { + if (err) { + console.error('Error reading directory:', err); + return; + } + files.forEach((file) => { + const srcPath = path.join(filesDir, file); + const dstPath = path.join(filesCopyDir, file); + fs.copyFile(srcPath, dstPath, (err) => { + if (err) throw err; + }); + }); + }); + }); + }); + }); }; await copy(); diff --git a/src/fs/create.js b/src/fs/create.js index 8d18cf9fc2..f91b17b1a2 100644 --- a/src/fs/create.js +++ b/src/fs/create.js @@ -1,5 +1,31 @@ +// implement function that creates new file fresh.txt with content "I am fresh and young" +// inside of the files folder (if file already exists Error with message FS operation failed must be thrown) +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const create = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + const freshFile = path.join(filesDir, 'fresh.txt'); + + fs.access(freshFile, fs.constants.F_OK, (err) => { + if (err === null) { + throw new Error("FS operation failed"); + } + const freshContent = 'I am fresh and young'; + fs.writeFile(freshFile, freshContent, (err) => { + if (err) { + throw err; + } + }); + }); + }; -await create(); \ No newline at end of file +await create(); diff --git a/src/fs/delete.js b/src/fs/delete.js index 4718dbc4c5..ae4702bff2 100644 --- a/src/fs/delete.js +++ b/src/fs/delete.js @@ -1,5 +1,29 @@ +// delete.js - implement function that deletes file fileToRemove.txt +// (if there's no file fileToRemove.txt Error with message FS operation failed must be thrown) + +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const remove = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + const removedFile = path.join(filesDir, 'fileToRemove.txt'); + fs.access(removedFile, fs.constants.F_OK, (err) => { + if (err) { + throw new Error("FS operation failed"); + } + fs.unlink(removedFile, (err) => { + if (err) { + throw err; + } + }); + }); }; -await remove(); \ No newline at end of file +await remove(); diff --git a/src/fs/list.js b/src/fs/list.js index c0a83dea15..4b0c7a2944 100644 --- a/src/fs/list.js +++ b/src/fs/list.js @@ -1,5 +1,29 @@ +// list.js - implement function that prints all array of filenames from +// files folder into console (if files folder doesn't exists Error with +// message FS operation failed must be thrown) +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const list = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + fs.stat(filesDir, (err, stats) => { + if (err && err.code === 'ENOENT') { + throw new Error("FS operation failed"); + } + fs.readdir(filesDir, (err, files) => { + if (err) { + throw new Error("FS operation failed"); + } + console.log(files); + }); + }); }; await list(); \ No newline at end of file diff --git a/src/fs/read.js b/src/fs/read.js index 52c78cc6ee..d0cc463ff6 100644 --- a/src/fs/read.js +++ b/src/fs/read.js @@ -1,5 +1,31 @@ +// read.js - implement function that prints content of the fileToRead.txt into console +// (if there's no file fileToRead.txt Error with message FS operation failed must be thrown) +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const read = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + const readFile = path.join(filesDir, 'fileToRead.txt'); + + fs.stat(readFile, (err, stats) => { + if (err && err.code === 'ENOENT') { + throw new Error("FS operation failed"); + } + fs.readFile(readFile, 'utf8', (err, data) => { + if (err) { + throw new Error("FS operation failed"); + } + console.log(data); + }); + }); + }; -await read(); \ No newline at end of file +await read(); diff --git a/src/fs/rename.js b/src/fs/rename.js index 2bb99ecdb5..ce3a4709f5 100644 --- a/src/fs/rename.js +++ b/src/fs/rename.js @@ -1,5 +1,36 @@ +// rename.js - implement function that renames file wrongFilename.txt to properFilename +// with extension .md (if there's no file wrongFilename.txt or properFilename.md already +// exists Error with message "FS operation failed" must be thrown) + +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const rename = async () => { - // Write your code here + const filesDir = path.join(__dirname, 'files'); + const wrongFile = path.join(filesDir, 'wrongFilename.txt'); + const properFile = path.join(filesDir, 'properFilename.md'); + fs.access(wrongFile, fs.constants.F_OK, (err) => { + if (err) { + throw new Error("FS operation failed"); + } + fs.access(properFile, fs.constants.F_OK, (err) => { + if (err === null) { + throw new Error("FS operation failed"); + } + fs.rename(wrongFile, properFile, (err) => { + if (err) { + throw new Error("FS operation failed"); + } + }); + }); + }); }; -await rename(); \ No newline at end of file +await rename(); diff --git a/src/hash/calcHash.js b/src/hash/calcHash.js index 450f8f72e2..c6c64a952f 100644 --- a/src/hash/calcHash.js +++ b/src/hash/calcHash.js @@ -1,5 +1,29 @@ +// implement function that calculates SHA256 hash for file fileToCalculateHashFor.txt +// and logs it into console as hex +import fs from 'fs'; +import path from 'path'; +import crypto from 'crypto'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const calculateHash = async () => { - // Write your code here + const hash = crypto.createHash('sha256'); + const fileName = path.join(__dirname, 'files/fileToCalculateHashFor.txt'); + + const fileStream = fs.createReadStream(fileName); + + fileStream.on('data', (data) => { + hash.update(data); + }); + + fileStream.on('end', () => { + console.log(hash.digest('hex')); + }); + }; -await calculateHash(); \ No newline at end of file +await calculateHash(); diff --git a/src/modules/cjsToEsm.cjs b/src/modules/cjsToEsm.cjs deleted file mode 100644 index 8b7be2a48b..0000000000 --- a/src/modules/cjsToEsm.cjs +++ /dev/null @@ -1,40 +0,0 @@ -const path = require('path'); -const { release, version } = require('os'); -const { createServer: createServerHttp } = require('http'); -require('./files/c'); - -const random = Math.random(); - -let unknownObject; - -if (random > 0.5) { - unknownObject = require('./files/a.json'); -} else { - unknownObject = require('./files/b.json'); -} - -console.log(`Release ${release()}`); -console.log(`Version ${version()}`); -console.log(`Path segment separator is "${path.sep}"`); - -console.log(`Path to current file is ${__filename}`); -console.log(`Path to current directory is ${__dirname}`); - -const myServer = createServerHttp((_, res) => { - res.end('Request accepted'); -}); - -const PORT = 3000; - -console.log(unknownObject); - -myServer.listen(PORT, () => { - console.log(`Server is listening on port ${PORT}`); - console.log('To terminate it, use Ctrl+C combination'); -}); - -module.exports = { - unknownObject, - myServer, -}; - diff --git a/src/modules/esm.mjs b/src/modules/esm.mjs new file mode 100644 index 0000000000..213604d894 --- /dev/null +++ b/src/modules/esm.mjs @@ -0,0 +1,60 @@ +// rewrite it to it's equivalent in ECMAScript notation (and rename it to esm.mjs) + +import path from 'path'; +import { release, version } from 'os'; +import { createServer as createServerHttp } from 'http'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +import { readFile } from 'fs/promises'; + +import './files/c.js'; + + +const importJson = async (fileName) => { + const data = await readFile(fileName, { encoding: 'utf8' }); + return JSON.parse(data); +}; + +const random = Math.random(); + +let unknownObject; +let fileName; + +if (random > 0.5) { + fileName = path.join(__dirname, '/files/a.json'); +} else { + fileName = path.join(__dirname, '/files/b.json'); +} + +unknownObject = await importJson(fileName); + +console.log(`Release ${release()}`); +console.log(`Version ${version()}`); +console.log(`Path segment separator is "${path.sep}"`); + +console.log(`Path to current file is ${__filename}`); +console.log(`Path to current directory is ${__dirname}`); + +const myServer = createServerHttp((_, res) => { + res.end('Request accepted'); +}); + +const PORT = 3000; + +console.log(unknownObject); + +myServer.listen(PORT, () => { + console.log(`Server is listening on port ${PORT}`); + console.log('To terminate it, use Ctrl+C combination'); +}); + +export { + unknownObject, + myServer, +}; + diff --git a/src/streams/read.js b/src/streams/read.js index 52c78cc6ee..0a2b390f5a 100644 --- a/src/streams/read.js +++ b/src/streams/read.js @@ -1,5 +1,20 @@ +// implement function that reads file fileToRead.txt content using +// Readable Stream and prints it's content into process.stdout +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const read = async () => { - // Write your code here + const fileName = path.join(__dirname, 'files/fileToRead.txt'); + + const inputStream = fs.createReadStream(fileName); + + inputStream.pipe(process.stdout); }; -await read(); \ No newline at end of file +await read(); diff --git a/src/streams/transform.js b/src/streams/transform.js index 315fc6597f..4010f41775 100644 --- a/src/streams/transform.js +++ b/src/streams/transform.js @@ -1,5 +1,25 @@ +// implement function that reads data from process.stdin, reverses text +// using Transform Stream and then writes it into process.stdout +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; +import { Transform } from 'stream'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +class ReverseStream extends Transform { + _transform(chunk, encoding, callback) { + const transformedChunk = chunk.toString().split('').reverse().join(''); + this.push(transformedChunk); + callback(); + } +} + const transform = async () => { - // Write your code here + const reverseStream = new ReverseStream(); + process.stdin.pipe(reverseStream).pipe(process.stdout); }; -await transform(); \ No newline at end of file +await transform(); diff --git a/src/streams/write.js b/src/streams/write.js index fc917160a2..bb3ee74b6d 100644 --- a/src/streams/write.js +++ b/src/streams/write.js @@ -1,5 +1,20 @@ +// implement function that writes process.stdin data into file fileToWrite.txt +// content using Writable Stream +import fs from 'fs'; +import path from 'path'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const write = async () => { - // Write your code here + const fileName = path.join(__dirname, 'files/fileToWrite.txt'); + + const outputStream = fs.createWriteStream(fileName); + + process.stdin.pipe(outputStream); }; -await write(); \ No newline at end of file +await write(); diff --git a/src/wt/main.js b/src/wt/main.js index 37d80484ec..52ccde94e1 100644 --- a/src/wt/main.js +++ b/src/wt/main.js @@ -1,5 +1,46 @@ +// implement function that creates number of worker threads (equal to the number +// of host machine logical CPU cores) from file worker.js + +import os from 'os'; +import path, { resolve } from 'path'; +import { Worker } from 'worker_threads'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const performCalculations = async () => { - // Write your code here + const workerFile = path.join(__dirname, 'worker.js'); + const cpus = os.cpus().length; + const results = []; + const promises = []; + const wid2idx = {}; + for (let i = 0; i < cpus; i++) { + const promise = new Promise((resolve, reject) => { + const worker = new Worker(workerFile); + wid2idx[worker.threadId] = i; + worker.postMessage(10 + i); + worker.on('message', (data) => { + results[wid2idx[worker.threadId]] = { 'status': 'resolved', 'data': data }; + resolve(); + }); + worker.on('error', (eror) => { + results[wid2idx[worker.threadId]] = { 'status': 'resolved', 'data': data }; + reject(); + }); + }); + promises.push(promise); + } + + Promise.all(promises) + .then(() => { + console.log(results); + }) + .catch(() => { + console.log(results); + }); }; -await performCalculations(); \ No newline at end of file +await performCalculations(); diff --git a/src/wt/worker.js b/src/wt/worker.js index 441b2154f8..3a3f3acef6 100644 --- a/src/wt/worker.js +++ b/src/wt/worker.js @@ -1,8 +1,17 @@ +// extend given function to work with data received from main thread and implement +// function which sends result of the computation to the main thread + +import { parentPort } from 'worker_threads'; + // n should be received from main thread const nthFibonacci = (n) => n < 2 ? n : nthFibonacci(n - 1) + nthFibonacci(n - 2); const sendResult = () => { // This function sends result of nthFibonacci computations to main thread + parentPort.on('message', (data) => { + parentPort.postMessage(nthFibonacci(data)); + parentPort.close(); + }); }; -sendResult(); \ No newline at end of file +sendResult(); diff --git a/src/zip/compress.js b/src/zip/compress.js index bb328f43c6..82a64b25c0 100644 --- a/src/zip/compress.js +++ b/src/zip/compress.js @@ -1,5 +1,24 @@ +// implement function that compresses file fileToCompress.txt to archive.gz using zlib and Streams API + +import fs from 'fs'; +import path from 'path'; +import zlib from 'zlib'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const compress = async () => { - // Write your code here + const fileName = path.join(__dirname, 'files/fileToCompress.txt'); + const archName = path.join(__dirname, 'files/archive.gz'); + + const inputStream = fs.createReadStream(fileName); + const gzipStream = zlib.createGzip(); + const outputStream = fs.createWriteStream(archName); + + inputStream.pipe(gzipStream).pipe(outputStream); }; -await compress(); \ No newline at end of file +await compress(); diff --git a/src/zip/decompress.js b/src/zip/decompress.js index 69f6c345f8..e6d8338fdc 100644 --- a/src/zip/decompress.js +++ b/src/zip/decompress.js @@ -1,5 +1,25 @@ +// implement function that decompresses archive.gz back to the fileToCompress.txt +// with same content as before compression using zlib and Streams API + +import fs from 'fs'; +import path from 'path'; +import zlib from 'zlib'; + +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + const decompress = async () => { - // Write your code here + const archName = path.join(__dirname, 'files/archive.gz'); + const fileName = path.join(__dirname, 'files/fileToCompress.txt'); + + const inputStream = fs.createReadStream(archName); + const gzipStream = zlib.createGunzip(); + const outputStream = fs.createWriteStream(fileName); + + inputStream.pipe(gzipStream).pipe(outputStream); }; -await decompress(); \ No newline at end of file +await decompress();