UNPKG

@microsoft.azure/async-io

Version:

Promisify'd asnyc wrappers (for Azure Open Source Projects)

185 lines 6.37 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); const promisify = require("pify"); const tasks_1 = require("@microsoft.azure/tasks"); class PathNotFoundException extends tasks_1.Exception { constructor(path, exitCode = 1) { super(`File '${path}' not found.`, exitCode); this.exitCode = exitCode; Object.setPrototypeOf(this, PathNotFoundException.prototype); } } exports.PathNotFoundException = PathNotFoundException; class PathIsNotFileException extends tasks_1.Exception { constructor(path, exitCode = 1) { super(`File '${path}' is not a file.`, exitCode); this.exitCode = exitCode; Object.setPrototypeOf(this, PathIsNotFileException.prototype); } } exports.PathIsNotFileException = PathIsNotFileException; class PathIsNotDirectoryException extends tasks_1.Exception { constructor(path, exitCode = 1) { super(`File '${path}' is not a directory.`, exitCode); this.exitCode = exitCode; Object.setPrototypeOf(this, PathIsNotFileException.prototype); } } exports.PathIsNotDirectoryException = PathIsNotDirectoryException; class UnableToRemoveException extends tasks_1.Exception { constructor(path, exitCode = 1) { super(`Unable to remove '${path}'.`, exitCode); this.exitCode = exitCode; Object.setPrototypeOf(this, UnableToRemoveException.prototype); } } exports.UnableToRemoveException = UnableToRemoveException; class UnableToMakeDirectoryException extends tasks_1.Exception { constructor(path, exitCode = 1) { super(`Unable to create directory '${path}'.`, exitCode); this.exitCode = exitCode; Object.setPrototypeOf(this, UnableToMakeDirectoryException.prototype); } } exports.UnableToMakeDirectoryException = UnableToMakeDirectoryException; exports.exists = path => new Promise((r, j) => fs.stat(path, (err, stats) => err ? r(false) : r(true))); exports.readdir = promisify(fs.readdir); exports.close = promisify(fs.close); exports.writeFile = (filename, content) => Promise.resolve(fs.writeFileSync(filename, content)); // for some reason writeFile only produced empty files exports.lstat = promisify(fs.lstat); const fs_rmdir = promisify(fs.rmdir); const unlink = promisify(fs.unlink); const fs_mkdir = promisify(fs.mkdir); const fs_open = promisify(fs.open); const fs_close = promisify(fs.close); async function mkdir(dirPath) { if (!await isDirectory(dirPath)) { const p = path.normalize(dirPath + "/"); const parent = path.dirname(dirPath); if (!await isDirectory(parent)) { if (p != parent) { await mkdir(parent); } } try { await fs_mkdir(p); } catch (e) { if (!await isDirectory(p)) { throw new UnableToMakeDirectoryException(p); } } } } exports.mkdir = mkdir; const fs_readFile = promisify(fs.readFile); async function readFile(filename) { return fs_readFile(filename, "utf-8"); } exports.readFile = readFile; async function isDirectory(dirPath) { try { if (await exports.exists(dirPath)) { return (await exports.lstat(dirPath)).isDirectory(); } } catch (e) { // don't throw! } return false; } exports.isDirectory = isDirectory; async function isFile(filePath) { try { if (await exports.exists(filePath)) { return !(await exports.lstat(filePath)).isDirectory(); } } catch (e) { // don't throw! } return false; } exports.isFile = isFile; async function rmdir(dirPath) { // if it's not there, do nothing. if (!await exports.exists(dirPath)) { return; } //if it's not a directory, that's bad. if (!await isDirectory(dirPath)) { throw new PathIsNotDirectoryException(dirPath); } // make sure this isn't the current directory. if (process.cwd() === path.normalize(dirPath)) { process.chdir(`${dirPath}/..`); } // make sure the folder is empty first. const files = await exports.readdir(dirPath); if (files.length) { const awaiter = new tasks_1.OutstandingTaskAwaiter(); try { for (const file of files) { try { const p = path.join(dirPath, file); if (await isDirectory(p)) { // folders are recursively rmdir'd awaiter.Await(rmdir(p)); } else { // files and symlinks are unlink'd awaiter.Await(unlink(p).catch(() => { })); } } catch (e) { // uh... can't.. ok. } } } finally { // after all the entries are done await awaiter.Wait(); } } try { // if this fails for some reason, check if it's important. await fs_rmdir(dirPath); } catch (e) { // is it gone? that's all we really care about. if (await isDirectory(dirPath)) { // directory did not delete throw new UnableToRemoveException(dirPath); } } } exports.rmdir = rmdir; async function rmFile(filePath) { // not there? no problem if (!exports.exists(filePath)) { return; } // not a file? that's not cool. if (await isDirectory(filePath)) { throw new PathIsNotFileException(filePath); } try { // files and symlinks are unlink'd await unlink(filePath); } catch (e) { // is it gone? that's all we really care about. if (await exports.exists(filePath)) { // directory did not delete throw new UnableToRemoveException(filePath); } } } exports.rmFile = rmFile; //# sourceMappingURL=file-io.js.map