file.js

"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);
    }
    lastModifiedSync() {
        return this.getStatsSync().mtime;
    }
    lastAccessedSync() {
        return this.getStatsSync().atime;
    }
    lastChangedSync() {
        return this.getStatsSync().ctime;
    }
    sizeSync() {
        return this.getStatsSync().size;
    }
    isWritable() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.access(fs_1.constants.W_OK);
        });
    }
    isReadable() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.access(fs_1.constants.R_OK);
        });
    }
    isExecutable() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.access(fs_1.constants.X_OK);
        });
    }
    delete() {
        return __awaiter(this, void 0, void 0, function* () {
            return fsp.unlink(this.pathname);
        });
    }
    exists() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.access(fs_1.constants.R_OK);
        });
    }
    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]();
        });
    }
}
exports.File = File;