Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fceda22
feat: implement create function
andriihordov Oct 24, 2025
4073835
feat: implement copy function
andriihordov Oct 24, 2025
ec79227
fix: remove redindant data
andriihordov Oct 24, 2025
93b5e96
feat: implement rename function
andriihordov Oct 24, 2025
04d65d9
feat: implement delete function
andriihordov Oct 25, 2025
e38ff2a
implement list function
andriihordov Oct 25, 2025
f076811
feat: implement read function
andriihordov Oct 25, 2025
51dd5b9
refactor: remove data definition repeating
andriihordov Oct 25, 2025
04e38dc
feat: implement parseArgs function refactor: change names in constant…
andriihordov Oct 26, 2025
79abd03
feat: implement parseEnv function
andriihordov Oct 26, 2025
5cdfd40
feat: refactor cjsToEsm.js
andriihordov Oct 26, 2025
4097f77
feat: implement hash function
andriihordov Oct 26, 2025
6393229
feat: implement read function for streams task
andriihordov Oct 26, 2025
a3e5652
feat: implement write function for streams task
andriihordov Oct 26, 2025
48e739c
feat: implement transform function for streams task
andriihordov Oct 26, 2025
089f0c5
feat: implement compress function
andriihordov Oct 26, 2025
31b7edf
feat: implement decompress function
andriihordov Oct 26, 2025
7740f3f
feat: implement both main and worker functions for wt task
andriihordov Oct 26, 2025
70f3e12
feat: implement spawnChildProcess function for cp task
andriihordov Oct 26, 2025
36f03b8
refactor: add data definitions for cp task
andriihordov Oct 26, 2025
89ae994
fix: fix names, define 'options' object for copy function, add 'await…
andriihordov Oct 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,8 @@
"bugs": {
"url": "https://github.com/AlreadyBored/node-nodejs-basics/issues"
},
"homepage": "https://github.com/AlreadyBored/node-nodejs-basics#readme"
"homepage": "https://github.com/AlreadyBored/node-nodejs-basics#readme",
"devDependencies": {
"cross-env": "^10.1.0"
}
}
11 changes: 10 additions & 1 deletion src/cli/args.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { cliConstants } from '../common/constants.js';
import { cliPrintArgument } from '../common/helpers.js';

const parseArgs = () => {
// Write your code here
const { DELIMITER, RE_DELIMITER, SLICE_FROM, JOINER } = cliConstants.parseArgs;
process.argv
.join(DELIMITER)
.split(RE_DELIMITER)
.slice(SLICE_FROM)
.map((string) => string.split(DELIMITER))
.forEach((pair) => cliPrintArgument(pair, JOINER));
};

parseArgs();
8 changes: 7 additions & 1 deletion src/cli/env.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { cliPrintArgument } from '../common/helpers.js';
import { cliConstants } from '../common/constants.js';

const parseEnv = () => {
// Write your code here
const { PATTERN, JOINER } = cliConstants.env;
for (const pair of Object.entries(process.env)) {
if (PATTERN.test(pair[0])) cliPrintArgument(pair, JOINER);
}
};

parseEnv();
102 changes: 102 additions & 0 deletions src/common/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const fsConstants = {
fsCreate: {
FILE_NAME: 'fresh.txt',
},
fsCopy: {
FOLDER_NAME: 'files',
COPY_POSTFIX: '_copy',
CP_OPTIONS: { recursive: true },
},
fsRename: {
OLD_NAME: 'wrongFilename.txt',
NEW_NAME: 'properFilename.md',
},
fsDelete: {
FILE_NAME: 'fileToRemove.txt',
},
fsRead: {
FILE_NAME: 'fileToRead.txt',
},
FS_PATHS: {
PATH_TO_FILES: 'src/fs/files/',
PATH_TO_FS: 'src/fs/',
},
FS_CONDITIONS: {
PRESENT: true,
ABSENT: false,
},
FS_ERRORS: {
ERROR_MESSAGE: 'FS operation failed',
},
};
const cliConstants = {
parseArgs: {
SLICE_FROM: 1,
DELIMITER: ' ',
RE_DELIMITER: /\s\-{2}/,
JOINER: ' is ',
},
env: {
PATTERN: /RSS_/,
JOINER: '=',
},
};
const hashConstants = {
FILE_NAME: 'fileToCalculateHashFor.txt',
PATH_TO_FILE: 'src/hash/files/',
ALGORITHM: 'sha256',
ENCODING: 'hex',
};
const streamsConstants = {
STREAMS_PATHS: {
PATH_TO_FILE: 'src/streams/files/',
},
read: {
FILE_NAME: fsConstants.fsRead.FILE_NAME,
},
write: {
FILE_NAME: 'fileToWrite.txt',
},
transform: {
ENCODING: 'utf-8',
},
NEW_LINE: '\n',
};
const zipConstants = {
ZIP_PATHS: {
PATH_TO_FILE: 'src/zip/files',
},
compress: {
FILE_NAME: 'fileToCompress.txt',
ARCHIVE_NAME: 'archive.gz',
},
};
const wtConstants = {
WT_PATHS: {
PATH_TO_WORKER: 'src/wt/',
WORKER_NAME: 'worker.js',
},
FIB_BASE_N: 10,
RESULTS: {
SUCCESS: {
status: 'resolved',
},
ERROR: {
status: 'error',
data: null,
},
},
};
const cpConstants = {
CP_PATHS: {
PATH_TO_FILE: 'src/cp/files/',
SCRIPT_NAME: 'script.js',
},
INTERPRETER: 'node',
TEST_ARGS: ['firstArg', null, 4, undefined],
OPTIONS: {
stdio: 'inherit',
},
};

export { fsConstants, cliConstants, hashConstants, streamsConstants, zipConstants, wtConstants, cpConstants };
122 changes: 122 additions & 0 deletions src/common/functionDescriptors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { fsPathResolver } from './helpers.js';
import { cpus } from 'node:os';
import { fsConstants, hashConstants, streamsConstants, zipConstants, wtConstants, cpConstants } from './constants.js';

const makeFsDescriptors = () => {
const { FS_CONDITIONS, FS_PATHS, fsCopy, fsCreate, fsDelete, fsRead, fsRename } = fsConstants;
const { PATH_TO_FILES, PATH_TO_FS } = FS_PATHS;
const pathToFilesBuilder = fsPathResolver(PATH_TO_FILES);
const pathToFSBuilder = fsPathResolver(PATH_TO_FS);
return {
create: {
text: 'I am fresh and young',
fileDescriptor: {
fullPath: pathToFilesBuilder(fsCreate.FILE_NAME),
condition: FS_CONDITIONS.PRESENT,
},
},
copy: {
sourceFileDescriptor: {
fullPath: pathToFSBuilder(fsCopy.FOLDER_NAME),
condition: FS_CONDITIONS.ABSENT,
},
destinationFileDescriptor: {
fullPath: pathToFSBuilder(fsCopy.FOLDER_NAME.concat(fsCopy.COPY_POSTFIX)),
condition: FS_CONDITIONS.PRESENT,
},
options: fsCopy.CP_OPTIONS,
},
rename: {
oldFileDescriptor: {
fullPath: pathToFilesBuilder(fsRename.OLD_NAME),
condition: FS_CONDITIONS.ABSENT,
},
newFileDescriptor: {
fullPath: pathToFilesBuilder(fsRename.NEW_NAME),
condition: FS_CONDITIONS.PRESENT,
},
},
delete: {
fileDescriptor: {
fullPath: pathToFilesBuilder(fsDelete.FILE_NAME),
condition: FS_CONDITIONS.ABSENT,
},
},
read: {
fileDescriptor: {
fullPath: pathToFilesBuilder(fsRead.FILE_NAME),
condition: FS_CONDITIONS.ABSENT,
},
},
list: {
directoryDescriptor: {
fullPath: pathToFilesBuilder(),
condition: FS_CONDITIONS.ABSENT,
},
},
};
};
const makeHashDescriptors = () => {
const { PATH_TO_FILE, FILE_NAME, ENCODING, ALGORITHM } = hashConstants;
const pathToHashBuilder = fsPathResolver(PATH_TO_FILE);
return {
fullPath: pathToHashBuilder(FILE_NAME),
algorithm: ALGORITHM,
encoding: ENCODING,
};
};
const makeStreamsDescriptors = () => {
const { PATH_TO_FILE } = streamsConstants.STREAMS_PATHS;
const { read, NEW_LINE, write } = streamsConstants;
const pathToStreamsBuilder = fsPathResolver(PATH_TO_FILE);
return {
read: {
fullPath: pathToStreamsBuilder(read.FILE_NAME),
inputEnd: NEW_LINE,
},
write: {
fullPath: pathToStreamsBuilder(write.FILE_NAME),
},
};
};
const makeZipDescriptors = () => {
const { PATH_TO_FILE } = zipConstants.ZIP_PATHS;
const { FILE_NAME, ARCHIVE_NAME } = zipConstants.compress;
const pathToZIPBuilder = fsPathResolver(PATH_TO_FILE);
return {
compress: {
fullPathToFile: pathToZIPBuilder(FILE_NAME),
fullPathToArchive: pathToZIPBuilder(ARCHIVE_NAME),
},
};
};
const makeWtDescriptors = () => {
const { PATH_TO_WORKER, WORKER_NAME } = wtConstants.WT_PATHS;
const { FIB_BASE_N, RESULTS } = wtConstants;
const pathToWorkerBuilder = fsPathResolver(PATH_TO_WORKER);
return {
fullPathToWorker: pathToWorkerBuilder(WORKER_NAME),
baseN: FIB_BASE_N,
success: RESULTS.SUCCESS,
error: RESULTS.ERROR,
workersCount: cpus().length,
};
};
const makeCpDescriptors = () => {
const { PATH_TO_FILE, SCRIPT_NAME } = cpConstants.CP_PATHS;
const pathToCpBuilder = fsPathResolver(PATH_TO_FILE);
const { INTERPRETER, TEST_ARGS, OPTIONS } = cpConstants;
return {
interpreter: INTERPRETER,
argsArr: [pathToCpBuilder(SCRIPT_NAME)].concat(TEST_ARGS),
options: OPTIONS,
};
};
const fsDescriptors = makeFsDescriptors();
const hashDescriptor = makeHashDescriptors();
const streamsDescriptors = makeStreamsDescriptors();
const zipDescriptors = makeZipDescriptors();
const wtDescriptors = makeWtDescriptors();
const cpDescriptor = makeCpDescriptors();

export { fsDescriptors, hashDescriptor, streamsDescriptors, zipDescriptors, wtDescriptors, cpDescriptor };
28 changes: 28 additions & 0 deletions src/common/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { access } from 'node:fs/promises';
import { resolve } from 'node:path';
import { fsConstants } from './constants.js';

const fsPathExists = async (path) => {
try {
await access(path);
return true;
} catch {
return false;
}
};
const fsChecker = async (...descriptors) => {
const { ERROR_MESSAGE } = fsConstants.FS_ERRORS;
for (const { fullPath, condition } of descriptors) {
if ((await fsPathExists(fullPath)) === condition) throw new Error(ERROR_MESSAGE);
}
};
const fsPathResolver =
(basePath) =>
(...pathParts) =>
resolve(resolve(basePath), ...pathParts);
const cliPrintArgument = (argument, joiner) => {
const [property, value] = argument;
console.log(`${property}${joiner}${value}`);
};

export { fsChecker, fsPathResolver, cliPrintArgument };
9 changes: 7 additions & 2 deletions src/cp/cp.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { spawn } from 'node:child_process';
import { cpDescriptor } from '../common/functionDescriptors.js';

const { argsArr } = cpDescriptor;
const spawnChildProcess = async (args) => {
// Write your code here
const { interpreter, options } = cpDescriptor;
spawn(interpreter, args, options);
};

// Put your arguments in function call to test this functionality
spawnChildProcess( /* [someArgument1, someArgument2, ...] */);
spawnChildProcess(argsArr);
10 changes: 9 additions & 1 deletion src/fs/copy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { cp } from 'node:fs/promises';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const copy = async () => {
// Write your code here
const { sourceFileDescriptor, destinationFileDescriptor, options } = fsDescriptors.copy;
await fsChecker(sourceFileDescriptor, destinationFileDescriptor);
const { fullPath: source } = sourceFileDescriptor;
const { fullPath: destination } = destinationFileDescriptor;
await cp(source, destination, options);
};

await copy();
8 changes: 7 additions & 1 deletion src/fs/create.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { appendFile } from 'node:fs/promises';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const create = async () => {
// Write your code here
const { fileDescriptor, text } = fsDescriptors.create;
await fsChecker(fileDescriptor);
await appendFile(fileDescriptor.fullPath, text);
};

await create();
8 changes: 7 additions & 1 deletion src/fs/delete.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { rm } from 'fs/promises';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const remove = async () => {
// Write your code here
const { fileDescriptor } = fsDescriptors.delete;
await fsChecker(fileDescriptor);
await rm(fileDescriptor.fullPath);
};

await remove();
12 changes: 11 additions & 1 deletion src/fs/list.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import { readdir } from 'node:fs/promises';
import { parse } from 'node:path';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const list = async () => {
// Write your code here
const { directoryDescriptor } = fsDescriptors.list;
await fsChecker(directoryDescriptor);
for (const file of await readdir(directoryDescriptor.fullPath)) {
const { name } = parse(file);
console.log(name);
}
};

await list();
8 changes: 7 additions & 1 deletion src/fs/read.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { readFile } from 'node:fs/promises';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const read = async () => {
// Write your code here
const { fileDescriptor } = fsDescriptors.read;
await fsChecker(fileDescriptor);
console.log(await readFile(fileDescriptor.fullPath, { encoding: 'utf-8' }));
};

await read();
10 changes: 9 additions & 1 deletion src/fs/rename.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { rename as renameFile } from 'node:fs/promises';
import { fsChecker } from '../common/helpers.js';
import { fsDescriptors } from '../common/functionDescriptors.js';

const rename = async () => {
// Write your code here
const { oldFileDescriptor, newFileDescriptor } = fsDescriptors.rename;
await fsChecker(oldFileDescriptor, newFileDescriptor);
const { fullPath: oldFilePath } = oldFileDescriptor;
const { fullPath: newFilePath } = newFileDescriptor;
await renameFile(oldFilePath, newFilePath);
};

await rename();
Loading