Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"type": "module",
"scripts": {
"start": "node src/index.js",
"cli:args": "node src/cli/args.js --some-arg value1 --other 1337 --arg2 42",
"cli:env": "npx cross-env SOME=any RSS_foo=bar RSS_bar=baz node src/cli/env.js",
"cp": "node src/cp/cp.js",
Expand Down
5 changes: 0 additions & 5 deletions src/cli/args.js

This file was deleted.

5 changes: 0 additions & 5 deletions src/cli/env.js

This file was deleted.

6 changes: 0 additions & 6 deletions src/cp/cp.js

This file was deleted.

19 changes: 0 additions & 19 deletions src/cp/files/script.js

This file was deleted.

32 changes: 32 additions & 0 deletions src/fileManager/commandExecutor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { up, cd, ls } from './commands/navigation.js';
import { cat, add, mkdir, rn, cp, mv, rm } from './commands/files.js';
import { osInfo } from './commands/os.js';
import { hash } from './commands/hash.js';
import { compress, decompress } from './commands/compress.js';

const commandHandlers = {
'up': up,
'cd': cd,
'ls': ls,
'cat': cat,
'add': add,
'mkdir': mkdir,
'rn': rn,
'cp': cp,
'mv': mv,
'rm': rm,
'os': osInfo,
'hash': hash,
'compress': compress,
'decompress': decompress,
};

export const executeCommand = async ({ command, args }) => {
const handler = commandHandlers[command];

if (!handler) {
throw new Error('Invalid input');
}

await handler(args);
};
7 changes: 7 additions & 0 deletions src/fileManager/commandParser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const parseCommand = (input) => {
const parts = input.trim().split(/\s+/);
const command = parts[0];
const args = parts.slice(1);

return { command, args };
};
42 changes: 42 additions & 0 deletions src/fileManager/commands/compress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createReadStream, createWriteStream } from 'fs';
import { resolve } from 'path';
import { createBrotliCompress, createBrotliDecompress } from 'zlib';
import { pipeline } from 'stream/promises';

export const compress = async (args) => {
if (args.length !== 2) {
throw new Error('Invalid input');
}

const sourcePath = resolve(args[0]);
const destPath = resolve(args[1]);

try {
const readStream = createReadStream(sourcePath);
const writeStream = createWriteStream(destPath);
const brotli = createBrotliCompress();

await pipeline(readStream, brotli, writeStream);
} catch (error) {
throw new Error('Operation failed');
}
};

export const decompress = async (args) => {
if (args.length !== 2) {
throw new Error('Invalid input');
}

const sourcePath = resolve(args[0]);
const destPath = resolve(args[1]);

try {
const readStream = createReadStream(sourcePath);
const writeStream = createWriteStream(destPath);
const brotli = createBrotliDecompress();

await pipeline(readStream, brotli, writeStream);
} catch (error) {
throw new Error('Operation failed');
}
};
176 changes: 176 additions & 0 deletions src/fileManager/commands/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { createReadStream, createWriteStream } from 'fs';
import { mkdir as mkdirFs, unlink, stat } from 'fs/promises';
import { resolve } from 'path';
import { cwd } from 'process';
import { pipeline } from 'stream/promises';
import { rename } from 'fs/promises';

export const cat = async (args) => {
if (args.length === 0) {
throw new Error('Invalid input');
}

const filePath = resolve(args[0]);

try {
const stream = createReadStream(filePath);

return new Promise((resolve, reject) => {
stream.on('error', (error) => {
reject(new Error('Operation failed'));
});

stream.on('end', () => {
resolve();
});

stream.pipe(process.stdout);
});
} catch (error) {
throw new Error('Operation failed');
}
};

export const add = async (args) => {
if (args.length === 0) {
throw new Error('Invalid input');
}

const fileName = args[0];
const filePath = resolve(cwd(), fileName);

try {
// Create empty file
const stream = createWriteStream(filePath);
stream.end();

return new Promise((resolve, reject) => {
stream.on('finish', resolve);
stream.on('error', reject);
});
} catch (error) {
throw new Error('Operation failed');
}
};

export const mkdir = async (args) => {
if (args.length === 0) {
throw new Error('Invalid input');
}

const dirName = args[0];
const dirPath = resolve(cwd(), dirName);

try {
await mkdirFs(dirPath);
} catch (error) {
throw new Error('Operation failed');
}
};

export const rn = async (args) => {
if (args.length !== 2) {
throw new Error('Invalid input');
}

const oldPath = resolve(args[0]);
const newFileName = args[1];
const newPath = resolve(cwd(), newFileName);

try {
await rename(oldPath, newPath);
} catch (error) {
throw new Error('Operation failed');
}
};

export const cp = async (args) => {
if (args.length !== 2) {
throw new Error('Invalid input');
}

const sourcePath = resolve(args[0]);
const destArg = resolve(args[1]);

try {
let destPath;

// Check if destination exists
try {
const destStats = await stat(destArg);
if (destStats.isDirectory()) {
// Destination is a directory, use source filename
const sourceFileName = sourcePath.split(/[/\\]/).pop();
destPath = resolve(destArg, sourceFileName);
} else {
// Destination exists but is not a directory - treat as file path
destPath = destArg;
}
} catch (error) {
// Destination doesn't exist - treat as file path
destPath = destArg;
}

// Copy using streams
const readStream = createReadStream(sourcePath);
const writeStream = createWriteStream(destPath);

await pipeline(readStream, writeStream);
} catch (error) {
throw new Error('Operation failed');
}
};

export const mv = async (args) => {
if (args.length !== 2) {
throw new Error('Invalid input');
}

const sourcePath = resolve(args[0]);
const destArg = resolve(args[1]);

try {
let destPath;

// Check if destination exists
try {
const destStats = await stat(destArg);
if (destStats.isDirectory()) {
// Destination is a directory, use source filename
const sourceFileName = sourcePath.split(/[/\\]/).pop();
destPath = resolve(destArg, sourceFileName);
} else {
// Destination exists but is not a directory - treat as file path
destPath = destArg;
}
} catch (error) {
// Destination doesn't exist - treat as file path
destPath = destArg;
}

// Copy using streams
const readStream = createReadStream(sourcePath);
const writeStream = createWriteStream(destPath);

await pipeline(readStream, writeStream);

// Delete original file
await unlink(sourcePath);
} catch (error) {
throw new Error('Operation failed');
}
};

export const rm = async (args) => {
if (args.length === 0) {
throw new Error('Invalid input');
}

const filePath = resolve(args[0]);

try {
await unlink(filePath);
} catch (error) {
throw new Error('Operation failed');
}
};
31 changes: 31 additions & 0 deletions src/fileManager/commands/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createReadStream } from 'fs';
import { resolve } from 'path';
import { createHash } from 'crypto';

export const hash = async (args) => {
if (args.length === 0) {
throw new Error('Invalid input');
}

const filePath = resolve(args[0]);
const hashStream = createHash('sha256');

try {
const readStream = createReadStream(filePath);

return new Promise((resolve, reject) => {
readStream.on('data', (data) => {
hashStream.update(data);
});

readStream.on('end', () => {
console.log(hashStream.digest('hex'));
resolve();
});

readStream.on('error', reject);
});
} catch (error) {
throw new Error('Operation failed');
}
};
Loading