node-op
Version:
Interactive 1Password CLI and installer
1,707 lines (1,468 loc) • 167 kB
JavaScript
'use strict';
var _commonjsHelpers = require('./chunk-1d702382.js');
var require$$1 = require('child_process');
var path = require('path');
var fs$3 = require('fs');
var os = require('os');
var util$1 = require('util');
var constants$1 = require('constants');
var require$$0 = require('stream');
var assert = require('assert');
var https = require('https');
var zlib = require('zlib');
var require$$0$1 = require('crypto');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$3);
var util__default = /*#__PURE__*/_interopDefaultLegacy(util$1);
var constants__default = /*#__PURE__*/_interopDefaultLegacy(constants$1);
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert);
var zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib);
var 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.apply(
this,
args.concat([(err, res) => err ? reject(err) : resolve(res)])
);
})
}
}, 'name', { value: fn.name })
};
var 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 universalify = {
fromCallback: fromCallback,
fromPromise: fromPromise
};
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 = patch;
function patch (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__default['default'].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__default['default'].O_WRONLY | constants__default['default'].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__default['default'].O_WRONLY | constants__default['default'].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__default['default'].hasOwnProperty("O_SYMLINK")) {
fs.lutimes = function (path, at, mt, cb) {
fs.open(path, constants__default['default'].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__default['default'].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['default'].Stream;
var legacyStreams = legacy;
function legacy (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;
function clone (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 gracefulFs = _commonjsHelpers.createCommonjsModule(function (module) {
/* 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__default['default'].debuglog)
debug = util__default['default'].debuglog('gfs4');
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
debug = function() {
var m = util__default['default'].format.apply(util__default['default'], arguments);
m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ');
console.error(m);
};
// Once time initialization
if (!fs__default['default'][gracefulQueue]) {
// This queue can be shared by multiple loaded instances
var queue = _commonjsHelpers.commonjsGlobal[gracefulQueue] || [];
publishQueue(fs__default['default'], 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__default['default'].close = (function (fs$close) {
function close (fd, cb) {
return fs$close.call(fs__default['default'], 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__default['default'].close);
fs__default['default'].closeSync = (function (fs$closeSync) {
function closeSync (fd) {
// This function uses the graceful-fs shared queue
fs$closeSync.apply(fs__default['default'], arguments);
retry();
}
Object.defineProperty(closeSync, previousSymbol, {
value: fs$closeSync
});
return closeSync
})(fs__default['default'].closeSync);
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
process.on('exit', function() {
debug(fs__default['default'][gracefulQueue]);
assert__default['default'].equal(fs__default['default'][gracefulQueue].length, 0);
});
}
}
if (!_commonjsHelpers.commonjsGlobal[gracefulQueue]) {
publishQueue(_commonjsHelpers.commonjsGlobal, fs__default['default'][gracefulQueue]);
}
module.exports = patch(clone_1(fs__default['default']));
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs__default['default'].__patched) {
module.exports = patch(fs__default['default']);
fs__default['default'].__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 = legacyStreams(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__default['default'][gracefulQueue].push(elem);
}
function retry () {
var elem = fs__default['default'][gracefulQueue].shift();
if (elem) {
debug('RETRY', elem[0].name, elem[1]);
elem[0].apply(null, elem[1]);
}
}
});
var fs_1 = _commonjsHelpers.createCommonjsModule(function (module, exports) {
// This is adapted from https://github.com/normalize/mz
// Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors
const u = universalify.fromCallback;
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',
'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.lchown is not available on at least some Linux
return typeof gracefulFs[key] === 'function'
});
// Export all keys:
Object.keys(gracefulFs).forEach(key => {
if (key === 'promises') {
// fs.promises is a getter property that triggers ExperimentalWarning
// Don't re-export it here, the getter is defined in "lib/index.js"
return
}
exports[key] = gracefulFs[key];
});
// Universalify async methods:
api.forEach(method => {
exports[method] = u(gracefulFs[method]);
});
// 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 gracefulFs.exists(filename, callback)
}
return new Promise(resolve => {
return gracefulFs.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 gracefulFs.read(fd, buffer, offset, length, position, callback)
}
return new Promise((resolve, reject) => {
gracefulFs.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 gracefulFs.write(fd, buffer, ...args)
}
return new Promise((resolve, reject) => {
gracefulFs.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 gracefulFs.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 gracefulFs.writev(fd, buffers, ...args)
}
return new Promise((resolve, reject) => {
gracefulFs.writev(fd, buffers, ...args, (err, bytesWritten, buffers) => {
if (err) return reject(err)
resolve({ bytesWritten, buffers });
});
})
};
}
// fs.realpath.native only available in Node v9.2+
if (typeof gracefulFs.realpath.native === 'function') {
exports.realpath.native = u(gracefulFs.realpath.native);
}
});
var atLeastNode = r => {
const n = process.versions.node.split('.').map(x => parseInt(x, 10));
r = r.split('.').map(x => parseInt(x, 10));
return n[0] > r[0] || (n[0] === r[0] && (n[1] > r[1] || (n[1] === r[1] && n[2] >= r[2])))
};
const useNativeRecursiveOption = atLeastNode('10.12.0');
// https://github.com/nodejs/node/issues/8987
// https://github.com/libuv/libuv/pull/1088
const checkPath = pth => {
if (process.platform === 'win32') {
const pathHasInvalidWinCharacters = /[<>:"|?*]/.test(pth.replace(path__default['default'].parse(pth).root, ''));
if (pathHasInvalidWinCharacters) {
const error = new Error(`Path contains invalid characters: ${pth}`);
error.code = 'EINVAL';
throw error
}
}
};
const processOptions = options => {
const defaults = { mode: 0o777 };
if (typeof options === 'number') options = { mode: options };
return { ...defaults, ...options }
};
const permissionError = pth => {
// This replicates the exception of `fs.mkdir` with native the
// `recusive` option when run on an invalid drive under Windows.
const error = new Error(`operation not permitted, mkdir '${pth}'`);
error.code = 'EPERM';
error.errno = -4048;
error.path = pth;
error.syscall = 'mkdir';
return error
};
var makeDir_1 = async (input, options) => {
checkPath(input);
options = processOptions(options);
if (useNativeRecursiveOption) {
const pth = path__default['default'].resolve(input);
return fs_1.mkdir(pth, {
mode: options.mode,
recursive: true
})
}
const make = async pth => {
try {
await fs_1.mkdir(pth, options.mode);
} catch (error) {
if (error.code === 'EPERM') {
throw error
}
if (error.code === 'ENOENT') {
if (path__default['default'].dirname(pth) === pth) {
throw permissionError(pth)
}
if (error.message.includes('null bytes')) {
throw error
}
await make(path__default['default'].dirname(pth));
return make(pth)
}
try {
const stats = await fs_1.stat(pth);
if (!stats.isDirectory()) {
// This error is never exposed to the user
// it is caught below, and the original error is thrown
throw new Error('The path is not a directory')
}
} catch {
throw error
}
}
};
return make(path__default['default'].resolve(input))
};
var makeDirSync = (input, options) => {
checkPath(input);
options = processOptions(options);
if (useNativeRecursiveOption) {
const pth = path__default['default'].resolve(input);
return fs_1.mkdirSync(pth, {
mode: options.mode,
recursive: true
})
}
const make = pth => {
try {
fs_1.mkdirSync(pth, options.mode);
} catch (error) {
if (error.code === 'EPERM') {
throw error
}
if (error.code === 'ENOENT') {
if (path__default['default'].dirname(pth) === pth) {
throw permissionError(pth)
}
if (error.message.includes('null bytes')) {
throw error
}
make(path__default['default'].dirname(pth));
return make(pth)
}
try {
if (!fs_1.statSync(pth).isDirectory()) {
// This error is never exposed to the user
// it is caught below, and the original error is thrown
throw new Error('The path is not a directory')
}
} catch {
throw error
}
}
};
return make(path__default['default'].resolve(input))
};
var makeDir = {
makeDir: makeDir_1,
makeDirSync: makeDirSync
};
const u = universalify.fromPromise;
const { makeDir: _makeDir, makeDirSync: makeDirSync$1 } = makeDir;
const makeDir$1 = u(_makeDir);
var mkdirs = {
mkdirs: makeDir$1,
mkdirsSync: makeDirSync$1,
// alias
mkdirp: makeDir$1,
mkdirpSync: makeDirSync$1,
ensureDir: makeDir$1,
ensureDirSync: makeDirSync$1
};
function utimesMillis (path, atime, mtime, callback) {
// if (!HAS_MILLIS_RES) return fs.utimes(path, atime, mtime, callback)
gracefulFs.open(path, 'r+', (err, fd) => {
if (err) return callback(err)
gracefulFs.futimes(fd, atime, mtime, futimesErr => {
gracefulFs.close(fd, closeErr => {
if (callback) callback(futimesErr || closeErr);
});
});
});
}
function utimesMillisSync (path, atime, mtime) {
const fd = gracefulFs.openSync(path, 'r+');
gracefulFs.futimesSync(fd, atime, mtime);
return gracefulFs.closeSync(fd)
}
var utimes = {
utimesMillis,
utimesMillisSync
};
const nodeSupportsBigInt = atLeastNode('10.5.0');
const stat = (file) => nodeSupportsBigInt ? fs_1.stat(file, { bigint: true }) : fs_1.stat(file);
const statSync = (file) => nodeSupportsBigInt ? fs_1.statSync(file, { bigint: true }) : fs_1.statSync(file);
function getStats (src, dest) {
return Promise.all([
stat(src),
stat(dest).catch(err => {
if (err.code === 'ENOENT') return null
throw err
})
]).then(([srcStat, destStat]) => ({ srcStat, destStat }))
}
function getStatsSync (src, dest) {
let destStat;
const srcStat = statSync(src);
try {
destStat = statSync(dest);
} catch (err) {
if (err.code === 'ENOENT') return { srcStat, destStat: null }
throw err
}
return { srcStat, destStat }
}
function checkPaths (src, dest, funcName, cb) {
util__default['default'].callbackify(getStats)(src, dest, (err, stats) => {
if (err) return cb(err)
const { srcStat, destStat } = stats;
if (destStat && areIdentical(srcStat, destStat)) {
return cb(new Error('Source and destination must not be the same.'))
}
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
return cb(new Error(errMsg(src, dest, funcName)))
}
return cb(null, { srcStat, destStat })
});
}
function checkPathsSync (src, dest, funcName) {
const { srcStat, destStat } = getStatsSync(src, dest);
if (destStat && areIdentical(srcStat, destStat)) {
throw new Error('Source and destination must not be the same.')
}
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__default['default'].resolve(path__default['default'].dirname(src));
const destParent = path__default['default'].resolve(path__default['default'].dirname(dest));
if (destParent === srcParent || destParent === path__default['default'].parse(destParent).root) return cb()
const callback = (err, destStat) => {
if (err) {
if (err.code === 'ENOENT') return cb()
return cb(err)
}
if (areIdentical(srcStat, destStat)) {
return cb(new Error(errMsg(src, dest, funcName)))
}
return checkParentPaths(src, srcStat, destParent, funcName, cb)
};
if (nodeSupportsBigInt) fs_1.stat(destParent, { bigint: true }, callback);
else fs_1.stat(destParent, callback);
}
function checkParentPathsSync (src, srcStat, dest, funcName) {
const srcParent = path__default['default'].resolve(path__default['default'].dirname(src));
const destParent = path__default['default'].resolve(path__default['default'].dirname(dest));
if (destParent === srcParent || destParent === path__default['default'].parse(destParent).root) return
let destStat;
try {
destStat = statSync(destParent);
} catch (err) {
if (err.code === 'ENOENT') return
throw err
}
if (areIdentical(srcStat, destStat)) {
throw new Error(errMsg(src, dest, funcName))
}
return checkParentPathsSync(src, srcStat, destParent, funcName)
}
function areIdentical (srcStat, destStat) {
if (destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev) {
if (nodeSupportsBigInt || destStat.ino < Number.MAX_SAFE_INTEGER) {
// definitive answer
return true
}
// Use additional heuristics if we can't use 'bigint'.
// Different 'ino' could be represented the same if they are >= Number.MAX_SAFE_INTEGER
// See issue 657
if (destStat.size === srcStat.size &&
destStat.mode === srcStat.mode &&
destStat.nlink === srcStat.nlink &&
destStat.atimeMs === srcStat.atimeMs &&
destStat.mtimeMs === srcStat.mtimeMs &&
destStat.ctimeMs === srcStat.ctimeMs &&
destStat.birthtimeMs === srcStat.birthtimeMs) {
// heuristic answer
return true
}
}
return false
}
// return true if dest is a subdir of src, otherwise false.
// It only checks the path strings.
function isSrcSubdir (src, dest) {
const srcArr = path__default['default'].resolve(src).split(path__default['default'].sep).filter(i => i);
const destArr = path__default['default'].resolve(dest).split(path__default['default'].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_1 = {
checkPaths,
checkPathsSync,
checkParentPaths,
checkParentPathsSync,
isSrcSubdir
};
const mkdirsSync = mkdirs.mkdirsSync;
const utimesMillisSync$1 = utimes.utimesMillisSync;
function copySync (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_1.checkPathsSync(src, dest, 'copy');
stat_1.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__default['default'].dirname(dest);
if (!gracefulFs.existsSync(destParent)) mkdirsSync(destParent);
return startCopy(destStat, src, dest, opts)
}
function startCopy (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 ? gracefulFs.statSync : gracefulFs.lstatSync;
const srcStat = statSync(src);
if (srcStat.isDirectory()) return onDir(srcStat, destStat, src, dest, opts)
else if (srcStat.isFile() ||
srcStat.isCharacterDevice() ||
srcStat.isBlockDevice()) return onFile(srcStat, destStat, src, dest, opts)
else if (srcStat.isSymbolicLink()) return onLink(destStat, src, dest, opts)
}
function onFile (srcStat, destStat, src, dest, opts) {
if (!destStat) return copyFile(srcStat, src, dest, opts)
return mayCopyFile(srcStat, src, dest, opts)
}
function mayCopyFile (srcStat, src, dest, opts) {
if (opts.overwrite) {
gracefulFs.unlinkSync(dest);
return copyFile(srcStat, src, dest, opts)
} else if (opts.errorOnExist) {
throw new Error(`'${dest}' already exists`)
}
}
function copyFile (srcStat, src, dest, opts) {
gracefulFs.copyFileSync(src, dest);
if (opts.preserveTimestamps) handleTimestamps(srcStat.mode, src, dest);
return setDestMode(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(srcMode)) makeFileWritable(dest, srcMode);
return setDestTimestamps(src, dest)
}
function fileIsNotWritable (srcMode) {
return (srcMode & 0o200) === 0
}
function makeFileWritable (dest, srcMode) {
return setDestMode(dest, srcMode | 0o200)
}
function setDestMode (dest, srcMode) {
return gracefulFs.chmodSync(dest, srcMode)
}
function setDestTimestamps (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 = gracefulFs.statSync(src);
return utimesMillisSync$1(dest, updatedSrcStat.atime, updatedSrcStat.mtime)
}
function onDir (srcStat, destStat, src, dest, opts) {
if (!destStat) return mkDirAndCopy(srcStat.mode, src, dest, opts)
if (destStat && !destStat.isDirectory()) {
throw new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`)
}
return copyDir(src, dest, opts)
}
function mkDirAndCopy (srcMode, src, dest, opts) {
gracefulFs.mkdirSync(dest);
copyDir(src, dest, opts);
return setDestMode(dest, srcMode)
}
function copyDir (src, dest, opts) {
gracefulFs.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts));
}
function copyDirItem (item, src, dest, opts) {
const srcItem = path__default['default'].join(src, item);
const destItem = path__default['default'].join(dest, item);
const { destStat } = stat_1.checkPathsSync(srcItem, destItem, 'copy');
return startCopy(destStat, srcItem, destItem, opts)
}
function onLink (destStat, src, dest, opts) {
let resolvedSrc = gracefulFs.readlinkSync(src);
if (opts.dereference) {
resolvedSrc = path__default['default'].resolve(process.cwd(), resolvedSrc);
}
if (!destStat) {
return gracefulFs.symlinkSync(resolvedSrc, dest)
} else {
let resolvedDest;
try {
resolvedDest = gracefulFs.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 gracefulFs.symlinkSync(resolvedSrc, dest)
throw err
}
if (opts.dereference) {
resolvedDest = path__default['default'].resolve(process.cwd(), resolvedDest);
}
if (stat_1.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 (gracefulFs.statSync(dest).isDirectory() && stat_1.isSrcSubdir(resolvedDest, resolvedSrc)) {
throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
}
return copyLink(resolvedSrc, dest)
}
}
function copyLink (resolvedSrc, dest) {
gracefulFs.unlinkSync(dest);
return gracefulFs.symlinkSync(resolvedSrc, dest)
}
var copySync_1 = copySync;
var copySync$1 = {
copySync: copySync_1
};
const u$1 = universalify.fromPromise;
function pathExists (path) {
return fs_1.access(path).then(() => true).catch(() => false)
}
var pathExists_1 = {
pathExists: u$1(pathExists),
pathExistsSync: fs_1.existsSync
};
const mkdirs$1 = mkdirs.mkdirs;
const pathExists$1 = pathExists_1.pathExists;
const utimesMillis$1 = utimes.utimesMillis;
function copy (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_1.checkPaths(src, dest, 'copy', (err, stats) => {
if (err) return cb(err)
const { srcStat, destStat } = stats;
stat_1.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__default['default'].dirname(dest);
pathExists$1(destParent, (err, dirExists) => {
if (err) return cb(err)
if (dirExists) return startCopy$1(destStat, src, dest, opts, cb)
mkdirs$1(destParent, err => {
if (err) return cb(err)
return startCopy$1(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$1 (destStat, src, dest, opts, cb) {
if (opts.filter) return handleFilter(getStats$2, destStat, src, dest, opts, cb)
return getStats$2(destStat, src, dest, opts, cb)
}
function getStats$2 (destStat, src, dest, opts, cb) {
const stat = opts.dereference ? gracefulFs.stat : gracefulFs.lstat;
stat(src, (err, srcStat) => {
if (err) return cb(err)
if (srcStat.isDirectory()) return onDir$1(srcStat, destStat, src, dest, opts, cb)
else if (srcStat.isFile() ||
srcStat.isCharacterDevice() ||
srcStat.isBlockDevice()) return onFile$1(srcStat, destStat, src, dest, opts, cb)
else if (srcStat.isSymbolicLink()) return onLink$1(destStat, src, dest, opts, cb)
});
}
function onFile$1 (srcStat, destStat, src, dest, opts, cb) {
if (!destStat) return copyFile$1(srcStat, src, dest, opts, cb)
return mayCopyFile$1(srcStat, src, dest, opts, cb)
}
function mayCopyFile$1 (srcStat, src, dest, opts, cb) {
if (opts.overwrite) {
gracefulFs.unlink(dest, err => {
if (err) return cb(err)
return copyFile$1(srcStat, src, dest, opts, cb)
});
} else if (opts.errorOnExist) {
return cb(new Error(`'${dest}' already exists`))
} else return cb()
}
function copyFile$1 (srcStat, src, dest, opts, cb) {
gracefulFs.copyFile(src, dest, err => {
if (err) return cb(err)
if (opts.preserveTimestamps) return handleTimestampsAndMode(srcStat.mode, src, dest, cb)
return setDestMode$1(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$1(srcMode)) {
return makeFileWritable$1(dest, srcMode, err => {
if (err) return cb(err)
return setDestTimestampsAndMode(srcMode, src, dest, cb)
})
}
return setDestTimestampsAndMode(srcMode, src, dest, cb)
}
function fileIsNotWritable$1 (srcMode) {
return (srcMode & 0o200) === 0
}
function makeFileWritable$1 (dest, srcMode, cb) {
return setDestMode$1(dest, srcMode | 0o200, cb)
}
function setDestTimestampsAndMode (srcMode, src, dest, cb) {
setDestTimestamps$1(src, dest, err => {
if (err) return cb(err)
return setDestMode$1(dest, srcMode, cb)
});
}
function setDestMode$1 (dest, srcMode, cb) {
return gracefulFs.chmod(dest, srcMode, cb)
}
function setDestTimestamps$1 (src, dest, cb) {
// 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)
gracefulFs.stat(src, (err, updatedSrcStat) => {
if (err) return cb(err)
return utimesMillis$1(dest, updatedSrcStat.atime, updatedSrcStat.mtime, cb)
});
}
function onDir$1 (srcStat, destStat, src, dest, opts, cb) {
if (!destStat) return mkDirAndCopy$1(srcStat.mode, src, dest, opts, cb)
if (destStat && !destStat.isDirectory()) {
return cb(new Error(`Cannot overwrite non-directory '${dest}' with directory '${src}'.`))
}
return copyDir$1(src, dest, opts, cb)
}
function mkDirAndCopy$1 (srcMode, src, dest, opts, cb) {
gracefulFs.mkdir(dest, err => {
if (err) return cb(err)
copyDir$1(src, dest, opts, err => {
if (err) return cb(err)
return setDestMode$1(dest, srcMode, cb)
});
});
}
function copyDir$1 (src, dest, opts, cb) {
gracefulFs.readdir(src, (err, items) => {
if (err) return cb(err)
return copyDirItems(items, src, dest, opts, cb)
});
}
function copyDirItems (items, src, dest, opts, cb) {
const item = items.pop();
if (!item) return cb()
return copyDirItem$1(items, item, src, dest, opts, cb)
}
function copyDirItem$1 (items, item, src, dest, opts, cb) {
const srcItem = path__default['default'].join(src, item);
const destItem = path__default['default'].join(dest, item);
stat_1.checkPaths(srcItem, destItem, 'copy', (err, stats) => {
if (err) return cb(err)
const { destStat } = stats;
startCopy$1(destStat, srcItem, destItem, opts, err => {
if (err) return cb(err)
return copyDirItems(items, src, dest, opts, cb)
});
});
}
function onLink$1 (destStat, src, dest, opts, cb) {
gracefulFs.readlink(src, (err, resolvedSrc) => {
if (err) return cb(err)
if (opts.dereference) {
resolvedSrc = path__default['default'].resolve(process.cwd(), resolvedSrc);
}
if (!destStat) {
return gracefulFs.symlink(resolvedSrc, dest, cb)
} else {
gracefulFs.readlink(dest, (err, resolvedDest) => {
if (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 gracefulFs.symlink(resolvedSrc, dest, cb)
return cb(err)
}
if (opts.dereference) {
resolvedDest = path__default['default'].resolve(process.cwd(), resolvedDest);
}