nope-js-node
Version:
NoPE Runtime for Nodejs. For Browser-Support please use nope-browser
246 lines (245 loc) • 8.71 kB
JavaScript
;
/**
* @module files
* @author Martin Karkowski
* @email m.karkowski@zema.de
*
* Helper to handle with files.
*
*
* Central Elements are:
* - {@link FOLDER_SPLIT}: The folder splitchar of the os.
* - {@link createFile}: A Helper to create a file.
* - {@link createPath}: A Helper to create a file and the corresponding folders if they doesnt exists.
* - {@link deletePath}: A Helper to remove a dir,
* - {@link relativePath}: Creates a releative path
* - {@link listFiles}: list files of a specific type in defined path.
* - {@link listFolders}: list Folders in defined path.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.listFolders = exports.listFiles = exports.relativePath = exports.deletePath = exports.createPath = exports.createFile = exports.FOLDER_SPLIT = exports.convertPathToOsPath = exports.getPathSeparator = exports.exists = void 0;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const util_1 = require("util");
const runtimeMethods_1 = require("./runtimeMethods");
const stringMethods_1 = require("./stringMethods");
exports.exists = (0, util_1.promisify)(fs_1.exists);
const _lstat = (0, util_1.promisify)(fs_1.lstat);
/**
* Helper to determine the Path Seperator.
* @returns
*/
function getPathSeparator() {
if (runtimeMethods_1.RUNNINGINWINDOWS) {
return "\\";
}
else if (runtimeMethods_1.RUNNINGINOSX || runtimeMethods_1.RUNNINGINLINUX) {
return "/";
}
// default to *nix system.
return "/";
}
exports.getPathSeparator = getPathSeparator;
/**
* Helper to convert the Path to an os specific path.
* @param path
* @returns
*/
function convertPathToOsPath(path) {
if (runtimeMethods_1.RUNNINGINWINDOWS) {
return (0, stringMethods_1.replaceAll)(path, "\\", exports.FOLDER_SPLIT);
}
return (0, stringMethods_1.replaceAll)(path, "/", exports.FOLDER_SPLIT);
}
exports.convertPathToOsPath = convertPathToOsPath;
// Based on the OS select the Path Element.
exports.FOLDER_SPLIT = getPathSeparator();
/**
* Function to create a File
* @param fileName Read the File.
* @param content content which should be stored
* @param options The options to write the file. See original docu: https://nodejs.org/dist/latest-v8.x/docs/api/fs.html#fs_fs_writefile_file_data_options_callback
*/
async function createFile(fileName, content, options) {
// Adapt the File Pathes
fileName = convertPathToOsPath(fileName);
// Split the Path into different segements.
const pathParts = fileName.split(exports.FOLDER_SPLIT);
// Pop the File.
pathParts.pop();
// Create the Path / Directories
await createPath(pathParts.join(exports.FOLDER_SPLIT));
// Wirte the File.
await (0, promises_1.writeFile)(fileName, content, options);
return fileName;
}
exports.createFile = createFile;
/**
* Function to create a File at a given Path. If the File or the dir doesnt exists it will be created.
* @param path Read the File.
* @param content content which should be stored
* @param options The options to write the file. See original docu: https://nodejs.org/dist/latest-v8.x/docs/api/fs.html#fs_fs_writefile_file_data_options_callback
*/
async function createPath(path) {
// Adapt the File Pathes
path = convertPathToOsPath(path);
await (0, promises_1.mkdir)(path, { recursive: true });
return path;
}
exports.createPath = createPath;
/**
* Deletes the complete Path recursevly.
* > *WARNING: * Deletes Everything in the Folder.
*
* Example:
* `deletePath('C:\\Test');`
*
* This deletes all Files and Subfolders in the given Path.
* Furthermore the Folder Test itself is removed.
*
* @export
* @param {string} dirPath
*/
async function deletePath(dirPath) {
if (!(await (0, exports.exists)(dirPath))) {
throw new URIError("path doesnt exits.");
}
// Make shure we are using the correct path.
dirPath = convertPathToOsPath(dirPath);
const _totalPath = dirPath;
/** Sort the Pathes according to their length. For instance:
* _pathes = ['C:\\Test\\Sub', 'C:\\Test\\Sub\\SubSub']
*
* => After Sorting :
* _pathes = ['C:\\Test\\Sub\\SubSub', 'C:\\Test\\Sub']
*
* This garantuees to delete all Sub Folders in a correct sequence.
*/
const _pathes = (await listFolders(_totalPath)).sort((a, b) => {
return b.split(exports.FOLDER_SPLIT).length - a.split(exports.FOLDER_SPLIT).length;
});
const _files = await listFiles(_totalPath);
/** Delete all Files. */
for (const _file of _files) {
await (0, promises_1.unlink)(_file);
}
/** Delete all Folders. */
for (const _path of _pathes) {
await (0, promises_1.rmdir)(_path);
}
await (0, promises_1.rmdir)(dirPath);
}
exports.deletePath = deletePath;
/**
* Creates a relative Path based on the Folder where
* 'node ...' was typed.
* @param _dirPath the path to Check
* @param _currentPath the current Path.
*/
function relativePath(_dirPath, _currentPath = process.cwd()) {
return (0, path_1.join)(convertPathToOsPath(_currentPath), convertPathToOsPath(_dirPath));
}
exports.relativePath = relativePath;
/**
* Returns a List of File-Names.
*
* @export
* @param {string} dirPath Path where the system should look
* @param {string} [type=''] specified ending of the File. For Instance '.conf'
* @returns {Array<string>} List containing all Files
*/
async function listFiles(dirPath, type = "") {
// Adapt the Path
dirPath = convertPathToOsPath(dirPath);
if (!(0, exports.exists)(dirPath)) {
throw new URIError("path doesnt exits.");
}
const _dirPath = dirPath;
const _files = new Array();
/** Define a Function to Handle the Files. */
const _fileFunc = async function (err, file_name) {
if (err) {
throw err;
}
// Check the File Ending.
if (file_name.endsWith(type)) {
_files.push(file_name);
}
};
/** Define a Function to Handle the Dirs => Recursive call. */
const _dirFunc = async function (err, _path) {
if (err) {
throw err;
}
else {
await _walkRecursive(_path, _fileFunc, _dirFunc);
}
};
// Function to Filter the Files and add it to the Array.
await _walkRecursive(_dirPath, _fileFunc, _dirFunc);
// Return the File.
return _files;
}
exports.listFiles = listFiles;
/**
* Lists all Subfolders in the given Path
*
* @export
* @param {string} dirPath Start path
* @returns {Array<string>} Array containing all Pathes to the Subfolders
*/
async function listFolders(dirPath) {
// Adapt the Path
dirPath = convertPathToOsPath(dirPath);
if (!(await (0, exports.exists)(dirPath))) {
throw new URIError("path doesnt exits.");
}
const _dirPath = dirPath;
const _pathes = new Array();
/** Define a Function to Handle the Dirs => Recursive call. */
const _dirFunc = async function (err, _path) {
if (err) {
throw err;
}
else {
_pathes.push(_path);
await _walkRecursive(_path, async () => {
// no callback
}, _dirFunc);
}
};
// Function to Filter the Files and add it to the Array.
await _walkRecursive(_dirPath, async () => {
// no callback
}, _dirFunc);
// Return the File.
return _pathes;
}
exports.listFolders = listFolders;
/**
* Internal Function to walk through a directory and
* call different functions on a found subdir or file.
*
* @param {string} dirPath start path
* @param {(err, data) => void} filecallback function which is called on a file
* @param {(err, data) => void} foldercallback function which is called on a folder
*/
async function _walkRecursive(dirPath, filecallback, foldercallback) {
// Adapt the Path
dirPath = convertPathToOsPath(dirPath);
for (const name of await (0, promises_1.readdir)(dirPath)) {
// Create the FilePath
const filePath = (0, path_1.join)(dirPath, name);
// Determine the Type
const stat = await _lstat(filePath);
if (stat.isFile()) {
// It is a File => Store it.
await filecallback(null, filePath);
}
else if (stat.isDirectory()) {
// It is a Directory.
await foldercallback(null, filePath);
}
}
}