diff --git a/src/cli/args.js b/src/cli/args.js index 9e3622f791..b33aab48c5 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 propName = args[i].slice(2); // Удалим '--' + const value = args[i + 1]; + result.push(`${propName} is ${value}`); + } + + console.log(result.join(', ')); }; -parseArgs(); +parseArgs(); \ No newline at end of file diff --git a/src/cli/env.js b/src/cli/env.js index e3616dc8e7..ff3fc99596 100644 --- a/src/cli/env.js +++ b/src/cli/env.js @@ -1,5 +1,12 @@ const parseEnv = () => { - // Write your code here + const envV = process.env; + const rssV = []; + for (const key in envV) { + if (key.startsWith('RSS_')) { + rssV.push(`${key}=${envV[key]}`); + } + } + console.log(rssV.join('; ')); }; parseEnv(); diff --git a/src/cp/cp.js b/src/cp/cp.js index 72c6addc9c..43b9c073b6 100644 --- a/src/cp/cp.js +++ b/src/cp/cp.js @@ -1,6 +1,32 @@ +import { spawn } from 'child_process'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// ДЛЯ ЦЕЛЕЙ ТЕСТИРОВАНИЯ РАБОТЫ ПРИЛОЖЕНИЯ СРАЗУ ПОСЛЕ СТАРТА ВВЕСТИ ЛЮБУЮ СТРОКУ +// И НАЖАТЬ ЕНТЕР. ЧТОБЫ ВЫЙТИЁ ИЗ ПРОЦЕССА ВВЕСЬТИ CLOSE именно большими буквами + const spawnChildProcess = async (args) => { - // Write your code here + // Путь к script.js в папке files + const scriptPath = join(__dirname, 'files', 'script.js'); + + const childProcess = spawn('node', [scriptPath, ...args], { + stdio: ['pipe', 'pipe', 'inherit'] + }); + + // Связываем stdin и stdout родительского и дочернего процессов + process.stdin.pipe(childProcess.stdin); + childProcess.stdout.pipe(process.stdout); + + // Обработка завершения дочернего процесса + childProcess.on('exit', (code) => { + console.log(`\nChild process exited with code ${code}`); + }); + + return childProcess; }; -// Put your arguments in function call to test this functionality -spawnChildProcess( /* [someArgument1, someArgument2, ...] */); +// Тестируем с аргументами +spawnChildProcess(['argument1', 'argument2', 'argument3', 'argument4']); \ No newline at end of file diff --git a/src/fs/copy.js b/src/fs/copy.js index e226075b4c..0dd27d4ddd 100644 --- a/src/fs/copy.js +++ b/src/fs/copy.js @@ -1,5 +1,67 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = path.dirname(_filename); + const copy = async () => { - // Write your code here + import fs from 'fs/promises'; + import path from 'path'; + import { fileURLToPath } from 'url'; + + const _filename = fileURLToPath(import.meta.url); + const _dirname = path.dirname(_filename); + + const copy = async () => { + const srcToFiles = path.join(_dirname, 'files'); + const destFilesCopy = path.join(_dirname, 'files_copy'); + + try { + // Проверка существования исходной папки + await fs.access(srcToFiles); + + // Проверка, существует ли уже папка назначения + try { + await fs.access(destFilesCopy); + throw new Error('FS operation failed'); + } catch (error) { + // Если ошибка не связана с отсутствием папки, работаем дальше + if (error.message === 'FS operation failed') throw error; + + // Создаем основную папку + await fs.mkdir(destFilesCopy); + + // Рекурсия-функция для копирования + const copyItems = async (currentSrc, currentDestination) => { + const items = await fs.readdir(currentSrc); + + for (const item of items) { + const srcPath = path.join(currentSrc, item); + const destPath = path.join(currentDestination, item); + const stat = await fs.stat(srcPath); + + if (stat.isFile()) { + // Копируем файл + await fs.copyFile(srcPath, destPath); + } else if (stat.isDirectory()) { + // Создаем подпапку и копируем её контент + await fs.mkdir(destPath); + await copyItems(srcPath, destPath); + } + } + }; + + // Стартуем копирование + await copyItems(srcToFiles, destFilesCopy); + } + } catch (error) { + if (error.message !== 'FS operation failed') { + throw new Error('FS operation failed'); + } + throw error; + } + } }; -await copy(); +await copy(); \ No newline at end of file diff --git a/src/fs/create.js b/src/fs/create.js index 6ede285599..b21ef4be37 100644 --- a/src/fs/create.js +++ b/src/fs/create.js @@ -1,5 +1,26 @@ +import { promises as fs } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const fileName = fileURLToPath(import.meta.url); +const _dirName = dirname(fileName); + const create = async () => { - // Write your code here -}; + const filePath = join(_dirName, 'files', 'fresh.txt'); + const content = 'I am fresh and young'; + try { + await fs.access(filePath); + + const errorText = 'FS operation failed'; + throw new Error(errorText); + } catch (error) { + if (error.code === 'ENOENT') { + const standard = 'utf8'; + await fs.writeFile(filePath, content, standard); + } else { + throw error; + } + } +}; await create(); diff --git a/src/fs/delete.js b/src/fs/delete.js index a70b13766c..918dfdc4b3 100644 --- a/src/fs/delete.js +++ b/src/fs/delete.js @@ -1,5 +1,23 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const fileName = fileURLToPath(import.meta.url); +const dirName = path.dirname(fileName); + const remove = async () => { - // Write your code here + const filePath = path.join(dirName, 'files', 'fileToRemove.txt'); + + try { + // Проверяем существует ли файл + await fs.access(filePath); + + // Удаляем файл + await fs.unlink(filePath); + } catch (error) { + // Если файла нет или произошла к-л ошибка + throw new Error('FS operation failed'); + } }; -await remove(); +await remove(); \ No newline at end of file diff --git a/src/fs/files/wrongFilename.txt b/src/fs/files/wrongFileName.md similarity index 100% rename from src/fs/files/wrongFilename.txt rename to src/fs/files/wrongFileName.md diff --git a/src/fs/list.js b/src/fs/list.js index 0c0fa21f7e..355ae1065a 100644 --- a/src/fs/list.js +++ b/src/fs/list.js @@ -1,5 +1,26 @@ +import { fileURLToPath } from 'url'; +import fs from 'fs/promises'; +import path from 'path'; + +const _fileName = fileURLToPath(import.meta.url); +const _dirName = path.dirname(_fileName); + const list = async () => { - // Write your code here + const folderPath = path.join(_dirName, 'files'); + + try { + // Проверяем существует ли папка + await fs.access(folderPath); + + // Смотрим содержимое папки + const files = await fs.readdir(folderPath); + + // Массив имен файлов в консоль + console.log(files); + } catch (error) { + // Даем ошибку + throw new Error('FS operation failed'); + } }; -await list(); +await list(); \ No newline at end of file diff --git a/src/fs/read.js b/src/fs/read.js index e3938be563..5af6833e2e 100644 --- a/src/fs/read.js +++ b/src/fs/read.js @@ -1,5 +1,22 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const _fileName = fileURLToPath(import.meta.url); +const _dirName = path.dirname(_fileName); + const read = async () => { - // Write your code here + const fileToReadName = 'fileToRead.txt'; + const filePath = path.join(_dirName, 'files', fileToReadName); + + try { + await fs.access(filePath); + const standard = 'utf-8'; + const content = await fs.readFile(filePath, standard); + console.log(content); + } catch (error) { + throw new Error('FS operation failed'); + } }; await read(); diff --git a/src/fs/rename.js b/src/fs/rename.js index b1d65b0c86..1e004a5af2 100644 --- a/src/fs/rename.js +++ b/src/fs/rename.js @@ -1,5 +1,35 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + const rename = async () => { - // Write your code here + const wrongFilePath = path.join(__dirname, 'files', 'wrongFilename.txt'); + const properFilePath = path.join(__dirname, 'files', 'wrongFileName.md'); + + try { + // Проверяем существование исходного файла + await fs.access(wrongFilePath); + + // Проверяем, не существует ли уже целевой файл + try { + await fs.access(properFilePath); + throw new Error('FS operation failed'); + } catch (error) { + // Если ошибка не связана с отсутствием файла, пробрасываем дальше + if (error.message === 'FS operation failed') throw error; + + // Переименовываем файл + await fs.rename(wrongFilePath, properFilePath); + } + } catch (error) { + if (error.message !== 'FS operation failed') { + throw new Error('FS operation failed'); + } + throw error; + } }; -await rename(); +await rename(); \ No newline at end of file diff --git a/src/hash/calcHash.js b/src/hash/calcHash.js index e37c17ed62..c69541575b 100644 --- a/src/hash/calcHash.js +++ b/src/hash/calcHash.js @@ -1,5 +1,32 @@ +import { createHash } from 'crypto'; +import { createReadStream } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + const calculateHash = async () => { - // Write your code here + const _filename = fileURLToPath(import.meta.url); + const _dirname = dirname(_filename); + const fileNameToCalculateHashFor = 'fileToCalculateHashFor.txt'; + const filePath = join(_dirname, 'files', fileNameToCalculateHashFor); + + return new Promise((res, rej) => { + const hash = createHash('sha256'); + const stream = createReadStream(filePath); + + stream.on('data', (chunk) => { + hash.update(chunk); + }); + + stream.on('end', () => { + const hexHash = hash.digest('hex'); + console.log(hexHash); + res(hexHash); + }); + + stream.on('error', (error) => { + rej(error); + }); + }); }; -await calculateHash(); +await calculateHash(); \ No newline at end of file diff --git a/src/modules/cjsToEsm.cjs b/src/modules/cjsToEsm.cjs deleted file mode 100644 index 089bd2db13..0000000000 --- a/src/modules/cjsToEsm.cjs +++ /dev/null @@ -1,34 +0,0 @@ -const path = require('node:path'); -const { release, version } = require('node:os'); -const { createServer: createServerHttp } = require('node:http'); - -require('./files/c.cjs'); - -const random = Math.random(); - -const unknownObject = random > 0.5 ? require('./files/a.json') : 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..2aa5bb5f9c --- /dev/null +++ b/src/modules/esm.mjs @@ -0,0 +1,40 @@ +import path from 'node:path'; +import { release, version } from 'node:os'; +import { createServer as createServerHttp } from 'node:http'; +import { fileURLToPath } from 'node:url'; +import { readFileSync } from 'node:fs'; +import './files/c.cjs'; + +// Get __filename and __dirname equivalents in ESM +const _filename = fileURLToPath(import.meta.url); +const _dirname = path.dirname(_filename); + +const random = Math.random(); + +// Load using readFileSync +const unknownObject = random > 0.5 + ? JSON.parse(readFileSync(new URL('./files/a.json', import.meta.url), 'utf-8')) + : JSON.parse(readFileSync(new URL('./files/b.json', import.meta.url), 'utf-8')); + +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'); +}); + +// ESM exports (replaces module.exports) +export { unknownObject, myServer }; \ No newline at end of file diff --git a/src/streams/read.js b/src/streams/read.js index e3938be563..744edcc459 100644 --- a/src/streams/read.js +++ b/src/streams/read.js @@ -1,5 +1,28 @@ +import { createReadStream } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const _filename = fileURLToPath(import.meta.url); +const _dirname = dirname(_filename); + const read = async () => { - // Write your code here + const filePath = join(_dirname, 'files', 'fileToRead.txt'); + const readableStream = createReadStream(filePath, { encoding: 'utf-8' }); + + return new Promise((resolve, reject) => { + let content = ''; + + readableStream.on('data', (chunk) => { + content += chunk; + }); + + readableStream.on('end', () => { + console.log(content); + resolve(); + }); + + readableStream.on('error', reject); + }); }; -await read(); +await read(); \ No newline at end of file diff --git a/src/streams/transform.js b/src/streams/transform.js index 9e6c15fe84..51722c0a16 100644 --- a/src/streams/transform.js +++ b/src/streams/transform.js @@ -1,5 +1,47 @@ +import { Transform } from 'stream'; + const transform = async () => { - // Write your code here + // Создаем Transform Stream для реверсирования текста + const reverseTransform = new Transform({ + transform(chunk, encoding, callback) { + // Преобразуем chunk в строку, реверсируем и добавляем перенос строки + const reversedText = chunk.toString().split('').reverse().join('') + '\n'; + this.push(reversedText); + callback(); + } + }); + + return new Promise((resolve, reject) => { + // Направляем stdin -> transform -> stdout + process.stdin + .pipe(reverseTransform) + .pipe(process.stdout); + + // Обработка завершения + process.stdin.on('end', () => { + console.log('\nTransform completed'); + resolve(); + }); + + // Обработка ошибок + process.stdin.on('error', (error) => { + reject(new Error(`Stdin error: ${error.message}`)); + }); + + reverseTransform.on('error', (error) => { + reject(new Error(`Transform error: ${error.message}`)); + }); + + process.stdout.on('error', (error) => { + reject(new Error(`Stdout error: ${error.message}`)); + }); + }); }; await transform(); + +// Как запустить скрипт и проверить результат +// Запустить +// Ввести в консоли строку для реверса +// Для завершения работы скрипта CTRL-C + diff --git a/src/streams/write.js b/src/streams/write.js index 84aa11e7cb..36606b3c30 100644 --- a/src/streams/write.js +++ b/src/streams/write.js @@ -1,5 +1,38 @@ +import { createWriteStream } from 'fs'; +import { pipeline } from 'stream/promises'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + const write = async () => { - // Write your code here + // Получаем текущую директорию файла + const _filename = fileURLToPath(import.meta.url); + const _dirname = dirname(_filename); + + // Формируем путь к файлу в папке files + const filePath = join(_dirname, 'files', 'fileToWrite.txt'); + + try { + await pipeline( + process.stdin, + createWriteStream(filePath) + ); + console.log(`Data successfully written to ${filePath}`); + } catch (error) { + console.error('Error:', error.message); + throw error; + } }; await write(); + +/** КАК ЗАПУСКАТЬ СКРИПТ И ПРОВЕРЯТЬ РЕЗУЛЬТАТ + * + * # Ввод с клавиатуры (завершить Ctrl+D или Ctrl+C) + * node write.js + * + * # Передача данных через pipe + * echo "Hello World" | node write.js + * + * # Передача файла + * cat input.txt | node write.js + */ \ No newline at end of file diff --git a/src/wt/main.js b/src/wt/main.js index e2ef054d41..3fb500016d 100644 --- a/src/wt/main.js +++ b/src/wt/main.js @@ -1,5 +1,38 @@ +import { Worker } from 'worker_threads'; +import os from 'os'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + const performCalculations = async () => { - // Write your code here + const cpuCores = os.cpus().length; + + // Создаем массив промисов для еври worker + const workerPromises = Array.from({ length: cpuCores }, (_, i) => { + return new Promise((resolve) => { + const worker = new Worker(join(__dirname, 'worker.js'), { + workerData: 10 + i + }); + + worker.on('message', (result) => { + resolve({ status: 'resolved', data: result }); + }); + + worker.on('error', () => { + resolve({ status: 'error', data: null }); + }); + + worker.on('exit', (code) => { + if (code !== 0) { + resolve({ status: 'error', data: null }); + } + }); + }); + }); + + const workerResults = await Promise.all(workerPromises); + console.log(workerResults); }; await performCalculations(); diff --git a/src/wt/worker.js b/src/wt/worker.js index 405595394d..f71d761bf0 100644 --- a/src/wt/worker.js +++ b/src/wt/worker.js @@ -1,8 +1,16 @@ +import { parentPort, workerData } 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 + try { + const n = workerData; + const result = nthFibonacci(n); + parentPort.postMessage(result); + } catch (error) { + parentPort.postMessage(null); + } }; sendResult(); diff --git a/src/zip/compress.js b/src/zip/compress.js index d55209587e..5ffc22119c 100644 --- a/src/zip/compress.js +++ b/src/zip/compress.js @@ -1,5 +1,48 @@ +import { createReadStream, createWriteStream } from 'fs'; +import { createGzip } from 'zlib'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + const compress = async () => { - // Write your code here + const _filename = fileURLToPath(import.meta.url); + const _dirname = dirname(_filename); + + const sourceFileName = 'fileToCompress.txt'; + const sourceFile = join(_dirname, 'files', sourceFileName); + + const archiveFileName = 'archive.gz'; + const archiveFile = join(_dirname, 'files', archiveFileName); + + return new Promise((resolve, reject) => { + const readStrm = createReadStream(sourceFile); + const writeStrm = createWriteStream(archiveFile); + const gzip = createGzip(); + + let tBytes = 0; + let comprBytes = 0; + + readStrm.on('data', (chunk) => { + tBytes += chunk.length; + }); + + writeStrm.on('data', (chunk) => { + comprBytes += chunk.length; + }); + + readStrm + .pipe(gzip) + .pipe(writeStrm) + .on('finish', () => { + console.log(`Compress finished!`); + console.log(`1st size: ${tBytes} bytes`); + console.log(`After compressing: ${comprBytes} bytes`); + resolve(); + }) + .on('error', (error) => { + console.error('Error:', error.message); + reject(error); + }); + }); }; -await compress(); +await compress(); \ No newline at end of file diff --git a/src/zip/decompress.js b/src/zip/decompress.js index 8aaf26c8a4..f2baba3a62 100644 --- a/src/zip/decompress.js +++ b/src/zip/decompress.js @@ -1,5 +1,29 @@ +import { createReadStream, createWriteStream } from 'fs'; +import { createGunzip } from 'zlib'; +import { pipeline } from 'stream/promises'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + const decompress = async () => { - // Write your code here + const _filename = fileURLToPath(import.meta.url); + const _dirname = dirname(_filename); + + const archFileName = 'archive.gz' + const archFile = join(_dirname, 'files', archFileName); + const outFileName = 'fileToCompress.txt'; + const outFile = join(_dirname, 'files', outFileName); + + try { + await pipeline( + createReadStream(archFile), + createGunzip(), + createWriteStream(outFile) + ); + console.log(`Decompressed to ${outFile}`); + } catch (error) { + console.error('Error:', error.message); + throw error; + } }; await decompress();