smartfile/dist/smartfile.fs.js

374 lines
23 KiB
JavaScript
Raw Normal View History

2016-06-23 16:31:55 +00:00
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
2016-07-17 15:34:15 +00:00
const plugins = require("./smartfile.plugins");
const SmartfileInterpreter = require("./smartfile.interpreter");
const smartfile_classes_smartfile_1 = require("./smartfile.classes.smartfile");
2016-09-24 19:42:45 +00:00
const memory = require("./smartfile.memory");
2016-06-23 16:31:55 +00:00
/*===============================================================
2016-06-24 01:36:51 +00:00
============================ Checks =============================
===============================================================*/
/**
*
* @param filePath
* @returns {boolean}
*/
exports.fileExistsSync = function (filePath) {
2016-07-17 15:34:15 +00:00
let fileExistsBool = false;
2016-06-24 01:36:51 +00:00
try {
2016-07-19 18:28:28 +00:00
plugins.fsExtra.readFileSync(filePath);
2016-06-24 01:36:51 +00:00
fileExistsBool = true;
}
catch (err) {
fileExistsBool = false;
}
return fileExistsBool;
};
/**
*
* @param filePath
* @returns {any}
*/
exports.fileExists = function (filePath) {
let done = plugins.smartpromise.defer();
2017-01-20 23:47:48 +00:00
plugins.fs.access(filePath, 4, function (err) {
2016-07-01 04:07:58 +00:00
err ? done.reject(err) : done.resolve();
2016-06-24 01:36:51 +00:00
});
return done.promise;
};
/**
* Checks if given path points to an existing directory
*/
exports.isDirectory = function (pathArg) {
try {
return plugins.fsExtra.statSync(pathArg).isDirectory();
}
catch (err) {
return false;
}
2016-06-24 01:36:51 +00:00
};
/**
* Checks if a given path points to an existing file
*/
exports.isFile = function (pathArg) {
2016-07-19 18:28:28 +00:00
return plugins.fsExtra.statSync(pathArg).isFile();
2016-06-24 01:36:51 +00:00
};
/*===============================================================
2016-06-23 16:31:55 +00:00
============================ FS ACTIONS =========================
===============================================================*/
2016-09-24 19:42:45 +00:00
/**
* copies a file from A to B on the local disk
*/
exports.copy = function (fromArg, toArg) {
let done = plugins.smartpromise.defer();
2016-09-24 19:42:45 +00:00
plugins.fsExtra.copy(fromArg, toArg, {}, function () {
done.resolve();
});
return done.promise;
};
/**
* copies a file SYNCHRONOUSLY from A to B on the local disk
*/
exports.copySync = function (fromArg, toArg) {
plugins.fsExtra.copySync(fromArg, toArg);
return true;
};
2016-06-28 04:57:51 +00:00
/**
* ensures that a directory is in place
*/
2016-07-17 15:34:15 +00:00
exports.ensureDir = (dirPathArg) => {
let done = plugins.smartpromise.defer();
2016-07-19 18:28:28 +00:00
plugins.fsExtra.ensureDir(dirPathArg, done.resolve);
2016-06-28 04:57:51 +00:00
return done.promise;
};
/**
* ensures that a directory is in place
*/
2016-07-17 15:34:15 +00:00
exports.ensureDirSync = (dirPathArg) => {
2016-07-19 18:28:28 +00:00
plugins.fsExtra.ensureDirSync(dirPathArg);
2016-06-28 04:57:51 +00:00
};
/**
* ensure an empty directory
* @executes ASYNC
*/
exports.ensureEmptyDir = (dirPathArg) => {
let done = plugins.smartpromise.defer();
plugins.fsExtra.ensureDir(dirPathArg, () => {
plugins.fsExtra.emptyDir(dirPathArg, done.resolve);
});
return done.promise;
};
/**
* ensure an empty directory
* @executes SYNC
*/
exports.ensureEmptyDirSync = (dirPathArg) => {
plugins.fsExtra.ensureDirSync(dirPathArg);
plugins.fsExtra.emptyDirSync(dirPathArg);
};
2016-06-23 16:39:02 +00:00
/**
2016-09-24 19:42:45 +00:00
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec ASYNC
2016-06-23 16:39:02 +00:00
*/
2016-09-24 19:42:45 +00:00
exports.ensureFile = (filePathArg, initFileStringArg) => {
let done = plugins.smartpromise.defer();
2016-09-24 19:42:45 +00:00
exports.ensureFileSync(filePathArg, initFileStringArg);
done.resolve();
2016-06-23 16:31:55 +00:00
return done.promise;
};
2016-06-23 16:39:02 +00:00
/**
2016-09-24 19:42:45 +00:00
* ensures that a file is on disk
* @param filePath the filePath to ensureDir
* @param the fileContent to place into a new file in case it doesn't exist yet
* @returns Promise<void>
* @exec SYNC
2016-06-23 16:39:02 +00:00
*/
2016-09-24 19:42:45 +00:00
exports.ensureFileSync = (filePathArg, initFileStringArg) => {
if (exports.fileExistsSync(filePathArg)) {
return null;
}
else {
memory.toFsSync(initFileStringArg, filePathArg);
}
2016-06-23 16:31:55 +00:00
};
2016-06-23 16:39:02 +00:00
/**
* removes a file or folder from local disk
*/
2016-06-23 16:31:55 +00:00
exports.remove = function (pathArg) {
let done = plugins.smartpromise.defer();
2016-07-19 18:28:28 +00:00
plugins.fsExtra.remove(pathArg, function () {
2016-06-23 16:31:55 +00:00
done.resolve();
});
return done.promise;
};
2016-06-23 16:39:02 +00:00
/**
* removes a file SYNCHRONOUSLY from local disk
*/
2016-06-23 16:31:55 +00:00
exports.removeSync = function (pathArg) {
2016-07-19 18:28:28 +00:00
plugins.fsExtra.removeSync(pathArg);
2016-06-23 16:31:55 +00:00
return true;
};
2016-09-29 12:17:46 +00:00
/**
* removes an array of filePaths from disk
*/
exports.removeMany = function (filePathArrayArg) {
let promiseArray = [];
for (let filePath of filePathArrayArg) {
promiseArray.push(exports.remove(filePath));
}
2017-01-20 23:47:48 +00:00
return Promise.all(promiseArray);
2016-09-29 12:17:46 +00:00
};
/**
* like removeFilePathArray but SYNCHRONOUSLY
*/
exports.removeManySync = function (filePathArrayArg) {
for (let filePath of filePathArrayArg) {
exports.removeSync(filePath);
}
};
2016-06-23 16:31:55 +00:00
/*===============================================================
============================ Write/Read =========================
===============================================================*/
/**
*
* @param filePathArg
* @param fileTypeArg
* @returns {any}
*/
exports.toObjectSync = function (filePathArg, fileTypeArg) {
2016-07-19 18:28:28 +00:00
let fileString = plugins.fsExtra.readFileSync(filePathArg, 'utf8');
2016-07-17 15:34:15 +00:00
let fileType;
2018-07-03 22:59:39 +00:00
fileTypeArg ? (fileType = fileTypeArg) : (fileType = SmartfileInterpreter.filetype(filePathArg));
2016-06-23 16:31:55 +00:00
return SmartfileInterpreter.objectFile(fileString, fileType);
};
/**
* reads a file content to a String
* @param filePath
* @returns {string|Buffer|any}
*/
exports.toStringSync = function (filePath) {
2017-03-11 23:06:56 +00:00
let fileString = plugins.fsExtra.readFileSync(filePath, 'utf8');
2016-06-23 16:31:55 +00:00
return fileString;
};
exports.fileTreeToObject = (dirPathArg, miniMatchFilter) => __awaiter(this, void 0, void 0, function* () {
2017-04-30 13:37:34 +00:00
// handle absolute miniMatchFilter
let dirPath;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
}
else {
dirPath = dirPathArg;
}
let fileTree = yield exports.listFileTree(dirPath, miniMatchFilter);
let smartfileArray = [];
for (let filePath of fileTree) {
2017-08-02 11:10:30 +00:00
let readPath = (() => {
if (!plugins.path.isAbsolute(filePath)) {
return plugins.path.join(dirPath, filePath);
}
else {
2017-08-02 11:16:07 +00:00
return filePath;
2017-08-02 11:10:30 +00:00
}
})();
let fileContentString = exports.toStringSync(readPath);
2017-05-26 12:47:41 +00:00
// push a read file as Smartfile
smartfileArray.push(new smartfile_classes_smartfile_1.Smartfile({
2017-05-01 17:49:34 +00:00
contentBuffer: new Buffer(fileContentString),
2017-04-30 16:13:17 +00:00
base: dirPath,
path: filePath
}));
}
return smartfileArray;
});
2016-06-23 16:31:55 +00:00
/**
*
* @param filePathArg
* @param options
* @returns {number}
*/
2016-07-17 15:34:15 +00:00
exports.toVinylSync = function (filePathArg, options = {}) {
2016-06-23 16:31:55 +00:00
return plugins.vinylFile.readSync(filePathArg, options);
};
/**
* lets you reload files hot.
* @param path
* @returns {any}
*/
exports.requireReload = function (path) {
return plugins.requireReload(path);
};
2016-06-23 16:39:02 +00:00
/**
* lists Folders in a directory on local disk
2016-06-28 04:57:51 +00:00
* @returns Promise
2016-06-23 16:39:02 +00:00
*/
exports.listFolders = function (pathArg, regexFilter) {
let done = plugins.smartpromise.defer();
2016-07-19 18:28:28 +00:00
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter(function (file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
2016-06-23 16:31:55 +00:00
});
if (regexFilter) {
2018-07-03 22:59:39 +00:00
folderArray = folderArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
2016-06-23 16:31:55 +00:00
done.resolve(folderArray);
return done.promise;
};
2016-06-23 16:39:02 +00:00
/**
* lists Folders SYNCHRONOUSLY in a directory on local disk
2016-06-28 04:57:51 +00:00
* @returns an array with the folder names as strings
2016-06-23 16:39:02 +00:00
*/
exports.listFoldersSync = function (pathArg, regexFilter) {
2016-07-19 18:28:28 +00:00
let folderArray = plugins.fsExtra.readdirSync(pathArg).filter(function (file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isDirectory();
2016-06-23 16:39:02 +00:00
});
if (regexFilter) {
2018-07-03 22:59:39 +00:00
folderArray = folderArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
return folderArray;
};
/**
* lists Files in a directory on local disk
* @returns Promise
*/
exports.listFiles = function (pathArg, regexFilter) {
let done = plugins.smartpromise.defer();
2016-07-19 18:28:28 +00:00
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter(function (file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
2018-07-03 22:59:39 +00:00
fileArray = fileArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
done.resolve(fileArray);
2016-06-28 07:59:59 +00:00
return done.promise;
};
/**
* lists Files SYNCHRONOUSLY in a directory on local disk
* @returns an array with the folder names as strings
*/
exports.listFilesSync = function (pathArg, regexFilter) {
2016-07-19 18:28:28 +00:00
let fileArray = plugins.fsExtra.readdirSync(pathArg).filter(function (file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
2018-07-03 22:59:39 +00:00
fileArray = fileArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
return fileArray;
};
/**
* lists all items (folders AND files) in a directory on local disk
2016-09-17 21:11:44 +00:00
* @returns Promise<string[]>
*/
exports.listAllItems = function (pathArg, regexFilter) {
let done = plugins.smartpromise.defer();
2016-07-19 18:28:28 +00:00
let allItmesArray = plugins.fsExtra.readdirSync(pathArg);
if (regexFilter) {
2018-07-03 22:59:39 +00:00
allItmesArray = allItmesArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
done.resolve(allItmesArray);
2016-06-28 07:59:59 +00:00
return done.promise;
};
/**
2016-09-17 21:11:44 +00:00
* lists all items (folders AND files) in a directory on local disk
* @returns an array with the folder names as strings
2016-09-17 21:11:44 +00:00
* @executes SYNC
*/
exports.listAllItemsSync = function (pathArg, regexFilter) {
2016-07-19 18:28:28 +00:00
let allItmesArray = plugins.fsExtra.readdirSync(pathArg).filter(function (file) {
return plugins.fsExtra.statSync(plugins.path.join(pathArg, file)).isFile();
});
if (regexFilter) {
2018-07-03 22:59:39 +00:00
allItmesArray = allItmesArray.filter(fileItem => {
2016-06-28 07:59:59 +00:00
return regexFilter.test(fileItem);
});
}
return allItmesArray;
2016-06-23 16:39:02 +00:00
};
2016-09-17 21:11:44 +00:00
/**
* lists a file tree using a miniMatch filter
2016-09-30 14:16:11 +00:00
* note: if the miniMatch Filter is an absolute path, the cwdArg will be omitted
2016-09-17 21:11:44 +00:00
* @returns Promise<string[]> string array with the absolute paths of all matching files
*/
2016-09-30 14:16:11 +00:00
exports.listFileTree = (dirPathArg, miniMatchFilter) => {
let done = plugins.smartpromise.defer();
2016-09-30 14:16:11 +00:00
// handle absolute miniMatchFilter
let dirPath;
if (plugins.path.isAbsolute(miniMatchFilter)) {
dirPath = '/';
}
else {
dirPath = dirPathArg;
}
2016-07-17 15:34:15 +00:00
let options = {
2017-05-26 23:07:32 +00:00
cwd: dirPath,
2017-05-27 00:54:22 +00:00
nodir: true,
dot: true
2016-06-30 23:37:48 +00:00
};
2016-07-17 15:34:15 +00:00
plugins.glob(miniMatchFilter, options, (err, files) => {
2016-06-30 23:37:48 +00:00
if (err) {
console.log(err);
2016-07-01 04:07:58 +00:00
done.reject(err);
2016-06-30 23:37:48 +00:00
}
done.resolve(files);
});
return done.promise;
};
2018-07-03 22:59:39 +00:00
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLmZzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRmaWxlLmZzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSwrQ0FBZ0Q7QUFDaEQsZ0VBQWlFO0FBRWpFLCtFQUEwRDtBQUUxRCw2Q0FBNkM7QUFDN0M7O2lFQUVpRTtBQUVqRTs7OztHQUlHO0FBQ1EsUUFBQSxjQUFjLEdBQUcsVUFBUyxRQUFRO0lBQzNDLElBQUksY0FBYyxHQUFZLEtBQUssQ0FBQztJQUNwQyxJQUFJO1FBQ0YsT0FBTyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkMsY0FBYyxHQUFHLElBQUksQ0FBQztLQUN2QjtJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1osY0FBYyxHQUFHLEtBQUssQ0FBQztLQUN4QjtJQUNELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDUSxRQUFBLFVBQVUsR0FBRyxVQUFTLFFBQVE7SUFDdkMsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QyxPQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFVBQVMsR0FBRztRQUN6QyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN0QixDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNRLFFBQUEsV0FBVyxHQUFHLFVBQVMsT0FBTztJQUN2QyxJQUFJO1FBQ0YsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztLQUN4RDtJ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