UNPKG

@microsoft.azure/async-io

Version:

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

190 lines 6.6 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 tasks_1 = require("@microsoft.azure/tasks"); const fs = require("fs"); const path = require("path"); const url_1 = require("url"); 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; function filePath(path) { path = path.toString(); return path.startsWith('file:///') ? url_1.fileURLToPath(path) : path; } exports.filePath = filePath; exports.exists = path => new Promise((r, j) => fs.stat(filePath(path), (err, stats) => err ? r(false) : r(true))); exports.readdir = tasks_1.promisify(fs.readdir); exports.close = tasks_1.promisify(fs.close); exports.writeFile = (filename, content) => Promise.resolve(fs.writeFileSync(filename, content)); // for some reason writeFile only produced empty files exports.lstat = tasks_1.promisify(fs.lstat); const fs_rmdir = tasks_1.promisify(fs.rmdir); const unlink = tasks_1.promisify(fs.unlink); const fs_mkdir = tasks_1.promisify(fs.mkdir); const fs_open = tasks_1.promisify(fs.open); const fs_close = tasks_1.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 = tasks_1.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