2016-06-23 16:31:55 +00:00
|
|
|
"use strict";
|
|
|
|
require("typings-global");
|
2016-07-17 15:34:15 +00:00
|
|
|
const plugins = require("./smartfile.plugins");
|
|
|
|
const SmartfileInterpreter = require("./smartfile.interpreter");
|
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) {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.defer();
|
2016-06-24 01:36:51 +00:00
|
|
|
plugins.fs.access(filePath, plugins.fs.R_OK, 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) {
|
2016-07-19 18:28:28 +00:00
|
|
|
return plugins.fsExtra.statSync(pathArg).isDirectory();
|
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-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) => {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.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
|
|
|
};
|
2016-06-23 16:39:02 +00:00
|
|
|
/**
|
|
|
|
* copies a file from A to B on the local disk
|
|
|
|
*/
|
2016-06-23 16:31:55 +00:00
|
|
|
exports.copy = function (fromArg, toArg) {
|
2016-09-17 21:11:44 +00:00
|
|
|
var done = plugins.q.defer();
|
2016-07-19 18:28:28 +00:00
|
|
|
plugins.fsExtra.copy(fromArg, toArg, {}, function () {
|
2016-06-23 16:31:55 +00:00
|
|
|
done.resolve();
|
|
|
|
});
|
|
|
|
return done.promise;
|
|
|
|
};
|
2016-06-23 16:39:02 +00:00
|
|
|
/**
|
|
|
|
* copies a file SYNCHRONOUSLY from A to B on the local disk
|
|
|
|
*/
|
2016-06-23 16:31:55 +00:00
|
|
|
exports.copySync = function (fromArg, toArg) {
|
2016-07-19 18:28:28 +00:00
|
|
|
plugins.fsExtra.copySync(fromArg, toArg);
|
2016-06-23 16:31:55 +00:00
|
|
|
return true;
|
|
|
|
};
|
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) {
|
2016-09-17 21:11:44 +00:00
|
|
|
var done = plugins.q.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;
|
|
|
|
};
|
|
|
|
/*===============================================================
|
|
|
|
============================ Write/Read =========================
|
|
|
|
===============================================================*/
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param filePathArg
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
exports.toGulpStreamSync = function (filePathArg) {
|
2016-07-17 15:34:15 +00:00
|
|
|
let stream = plugins.gulp.src(filePathArg);
|
2016-06-23 16:31:55 +00:00
|
|
|
return stream;
|
|
|
|
};
|
|
|
|
exports.toGulpDestSync = function (folderPathArg) {
|
|
|
|
return plugins.gulp.dest(folderPathArg);
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @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;
|
2016-06-23 16:31:55 +00:00
|
|
|
fileTypeArg ? fileType = fileTypeArg : fileType = SmartfileInterpreter.filetype(filePathArg);
|
|
|
|
return SmartfileInterpreter.objectFile(fileString, fileType);
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* reads a file content to a String
|
|
|
|
* @param filePath
|
|
|
|
* @returns {string|Buffer|any}
|
|
|
|
*/
|
|
|
|
exports.toStringSync = function (filePath) {
|
2016-07-17 15:34:15 +00:00
|
|
|
let fileString;
|
2016-07-19 18:28:28 +00:00
|
|
|
fileString = plugins.fsExtra.readFileSync(filePath, "utf8");
|
2016-06-23 16:31:55 +00:00
|
|
|
return fileString;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @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
|
|
|
*/
|
2016-06-28 06:40:22 +00:00
|
|
|
exports.listFolders = function (pathArg, regexFilter) {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.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
|
|
|
});
|
2016-06-28 06:40:22 +00:00
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
folderArray = folderArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
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
|
|
|
*/
|
2016-06-28 06:40:22 +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
|
|
|
});
|
2016-06-28 06:40:22 +00:00
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
folderArray = folderArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
;
|
|
|
|
return folderArray;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* lists Files in a directory on local disk
|
|
|
|
* @returns Promise
|
|
|
|
*/
|
|
|
|
exports.listFiles = function (pathArg, regexFilter) {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.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();
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
fileArray = fileArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
;
|
|
|
|
done.resolve(fileArray);
|
2016-06-28 07:59:59 +00:00
|
|
|
return done.promise;
|
2016-06-28 06:40:22 +00:00
|
|
|
};
|
|
|
|
/**
|
|
|
|
* 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();
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
fileArray = fileArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
;
|
|
|
|
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[]>
|
2016-06-28 06:40:22 +00:00
|
|
|
*/
|
|
|
|
exports.listAllItems = function (pathArg, regexFilter) {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.defer();
|
2016-07-19 18:28:28 +00:00
|
|
|
let allItmesArray = plugins.fsExtra.readdirSync(pathArg);
|
2016-06-28 06:40:22 +00:00
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
allItmesArray = allItmesArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
;
|
|
|
|
done.resolve(allItmesArray);
|
2016-06-28 07:59:59 +00:00
|
|
|
return done.promise;
|
2016-06-28 06:40:22 +00:00
|
|
|
};
|
|
|
|
/**
|
2016-09-17 21:11:44 +00:00
|
|
|
* lists all items (folders AND files) in a directory on local disk
|
2016-06-28 06:40:22 +00:00
|
|
|
* @returns an array with the folder names as strings
|
2016-09-17 21:11:44 +00:00
|
|
|
* @executes SYNC
|
2016-06-28 06:40:22 +00:00
|
|
|
*/
|
|
|
|
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();
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
if (regexFilter) {
|
2016-07-17 15:34:15 +00:00
|
|
|
allItmesArray = allItmesArray.filter((fileItem) => {
|
2016-06-28 07:59:59 +00:00
|
|
|
return regexFilter.test(fileItem);
|
2016-06-28 06:40:22 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
;
|
|
|
|
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
|
|
|
|
* @returns Promise<string[]> string array with the absolute paths of all matching files
|
|
|
|
*/
|
2016-07-17 15:34:15 +00:00
|
|
|
exports.listFileTree = (dirPath, miniMatchFilter) => {
|
2016-09-17 21:11:44 +00:00
|
|
|
let done = plugins.q.defer();
|
2016-07-17 15:34:15 +00:00
|
|
|
let options = {
|
2016-06-30 23:37:48 +00:00
|
|
|
cwd: dirPath
|
|
|
|
};
|
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;
|
|
|
|
};
|
2016-09-17 21:11:44 +00:00
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRmaWxlLmZzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRmaWxlLmZzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFFeEIsTUFBTyxPQUFPLFdBQVcscUJBQXFCLENBQUMsQ0FBQztBQUNoRCxNQUFPLG9CQUFvQixXQUFXLHlCQUF5QixDQUFDLENBQUM7QUFFakU7O2lFQUVpRTtBQUVqRTs7OztHQUlHO0FBQ1Esc0JBQWMsR0FBRyxVQUFTLFFBQVE7SUFDekMsSUFBSSxjQUFjLEdBQVcsS0FBSyxDQUFDO0lBQ25DLElBQUksQ0FBQztRQUNELE9BQU8sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZDLGNBQWMsR0FBRyxJQUFJLENBQUE7SUFDekIsQ0FDQTtJQUFBLEtBQUssQ0FBQSxDQUFDLEdBQUcsQ0FBQyxDQUFBLENBQUM7UUFDUCxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQzNCLENBQUM7SUFDRCxNQUFNLENBQUMsY0FBYyxDQUFDO0FBQzFCLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDUSxrQkFBVSxHQUFHLFVBQVMsUUFBUTtJQUNyQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLEdBQUc7UUFDdEQsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDeEIsQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDUSxtQkFBVyxHQUFHLFVBQVMsT0FBTztJQUNyQyxNQUFN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
|