filesurgeon.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 _ = require("highland");
const fs = require("fs");
const util_1 = require("util");
const streamEditor_1 = require("./streamEditor");
const bufferedEditor_1 = require("./bufferedEditor");
const lineStream_1 = require("./lineStream");
const readFileAsync = util_1.promisify(fs.readFile);
function touchSync(filename) {
    fs.closeSync(fs.openSync(filename, 'w'));
}
exports.touchSync = touchSync;
/** @class */
class FileSurgeon {
    constructor(filename) {
        this.filename = filename;
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
    * Static factory method to an array of concatenated file contents
    *
    * @static
    * @memberOf FileSurgeon
    * @method
    * concat
    * @return FileSurgeon Promise<string>
    * @example
    * import FileSurgeon from 'FileSurgeon';
    *
    * const contents = FileSurgeon.concat(file1, file2);
    * console.log(contents);
    */
    // tslint:disable-next-line:prefer-array-literal
    static concat(filename1, filename2) {
        return __awaiter(this, void 0, void 0, function* () {
            const f1 = yield FileSurgeon.asArray(filename1);
            const f2 = yield FileSurgeon.asArray(filename2);
            return f1.concat(f2);
        });
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * Static factory method to read the contents of a file as a string
     *
     * @static
     * @memberOf FileSurgeon
     * @method
     * asString
     * @return FileSurgeon Promise<string>
     * @example
     * import FileSurgeon from 'FileSurgeon';
     *
     * const contents = FileSurgeon.asString(file);
     */
    static asString(filename) {
        return readFileAsync(filename, 'utf8');
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * Static factory method to read the contents of a file as an array
     *
     * @static
     * @memberOf FileSurgeon
     * @method
     * asArray
     * @return FileSurgeon Promise<string>
     * @example
     * import FileSurgeon from 'FileSurgeon';
     *
     * const contents = FileSurgeon.asArray(file);
     */
    static asArray(filename) {
        return __awaiter(this, void 0, void 0, function* () {
            const source = lineStream_1.createStream(filename);
            const arr = yield _(source)
                .collect()
                .toPromise(Promise);
            source.destroy();
            if (arr.length > 0 && arr[arr.length - 1].toString() === '') { // remove extra blank line
                arr.pop();
            }
            return arr.map(buffer => buffer.toString());
        });
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * @deprecated since version 1.2.0
     */
    static create(filename) {
        return new FileSurgeon(filename);
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * Static factory method to edit existing file contents
     *
     * @static
     * @memberOf FileSurgeon
     * @method
     * edit
     * @return StreamEditor
     * @example
     * import FileSurgeon from 'FileSurgeon';
     *
     * const surgeon = FileSurgeon.edit(file);
     */
    static edit(filename) {
        return new streamEditor_1.StreamEditor(filename);
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * Static factory method create new files
     *
     * @static
     * @memberOf FileSurgeon
     * @method
     * newFile
     * @return StreamEditor
     * @example
     * import FileSurgeon from 'FileSurgeon';
     *
     * const surgeon = FileSurgeon.newFile(file);
     */
    static newFile(filename) {
        touchSync(filename);
        return new bufferedEditor_1.BufferedEditor(filename);
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * Static factory method get lines from a given file
     *
     * @static
     * @memberOf FileSurgeon
     * @method
     * getLines
     * @return Promise<String[]>
     * @example
     * import FileSurgeon from 'FileSurgeon';
     *
     * const lines = FileSurgeon.getLines(file, 1, 5, 10);
     */
    static getLines(filename, ...requiredLines) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                const source = lineStream_1.createStream(filename);
                const lines = [];
                let count = 0;
                source.on('readable', () => {
                    let line;
                    // tslint:disable-next-line:no-conditional-assignment
                    while (null !== (line = source.read())) {
                        count = count + 1;
                        if (line instanceof Buffer) {
                            line = line.toString('utf8');
                        }
                        if (requiredLines.indexOf(count) !== -1) {
                            lines.push(line);
                            break;
                        }
                    }
                });
                source.on('error', (err) => {
                    reject(err);
                });
                source.on('end', () => {
                    source.destroy();
                    resolve(lines);
                });
            });
        });
    }
    // tslint:disable-next-line:valid-jsdoc
    /**
     * @deprecated since version 1.2.0
     */
    edit() {
        return new streamEditor_1.StreamEditor(this.filename);
    }
}
exports.default = FileSurgeon;