UNPKG

fs-teardown

Version:

Teardown API for testing file system-dependent code.

1,667 lines (1,438 loc) 96.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var os = require('os'); var require$$1 = require('path'); var require$$0$2 = require('fs'); var require$$0 = require('constants'); var require$$0$1 = require('stream'); var require$$4 = require('util'); var require$$5 = require('assert'); var child_process = require('child_process'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var os__namespace = /*#__PURE__*/_interopNamespace(os); var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1); var require$$1__namespace = /*#__PURE__*/_interopNamespace(require$$1); var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2); var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0); var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4); var require$$5__default = /*#__PURE__*/_interopDefaultLegacy(require$$5); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spreadArray$1(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var fs$i = {}; var universalify$2 = {}; universalify$2.fromCallback = function (fn) { return Object.defineProperty(function (...args) { if (typeof args[args.length - 1] === 'function') fn.apply(this, args); else { return new Promise((resolve, reject) => { fn.call( this, ...args, (err, res) => (err != null) ? reject(err) : resolve(res) ); }) } }, 'name', { value: fn.name }) }; universalify$2.fromPromise = function (fn) { return Object.defineProperty(function (...args) { const cb = args[args.length - 1]; if (typeof cb !== 'function') return fn.apply(this, args) else fn.apply(this, args.slice(0, -1)).then(r => cb(null, r), cb); }, 'name', { value: fn.name }) }; var constants = require$$0__default["default"]; var origCwd = process.cwd; var cwd = null; var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform; process.cwd = function() { if (!cwd) cwd = origCwd.call(process); return cwd }; try { process.cwd(); } catch (er) {} var chdir = process.chdir; process.chdir = function(d) { cwd = null; chdir.call(process, d); }; var polyfills$1 = patch$1; function patch$1 (fs) { // (re-)implement some things that are known busted or missing. // lchmod, broken prior to 0.6.2 // back-port the fix here. if (constants.hasOwnProperty('O_SYMLINK') && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { patchLchmod(fs); } // lutimes implementation, or no-op if (!fs.lutimes) { patchLutimes(fs); } // https://github.com/isaacs/node-graceful-fs/issues/4 // Chown should not fail on einval or eperm if non-root. // It should not fail on enosys ever, as this just indicates // that a fs doesn't support the intended operation. fs.chown = chownFix(fs.chown); fs.fchown = chownFix(fs.fchown); fs.lchown = chownFix(fs.lchown); fs.chmod = chmodFix(fs.chmod); fs.fchmod = chmodFix(fs.fchmod); fs.lchmod = chmodFix(fs.lchmod); fs.chownSync = chownFixSync(fs.chownSync); fs.fchownSync = chownFixSync(fs.fchownSync); fs.lchownSync = chownFixSync(fs.lchownSync); fs.chmodSync = chmodFixSync(fs.chmodSync); fs.fchmodSync = chmodFixSync(fs.fchmodSync); fs.lchmodSync = chmodFixSync(fs.lchmodSync); fs.stat = statFix(fs.stat); fs.fstat = statFix(fs.fstat); fs.lstat = statFix(fs.lstat); fs.statSync = statFixSync(fs.statSync); fs.fstatSync = statFixSync(fs.fstatSync); fs.lstatSync = statFixSync(fs.lstatSync); // if lchmod/lchown do not exist, then make them no-ops if (!fs.lchmod) { fs.lchmod = function (path, mode, cb) { if (cb) process.nextTick(cb); }; fs.lchmodSync = function () {}; } if (!fs.lchown) { fs.lchown = function (path, uid, gid, cb) { if (cb) process.nextTick(cb); }; fs.lchownSync = function () {}; } // on Windows, A/V software can lock the directory, causing this // to fail with an EACCES or EPERM if the directory contains newly // created files. Try again on failure, for up to 60 seconds. // Set the timeout this long because some Windows Anti-Virus, such as Parity // bit9, may lock files for up to a minute, causing npm package install // failures. Also, take care to yield the scheduler. Windows scheduling gives // CPU to a busy looping process, which can cause the program causing the lock // contention to be starved of CPU by node, so the contention doesn't resolve. if (platform === "win32") { fs.rename = (function (fs$rename) { return function (from, to, cb) { var start = Date.now(); var backoff = 0; fs$rename(from, to, function CB (er) { if (er && (er.code === "EACCES" || er.code === "EPERM") && Date.now() - start < 60000) { setTimeout(function() { fs.stat(to, function (stater, st) { if (stater && stater.code === "ENOENT") fs$rename(from, to, CB); else cb(er); }); }, backoff); if (backoff < 100) backoff += 10; return; } if (cb) cb(er); }); }})(fs.rename); } // if read() returns EAGAIN, then just try it again. fs.read = (function (fs$read) { function read (fd, buffer, offset, length, position, callback_) { var callback; if (callback_ && typeof callback_ === 'function') { var eagCounter = 0; callback = function (er, _, __) { if (er && er.code === 'EAGAIN' && eagCounter < 10) { eagCounter ++; return fs$read.call(fs, fd, buffer, offset, length, position, callback) } callback_.apply(this, arguments); }; } return fs$read.call(fs, fd, buffer, offset, length, position, callback) } // This ensures `util.promisify` works as it does for native `fs.read`. read.__proto__ = fs$read; return read })(fs.read); fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) { var eagCounter = 0; while (true) { try { return fs$readSync.call(fs, fd, buffer, offset, length, position) } catch (er) { if (er.code === 'EAGAIN' && eagCounter < 10) { eagCounter ++; continue } throw er } } }})(fs.readSync); function patchLchmod (fs) { fs.lchmod = function (path, mode, callback) { fs.open( path , constants.O_WRONLY | constants.O_SYMLINK , mode , function (err, fd) { if (err) { if (callback) callback(err); return } // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. fs.fchmod(fd, mode, function (err) { fs.close(fd, function(err2) { if (callback) callback(err || err2); }); }); }); }; fs.lchmodSync = function (path, mode) { var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode); // prefer to return the chmod error, if one occurs, // but still try to close, and report closing errors if they occur. var threw = true; var ret; try { ret = fs.fchmodSync(fd, mode); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret }; } function patchLutimes (fs) { if (constants.hasOwnProperty("O_SYMLINK")) { fs.lutimes = function (path, at, mt, cb) { fs.open(path, constants.O_SYMLINK, function (er, fd) { if (er) { if (cb) cb(er); return } fs.futimes(fd, at, mt, function (er) { fs.close(fd, function (er2) { if (cb) cb(er || er2); }); }); }); }; fs.lutimesSync = function (path, at, mt) { var fd = fs.openSync(path, constants.O_SYMLINK); var ret; var threw = true; try { ret = fs.futimesSync(fd, at, mt); threw = false; } finally { if (threw) { try { fs.closeSync(fd); } catch (er) {} } else { fs.closeSync(fd); } } return ret }; } else { fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb); }; fs.lutimesSync = function () {}; } } function chmodFix (orig) { if (!orig) return orig return function (target, mode, cb) { return orig.call(fs, target, mode, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }) } } function chmodFixSync (orig) { if (!orig) return orig return function (target, mode) { try { return orig.call(fs, target, mode) } catch (er) { if (!chownErOk(er)) throw er } } } function chownFix (orig) { if (!orig) return orig return function (target, uid, gid, cb) { return orig.call(fs, target, uid, gid, function (er) { if (chownErOk(er)) er = null; if (cb) cb.apply(this, arguments); }) } } function chownFixSync (orig) { if (!orig) return orig return function (target, uid, gid) { try { return orig.call(fs, target, uid, gid) } catch (er) { if (!chownErOk(er)) throw er } } } function statFix (orig) { if (!orig) return orig // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options, cb) { if (typeof options === 'function') { cb = options; options = null; } function callback (er, stats) { if (stats) { if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; } if (cb) cb.apply(this, arguments); } return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback) } } function statFixSync (orig) { if (!orig) return orig // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, options) { var stats = options ? orig.call(fs, target, options) : orig.call(fs, target); if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; return stats; } } // ENOSYS means that the fs doesn't support the op. Just ignore // that, because it doesn't matter. // // if there's no getuid, or if getuid() is something other // than 0, and the error is EINVAL or EPERM, then just ignore // it. // // This specific case is a silent failure in cp, install, tar, // and most other unix tools that manage permissions. // // When running as root, or if other types of errors are // encountered, then it's strict. function chownErOk (er) { if (!er) return true if (er.code === "ENOSYS") return true var nonroot = !process.getuid || process.getuid() !== 0; if (nonroot) { if (er.code === "EINVAL" || er.code === "EPERM") return true } return false } } var Stream = require$$0__default$1["default"].Stream; var legacyStreams = legacy$1; function legacy$1 (fs) { return { ReadStream: ReadStream, WriteStream: WriteStream } function ReadStream (path, options) { if (!(this instanceof ReadStream)) return new ReadStream(path, options); Stream.call(this); var self = this; this.path = path; this.fd = null; this.readable = true; this.paused = false; this.flags = 'r'; this.mode = 438; /*=0666*/ this.bufferSize = 64 * 1024; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.encoding) this.setEncoding(this.encoding); if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.end === undefined) { this.end = Infinity; } else if ('number' !== typeof this.end) { throw TypeError('end must be a Number'); } if (this.start > this.end) { throw new Error('start must be <= end'); } this.pos = this.start; } if (this.fd !== null) { process.nextTick(function() { self._read(); }); return; } fs.open(this.path, this.flags, this.mode, function (err, fd) { if (err) { self.emit('error', err); self.readable = false; return; } self.fd = fd; self.emit('open', fd); self._read(); }); } function WriteStream (path, options) { if (!(this instanceof WriteStream)) return new WriteStream(path, options); Stream.call(this); this.path = path; this.fd = null; this.writable = true; this.flags = 'w'; this.encoding = 'binary'; this.mode = 438; /*=0666*/ this.bytesWritten = 0; options = options || {}; // Mixin options into this var keys = Object.keys(options); for (var index = 0, length = keys.length; index < length; index++) { var key = keys[index]; this[key] = options[key]; } if (this.start !== undefined) { if ('number' !== typeof this.start) { throw TypeError('start must be a Number'); } if (this.start < 0) { throw new Error('start must be >= zero'); } this.pos = this.start; } this.busy = false; this._queue = []; if (this.fd === null) { this._open = fs.open; this._queue.push([this._open, this.path, this.flags, this.mode, undefined]); this.flush(); } } } var clone_1 = clone$1; function clone$1 (obj) { if (obj === null || typeof obj !== 'object') return obj if (obj instanceof Object) var copy = { __proto__: obj.__proto__ }; else var copy = Object.create(null); Object.getOwnPropertyNames(obj).forEach(function (key) { Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)); }); return copy } var fs$h = require$$0__default$2["default"]; var polyfills = polyfills$1; var legacy = legacyStreams; var clone = clone_1; var util$1 = require$$4__default["default"]; /* istanbul ignore next - node 0.x polyfill */ var gracefulQueue; var previousSymbol; /* istanbul ignore else - node 0.x polyfill */ if (typeof Symbol === 'function' && typeof Symbol.for === 'function') { gracefulQueue = Symbol.for('graceful-fs.queue'); // This is used in testing by future versions previousSymbol = Symbol.for('graceful-fs.previous'); } else { gracefulQueue = '___graceful-fs.queue'; previousSymbol = '___graceful-fs.previous'; } function noop () {} function publishQueue(context, queue) { Object.defineProperty(context, gracefulQueue, { get: function() { return queue } }); } var debug = noop; if (util$1.debuglog) debug = util$1.debuglog('gfs4'); else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) debug = function() { var m = util$1.format.apply(util$1, arguments); m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: '); console.error(m); }; // Once time initialization if (!fs$h[gracefulQueue]) { // This queue can be shared by multiple loaded instances var queue = commonjsGlobal[gracefulQueue] || []; publishQueue(fs$h, queue); // Patch fs.close/closeSync to shared queue version, because we need // to retry() whenever a close happens *anywhere* in the program. // This is essential when multiple graceful-fs instances are // in play at the same time. fs$h.close = (function (fs$close) { function close (fd, cb) { return fs$close.call(fs$h, fd, function (err) { // This function uses the graceful-fs shared queue if (!err) { retry(); } if (typeof cb === 'function') cb.apply(this, arguments); }) } Object.defineProperty(close, previousSymbol, { value: fs$close }); return close })(fs$h.close); fs$h.closeSync = (function (fs$closeSync) { function closeSync (fd) { // This function uses the graceful-fs shared queue fs$closeSync.apply(fs$h, arguments); retry(); } Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync }); return closeSync })(fs$h.closeSync); if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { debug(fs$h[gracefulQueue]); require$$5__default["default"].equal(fs$h[gracefulQueue].length, 0); }); } } if (!commonjsGlobal[gracefulQueue]) { publishQueue(commonjsGlobal, fs$h[gracefulQueue]); } var gracefulFs = patch(clone(fs$h)); if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs$h.__patched) { gracefulFs = patch(fs$h); fs$h.__patched = true; } function patch (fs) { // Everything that references the open() function needs to be in here polyfills(fs); fs.gracefulify = patch; fs.createReadStream = createReadStream; fs.createWriteStream = createWriteStream; var fs$readFile = fs.readFile; fs.readFile = readFile; function readFile (path, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$readFile(path, options, cb) function go$readFile (path, options, cb) { return fs$readFile(path, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readFile, [path, options, cb]]); else { if (typeof cb === 'function') cb.apply(this, arguments); retry(); } }) } } var fs$writeFile = fs.writeFile; fs.writeFile = writeFile; function writeFile (path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$writeFile(path, data, options, cb) function go$writeFile (path, data, options, cb) { return fs$writeFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$writeFile, [path, data, options, cb]]); else { if (typeof cb === 'function') cb.apply(this, arguments); retry(); } }) } } var fs$appendFile = fs.appendFile; if (fs$appendFile) fs.appendFile = appendFile; function appendFile (path, data, options, cb) { if (typeof options === 'function') cb = options, options = null; return go$appendFile(path, data, options, cb) function go$appendFile (path, data, options, cb) { return fs$appendFile(path, data, options, function (err) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$appendFile, [path, data, options, cb]]); else { if (typeof cb === 'function') cb.apply(this, arguments); retry(); } }) } } var fs$readdir = fs.readdir; fs.readdir = readdir; function readdir (path, options, cb) { var args = [path]; if (typeof options !== 'function') { args.push(options); } else { cb = options; } args.push(go$readdir$cb); return go$readdir(args) function go$readdir$cb (err, files) { if (files && files.sort) files.sort(); if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readdir, [args]]); else { if (typeof cb === 'function') cb.apply(this, arguments); retry(); } } } function go$readdir (args) { return fs$readdir.apply(fs, args) } if (process.version.substr(0, 4) === 'v0.8') { var legStreams = legacy(fs); ReadStream = legStreams.ReadStream; WriteStream = legStreams.WriteStream; } var fs$ReadStream = fs.ReadStream; if (fs$ReadStream) { ReadStream.prototype = Object.create(fs$ReadStream.prototype); ReadStream.prototype.open = ReadStream$open; } var fs$WriteStream = fs.WriteStream; if (fs$WriteStream) { WriteStream.prototype = Object.create(fs$WriteStream.prototype); WriteStream.prototype.open = WriteStream$open; } Object.defineProperty(fs, 'ReadStream', { get: function () { return ReadStream }, set: function (val) { ReadStream = val; }, enumerable: true, configurable: true }); Object.defineProperty(fs, 'WriteStream', { get: function () { return WriteStream }, set: function (val) { WriteStream = val; }, enumerable: true, configurable: true }); // legacy names var FileReadStream = ReadStream; Object.defineProperty(fs, 'FileReadStream', { get: function () { return FileReadStream }, set: function (val) { FileReadStream = val; }, enumerable: true, configurable: true }); var FileWriteStream = WriteStream; Object.defineProperty(fs, 'FileWriteStream', { get: function () { return FileWriteStream }, set: function (val) { FileWriteStream = val; }, enumerable: true, configurable: true }); function ReadStream (path, options) { if (this instanceof ReadStream) return fs$ReadStream.apply(this, arguments), this else return ReadStream.apply(Object.create(ReadStream.prototype), arguments) } function ReadStream$open () { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { if (that.autoClose) that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); that.read(); } }); } function WriteStream (path, options) { if (this instanceof WriteStream) return fs$WriteStream.apply(this, arguments), this else return WriteStream.apply(Object.create(WriteStream.prototype), arguments) } function WriteStream$open () { var that = this; open(that.path, that.flags, that.mode, function (err, fd) { if (err) { that.destroy(); that.emit('error', err); } else { that.fd = fd; that.emit('open', fd); } }); } function createReadStream (path, options) { return new fs.ReadStream(path, options) } function createWriteStream (path, options) { return new fs.WriteStream(path, options) } var fs$open = fs.open; fs.open = open; function open (path, flags, mode, cb) { if (typeof mode === 'function') cb = mode, mode = null; return go$open(path, flags, mode, cb) function go$open (path, flags, mode, cb) { return fs$open(path, flags, mode, function (err, fd) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$open, [path, flags, mode, cb]]); else { if (typeof cb === 'function') cb.apply(this, arguments); retry(); } }) } } return fs } function enqueue (elem) { debug('ENQUEUE', elem[0].name, elem[1]); fs$h[gracefulQueue].push(elem); } function retry () { var elem = fs$h[gracefulQueue].shift(); if (elem) { debug('RETRY', elem[0].name, elem[1]); elem[0].apply(null, elem[1]); } } (function (exports) { // This is adapted from https://github.com/normalize/mz // Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors const u = universalify$2.fromCallback; const fs = gracefulFs; const api = [ 'access', 'appendFile', 'chmod', 'chown', 'close', 'copyFile', 'fchmod', 'fchown', 'fdatasync', 'fstat', 'fsync', 'ftruncate', 'futimes', 'lchmod', 'lchown', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'opendir', 'readdir', 'readFile', 'readlink', 'realpath', 'rename', 'rm', 'rmdir', 'stat', 'symlink', 'truncate', 'unlink', 'utimes', 'writeFile' ].filter(key => { // Some commands are not available on some systems. Ex: // fs.opendir was added in Node.js v12.12.0 // fs.rm was added in Node.js v14.14.0 // fs.lchown is not available on at least some Linux return typeof fs[key] === 'function' }); // Export cloned fs: Object.assign(exports, fs); // Universalify async methods: api.forEach(method => { exports[method] = u(fs[method]); }); exports.realpath.native = u(fs.realpath.native); // We differ from mz/fs in that we still ship the old, broken, fs.exists() // since we are a drop-in replacement for the native module exports.exists = function (filename, callback) { if (typeof callback === 'function') { return fs.exists(filename, callback) } return new Promise(resolve => { return fs.exists(filename, resolve) }) }; // fs.read(), fs.write(), & fs.writev() need special treatment due to multiple callback args exports.read = function (fd, buffer, offset, length, position, callback) { if (typeof callback === 'function') { return fs.read(fd, buffer, offset, length, position, callback) } return new Promise((resolve, reject) => { fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => { if (err) return reject(err) resolve({ bytesRead, buffer }); }); }) }; // Function signature can be // fs.write(fd, buffer[, offset[, length[, position]]], callback) // OR // fs.write(fd, string[, position[, encoding]], callback) // We need to handle both cases, so we use ...args exports.write = function (fd, buffer, ...args) { if (typeof args[args.length - 1] === 'function') { return fs.write(fd, buffer, ...args) } return new Promise((resolve, reject) => { fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => { if (err) return reject(err) resolve({ bytesWritten, buffer }); }); }) }; // fs.writev only available in Node v12.9.0+ if (typeof fs.writev === 'function') { // Function signature is // s.writev(fd, buffers[, position], callback) // We need to handle the optional arg, so we use ...args exports.writev = function (fd, buffers, ...args) { if (typeof args[args.length - 1] === 'function') { return fs.writev(fd, buffers, ...args) } return new Promise((resolve, reject) => { fs.writev(fd, buffers, ...args, (err, bytesWritten, buffers) => { if (err) return reject(err) resolve({ bytesWritten, buffers }); }); }) }; } }(fs$i)); var makeDir$1 = {}; var utils$1 = {}; const path$c = require$$1__default["default"]; // https://github.com/nodejs/node/issues/8987 // https://github.com/libuv/libuv/pull/1088 utils$1.checkPath = function checkPath (pth) { if (process.platform === 'win32') { const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path$c.parse(pth).root, '')); if (pathHasInvalidWinCharacters) { const error = new Error(`Path contains invalid characters: ${pth}`); error.code = 'EINVAL'; throw error } } }; const fs$g = fs$i; const { checkPath } = utils$1; const getMode = options => { const defaults = { mode: 0o777 }; if (typeof options === 'number') return options return ({ ...defaults, ...options }).mode }; makeDir$1.makeDir = async (dir, options) => { checkPath(dir); return fs$g.mkdir(dir, { mode: getMode(options), recursive: true }) }; makeDir$1.makeDirSync = (dir, options) => { checkPath(dir); return fs$g.mkdirSync(dir, { mode: getMode(options), recursive: true }) }; const u$a = universalify$2.fromPromise; const { makeDir: _makeDir, makeDirSync } = makeDir$1; const makeDir = u$a(_makeDir); var mkdirs$2 = { mkdirs: makeDir, mkdirsSync: makeDirSync, // alias mkdirp: makeDir, mkdirpSync: makeDirSync, ensureDir: makeDir, ensureDirSync: makeDirSync }; const fs$f = gracefulFs; function utimesMillis$1 (path, atime, mtime, callback) { // if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback) fs$f.open(path, 'r+', (err, fd) => { if (err) return callback(err) fs$f.futimes(fd, atime, mtime, futimesErr => { fs$f.close(fd, closeErr => { if (callback) callback(futimesErr || closeErr); }); }); }); } function utimesMillisSync$1 (path, atime, mtime) { const fd = fs$f.openSync(path, 'r+'); fs$f.futimesSync(fd, atime, mtime); return fs$f.closeSync(fd) } var utimes = { utimesMillis: utimesMillis$1, utimesMillisSync: utimesMillisSync$1 }; const fs$e = fs$i; const path$b = require$$1__default["default"]; const util = require$$4__default["default"]; function getStats$2 (src, dest, opts) { const statFunc = opts.dereference ? (file) => fs$e.stat(file, { bigint: true }) : (file) => fs$e.lstat(file, { bigint: true }); return Promise.all([ statFunc(src), statFunc(dest).catch(err => { if (err.code === 'ENOENT') return null throw err }) ]).then(([srcStat, destStat]) => ({ srcStat, destStat })) } function getStatsSync (src, dest, opts) { let destStat; const statFunc = opts.dereference ? (file) => fs$e.statSync(file, { bigint: true }) : (file) => fs$e.lstatSync(file, { bigint: true }); const srcStat = statFunc(src); try { destStat = statFunc(dest); } catch (err) { if (err.code === 'ENOENT') return { srcStat, destStat: null } throw err } return { srcStat, destStat } } function checkPaths (src, dest, funcName, opts, cb) { util.callbackify(getStats$2)(src, dest, opts, (err, stats) => { if (err) return cb(err) const { srcStat, destStat } = stats; if (destStat) { if (areIdentical$2(srcStat, destStat)) { const srcBaseName = path$b.basename(src); const destBaseName = path$b.basename(dest); if (funcName === 'move' && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { return cb(null, { srcStat, destStat, isChangingCase: true }) } return cb(new Error('Source and destination must not be the same.')) } if (srcStat.isDirectory() && !destStat.isDirectory()) { return cb(new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)) } if (!srcStat.isDirectory() && destStat.isDirectory()) { return cb(new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`)) } } if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { return cb(new Error(errMsg(src, dest, funcName))) } return cb(null, { srcStat, destStat }) }); } function checkPathsSync (src, dest, funcName, opts) { const { srcStat, destStat } = getStatsSync(src, dest, opts); if (destStat) { if (areIdentical$2(srcStat, destStat)) { const srcBaseName = path$b.basename(src); const destBaseName = path$b.basename(dest); if (funcName === 'move' && srcBaseName !== destBaseName && srcBaseName.toLowerCase() === destBaseName.toLowerCase()) { return { srcStat, destStat, isChangingCase: true } } throw new Error('Source and destination must not be the same.') } if (srcStat.isDirectory() && !destStat.isDirectory()) { throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`) } if (!srcStat.isDirectory() && destStat.isDirectory()) { throw new Error(`Cannot overwrite directory '${dest}' with non-directory '${src}'.`) } } if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { throw new Error(errMsg(src, dest, funcName)) } return { srcStat, destStat } } // recursively check if dest parent is a subdirectory of src. // It works for all file types including symlinks since it // checks the src and dest inodes. It starts from the deepest // parent and stops once it reaches the src parent or the root path. function checkParentPaths (src, srcStat, dest, funcName, cb) { const srcParent = path$b.resolve(path$b.dirname(src)); const destParent = path$b.resolve(path$b.dirname(dest)); if (destParent === srcParent || destParent === path$b.parse(destParent).root) return cb() fs$e.stat(destParent, { bigint: true }, (err, destStat) => { if (err) { if (err.code === 'ENOENT') return cb() return cb(err) } if (areIdentical$2(srcStat, destStat)) { return cb(new Error(errMsg(src, dest, funcName))) } return checkParentPaths(src, srcStat, destParent, funcName, cb) }); } function checkParentPathsSync (src, srcStat, dest, funcName) { const srcParent = path$b.resolve(path$b.dirname(src)); const destParent = path$b.resolve(path$b.dirname(dest)); if (destParent === srcParent || destParent === path$b.parse(destParent).root) return let destStat; try { destStat = fs$e.statSync(destParent, { bigint: true }); } catch (err) { if (err.code === 'ENOENT') return throw err } if (areIdentical$2(srcStat, destStat)) { throw new Error(errMsg(src, dest, funcName)) } return checkParentPathsSync(src, srcStat, destParent, funcName) } function areIdentical$2 (srcStat, destStat) { return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev } // return true if dest is a subdir of src, otherwise false. // It only checks the path strings. function isSrcSubdir (src, dest) { const srcArr = path$b.resolve(src).split(path$b.sep).filter(i => i); const destArr = path$b.resolve(dest).split(path$b.sep).filter(i => i); return srcArr.reduce((acc, cur, i) => acc && destArr[i] === cur, true) } function errMsg (src, dest, funcName) { return `Cannot ${funcName} '${src}' to a subdirectory of itself, '${dest}'.` } var stat$4 = { checkPaths, checkPathsSync, checkParentPaths, checkParentPathsSync, isSrcSubdir, areIdentical: areIdentical$2 }; const fs$d = gracefulFs; const path$a = require$$1__default["default"]; const mkdirsSync$1 = mkdirs$2.mkdirsSync; const utimesMillisSync = utimes.utimesMillisSync; const stat$3 = stat$4; function copySync$2 (src, dest, opts) { if (typeof opts === 'function') { opts = { filter: opts }; } opts = opts || {}; opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber // Warn about using preserveTimestamps on 32-bit node if (opts.preserveTimestamps && process.arch === 'ia32') { console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n see https://github.com/jprichardson/node-fs-extra/issues/269`); } const { srcStat, destStat } = stat$3.checkPathsSync(src, dest, 'copy', opts); stat$3.checkParentPathsSync(src, srcStat, dest, 'copy'); return handleFilterAndCopy(destStat, src, dest, opts) } function handleFilterAndCopy (destStat, src, dest, opts) { if (opts.filter && !opts.filter(src, dest)) return const destParent = path$a.dirname(dest); if (!fs$d.existsSync(destParent)) mkdirsSync$1(destParent); return getStats$1(destStat, src, dest, opts) } function startCopy$1 (destStat, src, dest, opts) { if (opts.filter && !opts.filter(src, dest)) return return getStats$1(destStat, src, dest, opts) } function getStats$1 (destStat, src, dest, opts) { const statSync = opts.dereference ? fs$d.statSync : fs$d.lstatSync; const srcStat = statSync(src); if (srcStat.isDirectory()) return onDir$1(srcStat, destStat, src, dest, opts) else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile$1(srcStat, destStat, src, dest, opts) else if (srcStat.isSymbolicLink()) return onLink$1(destStat, src, dest, opts) else if (srcStat.isSocket()) throw new Error(`Cannot copy a socket file: ${src}`) else if (srcStat.isFIFO()) throw new Error(`Cannot copy a FIFO pipe: ${src}`) throw new Error(`Unknown file: ${src}`) } function onFile$1 (srcStat, destStat, src, dest, opts) { if (!destStat) return copyFile$1(srcStat, src, dest, opts) return mayCopyFile$1(srcStat, src, dest, opts) } function mayCopyFile$1 (srcStat, src, dest, opts) { if (opts.overwrite) { fs$d.unlinkSync(dest); return copyFile$1(srcStat, src, dest, opts) } else if (opts.errorOnExist) { throw new Error(`'${dest}' already exists`) } } function copyFile$1 (srcStat, src, dest, opts) { fs$d.copyFileSync(src, dest); if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest); return setDestMode$1(dest, srcStat.mode) } function handleTimestamps (srcMode, src, dest) { // Make sure the file is writable before setting the timestamp // otherwise open fails with EPERM when invoked with 'r+' // (through utimes call) if (fileIsNotWritable$1(srcMode)) makeFileWritable$1(dest, srcMode); return setDestTimestamps$1(src, dest) } function fileIsNotWritable$1 (srcMode) { return (srcMode & 0o200) === 0 } function makeFileWritable$1 (dest, srcMode) { return setDestMode$1(dest, srcMode | 0o200) } function setDestMode$1 (dest, srcMode) { return fs$d.chmodSync(dest, srcMode) } function setDestTimestamps$1 (src, dest) { // The initial srcStat.atime cannot be trusted // because it is modified by the read(2) system call // (See https://nodejs.org/api/fs.html#fs_stat_time_values) const updatedSrcStat = fs$d.statSync(src); return utimesMillisSync(dest, updatedSrcStat.atime, updatedSrcStat.mtime) } function onDir$1 (srcStat, destStat, src, dest, opts) { if (!destStat) return mkDirAndCopy$1(srcStat.mode, src, dest, opts) return copyDir$1(src, dest, opts) } function mkDirAndCopy$1 (srcMode, src, dest, opts) { fs$d.mkdirSync(dest); copyDir$1(src, dest, opts); return setDestMode$1(dest, srcMode) } function copyDir$1 (src, dest, opts) { fs$d.readdirSync(src).forEach(item => copyDirItem$1(item, src, dest, opts)); } function copyDirItem$1 (item, src, dest, opts) { const srcItem = path$a.join(src, item); const destItem = path$a.join(dest, item); const { destStat } = stat$3.checkPathsSync(srcItem, destItem, 'copy', opts); return startCopy$1(destStat, srcItem, destItem, opts) } function onLink$1 (destStat, src, dest, opts) { let resolvedSrc = fs$d.readlinkSync(src); if (opts.dereference) { resolvedSrc = path$a.resolve(process.cwd(), resolvedSrc); } if (!destStat) { return fs$d.symlinkSync(resolvedSrc, dest) } else { let resolvedDest; try { resolvedDest = fs$d.readlinkSync(dest); } catch (err) { // dest exists and is a regular file or directory, // Windows may throw UNKNOWN error. If dest already exists, // fs throws error anyway, so no need to guard against it here. if (err.code === 'EINVAL' || err.code === 'UNKNOWN') return fs$d.symlinkSync(resolvedSrc, dest) throw err } if (opts.dereference) { resolvedDest = path$a.resolve(process.cwd(), resolvedDest); } if (stat$3.isSrcSubdir(resolvedSrc, resolvedDest)) { throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`) } // prevent copy if src is a subdir of dest since unlinking // dest in this case would result in removing src contents // and therefore a broken symlink would be created. if (fs$d.statSync(dest).isDirectory() && stat$3.isSrcSubdir(resolvedDest, resolvedSrc)) { throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`) } return copyLink$1(resolvedSrc, dest) } } function copyLink$1 (resolvedSrc, dest) { fs$d.unlinkSync(dest); return fs$d.symlinkSync(resolvedSrc, dest) } var copySync_1 = copySync$2; var copySync$1 = { copySync: copySync_1 }; const u$9 = universalify$2.fromPromise; const fs$c = fs$i; function pathExists$6 (path) { return fs$c.access(path).then(() => true).catch(() => false) } var pathExists_1 = { pathExists: u$9(pathExists$6), pathExistsSync: fs$c.existsSync }; const fs$b = gracefulFs; const path$9 = require$$1__default["default"]; const mkdirs$1 = mkdirs$2.mkdirs; const pathExists$5 = pathExists_1.pathExists; const utimesMillis = utimes.utimesMillis; const stat$2 = stat$4; function copy$2 (src, dest, opts, cb) { if (typeof opts === 'function' && !cb) { cb = opts; opts = {}; } else if (typeof opts === 'function') { opts = { filter: opts }; } cb = cb || function () {}; opts = opts || {}; opts.clobber = 'clobber' in opts ? !!opts.clobber : true; // default to true for now opts.overwrite = 'overwrite' in opts ? !!opts.overwrite : opts.clobber; // overwrite falls back to clobber // Warn about using preserveTimestamps on 32-bit node if (opts.preserveTimestamps && process.arch === 'ia32') { console.warn(`fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n see https://github.com/jprichardson/node-fs-extra/issues/269`); } stat$2.checkPaths(src, dest, 'copy', opts, (err, stats) => { if (err) return cb(err) const { srcStat, destStat } = stats; stat$2.checkParentPaths(src, srcStat, dest, 'copy', err => { if (err) return cb(err) if (opts.filter) return handleFilter(checkParentDir, destStat, src, dest, opts, cb) return checkParentDir(destStat, src, dest, opts, cb) }); }); } function checkParentDir (destStat, src, dest, opts, cb) { const destParent = path$9.dirname(dest); pathExists$5(destParent, (err, dirExists) => { if (err) return cb(err) if (dirExists) return getStats(destStat, src, dest, opts, cb) mkdirs$1(destParent, err => { if (err) return cb(err) return getStats(destStat, src, dest, opts, cb) }); }); } function handleFilter (onInclude, destStat, src, dest, opts, cb) { Promise.resolve(opts.filter(src, dest)).then(include => { if (include) return onInclude(destStat, src, dest, opts, cb) return cb() }, error => cb(error)); } function startCopy (destStat, src, dest, opts, cb) { if (opts.filter) return handleFilter(getStats, destStat, src, dest, opts, cb) return getStats(destStat, src, dest, opts, cb) } function getStats (destStat, src, dest, opts, cb) { const stat = opts.dereference ? fs$b.stat : fs$b.lstat; stat(src, (err, srcStat) => { if (err) return cb(err) if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts, cb) else if (srcStat.isFile() || srcStat.isCharacterDevice() || srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts, cb) else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts, cb) else if (srcStat.isSocket()) return cb(new Error(`Cannot copy a socket file: ${src}`)) else if (srcStat.isFIFO()) return cb(new Error(`Cannot copy a FIFO pipe: ${src}`)) return cb(new Error(`Unknown file: ${src}`)) }); } function onFile (srcStat, destStat, src, dest, opts, cb) { if (!destStat) return copyFile(srcStat, src, dest, opts, cb) return mayCopyFile(srcStat, src, dest, opts, cb) } function mayCopyFile (srcStat, src, dest, opts, cb) { if (opts.overwrite) { fs$b.unlink(dest, err => { if (err) return cb(err) return copyFile(srcStat, src, dest, opts, cb) }); } else if (opts.errorOnExist) { return cb(new Error(`'${dest}' already exists`)) } else return cb() } function copyFile (srcStat, src, dest, opts, cb) { fs$b.copyFile(src, dest, err => { if (err) return cb(err) if (opts.preserveTimestamps) return handleTimestampsAndMode(srcStat.mode, src, dest, cb) return setDestMode(dest, srcStat.mode, cb) }); } function handleTimestampsAndMode (srcMode, src, dest, cb) { // Make sure the file is writable before setting the timestamp // otherwise open fails with EPERM when invoked with 'r+' // (through utimes call) if (fileIsNotWritable(srcMode)) { return makeFileWritable(dest, srcMode, err => { if (err) return cb(err) return setDestTimestampsAndMode(srcMode, src, dest, cb) }) } return setDestTimestampsAndMode(srcMode, src, dest, cb) } function fileIsNotWritable (srcMode) { return