file-js
Version:
Abstract representation of a pathname
740 lines (719 loc) • 20.5 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>file.js - Documentation</title>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav>
<h2><a href="index.html">Home</a></h2>
</nav>
<div id="main">
<h1 class="page-title">file.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>"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 });
const fs_1 = require("fs");
const fileGlob = require("minimatch");
const path = require("path");
const fsp = require("./fsp");
function joinWith(dir) {
return (file) => {
return path.join(dir, file);
};
}
class File {
constructor(pathname) {
this.dir = process.cwd();
this.pathname = pathname;
}
/**
* Synchronously determine if pathname is a directory
*
* @memberOf File
* @method
* isDirectorySync
* @return boolean
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* if (file.isDirectorySync()) {
* console.log('processing directory');
* }
*/
isDirectorySync() {
return this.getStatsSync().isDirectory();
}
/**
* Synchronously determine if pathname is a socket
*
* @memberOf File
* @method
* isSocketSync
* @return boolean
* @example
* import File from 'file-js';
*
* const file = new File('mysocket');
* if (file.isSocketSync()) {
* console.log('processing socket');
* }
*/
isSocketSync() {
return this.getStatsSync().isSocket();
}
/**
* Synchronously determine if pathname is a file
*
* @memberOf File
* @method
* isFileSync
* @return boolean
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* if (file.isFileSync()) {
* console.log('processing file');
* }
*/
isFileSync() {
return this.getStatsSync().isFile();
}
/**
* Determine if pathname is a directory
*
* @memberOf File
* @method
* isDirectory
* @return If the Promise fulfils, the fulfilment value is
* a boolean indicating if the pathname is a directory
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* const isDirectory = await file.isDirectory((isDirectory);
* console.log(isDirectory);
*/
isDirectory() {
return __awaiter(this, void 0, void 0, function* () {
return this.checkAsyncStats('isDirectory');
});
}
/**
* Determine if pathname is a Socket
*
* @memberOf File
* @method
* isSocket
* @return If the Promise fulfils, the fulfilment value is
* a boolean indicating if the pathname is a Socket
* @example
* import File from 'file-js';
*
* const file = new File('mySocket');
* const isSocket = await file.isSocket((isSocket));
* console.log(isSocket);
*/
isSocket() {
return __awaiter(this, void 0, void 0, function* () {
return this.checkAsyncStats('isSocket');
});
}
/**
* Determine if pathname is a file
*
* @memberOf File
* @method
* isFile
* @return If the Promise fulfils, the fulfilment value is
* a boolean indicating if the pathname is a file
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* const isFile = await file.isFile();
* console.log(isFile);
*/
isFile() {
return __awaiter(this, void 0, void 0, function* () {
return this.checkAsyncStats('isFile');
});
}
/**
* Synchronously determine if pathname is a hidden file
*
* @memberOf File
* @method
* isHiddenSync
* @return boolean
* @example
* import File from 'file-js';
*
* const file = new File('./myHiddenFile');
* if (file.isHiddenSync()) {
* console.log('processing hidden file');
* }
*/
isHiddenSync() {
if (!this.isDirectorySync()) {
return this.isHiddenFile();
}
return this.isHiddenDirectory();
}
/**
* Determine if pathname is a file
*
* @memberOf File
* @method
* isHidden
* @return If the Promise fulfils, the fulfilment value is
* a boolean indicating if the pathname is a hidden file
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* const isHidden = await file.isHidden();
* console.log(isHidden);
*/
isHidden() {
return __awaiter(this, void 0, void 0, function* () {
if (!(yield this.isDirectory())) {
return this.isHiddenFile();
}
return this.isHiddenDirectory();
});
}
/**
* Synchronously get list of files, if pathname is a directory
*
* @memberOf File
* @method
* getListSync
* @return array of files
* @example
* import File from 'file-js';
*
* const file = new File('./myHiddenFile');
* const files = file.getListSync();
* console.log(files);
*/
getListSync() {
if (this.isDirectorySync()) {
return fs_1.readdirSync(this.pathname)
.map((file) => {
return path.join(this.pathname, file);
});
}
return null;
}
/**
* Get list of file objects, if pathname is a directory
*
* @memberOf File
* @method
* getList
* @return a promise. If the Promise fulfils, the fulfilment value is
* a list of pathnames
* @example
* import File from 'file-js';
*
* // get all json files
* const file = new File('./myDirectory');
* const files = await file.getFiles('*.json');
* console.log(jsonFiles);
*/
getList(glob) {
return __awaiter(this, void 0, void 0, function* () {
const files = yield this.getFiles(glob);
if (files.length > 0) {
return files.map(pathname => pathname.getName());
}
return [];
});
}
/**
* Get list of file objects, if pathname is a directory
*
* @memberOf File
* @method
* getFiles
* @return a promise. If the Promise fulfils, the fulfilment value is
* a list of File objects
* @example
* import File from 'file-js';
*
* // get last modified time of all json files
* const file = new File('./myDirectory');
* const files = await file.getFiles('*.json');
* console.log(jsonFiles.map(file => file.lastModifiedSync()));
*/
getFiles(glob) {
return __awaiter(this, void 0, void 0, function* () {
if (!(yield this.isDirectory())) {
return [];
}
const files = yield fsp.readdir(this.pathname);
const results = files
.map(joinWith(this.pathname))
.map(pathname => new File(pathname));
if (results.length === 0) {
return [];
}
if (glob) {
return results.filter(file => file.isMatch(glob));
}
return results;
});
}
/**
* Synchronously get list of file objects, if pathname is a directory
*
* @memberOf File
* @method
* getFileSync
* @return array of files
* @example
* import File from 'file-js';
*
* const file = new File('./myHiddenFile');
* const files = file.getFileSync();
* console.log(files);
*/
getFilesSync(glob) {
if (this.isDirectorySync()) {
const files = this.getListSync()
.map((pathname) => {
return new File(pathname);
});
if (glob) {
return files.filter(file => file.isMatch(glob));
}
return files;
}
return null;
}
/**
* Synchronously calculate the depth of a directory
*
* @memberOf File
* @method
* getDepthSync
* @return boolean
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* console.log(file.getDepthSync());
*/
getDepthSync() {
if (!this.isDirectorySync()) {
return this.depth(path.dirname(this.pathname));
}
return this.depth(this.pathname);
}
/**
* Returns the pathname as a string
*
* @memberOf File
* @method
* getName
* @return String
* @example
* import File from 'file-js';
*
* const file = new File('myDirectory');
* console.log(file.getName());
*/
getName() {
return this.pathname;
}
/**
* Returns the absolutePath
*
* @memberOf File
* @method
* getAbsolutePath
* @return String
* @example
* import File from 'file-js';
*
* const file = new File('myFile');
* console.log(file.getAbsolutePath());
*/
getAbsolutePath() {
if (path.isAbsolute(this.pathname)) {
return this.pathname;
}
return [this.dir, this.pathname].join(path.sep);
}
/**
* Returns the canonical path
*
* @memberOf File
* @method
* getCanonicalPath
* @return String
* @example
* import File from 'file-js';
*
* const file = new File('myFile');
* console.log(file.getCanonicalPath());
*/
getCanonicalPath() {
return path.normalize(this.getAbsolutePath());
}
/**
* Returns the file extension.
*
* @memberOf File
* @method
* getPathExtension
* @return String
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.getPathExtension()); // sh
*/
getPathExtension() {
return path.extname(this.pathname).substring(1);
}
/**
* Returns the last modified date.
*
* @memberOf File
* @method
* lastModifiedSync
* @return Date
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.lastModifiedSync());
*/
lastModifiedSync() {
return this.getStatsSync().mtime;
}
/**
* Returns the last the file was accessed.
*
* @memberOf File
* @method
* lastAccessedSync
* @return Date
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.lastAccessedSync());
*/
lastAccessedSync() {
return this.getStatsSync().atime;
}
/**
* Returns the last the file was changed.
*
* @memberOf File
* @method
* lastChangedSync
* @return Date
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.lastChangedSync());
*/
lastChangedSync() {
return this.getStatsSync().ctime;
}
/**
* Returns the size of the file.
*
* @memberOf File
* @method
* sizeSync
* @return Date
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.sizeSync());
*/
sizeSync() {
return this.getStatsSync().size;
}
/**
* Returns true if the file is writable
*
* @memberOf File
* @method
* isWritable
* @return Boolean
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.isWritable());
*/
isWritable() {
return __awaiter(this, void 0, void 0, function* () {
return this.access(fs_1.constants.W_OK);
});
}
/**
* Returns true if the file is readable
*
* @memberOf File
* @method
* isReadable
* @return Boolean
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.isReadable());
*/
isReadable() {
return __awaiter(this, void 0, void 0, function* () {
return this.access(fs_1.constants.R_OK);
});
}
/**
* Returns true if the file is executable
*
* @memberOf File
* @method
* isExecutable
* @return Boolean
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.sizeSync());
*/
isExecutable() {
return __awaiter(this, void 0, void 0, function* () {
return this.access(fs_1.constants.X_OK);
});
}
/**
* Deletes the file.
*
* @memberOf File
* @method
* delete
* @return void
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* file.delete();
*/
delete() {
return __awaiter(this, void 0, void 0, function* () {
return fsp.unlink(this.pathname);
});
}
/**
* Recursively delete the folder and contents.
*
* @memberOf File
* @method
* deleteRecursively
* @return void
* @example
* import File from 'file-js';
*
* const file = new File('./dir/');
* file.deleteRecursively();
*/
deleteRecursively(dirPath = this.pathname) {
return __awaiter(this, void 0, void 0, function* () {
if (this.exists()) {
const files = yield fsp.readdir(dirPath);
for (const file of files) {
const curPath = `${dirPath}/${file}`;
const isDirectory = (yield fsp.lstat(curPath)).isDirectory();
const isFile = (yield fsp.lstat(curPath)).isFile();
if (isDirectory) {
const hasFiles = (yield fsp.readdir(curPath)).length > 0;
if (hasFiles) {
yield this.deleteRecursively(curPath);
}
}
if (isFile) {
yield fsp.unlink(curPath);
}
}
yield fsp.rmdir(dirPath);
}
});
}
/**
* Recursively copy the folder and contents.
*
* @memberOf File
* @method
* copyRecursively
* @return : void
* @example
* import File from 'file-js';
*
* const file = new File('dir/');
* file.copyRecursively('destination/');
*/
copyRecursively(destination, opts = { overwrite: false }) {
return __awaiter(this, void 0, void 0, function* () {
if (!opts.source) {
opts.source = this.pathname;
}
// check if destination directory already exists
const directoryExists = fs_1.existsSync(destination);
if (directoryExists && !opts.overwrite) {
throw new Error(`Directory: "${destination}" already exists.`);
}
else if (directoryExists && opts.overwrite) {
yield this.deleteRecursively(destination);
}
// make destination directory
yield fsp.mkdir(destination);
// get source directory files
const files = yield fsp.readdir(opts.source);
// copy source directory contents into destination directory
for (const i of files.keys()) {
const current = yield fsp.stat(this.createPath(opts.source, files[i]));
if (current.isDirectory()) {
const newSource = this.createPath(opts.source, files[i]);
const newDestination = this.createPath(destination, files[i]);
yield this.copyRecursively(newDestination, { overwrite: opts.overwrite, source: newSource });
}
else if (current.isSymbolicLink()) {
const symlink = yield fsp.readLink(this.createPath(opts.source, files[i]));
yield fsp.symLink(symlink, this.createPath(destination, files[i]));
}
else {
this.copy(opts.source, destination, files[i]);
}
}
});
}
/**
* Returns true if the file exists
*
* @memberOf File
* @method
* exists
* @return Boolean
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.exists());
*/
exists() {
return __awaiter(this, void 0, void 0, function* () {
return this.access(fs_1.constants.R_OK);
});
}
/**
* Returns true if the given file glob matches
*
* @memberOf File
* @method
* isMatch
* @return Boolean
* @example
* import File from 'file-js';
*
* const file = new File('./tmp.sh');
* console.log(file.isMatch());
*/
isMatch(globPattern) {
const glob = new fileGlob.Minimatch(globPattern, {
matchBase: true
});
return glob.match(this.pathname);
}
getStatsSync() {
return fs_1.statSync(this.pathname);
}
getStats() {
return __awaiter(this, void 0, void 0, function* () {
return fsp.stat(this.pathname);
});
}
isHiddenFile() {
return (/^\./).test(path.basename(this.pathname));
}
isHiddenDirectory() {
return (/(^|\/)\.[^\/\.]/g).test(this.pathname);
}
depth(pathname) {
return pathname.split(path.sep).length - 1;
}
access(permission) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield fsp.access(this.pathname, permission);
}
catch (err) {
return false;
}
return true;
});
}
checkAsyncStats(type) {
return __awaiter(this, void 0, void 0, function* () {
const stats = yield this.getStats();
return stats[type]();
});
}
copy(src, dest, files) {
const sourcePath = this.createPath(src, files);
const destPath = this.createPath(dest, files);
const oldFile = fs_1.createReadStream(sourcePath);
const newFile = fs_1.createWriteStream(destPath);
oldFile.pipe(newFile);
}
createPath(directory, file) {
return path.join(directory, file);
}
}
exports.File = File;
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Feb 25 2019 09:57:56 GMT+0000 (GMT) using the Minami theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>