UNPKG

rollup-plugin-copy-assets

Version:

Copy additional assets into the output directory of your rollup bundle.

1,745 lines (1,431 loc) 75.6 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var fs = _interopDefault(require('fs')); var constants = _interopDefault(require('constants')); var stream = _interopDefault(require('stream')); var util = _interopDefault(require('util')); var assert = _interopDefault(require('assert')); var path = _interopDefault(require('path')); var os = _interopDefault(require('os')); function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var fromCallback = function (fn) { return Object.defineProperty(function () { if (typeof arguments[arguments.length - 1] === 'function') fn.apply(this, arguments);else { return new Promise((resolve, reject) => { arguments[arguments.length] = (err, res) => { if (err) return reject(err); resolve(res); }; arguments.length++; fn.apply(this, arguments); }); } }, 'name', { value: fn.name }); }; var fromPromise = function (fn) { return Object.defineProperty(function () { const cb = arguments[arguments.length - 1]; if (typeof cb !== 'function') return fn.apply(this, arguments);else fn.apply(this, arguments).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.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) { return function (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); }; }(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, cb) { return orig.call(fs, target, function (er, stats) { if (!stats) return cb.apply(this, arguments); if (stats.uid < 0) stats.uid += 0x100000000; if (stats.gid < 0) stats.gid += 0x100000000; if (cb) cb.apply(this, arguments); }); }; } function statFixSync(orig) { if (!orig) return orig; // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target) { var stats = 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 = stream.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 = createCommonjsModule(function (module) { var queue = []; function noop() {} var debug = noop; if (util.debuglog) debug = util.debuglog('gfs4');else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) debug = function () { var m = util.format.apply(util, arguments); m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: '); console.error(m); }; if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function () { debug(queue); assert.equal(queue.length, 0); }); } module.exports = patch(clone_1(fs)); if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { module.exports = patch(fs); fs.__patched = true; } // Always patch fs.close/closeSync, because we want 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. module.exports.close = function (fs$close) { return function (fd, cb) { return fs$close.call(fs, fd, function (err) { if (!err) retry(); if (typeof cb === 'function') cb.apply(this, arguments); }); }; }(fs.close); module.exports.closeSync = function (fs$closeSync) { return function (fd) { // Note that graceful-fs also retries when fs.closeSync() fails. // Looks like a bug to me, although it's probably a harmless one. var rval = fs$closeSync.apply(fs, arguments); retry(); return rval; }; }(fs.closeSync); // Only patch fs once, otherwise we'll run into a memory leak if // graceful-fs is loaded multiple times, such as in test environments that // reset the loaded modules between tests. // We look for the string `graceful-fs` from the comment above. This // way we are not adding any extra properties and it will detect if older // versions of graceful-fs are installed. if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { fs.closeSync = module.exports.closeSync; fs.close = module.exports.close; } function patch(fs) { // Everything that references the open() function needs to be in here polyfills(fs); fs.gracefulify = patch; fs.FileReadStream = ReadStream; // Legacy name. fs.FileWriteStream = WriteStream; // Legacy name. 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; } fs.ReadStream = ReadStream; fs.WriteStream = WriteStream; 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 ReadStream(path, options); } function createWriteStream(path, options) { return new 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]); queue.push(elem); } function retry() { var elem = queue.shift(); if (elem) { debug('RETRY', elem[0].name, elem[1]); elem[0].apply(null, elem[1]); } } }); var gracefulFs_1 = gracefulFs.close; var gracefulFs_2 = gracefulFs.closeSync; var fs_1 = createCommonjsModule(function (module, exports) { // 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', 'lchown', 'lchmod', 'link', 'lstat', 'mkdir', 'mkdtemp', 'open', 'readFile', 'readdir', 'readlink', 'realpath', 'rename', 'rmdir', 'stat', 'symlink', 'truncate', 'unlink', 'utimes', 'writeFile'].filter(key => { // Some commands are not available on some systems. Ex: // fs.copyFile was added in Node.js v8.5.0 // fs.mkdtemp was added in Node.js v5.10.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 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 }); }); }); }; }); var fs_2 = fs_1.exists; var fs_3 = fs_1.read; var fs_4 = fs_1.write; function getRootPath(p) { p = path.normalize(path.resolve(p)).split(path.sep); if (p.length > 0) return p[0]; return null; } // http://stackoverflow.com/a/62888/10333 contains more accurate // TODO: expand to include the rest const INVALID_PATH_CHARS = /[<>:"|?*]/; function invalidWin32Path(p) { const rp = getRootPath(p); p = p.replace(rp, ''); return INVALID_PATH_CHARS.test(p); } var win32 = { getRootPath, invalidWin32Path }; const invalidWin32Path$1 = win32.invalidWin32Path; const o777 = parseInt('0777', 8); function mkdirs(p, opts, callback, made) { if (typeof opts === 'function') { callback = opts; opts = {}; } else if (!opts || typeof opts !== 'object') { opts = { mode: opts }; } if (process.platform === 'win32' && invalidWin32Path$1(p)) { const errInval = new Error(p + ' contains invalid WIN32 path characters.'); errInval.code = 'EINVAL'; return callback(errInval); } let mode = opts.mode; const xfs = opts.fs || gracefulFs; if (mode === undefined) { mode = o777 & ~process.umask(); } if (!made) made = null; callback = callback || function () {}; p = path.resolve(p); xfs.mkdir(p, mode, er => { if (!er) { made = made || p; return callback(null, made); } switch (er.code) { case 'ENOENT': if (path.dirname(p) === p) return callback(er); mkdirs(path.dirname(p), opts, (er, made) => { if (er) callback(er, made);else mkdirs(p, opts, callback, made); }); break; // In the case of any other error, just see if there's a dir // there already. If so, then hooray! If not, then something // is borked. default: xfs.stat(p, (er2, stat) => { // if the stat fails, then that's super weird. // let the original error be the failure reason. if (er2 || !stat.isDirectory()) callback(er, made);else callback(null, made); }); break; } }); } var mkdirs_1 = mkdirs; const invalidWin32Path$2 = win32.invalidWin32Path; const o777$1 = parseInt('0777', 8); function mkdirsSync(p, opts, made) { if (!opts || typeof opts !== 'object') { opts = { mode: opts }; } let mode = opts.mode; const xfs = opts.fs || gracefulFs; if (process.platform === 'win32' && invalidWin32Path$2(p)) { const errInval = new Error(p + ' contains invalid WIN32 path characters.'); errInval.code = 'EINVAL'; throw errInval; } if (mode === undefined) { mode = o777$1 & ~process.umask(); } if (!made) made = null; p = path.resolve(p); try { xfs.mkdirSync(p, mode); made = made || p; } catch (err0) { if (err0.code === 'ENOENT') { if (path.dirname(p) === p) throw err0; made = mkdirsSync(path.dirname(p), opts, made); mkdirsSync(p, opts, made); } else { // In the case of any other error, just see if there's a dir there // already. If so, then hooray! If not, then something is borked. let stat; try { stat = xfs.statSync(p); } catch (err1) { throw err0; } if (!stat.isDirectory()) throw err0; } } return made; } var mkdirsSync_1 = mkdirsSync; const u = universalify.fromCallback; const mkdirs$1 = u(mkdirs_1); var mkdirs_1$1 = { mkdirs: mkdirs$1, mkdirsSync: mkdirsSync_1, // alias mkdirp: mkdirs$1, mkdirpSync: mkdirsSync_1, ensureDir: mkdirs$1, ensureDirSync: mkdirsSync_1 }; function hasMillisResSync() { let tmpfile = path.join('millis-test-sync' + Date.now().toString() + Math.random().toString().slice(2)); tmpfile = path.join(os.tmpdir(), tmpfile); // 550 millis past UNIX epoch const d = new Date(1435410243862); gracefulFs.writeFileSync(tmpfile, 'https://github.com/jprichardson/node-fs-extra/pull/141'); const fd = gracefulFs.openSync(tmpfile, 'r+'); gracefulFs.futimesSync(fd, d, d); gracefulFs.closeSync(fd); return gracefulFs.statSync(tmpfile).mtime > 1435410243000; } function hasMillisRes(callback) { let tmpfile = path.join('millis-test' + Date.now().toString() + Math.random().toString().slice(2)); tmpfile = path.join(os.tmpdir(), tmpfile); // 550 millis past UNIX epoch const d = new Date(1435410243862); gracefulFs.writeFile(tmpfile, 'https://github.com/jprichardson/node-fs-extra/pull/141', err => { if (err) return callback(err); gracefulFs.open(tmpfile, 'r+', (err, fd) => { if (err) return callback(err); gracefulFs.futimes(fd, d, d, err => { if (err) return callback(err); gracefulFs.close(fd, err => { if (err) return callback(err); gracefulFs.stat(tmpfile, (err, stats) => { if (err) return callback(err); callback(null, stats.mtime > 1435410243000); }); }); }); }); }); } function timeRemoveMillis(timestamp) { if (typeof timestamp === 'number') { return Math.floor(timestamp / 1000) * 1000; } else if (timestamp instanceof Date) { return new Date(Math.floor(timestamp.getTime() / 1000) * 1000); } else { throw new Error('fs-extra: timeRemoveMillis() unknown parameter type'); } } 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 = { hasMillisRes, hasMillisResSync, timeRemoveMillis, utimesMillis, utimesMillisSync }; /* eslint-disable node/no-deprecated-api */ var buffer = function (size) { if (typeof Buffer.allocUnsafe === 'function') { try { return Buffer.allocUnsafe(size); } catch (e) { return new Buffer(size); } } return new Buffer(size); }; const mkdirpSync = mkdirs_1$1.mkdirsSync; const utimesSync = utimes.utimesMillisSync; const notExist = Symbol('notExist'); 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 destStat = checkPaths(src, dest); if (opts.filter && !opts.filter(src, dest)) return; const destParent = path.dirname(dest); if (!gracefulFs.existsSync(destParent)) mkdirpSync(destParent); return startCopy(destStat, src, dest, opts); } function startCopy(destStat, src, dest, opts) { if (opts.filter && !opts.filter(src, dest)) return; return getStats(destStat, src, dest, opts); } function getStats(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 === notExist) 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) { if (typeof gracefulFs.copyFileSync === 'function') { gracefulFs.copyFileSync(src, dest); gracefulFs.chmodSync(dest, srcStat.mode); if (opts.preserveTimestamps) { return utimesSync(dest, srcStat.atime, srcStat.mtime); } return; } return copyFileFallback(srcStat, src, dest, opts); } function copyFileFallback(srcStat, src, dest, opts) { const BUF_LENGTH = 64 * 1024; const _buff = buffer(BUF_LENGTH); const fdr = gracefulFs.openSync(src, 'r'); const fdw = gracefulFs.openSync(dest, 'w', srcStat.mode); let pos = 0; while (pos < srcStat.size) { const bytesRead = gracefulFs.readSync(fdr, _buff, 0, BUF_LENGTH, pos); gracefulFs.writeSync(fdw, _buff, 0, bytesRead); pos += bytesRead; } if (opts.preserveTimestamps) gracefulFs.futimesSync(fdw, srcStat.atime, srcStat.mtime); gracefulFs.closeSync(fdr); gracefulFs.closeSync(fdw); } function onDir(srcStat, destStat, src, dest, opts) { if (destStat === notExist) return mkDirAndCopy(srcStat, 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(srcStat, src, dest, opts) { gracefulFs.mkdirSync(dest); copyDir(src, dest, opts); return gracefulFs.chmodSync(dest, srcStat.mode); } function copyDir(src, dest, opts) { gracefulFs.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts)); } function copyDirItem(item, src, dest, opts) { const srcItem = path.join(src, item); const destItem = path.join(dest, item); const destStat = checkPaths(srcItem, destItem); return startCopy(destStat, srcItem, destItem, opts); } function onLink(destStat, src, dest, opts) { let resolvedSrc = gracefulFs.readlinkSync(src); if (opts.dereference) { resolvedSrc = path.resolve(process.cwd(), resolvedSrc); } if (destStat === notExist) { 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.resolve(process.cwd(), resolvedDest); } if (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() && 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); } // return true if dest is a subdir of src, otherwise false. function isSrcSubdir(src, dest) { const srcArray = path.resolve(src).split(path.sep); const destArray = path.resolve(dest).split(path.sep); return srcArray.reduce((acc, current, i) => acc && destArray[i] === current, true); } function checkStats(src, dest) { const srcStat = gracefulFs.statSync(src); let destStat; try { destStat = gracefulFs.statSync(dest); } catch (err) { if (err.code === 'ENOENT') return { srcStat, destStat: notExist }; throw err; } return { srcStat, destStat }; } function checkPaths(src, dest) { const { srcStat, destStat } = checkStats(src, dest); if (destStat.ino && destStat.ino === srcStat.ino) { throw new Error('Source and destination must not be the same.'); } if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { throw new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`); } return destStat; } 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 mkdirp = mkdirs_1$1.mkdirs; const pathExists$1 = pathExists_1.pathExists; const utimes$1 = utimes.utimesMillis; const notExist$1 = Symbol('notExist'); 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`); } checkPaths$1(src, dest, (err, destStat) => { 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.dirname(dest); pathExists$1(destParent, (err, dirExists) => { if (err) return cb(err); if (dirExists) return startCopy$1(destStat, src, dest, opts, cb); mkdirp(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) { if (destStat) return onInclude(destStat, src, dest, opts, cb); return onInclude(src, dest, opts, cb); } return cb(); }, error => cb(error)); } function startCopy$1(destStat, src, dest, opts, cb) { if (opts.filter) return handleFilter(getStats$1, destStat, src, dest, opts, cb); return getStats$1(destStat, src, dest, opts, cb); } function getStats$1(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 === notExist$1) 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) { if (typeof gracefulFs.copyFile === 'function') { return gracefulFs.copyFile(src, dest, err => { if (err) return cb(err); return setDestModeAndTimestamps(srcStat, dest, opts, cb); }); } return copyFileFallback$1(srcStat, src, dest, opts, cb); } function copyFileFallback$1(srcStat, src, dest, opts, cb) { const rs = gracefulFs.createReadStream(src); rs.on('error', err => cb(err)).once('open', () => { const ws = gracefulFs.createWriteStream(dest, { mode: srcStat.mode }); ws.on('error', err => cb(err)).on('open', () => rs.pipe(ws)).once('close', () => setDestModeAndTimestamps(srcStat, dest, opts, cb)); }); } function setDestModeAndTimestamps(srcStat, dest, opts, cb) { gracefulFs.chmod(dest, srcStat.mode, err => { if (err) return cb(err); if (opts.preserveTimestamps) { return utimes$1(dest, srcStat.atime, srcStat.mtime, cb); } return cb(); }); } function onDir$1(srcStat, destStat, src, dest, opts, cb) { if (destStat === notExist$1) return mkDirAndCopy$1(srcStat, 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(srcStat, 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 gracefulFs.chmod(dest, srcStat.mode, 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.join(src, item); const destItem = path.join(dest, item); checkPaths$1(srcItem, destItem, (err, destStat) => { if (err) return cb(err); 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.resolve(process.cwd(), resolvedSrc); } if (destStat === notExist$1) { 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.resolve(process.cwd(), resolvedDest); } if (isSrcSubdir$1(resolvedSrc, resolvedDest)) { return cb(new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)); } // do not 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 (destStat.isDirectory() && isSrcSubdir$1(resolvedDest, resolvedSrc)) { return cb(new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)); } return copyLink$1(resolvedSrc, dest, cb); }); } }); } function copyLink$1(resolvedSrc, dest, cb) { gracefulFs.unlink(dest, err => { if (err) return cb(err); return gracefulFs.symlink(resolvedSrc, dest, cb); }); } // return true if dest is a subdir of src, otherwise false. function isSrcSubdir$1(src, dest) { const srcArray = path.resolve(src).split(path.sep); const destArray = path.resolve(dest).split(path.sep); return srcArray.reduce((acc, current, i) => acc && destArray[i] === current, true); } function checkStats$1(src, dest, cb) { gracefulFs.stat(src, (err, srcStat) => { if (err) return cb(err); gracefulFs.stat(dest, (err, destStat) => { if (err) { if (err.code === 'ENOENT') return cb(null, { srcStat, destStat: notExist$1 }); return cb(err); } return cb(null, { srcStat, destStat }); }); }); } function checkPaths$1(src, dest, cb) { checkStats$1(src, dest, (err, stats) => { if (err) return cb(err); const { srcStat, destStat } = stats; if (destStat.ino && destStat.ino === srcStat.ino) { return cb(new Error('Source and destination must not be the same.')); } if (srcStat.isDirectory() && isSrcSubdir$1(src, dest)) { return cb(new Error(`Cannot copy '${src}' to a subdirectory of itself, '${dest}'.`)); } return cb(null, destStat); }); } var copy_1 = copy; const u$2 = universalify.fromCallback; var copy$1 = { copy: u$2(copy_1) }; const isWindows = process.platform === 'win32'; function defaults(options) { const methods = ['unlink', 'chmod', 'stat', 'lstat', 'rmdir', 'readdir']; methods.forEach(m => { options[m] = options[m] || gracefulFs[m]; m = m + 'Sync'; options[m] = options[m] || gracefulFs[m]; }); options.maxBusyTries = options.maxBusyTries || 3; } function rimraf(p, options, cb) { let busyTries = 0; if (typeof options === 'function') { cb = options; options = {}; } assert(p, 'rimraf: missing path'); assert.strictEqual(typeof p, 'string', 'rimraf: path should be a string'); assert.strictEqual(typeof cb, 'function', 'rimraf: callback function required'); assert(options, 'rimraf: invalid options argument provided'); assert.strictEqual(typeof options, 'object', 'rimraf: options should be object'); defaults(options); rimraf_(p, options, function CB(er) { if (er) { if ((er.code === 'EBUSY' || er.code === 'ENOTEMPTY' || er.code === 'EPERM') && busyTries < options.maxBusyTries) { busyTries++; const time = busyTries * 100; // try again, with the same exact callback as this one. return setTimeout(() => rimraf_(p, options, CB), time); } // already gone if (er.code === 'ENOENT') er = null; } cb(er); }); } // Two possible strategies. // 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR // 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR // // Both result in an extra syscall when you guess wrong. However, there // are likely far more normal files in the world than directories. This // is based on the assumption that a the average number of files per // directory is >= 1. // // If anyone ever complains about this, then I guess the strategy could // be made configurable somehow. But until then, YAGNI. function rimraf_(p, options, cb) { assert(p); assert(options); assert(typeof cb === 'function'); // sunos lets the root user unlink directories, which is... weird. // so we have to lstat here and make sure it's not a dir. options.lstat(p, (er, st) => { if (er && er.code === 'ENOENT') { return cb(null); } // Windows can EPERM on stat. Life is suffering. if (er && er.code === 'EPERM' && isWindows) { return fixWinEPERM(p, options, er, cb); } if (st && st.isDirectory()) { return rmdir(p, options, er, cb); } options.unlink(p, er => { if (er) { if (er.code === 'ENOENT') { return cb(null); } if (er.code === 'EPERM') { return isWindows ? fixWinEPERM(p, options, er, cb) : rmdir(p, options, er, cb); } if (er.code === 'EISDIR') { return rmdir(p, options, er, cb); } } return cb(er); }); }); } function fixWinEPERM(p, options, er, cb) { assert(p); assert(options); assert(typeof cb === 'function'); if (er) { assert(er instanceof Error); } options.chmod(p, 0o666, er2 => { if (er2) { cb(er2.code === 'ENOENT' ? null : er); } else { options.stat(p, (er3, stats) => { if (er3) { cb(er3.code === 'ENOENT' ? null : er); } else if (stats.isDirectory()) { rmdir(p, options, er, cb); } else { options.unlink(p, cb); } }); } }); } function fixWinEPERMSync(p, options, er) { let stats; assert(p); assert(options); if (er) { assert(er instanceof Error); } try { options.chmodSync(p, 0o666); } catch (er2) { if (er2.code === 'ENOENT') { return; } else { throw er; } } try { stats = options.statSync(p); } catch (er3) { if (er3.code === 'ENOENT') { return; } else { throw er; } } if (stats.isDirectory()) { rmdirSync(p, options, er); } else { options.unlinkSync(p); } } function rmdir(p, options, originalEr, cb) { assert(p); assert(options); if (originalEr) { assert(originalEr instanceof Error); } assert(typeof cb === 'function'); // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) // if we guessed wrong, and it's not a directory, then // raise the original error. options.rmdir(p, er => { if (er && (er.code === 'ENOTEMPTY' || er.code === 'EEXIST' || er.code === 'EPERM')) { rmkids(p, options, cb); } else if (er && er.code === 'ENOTDIR') { cb(originalEr); } else { cb(er); } }); } function rmkids(p, options, cb) { assert(p); assert(options); assert(typeof cb === 'function'); options.readdir(p, (er, files) => { if (er) return cb(er);