lemonutilities
Version:
Lightweight and simple JavaScript library for file management, randomization, and for CLIs.
296 lines (243 loc) • 9.91 kB
JavaScript
/*
_ ____ __ __ ____ __ _ __ __ _____ _ _ _ _____ _ ____ ____
| |__ | ===|| \/ |/ () \| \| || | ||_ _|| || |__ | ||_ _|| || ===| (_ (_`
|____||____||_|\/|_|\____/|_|\__| \___/ |_| |_||____||_| |_| |_||____|.__)__)
*/
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const file = {
getFiles(directoryPath, fileExtension = '') {
try {
const files = fs.readdirSync(directoryPath);
const filteredFiles = files.filter((currentFile) => {
const filePath = path.join(directoryPath, currentFile);
const fileStats = fs.statSync(filePath);
const ext = fileExtension ? `.${fileExtension}` : '';
return (
fileStats.isFile() &&
(fileExtension === '' || path.extname(filePath) === ext)
);
});
return filteredFiles;
} catch (error) {
console.error('Cannot get files: dir:', directoryPath);
return [];
}
},
getSubFolders(directoryPath) {
try {
const scanned = fs.readdirSync(directoryPath);
const subfolders = scanned.filter(sub => {
const subfolderPath = path.join(directoryPath, sub);
return fs.statSync(subfolderPath).isDirectory();
});
return subfolders;
} catch (error) {
console.error('Cannot get subfolders: dir:', directoryPath);
return [];
}
},
moveDir(directoryPath, destinationFolderPath) {
if (!fs.accessSync(directoryPath)) {
console.error('lemkit: Cannot move directory: Specified source directory does not exist or is not accessible.');
return;
}
if (!fs.accessSync(destinationFolderPath)) {
console.error('lemkit: Cannot move directory: Specified destination directory does not exist or is not accessible.');
return;
}
const baseDirName = path.basename(directoryPath);
const destFolderPath = path.join(destinationFolderPath, baseDirName);
if (fs.existsSync(destFolderPath)) {
console.error('lemkit: Cannot move directory: Another directory with the same name already exists.');
return;
}
fs.rename(directoryPath, destFolderPath, (error) => {
if (error) {
console.error('lemkit: Cannot move directory:', error);
}
});
},
renameDir(directoryPath, newDirName) {
try {
if (!fs.accessSync(directoryPath)) {
console.error('lemkit: Cannot rename directory: Specified source directory does not exist or is not accessible.');
return;
}
const baseDirName = path.dirname(directoryPath);
const newName = path.join(baseDirName, newDirName);
if (fs.existsSync(newName)) {
console.error('lemkit: Cannot rename directory: Another directory with the same name already exists.');
return;
}
fs.rename(directoryPath, newName, (error) => {
if (error) {
console.error('lemkit: Cannot rename directory:', error);
}
});
} catch (error) {
console.error('lemkit: Error renaming directory:', error);
}
},
cloneFile(filePath, destinationFilePath) {
try {
if (!fs.accessSync(filePath)) {
console.error('lemkit: Cannot clone file: Specified source file does not exist or is not accessible.');
return;
}
const destinationDir = path.dirname(destinationFilePath);
if (!fs.existsSync(destinationDir)) {
fs.mkdirSync(destinationDir, { recursive: true });
}
if (!fs.accessSync(destinationDir)) {
console.error('lemkit: Cannot clone file: Specified destination directory does not exist or is not accessible.');
return;
}
fs.copyFileSync(filePath, destinationFilePath);
} catch (error) {
console.error('lemkit: Cannot clone file:', error);
}
},
cloneDir(directoryPath, destinationFolderPath) {
try {
if (!fs.accessSync(directoryPath)) {
console.error('lemkit: Cannot clone directory: Specified source directory does not exist or is not accessible.');
return;
}
if (!fs.existsSync(destinationFolderPath)) {
fs.mkdirSync(destinationFolderPath, { recursive: true });
}
if (!fs.accessSync(destinationFolderPath)) {
console.error('lemkit: Cannot clone directory: Specified destination directory is not accessible.');
return;
}
const dirName = path.basename(directoryPath);
const destinationFilePath = path.join(destinationFolderPath, dirName);
if (fs.existsSync(destinationFilePath)) {
console.error('lemkit: Cannot clone directory: Another directory with the same name already exists.');
return;
}
fs.mkdirSync(destinationFilePath);
const items = fs.readdirSync(directoryPath);
for (const item of items) {
const sourceItemPath = path.join(directoryPath, item);
const destinationItemPath = path.join(destinationFilePath, item);
const itemStats = fs.statSync(sourceItemPath);
if (itemStats.isDirectory()) {
this.cloneDir(sourceItemPath, destinationItemPath);
} else if (itemStats.isFile()) {
this.cloneFile(sourceItemPath, destinationItemPath);
}
}
} catch (error) {
console.error('lemkit: Cannot clone directory:', error);
}
},
calculateSize(directoryPath) {
try {
const stats = fs.statSync(directoryPath);
if (stats.isFile()) {
return stats.size;
}
if (stats.isDirectory()) {
let totalSize = 0;
const files = fs.readdirSync(directoryPath);
files.forEach((file) => {
const fullPath = path.join(directoryPath, file);
totalSize += this.calculateSize(fullPath);
});
return totalSize;
}
return 0;
} catch (error) {
console.error('lemkit: Cannot calculate file or directory size:', error);
return null;
}
}
}
const random = {
num(min, max) {
return Math.random() * (max - min) + min;
},
int(min, max) {
return Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1)) + Math.ceil(min);
},
item(array) {
return array[this.int(0, array.length - 1)];
},
arrayShuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
},
chance(...chances) {
const totalProbability = chances.reduce((sum, prob) => sum + prob, 0);
const randomValue = this.num(0, totalProbability);
let cumulativeProbability = 0;
for (let i = 0; i < chances.length; i++) {
cumulativeProbability += chances[i];
if (randomValue < cumulativeProbability) {
return i;
}
}
}
}
const cli = {
async consoleInput() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise(resolve => {
rl.question('\n> ', answer => {
rl.close();
resolve(answer);
});
});
},
deleteLines(num) {
for (let i = 0; i < num; i++) {
process.stdout.moveCursor(0, -1);
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
}
},
clear() {
// Feel pree to laugh at this function
process.stdout.write('\x1Bc');
},
async wait(seconds, showCountdown) {
return new Promise(resolve => {
let remaining = seconds;
if (showCountdown) {
console.log(`\nWaiting... ${remaining}`);
}
const countdown = setInterval(() => {
remaining--;
if (showCountdown) {
this.deleteLines(1);
console.log(`Waiting... ${remaining}`);
}
if (remaining <= 0) {
clearInterval(countdown);
resolve();
}
}, 1000);
});
},
async pause() {
return new Promise(resolve => {
console.log('\nPress any key to continue...');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.once('data', () => {
process.stdin.setRawMode(false);
process.stdin.pause();
resolve();
});
});
}
}
module.exports = { file, random, cli };