refactor(Cypress): add nodemodules
This commit is contained in:
6
node_modules/watchify/.travis.yml
generated
vendored
Normal file
6
node_modules/watchify/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- node
|
18
node_modules/watchify/LICENSE
generated
vendored
Normal file
18
node_modules/watchify/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
This software is released under the MIT license:
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
node_modules/watchify/bin/args.js
generated
vendored
Normal file
16
node_modules/watchify/bin/args.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
var fromArgs = require('browserify/bin/args');
|
||||
var watchify = require('../');
|
||||
var defined = require('defined');
|
||||
var xtend = require('xtend');
|
||||
|
||||
module.exports = function (args) {
|
||||
var b = fromArgs(args, watchify.args);
|
||||
|
||||
var opts = {};
|
||||
var ignoreWatch = defined(b.argv['ignore-watch'], b.argv.iw);
|
||||
if (ignoreWatch) {
|
||||
opts.ignoreWatch = ignoreWatch;
|
||||
}
|
||||
|
||||
return watchify(b, xtend(opts, b.argv));
|
||||
};
|
69
node_modules/watchify/bin/cmd.js
generated
vendored
Executable file
69
node_modules/watchify/bin/cmd.js
generated
vendored
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var path = require('path');
|
||||
var outpipe = require('outpipe');
|
||||
var through = require('through2');
|
||||
|
||||
var fromArgs = require('./args.js');
|
||||
var w = fromArgs(process.argv.slice(2));
|
||||
|
||||
var outfile = w.argv.o || w.argv.outfile;
|
||||
var verbose = w.argv.v || w.argv.verbose;
|
||||
|
||||
if (w.argv.version) {
|
||||
console.error('watchify v' + require('../package.json').version +
|
||||
' (in ' + path.resolve(__dirname, '..') + ')'
|
||||
);
|
||||
console.error('browserify v' + require('browserify/package.json').version +
|
||||
' (in ' + path.dirname(require.resolve('browserify')) + ')'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!outfile) {
|
||||
console.error('You MUST specify an outfile with -o.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var bytes, time;
|
||||
w.on('bytes', function (b) { bytes = b });
|
||||
w.on('time', function (t) { time = t });
|
||||
|
||||
w.on('update', bundle);
|
||||
bundle();
|
||||
|
||||
function bundle () {
|
||||
var didError = false;
|
||||
var writer = through();
|
||||
var wb = w.bundle();
|
||||
|
||||
w.pipeline.get('pack').once('readable', function() {
|
||||
if (!didError) {
|
||||
wb.pipe(writer);
|
||||
}
|
||||
});
|
||||
|
||||
wb.on('error', function (err) {
|
||||
console.error(String(err));
|
||||
if (!didError) {
|
||||
didError = true;
|
||||
writer.end('console.error(' + JSON.stringify(String(err)) + ');');
|
||||
}
|
||||
});
|
||||
|
||||
writer.once('readable', function() {
|
||||
var outStream = outpipe(outfile);
|
||||
outStream.on('error', function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
outStream.on('exit', function () {
|
||||
if (verbose && !didError) {
|
||||
console.error(bytes + ' bytes written to ' + outfile
|
||||
+ ' (' + (time / 1000).toFixed(2) + ' seconds) at '
|
||||
+ new Date().toLocaleTimeString()
|
||||
);
|
||||
}
|
||||
});
|
||||
writer.pipe(outStream);
|
||||
});
|
||||
}
|
2
node_modules/watchify/example/files/main.js
generated
vendored
Normal file
2
node_modules/watchify/example/files/main.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
var one = require('./one');
|
||||
console.log(one(5));
|
3
node_modules/watchify/example/files/one.js
generated
vendored
Normal file
3
node_modules/watchify/example/files/one.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
var two = require('./two');
|
||||
|
||||
module.exports = function (x) { return x * two(x + 5) };
|
1
node_modules/watchify/example/files/two.js
generated
vendored
Normal file
1
node_modules/watchify/example/files/two.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = function (n) { return n * 11 };
|
165
node_modules/watchify/index.js
generated
vendored
Normal file
165
node_modules/watchify/index.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
var through = require('through2');
|
||||
var path = require('path');
|
||||
var chokidar = require('chokidar');
|
||||
var xtend = require('xtend');
|
||||
var anymatch = require('anymatch');
|
||||
|
||||
module.exports = watchify;
|
||||
module.exports.args = {
|
||||
cache: {}, packageCache: {}
|
||||
};
|
||||
|
||||
function watchify (b, opts) {
|
||||
if (!opts) opts = {};
|
||||
var cache = b._options.cache;
|
||||
var pkgcache = b._options.packageCache;
|
||||
var delay = typeof opts.delay === 'number' ? opts.delay : 100;
|
||||
var changingDeps = {};
|
||||
var pending = false;
|
||||
var updating = false;
|
||||
|
||||
var wopts = {persistent: true};
|
||||
if (opts.ignoreWatch) {
|
||||
var ignored = opts.ignoreWatch !== true
|
||||
? opts.ignoreWatch
|
||||
: '**/node_modules/**';
|
||||
}
|
||||
if (opts.poll || typeof opts.poll === 'number') {
|
||||
wopts.usePolling = true;
|
||||
wopts.interval = opts.poll !== true
|
||||
? opts.poll
|
||||
: undefined;
|
||||
}
|
||||
|
||||
if (cache) {
|
||||
b.on('reset', collect);
|
||||
collect();
|
||||
}
|
||||
|
||||
function collect () {
|
||||
b.pipeline.get('deps').push(through.obj(function(row, enc, next) {
|
||||
var file = row.expose ? b._expose[row.id] : row.file;
|
||||
cache[file] = {
|
||||
source: row.source,
|
||||
deps: xtend(row.deps)
|
||||
};
|
||||
this.push(row);
|
||||
next();
|
||||
}));
|
||||
}
|
||||
|
||||
b.on('file', function (file) {
|
||||
watchFile(file);
|
||||
});
|
||||
|
||||
b.on('package', function (pkg) {
|
||||
var file = path.join(pkg.__dirname, 'package.json');
|
||||
watchFile(file);
|
||||
if (pkgcache) pkgcache[file] = pkg;
|
||||
});
|
||||
|
||||
b.on('reset', reset);
|
||||
reset();
|
||||
|
||||
function reset () {
|
||||
var time = null;
|
||||
var bytes = 0;
|
||||
b.pipeline.get('record').on('end', function () {
|
||||
time = Date.now();
|
||||
});
|
||||
|
||||
b.pipeline.get('wrap').push(through(write, end));
|
||||
function write (buf, enc, next) {
|
||||
bytes += buf.length;
|
||||
this.push(buf);
|
||||
next();
|
||||
}
|
||||
function end () {
|
||||
var delta = Date.now() - time;
|
||||
b.emit('time', delta);
|
||||
b.emit('bytes', bytes);
|
||||
b.emit('log', bytes + ' bytes written ('
|
||||
+ (delta / 1000).toFixed(2) + ' seconds)'
|
||||
);
|
||||
this.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
var fwatchers = {};
|
||||
var fwatcherFiles = {};
|
||||
var ignoredFiles = {};
|
||||
|
||||
b.on('transform', function (tr, mfile) {
|
||||
tr.on('file', function (dep) {
|
||||
watchFile(mfile, dep);
|
||||
});
|
||||
});
|
||||
b.on('bundle', function (bundle) {
|
||||
updating = true;
|
||||
bundle.on('error', onend);
|
||||
bundle.on('end', onend);
|
||||
function onend () { updating = false }
|
||||
});
|
||||
|
||||
function watchFile (file, dep) {
|
||||
dep = dep || file;
|
||||
if (ignored) {
|
||||
if (!ignoredFiles.hasOwnProperty(file)) {
|
||||
ignoredFiles[file] = anymatch(ignored, file);
|
||||
}
|
||||
if (ignoredFiles[file]) return;
|
||||
}
|
||||
if (!fwatchers[file]) fwatchers[file] = [];
|
||||
if (!fwatcherFiles[file]) fwatcherFiles[file] = [];
|
||||
if (fwatcherFiles[file].indexOf(dep) >= 0) return;
|
||||
|
||||
var w = b._watcher(dep, wopts);
|
||||
w.setMaxListeners(0);
|
||||
w.on('error', b.emit.bind(b, 'error'));
|
||||
w.on('change', function () {
|
||||
invalidate(file);
|
||||
});
|
||||
fwatchers[file].push(w);
|
||||
fwatcherFiles[file].push(dep);
|
||||
}
|
||||
|
||||
function invalidate (id) {
|
||||
if (cache) delete cache[id];
|
||||
if (pkgcache) delete pkgcache[id];
|
||||
changingDeps[id] = true;
|
||||
|
||||
if (!updating && fwatchers[id]) {
|
||||
fwatchers[id].forEach(function (w) {
|
||||
w.close();
|
||||
});
|
||||
delete fwatchers[id];
|
||||
delete fwatcherFiles[id];
|
||||
}
|
||||
|
||||
// wait for the disk/editor to quiet down first:
|
||||
if (pending) clearTimeout(pending);
|
||||
pending = setTimeout(notify, delay);
|
||||
}
|
||||
|
||||
function notify () {
|
||||
if (updating) {
|
||||
pending = setTimeout(notify, delay);
|
||||
} else {
|
||||
pending = false;
|
||||
b.emit('update', Object.keys(changingDeps));
|
||||
changingDeps = {};
|
||||
}
|
||||
}
|
||||
|
||||
b.close = function () {
|
||||
Object.keys(fwatchers).forEach(function (id) {
|
||||
fwatchers[id].forEach(function (w) { w.close() });
|
||||
});
|
||||
};
|
||||
|
||||
b._watcher = function (file, opts) {
|
||||
return chokidar.watch(file, opts);
|
||||
};
|
||||
|
||||
return b;
|
||||
}
|
317
node_modules/watchify/node_modules/chokidar/CHANGELOG.md
generated
vendored
Normal file
317
node_modules/watchify/node_modules/chokidar/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
# Chokidar 2.1.5 (Mar 22, 2019)
|
||||
* Revert 2.1.3 atomic writing changes.
|
||||
|
||||
# Chokidar 2.1.4 (Mar 22, 2019)
|
||||
* Improve TypeScript type definitions for `on` method.
|
||||
|
||||
# Chokidar 2.1.3 (Mar 22, 2019)
|
||||
* Improve atomic writes handling
|
||||
|
||||
# Chokidar 2.1.2 (Feb 18, 2019)
|
||||
* Add TypeScript type definitions
|
||||
* More fixes for accessTime behavior (#800)
|
||||
|
||||
# Chokidar 2.1.1 (Feb 8, 2019)
|
||||
* Handle simultaneous change of LastAccessTime and ModifiedTime (#793)
|
||||
|
||||
# Chokidar 2.1.0 (Feb 5, 2019)
|
||||
* Ignore accessTime updates caused by read operations (#762).
|
||||
* Updated dependencies. Removed `lodash.debounce`.
|
||||
|
||||
# Chokidar 2.0.4 (Jun 18, 2018)
|
||||
* Prevent watcher.close() from crashing (#730).
|
||||
|
||||
# Chokidar 2.0.3 (Mar 22, 2018)
|
||||
* Fixes an issue that using fd = 0 is not closed in case
|
||||
Windows is used and a `EPERM` error is triggered.
|
||||
|
||||
# Chokidar 2.0.2 (Feb 14, 2018)
|
||||
* Allow semver range updates for upath dependency
|
||||
|
||||
# Chokidar 2.0.1 (Feb 8, 2018)
|
||||
* Fix #668 glob issue on Windows when using `ignore` and `cwd`. Thanks @remy!
|
||||
* Fix #546 possible uncaught exception when using `awaitWriteFinish`.
|
||||
Thanks @dsagal!
|
||||
|
||||
# Chokidar 2.0.0 (Dec 29, 2017)
|
||||
* Breaking: Upgrade globbing dependencies which require globs to be more strict and always use POSIX-style slashes because Windows-style slashes are used as escape sequences
|
||||
* Update tests to work with upgraded globbing dependencies
|
||||
* Add ability to log FSEvents require error by setting `CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR` env
|
||||
* Fix for handling braces in globs
|
||||
* Add node 8 & 9 to CI configs
|
||||
* Allow node 0.10 failures on Windows
|
||||
|
||||
# Chokidar 1.7.0 (May 8, 2017)
|
||||
* Add `disableGlobbing` option
|
||||
* Add ability to force interval value by setting CHOKIDAR_INTERVAL env
|
||||
variable
|
||||
* Fix issue with `.close()` being called before `ready`
|
||||
|
||||
# Chokidar 1.6.0 (Jun 22, 2016)
|
||||
* Added ability for force `usePolling` mode by setting `CHOKIDAR_USEPOLLING`
|
||||
env variable
|
||||
|
||||
# Chokidar 1.5.2 (Jun 7, 2016)
|
||||
* Fix missing `addDir` events when using `cwd` and `alwaysStat` options
|
||||
* Fix missing `add` events for files within a renamed directory
|
||||
|
||||
# Chokidar 1.5.1 (May 20, 2016)
|
||||
* To help prevent exhaustion of FSEvents system limitations, consolidate watch
|
||||
instances to the common parent upon detection of separate watch instances on
|
||||
many siblings
|
||||
|
||||
# Chokidar 1.5.0 (May 10, 2016)
|
||||
* Make debounce delay setting used with `atomic: true` user-customizable
|
||||
* Fixes and improvements to `awaitWriteFinish` features
|
||||
|
||||
# Chokidar 1.4.3 (Feb 26, 2016)
|
||||
* Update async-each dependency to ^1.0.0
|
||||
|
||||
# Chokidar 1.4.2 (Dec 30, 2015)
|
||||
* Now correctly emitting `stats` with `awaitWriteFinish` option.
|
||||
|
||||
# Chokidar 1.4.1 (Dec 9, 2015)
|
||||
* The watcher could now be correctly subclassed with ES6 class syntax.
|
||||
|
||||
# Chokidar 1.4.0 (Dec 3, 2015)
|
||||
* Add `.getWatched()` method, exposing all file system entries being watched
|
||||
* Apply `awaitWriteFinish` methodology to `change` events (in addition to `add`)
|
||||
* Fix handling of symlinks within glob paths (#293)
|
||||
* Fix `addDir` and `unlinkDir` events under globs (#337, #401)
|
||||
* Fix issues with `.unwatch()` (#374, #403)
|
||||
|
||||
# Chokidar 1.3.0 (Nov 18, 2015)
|
||||
* Improve `awaitWriteFinish` option behavior
|
||||
* Fix some `cwd` option behavior on Windows
|
||||
* `awaitWriteFinish` and `cwd` are now compatible
|
||||
* Fix some race conditions.
|
||||
* #379: Recreating deleted directory doesn't trigger event
|
||||
* When adding a previously-deleted file, emit 'add', not 'change'
|
||||
|
||||
# Chokidar 1.2.0 (Oct 1, 2015)
|
||||
* Allow nested arrays of paths to be provided to `.watch()` and `.add()`
|
||||
* Add `awaitWriteFinish` option
|
||||
|
||||
# Chokidar 1.1.0 (Sep 23, 2015)
|
||||
* Dependency updates including fsevents@1.0.0, improving installation
|
||||
|
||||
# Chokidar 1.0.6 (Sep 18, 2015)
|
||||
* Fix issue with `.unwatch()` method and relative paths
|
||||
|
||||
# Chokidar 1.0.5 (Jul 20, 2015)
|
||||
* Fix regression with regexes/fns using in `ignored`
|
||||
|
||||
# Chokidar 1.0.4 (Jul 15, 2015)
|
||||
* Fix bug with `ignored` files/globs while `cwd` option is set
|
||||
|
||||
# Chokidar 1.0.3 (Jun 4, 2015)
|
||||
* Fix race issue with `alwaysStat` option and removed files
|
||||
|
||||
# Chokidar 1.0.2 (May 30, 2015)
|
||||
* Fix bug with absolute paths and ENAMETOOLONG error
|
||||
|
||||
# Chokidar 1.0.1 (Apr 8, 2015)
|
||||
* Fix bug with `.close()` method in `fs.watch` mode with `persistent: false`
|
||||
option
|
||||
|
||||
# Chokidar 1.0.0 (Apr 7, 2015)
|
||||
* Glob support! Use globs in `watch`, `add`, and `unwatch` methods
|
||||
* Comprehensive symlink support
|
||||
* New `unwatch` method to turn off watching of previously watched paths
|
||||
* More flexible `ignored` option allowing regex, function, glob, or array
|
||||
courtesy of [anymatch](https://github.com/es128/anymatch)
|
||||
* New `cwd` option to set base dir from which relative paths are derived
|
||||
* New `depth` option for limiting recursion
|
||||
* New `alwaysStat` option to ensure
|
||||
[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) gets passed
|
||||
with every add/change event
|
||||
* New `ready` event emitted when initial fs tree scan is done and watcher is
|
||||
ready for changes
|
||||
* New `raw` event exposing data and events from the lower-level watch modules
|
||||
* New `followSymlinks` option to impact whether symlinks' targets or the symlink
|
||||
files themselves are watched
|
||||
* New `atomic` option for normalizing artifacts from text editors that use
|
||||
atomic write methods
|
||||
* Ensured watcher's stability with lots of bugfixes.
|
||||
|
||||
# Chokidar 0.12.6 (Jan 6, 2015)
|
||||
* Fix bug which breaks `persistent: false` mode when change events occur
|
||||
|
||||
# Chokidar 0.12.5 (Dec 17, 2014)
|
||||
* Fix bug with matching parent path detection for fsevents instance sharing
|
||||
* Fix bug with ignored watch path in nodefs modes
|
||||
|
||||
# Chokidar 0.12.4 (Dec 14, 2014)
|
||||
* Fix bug in `fs.watch` mode that caused watcher to leak into `cwd`
|
||||
* Fix bug preventing ready event when there are symlinks to ignored paths
|
||||
|
||||
# Chokidar 0.12.3 (Dec 13, 2014)
|
||||
* Fix handling of special files such as named pipes and sockets
|
||||
|
||||
# Chokidar 0.12.2 (Dec 12, 2014)
|
||||
* Fix recursive symlink handling and some other path resolution problems
|
||||
|
||||
# Chokidar 0.12.1 (Dec 10, 2014)
|
||||
* Fix a case where file symlinks were not followed properly
|
||||
|
||||
# Chokidar 0.12.0 (Dec 8, 2014)
|
||||
* Symlink support
|
||||
* Add `followSymlinks` option, which defaults to `true`
|
||||
* Change default watch mode on Linux to non-polling `fs.watch`
|
||||
* Add `atomic` option to normalize events from editors using atomic writes
|
||||
* Particularly Vim and Sublime
|
||||
* Add `raw` event which exposes data from the underlying watch method
|
||||
|
||||
# Chokidar 0.11.1 (Nov 19, 2014)
|
||||
* Fix a bug where an error is thrown when `fs.watch` instantiation fails
|
||||
|
||||
# Chokidar 0.11.0 (Nov 16, 2014)
|
||||
* Add a `ready` event, which is emitted after initial file scan completes
|
||||
* Fix issue with options keys passed in defined as `undefined`
|
||||
* Rename some internal `FSWatcher` properties to indicate they're private
|
||||
|
||||
# Chokidar 0.10.9 (Nov 15, 2014)
|
||||
* Fix some leftover issues from adding watcher reuse
|
||||
|
||||
# Chokidar 0.10.8 (Nov 14, 2014)
|
||||
* Remove accidentally committed/published `console.log` statement.
|
||||
* Sry 'bout that :crying_cat_face:
|
||||
|
||||
# Chokidar 0.10.7 (Nov 14, 2014)
|
||||
* Apply watcher reuse methodology to `fs.watch` and `fs.watchFile` as well
|
||||
|
||||
# Chokidar 0.10.6 (Nov 12, 2014)
|
||||
* More efficient creation/reuse of FSEvents instances to avoid system limits
|
||||
* Reduce simultaneous FSEvents instances allowed in a process
|
||||
* Handle errors thrown by `fs.watch` upon invocation
|
||||
|
||||
# Chokidar 0.10.5 (Nov 6, 2014)
|
||||
* Limit number of simultaneous FSEvents instances (fall back to other methods)
|
||||
* Prevent some cases of EMFILE errors during initialization
|
||||
* Fix ignored files emitting events in some fsevents-mode circumstances
|
||||
|
||||
# Chokidar 0.10.4 (Nov 5, 2014)
|
||||
* Bump fsevents dependency to ~0.3.1
|
||||
* Should resolve build warnings and `npm rebuild` on non-Macs
|
||||
|
||||
# Chokidar 0.10.3 (Oct 28, 2014)
|
||||
* Fix removed dir emitting as `unlink` instead of `unlinkDir`
|
||||
* Fix issues with file changing to dir or vice versa (gh-165)
|
||||
* Fix handling of `ignored` option in fsevents mode
|
||||
|
||||
# Chokidar 0.10.2 (Oct 23, 2014)
|
||||
* Improve individual file watching
|
||||
* Fix fsevents keeping process alive when `persistent: false`
|
||||
|
||||
# Chokidar 0.10.1 (19 October 2014)
|
||||
* Improve handling of text editor atomic writes
|
||||
|
||||
# Chokidar 0.10.0 (Oct 18, 2014)
|
||||
* Many stability and consistency improvements
|
||||
* Resolve many cases of duplicate or wrong events
|
||||
* Correct for fsevents inconsistencies
|
||||
* Standardize handling of errors and relative paths
|
||||
* Fix issues with watching `./`
|
||||
|
||||
# Chokidar 0.9.0 (Sep 25, 2014)
|
||||
* Updated fsevents to 0.3
|
||||
* Update per-system defaults
|
||||
* Fix issues with closing chokidar instance
|
||||
* Fix duplicate change events on win32
|
||||
|
||||
# Chokidar 0.8.2 (Mar 26, 2014)
|
||||
* Fixed npm issues related to fsevents dep.
|
||||
* Updated fsevents to 0.2.
|
||||
|
||||
# Chokidar 0.8.1 (Dec 16, 2013)
|
||||
* Optional deps are now truly optional on windows and
|
||||
linux.
|
||||
* Rewritten in JS, again.
|
||||
* Fixed some FSEvents-related bugs.
|
||||
|
||||
# Chokidar 0.8.0 (Nov 29, 2013)
|
||||
* Added ultra-fast low-CPU OS X file watching with FSEvents.
|
||||
It is enabled by default.
|
||||
* Added `addDir` and `unlinkDir` events.
|
||||
* Polling is now disabled by default on all platforms.
|
||||
|
||||
# Chokidar 0.7.1 (Nov 18, 2013)
|
||||
* `Watcher#close` now also removes all event listeners.
|
||||
|
||||
# Chokidar 0.7.0 (Oct 22, 2013)
|
||||
* When `options.ignored` is two-argument function, it will
|
||||
also be called after stating the FS, with `stats` argument.
|
||||
* `unlink` is no longer emitted on directories.
|
||||
|
||||
# Chokidar 0.6.3 (Aug 12, 2013)
|
||||
* Added `usePolling` option (default: `true`).
|
||||
When `false`, chokidar will use `fs.watch` as backend.
|
||||
`fs.watch` is much faster, but not like super reliable.
|
||||
|
||||
# Chokidar 0.6.2 (Mar 19, 2013)
|
||||
* Fixed watching initially empty directories with `ignoreInitial` option.
|
||||
|
||||
# Chokidar 0.6.1 (Mar 19, 2013)
|
||||
* Added node.js 0.10 support.
|
||||
|
||||
# Chokidar 0.6.0 (Mar 10, 2013)
|
||||
* File attributes (stat()) are now passed to `add` and `change` events as second
|
||||
arguments.
|
||||
* Changed default polling interval for binary files to 300ms.
|
||||
|
||||
# Chokidar 0.5.3 (Jan 13, 2013)
|
||||
* Removed emitting of `change` events before `unlink`.
|
||||
|
||||
# Chokidar 0.5.2 (Jan 13, 2013)
|
||||
* Removed postinstall script to prevent various npm bugs.
|
||||
|
||||
# Chokidar 0.5.1 (Jan 6, 2013)
|
||||
* When starting to watch non-existing paths, chokidar will no longer throw
|
||||
ENOENT error.
|
||||
* Fixed bug with absolute path.
|
||||
|
||||
# Chokidar 0.5.0 (Dec 9, 2012)
|
||||
* Added a bunch of new options:
|
||||
* `ignoreInitial` that allows to ignore initial `add` events.
|
||||
* `ignorePermissionErrors` that allows to ignore ENOENT etc perm errors.
|
||||
* `interval` and `binaryInterval` that allow to change default
|
||||
fs polling intervals.
|
||||
|
||||
# Chokidar 0.4.0 (Jul 26, 2012)
|
||||
* Added `all` event that receives two args (event name and path) that combines
|
||||
`add`, `change` and `unlink` events.
|
||||
* Switched to `fs.watchFile` on node.js 0.8 on windows.
|
||||
* Files are now correctly unwatched after unlink.
|
||||
|
||||
# Chokidar 0.3.0 (Jun 24, 2012)
|
||||
* `unlink` event are no longer emitted for directories, for consistency with
|
||||
`add`.
|
||||
|
||||
# Chokidar 0.2.6 (Jun 8, 2012)
|
||||
* Prevented creating of duplicate 'add' events.
|
||||
|
||||
# Chokidar 0.2.5 (Jun 8, 2012)
|
||||
* Fixed a bug when new files in new directories hadn't been added.
|
||||
|
||||
# Chokidar 0.2.4 (Jun 7, 2012)
|
||||
* Fixed a bug when unlinked files emitted events after unlink.
|
||||
|
||||
# Chokidar 0.2.3 (May 12, 2012)
|
||||
* Fixed watching of files on windows.
|
||||
|
||||
# Chokidar 0.2.2 (May 4, 2012)
|
||||
* Fixed watcher signature.
|
||||
|
||||
# Chokidar 0.2.1 (May 4, 2012)
|
||||
* Fixed invalid API bug when using `watch()`.
|
||||
|
||||
# Chokidar 0.2.0 (May 4, 2012)
|
||||
* Rewritten in js.
|
||||
|
||||
# Chokidar 0.1.1 (Apr 26, 2012)
|
||||
* Changed api to `chokidar.watch()`.
|
||||
* Fixed compilation on windows.
|
||||
|
||||
# Chokidar 0.1.0 (Apr 20, 2012)
|
||||
* Initial release, extracted from
|
||||
[Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)
|
294
node_modules/watchify/node_modules/chokidar/README.md
generated
vendored
Normal file
294
node_modules/watchify/node_modules/chokidar/README.md
generated
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
# Chokidar [](https://github.com/paulmillr/chokidar) [](https://github.com/paulmillr/chokidar) [](https://travis-ci.org/paulmillr/chokidar) [](https://ci.appveyor.com/project/paulmillr/chokidar/branch/master) [](https://coveralls.io/r/paulmillr/chokidar)
|
||||
|
||||
> A neat wrapper around node.js fs.watch / fs.watchFile / FSEvents.
|
||||
|
||||
[](https://www.npmjs.com/package/chokidar)
|
||||
|
||||
## Why?
|
||||
Node.js `fs.watch`:
|
||||
|
||||
* Doesn't report filenames on MacOS.
|
||||
* Doesn't report events at all when using editors like Sublime on MacOS.
|
||||
* Often reports events twice.
|
||||
* Emits most changes as `rename`.
|
||||
* Has [a lot of other issues](https://github.com/nodejs/node/search?q=fs.watch&type=Issues)
|
||||
* Does not provide an easy way to recursively watch file trees.
|
||||
|
||||
Node.js `fs.watchFile`:
|
||||
|
||||
* Almost as bad at event handling.
|
||||
* Also does not provide any recursive watching.
|
||||
* Results in high CPU utilization.
|
||||
|
||||
Chokidar resolves these problems.
|
||||
|
||||
Initially made for **[Brunch](http://brunch.io)** (an ultra-swift web app build tool), it is now used in
|
||||
[gulp](https://github.com/gulpjs/gulp/),
|
||||
[karma](http://karma-runner.github.io),
|
||||
[PM2](https://github.com/Unitech/PM2),
|
||||
[browserify](http://browserify.org/),
|
||||
[webpack](http://webpack.github.io/),
|
||||
[BrowserSync](http://www.browsersync.io/),
|
||||
[Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
|
||||
and [many others](https://www.npmjs.org/browse/depended/chokidar/).
|
||||
It has proven itself in production environments.
|
||||
|
||||
## How?
|
||||
Chokidar does still rely on the Node.js core `fs` module, but when using
|
||||
`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
|
||||
receives, often checking for truth by getting file stats and/or dir contents.
|
||||
|
||||
On MacOS, chokidar by default uses a native extension exposing the Darwin
|
||||
`FSEvents` API. This provides very efficient recursive watching compared with
|
||||
implementations like `kqueue` available on most \*nix platforms. Chokidar still
|
||||
does have to do some work to normalize the events received that way as well.
|
||||
|
||||
On other platforms, the `fs.watch`-based implementation is the default, which
|
||||
avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
|
||||
watchers recursively for everything within scope of the paths that have been
|
||||
specified, so be judicious about not wasting system resources by watching much
|
||||
more than needed.
|
||||
|
||||
## Getting started
|
||||
Install with npm:
|
||||
|
||||
```sh
|
||||
npm install chokidar
|
||||
```
|
||||
|
||||
Then `require` and use it in your code:
|
||||
|
||||
```javascript
|
||||
var chokidar = require('chokidar');
|
||||
|
||||
// One-liner for current directory, ignores .dotfiles
|
||||
chokidar.watch('.', {ignored: /(^|[\/\\])\../}).on('all', (event, path) => {
|
||||
console.log(event, path);
|
||||
});
|
||||
```
|
||||
|
||||
```javascript
|
||||
// Example of a more typical implementation structure:
|
||||
|
||||
// Initialize watcher.
|
||||
var watcher = chokidar.watch('file, dir, glob, or array', {
|
||||
ignored: /(^|[\/\\])\../,
|
||||
persistent: true
|
||||
});
|
||||
|
||||
// Something to use when events are received.
|
||||
var log = console.log.bind(console);
|
||||
// Add event listeners.
|
||||
watcher
|
||||
.on('add', path => log(`File ${path} has been added`))
|
||||
.on('change', path => log(`File ${path} has been changed`))
|
||||
.on('unlink', path => log(`File ${path} has been removed`));
|
||||
|
||||
// More possible events.
|
||||
watcher
|
||||
.on('addDir', path => log(`Directory ${path} has been added`))
|
||||
.on('unlinkDir', path => log(`Directory ${path} has been removed`))
|
||||
.on('error', error => log(`Watcher error: ${error}`))
|
||||
.on('ready', () => log('Initial scan complete. Ready for changes'))
|
||||
.on('raw', (event, path, details) => {
|
||||
log('Raw event info:', event, path, details);
|
||||
});
|
||||
|
||||
// 'add', 'addDir' and 'change' events also receive stat() results as second
|
||||
// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats
|
||||
watcher.on('change', (path, stats) => {
|
||||
if (stats) console.log(`File ${path} changed size to ${stats.size}`);
|
||||
});
|
||||
|
||||
// Watch new files.
|
||||
watcher.add('new-file');
|
||||
watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
|
||||
|
||||
// Get list of actual paths being watched on the filesystem
|
||||
var watchedPaths = watcher.getWatched();
|
||||
|
||||
// Un-watch some files.
|
||||
watcher.unwatch('new-file*');
|
||||
|
||||
// Stop watching.
|
||||
watcher.close();
|
||||
|
||||
// Full list of options. See below for descriptions. (do not use this example)
|
||||
chokidar.watch('file', {
|
||||
persistent: true,
|
||||
|
||||
ignored: '*.txt',
|
||||
ignoreInitial: false,
|
||||
followSymlinks: true,
|
||||
cwd: '.',
|
||||
disableGlobbing: false,
|
||||
|
||||
usePolling: true,
|
||||
interval: 100,
|
||||
binaryInterval: 300,
|
||||
alwaysStat: false,
|
||||
depth: 99,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 2000,
|
||||
pollInterval: 100
|
||||
},
|
||||
|
||||
ignorePermissionErrors: false,
|
||||
atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
`chokidar.watch(paths, [options])`
|
||||
|
||||
* `paths` (string or array of strings). Paths to files, dirs to be watched
|
||||
recursively, or glob patterns.
|
||||
* `options` (object) Options object as defined below:
|
||||
|
||||
#### Persistence
|
||||
|
||||
* `persistent` (default: `true`). Indicates whether the process
|
||||
should continue to run as long as files are being watched. If set to
|
||||
`false` when using `fsevents` to watch, no more events will be emitted
|
||||
after `ready`, even if the process continues to run.
|
||||
|
||||
#### Path filtering
|
||||
|
||||
* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
|
||||
Defines files/paths to be ignored. The whole relative or absolute path is
|
||||
tested, not just filename. If a function with two arguments is provided, it
|
||||
gets called twice per path - once with a single argument (the path), second
|
||||
time with two arguments (the path and the
|
||||
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object of that path).
|
||||
* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while
|
||||
instantiating the watching as chokidar discovers these file paths (before the `ready` event).
|
||||
* `followSymlinks` (default: `true`). When `false`, only the
|
||||
symlinks themselves will be watched for changes instead of following
|
||||
the link references and bubbling events through the link's path.
|
||||
* `cwd` (no default). The base directory from which watch `paths` are to be
|
||||
derived. Paths emitted with events will be relative to this.
|
||||
* `disableGlobbing` (default: `false`). If set to `true` then the strings passed to `.watch()` and `.add()` are treated as
|
||||
literal path names, even if they look like globs.
|
||||
|
||||
#### Performance
|
||||
|
||||
* `usePolling` (default: `false`).
|
||||
Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
|
||||
leads to high CPU utilization, consider setting this to `false`. It is
|
||||
typically necessary to **set this to `true` to successfully watch files over
|
||||
a network**, and it may be necessary to successfully watch files in other
|
||||
non-standard situations. Setting to `true` explicitly on MacOS overrides the
|
||||
`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
|
||||
to true (1) or false (0) in order to override this option.
|
||||
* _Polling-specific settings_ (effective when `usePolling: true`)
|
||||
* `interval` (default: `100`). Interval of file system polling. You may also
|
||||
set the CHOKIDAR_INTERVAL env variable to override this option.
|
||||
* `binaryInterval` (default: `300`). Interval of file system
|
||||
polling for binary files.
|
||||
([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
|
||||
* `useFsEvents` (default: `true` on MacOS). Whether to use the
|
||||
`fsevents` watching interface if available. When set to `true` explicitly
|
||||
and `fsevents` is available this supercedes the `usePolling` setting. When
|
||||
set to `false` on MacOS, `usePolling: true` becomes the default.
|
||||
* `alwaysStat` (default: `false`). If relying upon the
|
||||
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object that may get passed with `add`, `addDir`, and `change` events, set
|
||||
this to `true` to ensure it is provided even in cases where it wasn't
|
||||
already available from the underlying watch events.
|
||||
* `depth` (default: `undefined`). If set, limits how many levels of
|
||||
subdirectories will be traversed.
|
||||
* `awaitWriteFinish` (default: `false`).
|
||||
By default, the `add` event will fire when a file first appears on disk, before
|
||||
the entire file has been written. Furthermore, in some cases some `change`
|
||||
events will be emitted while the file is being written. In some cases,
|
||||
especially when watching for large files there will be a need to wait for the
|
||||
write operation to finish before responding to a file creation or modification.
|
||||
Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
|
||||
holding its `add` and `change` events until the size does not change for a
|
||||
configurable amount of time. The appropriate duration setting is heavily
|
||||
dependent on the OS and hardware. For accurate detection this parameter should
|
||||
be relatively high, making file watching much less responsive.
|
||||
Use with caution.
|
||||
* *`options.awaitWriteFinish` can be set to an object in order to adjust
|
||||
timing params:*
|
||||
* `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
|
||||
milliseconds for a file size to remain constant before emitting its event.
|
||||
* `awaitWriteFinish.pollInterval` (default: 100). File size polling interval.
|
||||
|
||||
#### Errors
|
||||
* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
|
||||
that don't have read permissions if possible. If watching fails due to `EPERM`
|
||||
or `EACCES` with this set to `true`, the errors will be suppressed silently.
|
||||
* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
|
||||
Automatically filters out artifacts that occur when using editors that use
|
||||
"atomic writes" instead of writing directly to the source file. If a file is
|
||||
re-added within 100 ms of being deleted, Chokidar emits a `change` event
|
||||
rather than `unlink` then `add`. If the default of 100 ms does not work well
|
||||
for you, you can override it by setting `atomic` to a custom value, in
|
||||
milliseconds.
|
||||
|
||||
### Methods & Events
|
||||
|
||||
`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
|
||||
|
||||
* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
|
||||
Takes an array of strings or just one string.
|
||||
* `.on(event, callback)`: Listen for an FS event.
|
||||
Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
|
||||
`raw`, `error`.
|
||||
Additionally `all` is available which gets emitted with the underlying event
|
||||
name and path for every event other than `ready`, `raw`, and `error`.
|
||||
* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
|
||||
Takes an array of strings or just one string.
|
||||
* `.close()`: Removes all listeners from watched files.
|
||||
* `.getWatched()`: Returns an object representing all the paths on the file
|
||||
system being watched by this `FSWatcher` instance. The object's keys are all the
|
||||
directories (using absolute paths unless the `cwd` option was used), and the
|
||||
values are arrays of the names of the items contained in each directory.
|
||||
|
||||
## CLI
|
||||
|
||||
If you need a CLI interface for your file watching, check out
|
||||
[chokidar-cli](https://github.com/kimmobrunfeldt/chokidar-cli), allowing you to
|
||||
execute a command on each change, or get a stdio stream of change events.
|
||||
|
||||
## Install Troubleshooting
|
||||
|
||||
* `npm WARN optional dep failed, continuing fsevents@n.n.n`
|
||||
* This message is normal part of how `npm` handles optional dependencies and is
|
||||
not indicative of a problem. Even if accompanied by other related error messages,
|
||||
Chokidar should function properly.
|
||||
|
||||
* `ERR! stack Error: Python executable "python" is v3.4.1, which is not supported by gyp.`
|
||||
* You should be able to resolve this by installing python 2.7 and running:
|
||||
`npm config set python python2.7`
|
||||
|
||||
* `gyp ERR! stack Error: not found: make`
|
||||
* On Mac, install the XCode command-line tools
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com) & Elan Shanker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
747
node_modules/watchify/node_modules/chokidar/index.js
generated
vendored
Normal file
747
node_modules/watchify/node_modules/chokidar/index.js
generated
vendored
Normal file
@@ -0,0 +1,747 @@
|
||||
'use strict';
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var asyncEach = require('async-each');
|
||||
var anymatch = require('anymatch');
|
||||
var globParent = require('glob-parent');
|
||||
var isGlob = require('is-glob');
|
||||
var isAbsolute = require('path-is-absolute');
|
||||
var inherits = require('inherits');
|
||||
var braces = require('braces');
|
||||
var normalizePath = require('normalize-path');
|
||||
var upath = require('upath');
|
||||
|
||||
var NodeFsHandler = require('./lib/nodefs-handler');
|
||||
var FsEventsHandler = require('./lib/fsevents-handler');
|
||||
|
||||
var arrify = function(value) {
|
||||
if (value == null) return [];
|
||||
return Array.isArray(value) ? value : [value];
|
||||
};
|
||||
|
||||
var flatten = function(list, result) {
|
||||
if (result == null) result = [];
|
||||
list.forEach(function(item) {
|
||||
if (Array.isArray(item)) {
|
||||
flatten(item, result);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Little isString util for use in Array#every.
|
||||
var isString = function(thing) {
|
||||
return typeof thing === 'string';
|
||||
};
|
||||
|
||||
// Public: Main class.
|
||||
// Watches files & directories for changes.
|
||||
//
|
||||
// * _opts - object, chokidar options hash
|
||||
//
|
||||
// Emitted events:
|
||||
// `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// var watcher = new FSWatcher()
|
||||
// .add(directories)
|
||||
// .on('add', path => console.log('File', path, 'was added'))
|
||||
// .on('change', path => console.log('File', path, 'was changed'))
|
||||
// .on('unlink', path => console.log('File', path, 'was removed'))
|
||||
// .on('all', (event, path) => console.log(path, ' emitted ', event))
|
||||
//
|
||||
function FSWatcher(_opts) {
|
||||
EventEmitter.call(this);
|
||||
var opts = {};
|
||||
// in case _opts that is passed in is a frozen object
|
||||
if (_opts) for (var opt in _opts) opts[opt] = _opts[opt];
|
||||
this._watched = Object.create(null);
|
||||
this._closers = Object.create(null);
|
||||
this._ignoredPaths = Object.create(null);
|
||||
Object.defineProperty(this, '_globIgnored', {
|
||||
get: function() { return Object.keys(this._ignoredPaths); }
|
||||
});
|
||||
this.closed = false;
|
||||
this._throttled = Object.create(null);
|
||||
this._symlinkPaths = Object.create(null);
|
||||
|
||||
function undef(key) {
|
||||
return opts[key] === undefined;
|
||||
}
|
||||
|
||||
// Set up default options.
|
||||
if (undef('persistent')) opts.persistent = true;
|
||||
if (undef('ignoreInitial')) opts.ignoreInitial = false;
|
||||
if (undef('ignorePermissionErrors')) opts.ignorePermissionErrors = false;
|
||||
if (undef('interval')) opts.interval = 100;
|
||||
if (undef('binaryInterval')) opts.binaryInterval = 300;
|
||||
if (undef('disableGlobbing')) opts.disableGlobbing = false;
|
||||
this.enableBinaryInterval = opts.binaryInterval !== opts.interval;
|
||||
|
||||
// Enable fsevents on OS X when polling isn't explicitly enabled.
|
||||
if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;
|
||||
|
||||
// If we can't use fsevents, ensure the options reflect it's disabled.
|
||||
if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
|
||||
|
||||
// Use polling on Mac if not using fsevents.
|
||||
// Other platforms use non-polling fs.watch.
|
||||
if (undef('usePolling') && !opts.useFsEvents) {
|
||||
opts.usePolling = process.platform === 'darwin';
|
||||
}
|
||||
|
||||
// Global override (useful for end-developers that need to force polling for all
|
||||
// instances of chokidar, regardless of usage/dependency depth)
|
||||
var envPoll = process.env.CHOKIDAR_USEPOLLING;
|
||||
if (envPoll !== undefined) {
|
||||
var envLower = envPoll.toLowerCase();
|
||||
|
||||
if (envLower === 'false' || envLower === '0') {
|
||||
opts.usePolling = false;
|
||||
} else if (envLower === 'true' || envLower === '1') {
|
||||
opts.usePolling = true;
|
||||
} else {
|
||||
opts.usePolling = !!envLower
|
||||
}
|
||||
}
|
||||
var envInterval = process.env.CHOKIDAR_INTERVAL;
|
||||
if (envInterval) {
|
||||
opts.interval = parseInt(envInterval);
|
||||
}
|
||||
|
||||
// Editor atomic write normalization enabled by default with fs.watch
|
||||
if (undef('atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
|
||||
if (opts.atomic) this._pendingUnlinks = Object.create(null);
|
||||
|
||||
if (undef('followSymlinks')) opts.followSymlinks = true;
|
||||
|
||||
if (undef('awaitWriteFinish')) opts.awaitWriteFinish = false;
|
||||
if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
|
||||
var awf = opts.awaitWriteFinish;
|
||||
if (awf) {
|
||||
if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
|
||||
if (!awf.pollInterval) awf.pollInterval = 100;
|
||||
|
||||
this._pendingWrites = Object.create(null);
|
||||
}
|
||||
if (opts.ignored) opts.ignored = arrify(opts.ignored);
|
||||
|
||||
this._isntIgnored = function(path, stat) {
|
||||
return !this._isIgnored(path, stat);
|
||||
}.bind(this);
|
||||
|
||||
var readyCalls = 0;
|
||||
this._emitReady = function() {
|
||||
if (++readyCalls >= this._readyCount) {
|
||||
this._emitReady = Function.prototype;
|
||||
this._readyEmitted = true;
|
||||
// use process.nextTick to allow time for listener to be bound
|
||||
process.nextTick(this.emit.bind(this, 'ready'));
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
this.options = opts;
|
||||
|
||||
// You’re frozen when your heart’s not open.
|
||||
Object.freeze(opts);
|
||||
}
|
||||
|
||||
inherits(FSWatcher, EventEmitter);
|
||||
|
||||
// Common helpers
|
||||
// --------------
|
||||
|
||||
// Private method: Normalize and emit events
|
||||
//
|
||||
// * event - string, type of event
|
||||
// * path - string, file or directory path
|
||||
// * val[1..3] - arguments to be passed with event
|
||||
//
|
||||
// Returns the error if defined, otherwise the value of the
|
||||
// FSWatcher instance's `closed` flag
|
||||
FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
|
||||
if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
|
||||
var args = [event, path];
|
||||
if (val3 !== undefined) args.push(val1, val2, val3);
|
||||
else if (val2 !== undefined) args.push(val1, val2);
|
||||
else if (val1 !== undefined) args.push(val1);
|
||||
|
||||
var awf = this.options.awaitWriteFinish;
|
||||
if (awf && this._pendingWrites[path]) {
|
||||
this._pendingWrites[path].lastChange = new Date();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (this.options.atomic) {
|
||||
if (event === 'unlink') {
|
||||
this._pendingUnlinks[path] = args;
|
||||
setTimeout(function() {
|
||||
Object.keys(this._pendingUnlinks).forEach(function(path) {
|
||||
this.emit.apply(this, this._pendingUnlinks[path]);
|
||||
this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
|
||||
delete this._pendingUnlinks[path];
|
||||
}.bind(this));
|
||||
}.bind(this), typeof this.options.atomic === "number"
|
||||
? this.options.atomic
|
||||
: 100);
|
||||
return this;
|
||||
} else if (event === 'add' && this._pendingUnlinks[path]) {
|
||||
event = args[0] = 'change';
|
||||
delete this._pendingUnlinks[path];
|
||||
}
|
||||
}
|
||||
|
||||
var emitEvent = function() {
|
||||
this.emit.apply(this, args);
|
||||
if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
|
||||
}.bind(this);
|
||||
|
||||
if (awf && (event === 'add' || event === 'change') && this._readyEmitted) {
|
||||
var awfEmit = function(err, stats) {
|
||||
if (err) {
|
||||
event = args[0] = 'error';
|
||||
args[1] = err;
|
||||
emitEvent();
|
||||
} else if (stats) {
|
||||
// if stats doesn't exist the file must have been deleted
|
||||
if (args.length > 2) {
|
||||
args[2] = stats;
|
||||
} else {
|
||||
args.push(stats);
|
||||
}
|
||||
emitEvent();
|
||||
}
|
||||
};
|
||||
|
||||
this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (event === 'change') {
|
||||
if (!this._throttle('change', path, 50)) return this;
|
||||
}
|
||||
|
||||
if (
|
||||
this.options.alwaysStat && val1 === undefined &&
|
||||
(event === 'add' || event === 'addDir' || event === 'change')
|
||||
) {
|
||||
var fullPath = this.options.cwd ? sysPath.join(this.options.cwd, path) : path;
|
||||
fs.stat(fullPath, function(error, stats) {
|
||||
// Suppress event when fs.stat fails, to avoid sending undefined 'stat'
|
||||
if (error || !stats) return;
|
||||
|
||||
args.push(stats);
|
||||
emitEvent();
|
||||
});
|
||||
} else {
|
||||
emitEvent();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Private method: Common handler for errors
|
||||
//
|
||||
// * error - object, Error instance
|
||||
//
|
||||
// Returns the error if defined, otherwise the value of the
|
||||
// FSWatcher instance's `closed` flag
|
||||
FSWatcher.prototype._handleError = function(error) {
|
||||
var code = error && error.code;
|
||||
var ipe = this.options.ignorePermissionErrors;
|
||||
if (error &&
|
||||
code !== 'ENOENT' &&
|
||||
code !== 'ENOTDIR' &&
|
||||
(!ipe || (code !== 'EPERM' && code !== 'EACCES'))
|
||||
) this.emit('error', error);
|
||||
return error || this.closed;
|
||||
};
|
||||
|
||||
// Private method: Helper utility for throttling
|
||||
//
|
||||
// * action - string, type of action being throttled
|
||||
// * path - string, path being acted upon
|
||||
// * timeout - int, duration of time to suppress duplicate actions
|
||||
//
|
||||
// Returns throttle tracking object or false if action should be suppressed
|
||||
FSWatcher.prototype._throttle = function(action, path, timeout) {
|
||||
if (!(action in this._throttled)) {
|
||||
this._throttled[action] = Object.create(null);
|
||||
}
|
||||
var throttled = this._throttled[action];
|
||||
if (path in throttled) {
|
||||
throttled[path].count++;
|
||||
return false;
|
||||
}
|
||||
function clear() {
|
||||
var count = throttled[path] ? throttled[path].count : 0;
|
||||
delete throttled[path];
|
||||
clearTimeout(timeoutObject);
|
||||
return count;
|
||||
}
|
||||
var timeoutObject = setTimeout(clear, timeout);
|
||||
throttled[path] = {timeoutObject: timeoutObject, clear: clear, count: 0};
|
||||
return throttled[path];
|
||||
};
|
||||
|
||||
// Private method: Awaits write operation to finish
|
||||
//
|
||||
// * path - string, path being acted upon
|
||||
// * threshold - int, time in milliseconds a file size must be fixed before
|
||||
// acknowledging write operation is finished
|
||||
// * awfEmit - function, to be called when ready for event to be emitted
|
||||
// Polls a newly created file for size variations. When files size does not
|
||||
// change for 'threshold' milliseconds calls callback.
|
||||
FSWatcher.prototype._awaitWriteFinish = function(path, threshold, event, awfEmit) {
|
||||
var timeoutHandler;
|
||||
|
||||
var fullPath = path;
|
||||
if (this.options.cwd && !isAbsolute(path)) {
|
||||
fullPath = sysPath.join(this.options.cwd, path);
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
|
||||
var awaitWriteFinish = (function (prevStat) {
|
||||
fs.stat(fullPath, function(err, curStat) {
|
||||
if (err || !(path in this._pendingWrites)) {
|
||||
if (err && err.code !== 'ENOENT') awfEmit(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
|
||||
if (prevStat && curStat.size != prevStat.size) {
|
||||
this._pendingWrites[path].lastChange = now;
|
||||
}
|
||||
|
||||
if (now - this._pendingWrites[path].lastChange >= threshold) {
|
||||
delete this._pendingWrites[path];
|
||||
awfEmit(null, curStat);
|
||||
} else {
|
||||
timeoutHandler = setTimeout(
|
||||
awaitWriteFinish.bind(this, curStat),
|
||||
this.options.awaitWriteFinish.pollInterval
|
||||
);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
if (!(path in this._pendingWrites)) {
|
||||
this._pendingWrites[path] = {
|
||||
lastChange: now,
|
||||
cancelWait: function() {
|
||||
delete this._pendingWrites[path];
|
||||
clearTimeout(timeoutHandler);
|
||||
return event;
|
||||
}.bind(this)
|
||||
};
|
||||
timeoutHandler = setTimeout(
|
||||
awaitWriteFinish.bind(this),
|
||||
this.options.awaitWriteFinish.pollInterval
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Private method: Determines whether user has asked to ignore this path
|
||||
//
|
||||
// * path - string, path to file or directory
|
||||
// * stats - object, result of fs.stat
|
||||
//
|
||||
// Returns boolean
|
||||
var dotRe = /\..*\.(sw[px])$|\~$|\.subl.*\.tmp/;
|
||||
FSWatcher.prototype._isIgnored = function(path, stats) {
|
||||
if (this.options.atomic && dotRe.test(path)) return true;
|
||||
|
||||
if (!this._userIgnored) {
|
||||
var cwd = this.options.cwd;
|
||||
var ignored = this.options.ignored;
|
||||
if (cwd && ignored) {
|
||||
ignored = ignored.map(function (path) {
|
||||
if (typeof path !== 'string') return path;
|
||||
return upath.normalize(isAbsolute(path) ? path : sysPath.join(cwd, path));
|
||||
});
|
||||
}
|
||||
var paths = arrify(ignored)
|
||||
.filter(function(path) {
|
||||
return typeof path === 'string' && !isGlob(path);
|
||||
}).map(function(path) {
|
||||
return path + '/**';
|
||||
});
|
||||
this._userIgnored = anymatch(
|
||||
this._globIgnored.concat(ignored).concat(paths)
|
||||
);
|
||||
}
|
||||
|
||||
return this._userIgnored([path, stats]);
|
||||
};
|
||||
|
||||
// Private method: Provides a set of common helpers and properties relating to
|
||||
// symlink and glob handling
|
||||
//
|
||||
// * path - string, file, directory, or glob pattern being watched
|
||||
// * depth - int, at any depth > 0, this isn't a glob
|
||||
//
|
||||
// Returns object containing helpers for this path
|
||||
var replacerRe = /^\.[\/\\]/;
|
||||
FSWatcher.prototype._getWatchHelpers = function(path, depth) {
|
||||
path = path.replace(replacerRe, '');
|
||||
var watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
|
||||
var fullWatchPath = sysPath.resolve(watchPath);
|
||||
var hasGlob = watchPath !== path;
|
||||
var globFilter = hasGlob ? anymatch(path) : false;
|
||||
var follow = this.options.followSymlinks;
|
||||
var globSymlink = hasGlob && follow ? null : false;
|
||||
|
||||
var checkGlobSymlink = function(entry) {
|
||||
// only need to resolve once
|
||||
// first entry should always have entry.parentDir === ''
|
||||
if (globSymlink == null) {
|
||||
globSymlink = entry.fullParentDir === fullWatchPath ? false : {
|
||||
realPath: entry.fullParentDir,
|
||||
linkPath: fullWatchPath
|
||||
};
|
||||
}
|
||||
|
||||
if (globSymlink) {
|
||||
return entry.fullPath.replace(globSymlink.realPath, globSymlink.linkPath);
|
||||
}
|
||||
|
||||
return entry.fullPath;
|
||||
};
|
||||
|
||||
var entryPath = function(entry) {
|
||||
return sysPath.join(watchPath,
|
||||
sysPath.relative(watchPath, checkGlobSymlink(entry))
|
||||
);
|
||||
};
|
||||
|
||||
var filterPath = function(entry) {
|
||||
if (entry.stat && entry.stat.isSymbolicLink()) return filterDir(entry);
|
||||
var resolvedPath = entryPath(entry);
|
||||
return (!hasGlob || globFilter(resolvedPath)) &&
|
||||
this._isntIgnored(resolvedPath, entry.stat) &&
|
||||
(this.options.ignorePermissionErrors ||
|
||||
this._hasReadPermissions(entry.stat));
|
||||
}.bind(this);
|
||||
|
||||
var getDirParts = function(path) {
|
||||
if (!hasGlob) return false;
|
||||
var parts = [];
|
||||
var expandedPath = braces.expand(path);
|
||||
expandedPath.forEach(function(path) {
|
||||
parts.push(sysPath.relative(watchPath, path).split(/[\/\\]/));
|
||||
});
|
||||
return parts;
|
||||
};
|
||||
|
||||
var dirParts = getDirParts(path);
|
||||
if (dirParts) {
|
||||
dirParts.forEach(function(parts) {
|
||||
if (parts.length > 1) parts.pop();
|
||||
});
|
||||
}
|
||||
var unmatchedGlob;
|
||||
|
||||
var filterDir = function(entry) {
|
||||
if (hasGlob) {
|
||||
var entryParts = getDirParts(checkGlobSymlink(entry));
|
||||
var globstar = false;
|
||||
unmatchedGlob = !dirParts.some(function(parts) {
|
||||
return parts.every(function(part, i) {
|
||||
if (part === '**') globstar = true;
|
||||
return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i]);
|
||||
});
|
||||
});
|
||||
}
|
||||
return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat);
|
||||
}.bind(this);
|
||||
|
||||
return {
|
||||
followSymlinks: follow,
|
||||
statMethod: follow ? 'stat' : 'lstat',
|
||||
path: path,
|
||||
watchPath: watchPath,
|
||||
entryPath: entryPath,
|
||||
hasGlob: hasGlob,
|
||||
globFilter: globFilter,
|
||||
filterPath: filterPath,
|
||||
filterDir: filterDir
|
||||
};
|
||||
};
|
||||
|
||||
// Directory helpers
|
||||
// -----------------
|
||||
|
||||
// Private method: Provides directory tracking objects
|
||||
//
|
||||
// * directory - string, path of the directory
|
||||
//
|
||||
// Returns the directory's tracking object
|
||||
FSWatcher.prototype._getWatchedDir = function(directory) {
|
||||
var dir = sysPath.resolve(directory);
|
||||
var watcherRemove = this._remove.bind(this);
|
||||
if (!(dir in this._watched)) this._watched[dir] = {
|
||||
_items: Object.create(null),
|
||||
add: function(item) {
|
||||
if (item !== '.' && item !== '..') this._items[item] = true;
|
||||
},
|
||||
remove: function(item) {
|
||||
delete this._items[item];
|
||||
if (!this.children().length) {
|
||||
fs.readdir(dir, function(err) {
|
||||
if (err) watcherRemove(sysPath.dirname(dir), sysPath.basename(dir));
|
||||
});
|
||||
}
|
||||
},
|
||||
has: function(item) {return item in this._items;},
|
||||
children: function() {return Object.keys(this._items);}
|
||||
};
|
||||
return this._watched[dir];
|
||||
};
|
||||
|
||||
// File helpers
|
||||
// ------------
|
||||
|
||||
// Private method: Check for read permissions
|
||||
// Based on this answer on SO: http://stackoverflow.com/a/11781404/1358405
|
||||
//
|
||||
// * stats - object, result of fs.stat
|
||||
//
|
||||
// Returns boolean
|
||||
FSWatcher.prototype._hasReadPermissions = function(stats) {
|
||||
return Boolean(4 & parseInt(((stats && stats.mode) & 0x1ff).toString(8)[0], 10));
|
||||
};
|
||||
|
||||
// Private method: Handles emitting unlink events for
|
||||
// files and directories, and via recursion, for
|
||||
// files and directories within directories that are unlinked
|
||||
//
|
||||
// * directory - string, directory within which the following item is located
|
||||
// * item - string, base path of item/directory
|
||||
//
|
||||
// Returns nothing
|
||||
FSWatcher.prototype._remove = function(directory, item) {
|
||||
// if what is being deleted is a directory, get that directory's paths
|
||||
// for recursive deleting and cleaning of watched object
|
||||
// if it is not a directory, nestedDirectoryChildren will be empty array
|
||||
var path = sysPath.join(directory, item);
|
||||
var fullPath = sysPath.resolve(path);
|
||||
var isDirectory = this._watched[path] || this._watched[fullPath];
|
||||
|
||||
// prevent duplicate handling in case of arriving here nearly simultaneously
|
||||
// via multiple paths (such as _handleFile and _handleDir)
|
||||
if (!this._throttle('remove', path, 100)) return;
|
||||
|
||||
// if the only watched file is removed, watch for its return
|
||||
var watchedDirs = Object.keys(this._watched);
|
||||
if (!isDirectory && !this.options.useFsEvents && watchedDirs.length === 1) {
|
||||
this.add(directory, item, true);
|
||||
}
|
||||
|
||||
// This will create a new entry in the watched object in either case
|
||||
// so we got to do the directory check beforehand
|
||||
var nestedDirectoryChildren = this._getWatchedDir(path).children();
|
||||
|
||||
// Recursively remove children directories / files.
|
||||
nestedDirectoryChildren.forEach(function(nestedItem) {
|
||||
this._remove(path, nestedItem);
|
||||
}, this);
|
||||
|
||||
// Check if item was on the watched list and remove it
|
||||
var parent = this._getWatchedDir(directory);
|
||||
var wasTracked = parent.has(item);
|
||||
parent.remove(item);
|
||||
|
||||
// If we wait for this file to be fully written, cancel the wait.
|
||||
var relPath = path;
|
||||
if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
|
||||
if (this.options.awaitWriteFinish && this._pendingWrites[relPath]) {
|
||||
var event = this._pendingWrites[relPath].cancelWait();
|
||||
if (event === 'add') return;
|
||||
}
|
||||
|
||||
// The Entry will either be a directory that just got removed
|
||||
// or a bogus entry to a file, in either case we have to remove it
|
||||
delete this._watched[path];
|
||||
delete this._watched[fullPath];
|
||||
var eventName = isDirectory ? 'unlinkDir' : 'unlink';
|
||||
if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
|
||||
|
||||
// Avoid conflicts if we later create another file with the same name
|
||||
if (!this.options.useFsEvents) {
|
||||
this._closePath(path);
|
||||
}
|
||||
};
|
||||
|
||||
FSWatcher.prototype._closePath = function(path) {
|
||||
if (!this._closers[path]) return;
|
||||
this._closers[path].forEach(function(closer) {
|
||||
closer();
|
||||
});
|
||||
delete this._closers[path];
|
||||
this._getWatchedDir(sysPath.dirname(path)).remove(sysPath.basename(path));
|
||||
}
|
||||
|
||||
// Public method: Adds paths to be watched on an existing FSWatcher instance
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
// * _origAdd - private boolean, for handling non-existent paths to be watched
|
||||
// * _internal - private boolean, indicates a non-user add
|
||||
|
||||
// Returns an instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.add = function(paths, _origAdd, _internal) {
|
||||
var disableGlobbing = this.options.disableGlobbing;
|
||||
var cwd = this.options.cwd;
|
||||
this.closed = false;
|
||||
paths = flatten(arrify(paths));
|
||||
|
||||
if (!paths.every(isString)) {
|
||||
throw new TypeError('Non-string provided as watch path: ' + paths);
|
||||
}
|
||||
|
||||
if (cwd) paths = paths.map(function(path) {
|
||||
var absPath;
|
||||
if (isAbsolute(path)) {
|
||||
absPath = path;
|
||||
} else if (path[0] === '!') {
|
||||
absPath = '!' + sysPath.join(cwd, path.substring(1));
|
||||
} else {
|
||||
absPath = sysPath.join(cwd, path);
|
||||
}
|
||||
|
||||
// Check `path` instead of `absPath` because the cwd portion can't be a glob
|
||||
if (disableGlobbing || !isGlob(path)) {
|
||||
return absPath;
|
||||
} else {
|
||||
return normalizePath(absPath);
|
||||
}
|
||||
});
|
||||
|
||||
// set aside negated glob strings
|
||||
paths = paths.filter(function(path) {
|
||||
if (path[0] === '!') {
|
||||
this._ignoredPaths[path.substring(1)] = true;
|
||||
} else {
|
||||
// if a path is being added that was previously ignored, stop ignoring it
|
||||
delete this._ignoredPaths[path];
|
||||
delete this._ignoredPaths[path + '/**'];
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (this.options.useFsEvents && FsEventsHandler.canUse()) {
|
||||
if (!this._readyCount) this._readyCount = paths.length;
|
||||
if (this.options.persistent) this._readyCount *= 2;
|
||||
paths.forEach(this._addToFsEvents, this);
|
||||
} else {
|
||||
if (!this._readyCount) this._readyCount = 0;
|
||||
this._readyCount += paths.length;
|
||||
asyncEach(paths, function(path, next) {
|
||||
this._addToNodeFs(path, !_internal, 0, 0, _origAdd, function(err, res) {
|
||||
if (res) this._emitReady();
|
||||
next(err, res);
|
||||
}.bind(this));
|
||||
}.bind(this), function(error, results) {
|
||||
results.forEach(function(item) {
|
||||
if (!item || this.closed) return;
|
||||
this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
|
||||
}, this);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Public method: Close watchers or start ignoring events from specified paths.
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
|
||||
// Returns instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.unwatch = function(paths) {
|
||||
if (this.closed) return this;
|
||||
paths = flatten(arrify(paths));
|
||||
|
||||
paths.forEach(function(path) {
|
||||
// convert to absolute path unless relative path already matches
|
||||
if (!isAbsolute(path) && !this._closers[path]) {
|
||||
if (this.options.cwd) path = sysPath.join(this.options.cwd, path);
|
||||
path = sysPath.resolve(path);
|
||||
}
|
||||
|
||||
this._closePath(path);
|
||||
|
||||
this._ignoredPaths[path] = true;
|
||||
if (path in this._watched) {
|
||||
this._ignoredPaths[path + '/**'] = true;
|
||||
}
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = null;
|
||||
}, this);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Public method: Close watchers and remove all listeners from watched paths.
|
||||
|
||||
// Returns instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.close = function() {
|
||||
if (this.closed) return this;
|
||||
|
||||
this.closed = true;
|
||||
Object.keys(this._closers).forEach(function(watchPath) {
|
||||
this._closers[watchPath].forEach(function(closer) {
|
||||
closer();
|
||||
});
|
||||
delete this._closers[watchPath];
|
||||
}, this);
|
||||
this._watched = Object.create(null);
|
||||
|
||||
this.removeAllListeners();
|
||||
return this;
|
||||
};
|
||||
|
||||
// Public method: Expose list of watched paths
|
||||
|
||||
// Returns object w/ dir paths as keys and arrays of contained paths as values.
|
||||
FSWatcher.prototype.getWatched = function() {
|
||||
var watchList = {};
|
||||
Object.keys(this._watched).forEach(function(dir) {
|
||||
var key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
|
||||
watchList[key || '.'] = Object.keys(this._watched[dir]._items).sort();
|
||||
}.bind(this));
|
||||
return watchList;
|
||||
};
|
||||
|
||||
// Attach watch handler prototype methods
|
||||
function importHandler(handler) {
|
||||
Object.keys(handler.prototype).forEach(function(method) {
|
||||
FSWatcher.prototype[method] = handler.prototype[method];
|
||||
});
|
||||
}
|
||||
importHandler(NodeFsHandler);
|
||||
if (FsEventsHandler.canUse()) importHandler(FsEventsHandler);
|
||||
|
||||
// Export FSWatcher class
|
||||
exports.FSWatcher = FSWatcher;
|
||||
|
||||
// Public function: Instantiates watcher with paths to be tracked.
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
// * options - object, chokidar options
|
||||
|
||||
// Returns an instance of FSWatcher for chaining.
|
||||
exports.watch = function(paths, options) {
|
||||
return new FSWatcher(options).add(paths);
|
||||
};
|
412
node_modules/watchify/node_modules/chokidar/lib/fsevents-handler.js
generated
vendored
Normal file
412
node_modules/watchify/node_modules/chokidar/lib/fsevents-handler.js
generated
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var readdirp = require('readdirp');
|
||||
var fsevents;
|
||||
try { fsevents = require('fsevents'); } catch (error) {
|
||||
if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error)
|
||||
}
|
||||
|
||||
// fsevents instance helper functions
|
||||
|
||||
// object to hold per-process fsevents instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FSEventsWatchers = Object.create(null);
|
||||
|
||||
// Threshold of duplicate path prefixes at which to start
|
||||
// consolidating going forward
|
||||
var consolidateThreshhold = 10;
|
||||
|
||||
// Private function: Instantiates the fsevents interface
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * callback - function, called when fsevents is bound and ready
|
||||
|
||||
// Returns new fsevents instance
|
||||
function createFSEventsInstance(path, callback) {
|
||||
return (new fsevents(path)).on('fsevent', callback).start();
|
||||
}
|
||||
|
||||
// Private function: Instantiates the fsevents interface or binds listeners
|
||||
// to an existing one covering the same file tree
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * realPath - string, real path (in case of symlinks)
|
||||
// * listener - function, called when fsevents emits events
|
||||
// * rawEmitter - function, passes data to listeners of the 'raw' event
|
||||
|
||||
// Returns close function
|
||||
function setFSEventsListener(path, realPath, listener, rawEmitter) {
|
||||
var watchPath = sysPath.extname(path) ? sysPath.dirname(path) : path;
|
||||
var watchContainer;
|
||||
var parentPath = sysPath.dirname(watchPath);
|
||||
|
||||
// If we've accumulated a substantial number of paths that
|
||||
// could have been consolidated by watching one directory
|
||||
// above the current one, create a watcher on the parent
|
||||
// path instead, so that we do consolidate going forward.
|
||||
if (couldConsolidate(parentPath)) {
|
||||
watchPath = parentPath;
|
||||
}
|
||||
|
||||
var resolvedPath = sysPath.resolve(path);
|
||||
var hasSymlink = resolvedPath !== realPath;
|
||||
function filteredListener(fullPath, flags, info) {
|
||||
if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
|
||||
if (
|
||||
fullPath === resolvedPath ||
|
||||
!fullPath.indexOf(resolvedPath + sysPath.sep)
|
||||
) listener(fullPath, flags, info);
|
||||
}
|
||||
|
||||
// check if there is already a watcher on a parent path
|
||||
// modifies `watchPath` to the parent path when it finds a match
|
||||
function watchedParent() {
|
||||
return Object.keys(FSEventsWatchers).some(function(watchedPath) {
|
||||
// condition is met when indexOf returns 0
|
||||
if (!realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep)) {
|
||||
watchPath = watchedPath;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (watchPath in FSEventsWatchers || watchedParent()) {
|
||||
watchContainer = FSEventsWatchers[watchPath];
|
||||
watchContainer.listeners.push(filteredListener);
|
||||
} else {
|
||||
watchContainer = FSEventsWatchers[watchPath] = {
|
||||
listeners: [filteredListener],
|
||||
rawEmitters: [rawEmitter],
|
||||
watcher: createFSEventsInstance(watchPath, function(fullPath, flags) {
|
||||
var info = fsevents.getInfo(fullPath, flags);
|
||||
watchContainer.listeners.forEach(function(listener) {
|
||||
listener(fullPath, flags, info);
|
||||
});
|
||||
watchContainer.rawEmitters.forEach(function(emitter) {
|
||||
emitter(info.event, fullPath, info);
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
var listenerIndex = watchContainer.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fsevents
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete watchContainer.listeners[listenerIndex];
|
||||
delete watchContainer.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(watchContainer.listeners).length) {
|
||||
watchContainer.watcher.stop();
|
||||
delete FSEventsWatchers[watchPath];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Decide whether or not we should start a new higher-level
|
||||
// parent watcher
|
||||
function couldConsolidate(path) {
|
||||
var keys = Object.keys(FSEventsWatchers);
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0, len = keys.length; i < len; ++i) {
|
||||
var watchPath = keys[i];
|
||||
if (watchPath.indexOf(path) === 0) {
|
||||
count++;
|
||||
if (count >= consolidateThreshhold) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isConstructor(obj) {
|
||||
return obj.prototype !== undefined && obj.prototype.constructor !== undefined;
|
||||
}
|
||||
|
||||
// returns boolean indicating whether fsevents can be used
|
||||
function canUse() {
|
||||
return fsevents && Object.keys(FSEventsWatchers).length < 128 && isConstructor(fsevents);
|
||||
}
|
||||
|
||||
// determines subdirectory traversal levels from root to path
|
||||
function depth(path, root) {
|
||||
var i = 0;
|
||||
while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
// fake constructor for attaching fsevents-specific prototype methods that
|
||||
// will be copied to FSWatcher's prototype
|
||||
function FsEventsHandler() {}
|
||||
|
||||
// Private method: Handle symlinks encountered during directory scan
|
||||
|
||||
// * watchPath - string, file/dir path to be watched with fsevents
|
||||
// * realPath - string, real path (in case of symlinks)
|
||||
// * transform - function, path transformer
|
||||
// * globFilter - function, path filter in case a glob pattern was provided
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
FsEventsHandler.prototype._watchWithFsEvents =
|
||||
function(watchPath, realPath, transform, globFilter) {
|
||||
if (this._isIgnored(watchPath)) return;
|
||||
var watchCallback = function(fullPath, flags, info) {
|
||||
if (
|
||||
this.options.depth !== undefined &&
|
||||
depth(fullPath, realPath) > this.options.depth
|
||||
) return;
|
||||
var path = transform(sysPath.join(
|
||||
watchPath, sysPath.relative(watchPath, fullPath)
|
||||
));
|
||||
if (globFilter && !globFilter(path)) return;
|
||||
// ensure directories are tracked
|
||||
var parent = sysPath.dirname(path);
|
||||
var item = sysPath.basename(path);
|
||||
var watchedDir = this._getWatchedDir(
|
||||
info.type === 'directory' ? path : parent
|
||||
);
|
||||
var checkIgnored = function(stats) {
|
||||
if (this._isIgnored(path, stats)) {
|
||||
this._ignoredPaths[path] = true;
|
||||
if (stats && stats.isDirectory()) {
|
||||
this._ignoredPaths[path + '/**/*'] = true;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
delete this._ignoredPaths[path];
|
||||
delete this._ignoredPaths[path + '/**/*'];
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var handleEvent = function(event) {
|
||||
if (checkIgnored()) return;
|
||||
|
||||
if (event === 'unlink') {
|
||||
// suppress unlink events on never before seen files
|
||||
if (info.type === 'directory' || watchedDir.has(item)) {
|
||||
this._remove(parent, item);
|
||||
}
|
||||
} else {
|
||||
if (event === 'add') {
|
||||
// track new directories
|
||||
if (info.type === 'directory') this._getWatchedDir(path);
|
||||
|
||||
if (info.type === 'symlink' && this.options.followSymlinks) {
|
||||
// push symlinks back to the top of the stack to get handled
|
||||
var curDepth = this.options.depth === undefined ?
|
||||
undefined : depth(fullPath, realPath) + 1;
|
||||
return this._addToFsEvents(path, false, true, curDepth);
|
||||
} else {
|
||||
// track new paths
|
||||
// (other than symlinks being followed, which will be tracked soon)
|
||||
this._getWatchedDir(parent).add(item);
|
||||
}
|
||||
}
|
||||
var eventName = info.type === 'directory' ? event + 'Dir' : event;
|
||||
this._emit(eventName, path);
|
||||
if (eventName === 'addDir') this._addToFsEvents(path, false, true);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
function addOrChange() {
|
||||
handleEvent(watchedDir.has(item) ? 'change' : 'add');
|
||||
}
|
||||
function checkFd() {
|
||||
fs.open(path, 'r', function(error, fd) {
|
||||
if (error) {
|
||||
error.code !== 'EACCES' ?
|
||||
handleEvent('unlink') : addOrChange();
|
||||
} else {
|
||||
fs.close(fd, function(err) {
|
||||
err && err.code !== 'EACCES' ?
|
||||
handleEvent('unlink') : addOrChange();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// correct for wrong events emitted
|
||||
var wrongEventFlags = [
|
||||
69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
|
||||
];
|
||||
if (wrongEventFlags.indexOf(flags) !== -1 || info.event === 'unknown') {
|
||||
if (typeof this.options.ignored === 'function') {
|
||||
fs.stat(path, function(error, stats) {
|
||||
if (checkIgnored(stats)) return;
|
||||
stats ? addOrChange() : handleEvent('unlink');
|
||||
});
|
||||
} else {
|
||||
checkFd();
|
||||
}
|
||||
} else {
|
||||
switch (info.event) {
|
||||
case 'created':
|
||||
case 'modified':
|
||||
return addOrChange();
|
||||
case 'deleted':
|
||||
case 'moved':
|
||||
return checkFd();
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var closer = setFSEventsListener(
|
||||
watchPath,
|
||||
realPath,
|
||||
watchCallback,
|
||||
this.emit.bind(this, 'raw')
|
||||
);
|
||||
|
||||
this._emitReady();
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle symlinks encountered during directory scan
|
||||
|
||||
// * linkPath - string, path to symlink
|
||||
// * fullPath - string, absolute path to the symlink
|
||||
// * transform - function, pre-existing path transformer
|
||||
// * curDepth - int, level of subdirectories traversed to where symlink is
|
||||
|
||||
// Returns nothing
|
||||
FsEventsHandler.prototype._handleFsEventsSymlink =
|
||||
function(linkPath, fullPath, transform, curDepth) {
|
||||
// don't follow the same symlink more than once
|
||||
if (this._symlinkPaths[fullPath]) return;
|
||||
else this._symlinkPaths[fullPath] = true;
|
||||
|
||||
this._readyCount++;
|
||||
|
||||
fs.realpath(linkPath, function(error, linkTarget) {
|
||||
if (this._handleError(error) || this._isIgnored(linkTarget)) {
|
||||
return this._emitReady();
|
||||
}
|
||||
|
||||
this._readyCount++;
|
||||
|
||||
// add the linkTarget for watching with a wrapper for transform
|
||||
// that causes emitted paths to incorporate the link's path
|
||||
this._addToFsEvents(linkTarget || linkPath, function(path) {
|
||||
var dotSlash = '.' + sysPath.sep;
|
||||
var aliasedPath = linkPath;
|
||||
if (linkTarget && linkTarget !== dotSlash) {
|
||||
aliasedPath = path.replace(linkTarget, linkPath);
|
||||
} else if (path !== dotSlash) {
|
||||
aliasedPath = sysPath.join(linkPath, path);
|
||||
}
|
||||
return transform(aliasedPath);
|
||||
}, false, curDepth);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
// Private method: Handle added path with fsevents
|
||||
|
||||
// * path - string, file/directory path or glob pattern
|
||||
// * transform - function, converts working path to what the user expects
|
||||
// * forceAdd - boolean, ensure add is emitted
|
||||
// * priorDepth - int, level of subdirectories already traversed
|
||||
|
||||
// Returns nothing
|
||||
FsEventsHandler.prototype._addToFsEvents =
|
||||
function(path, transform, forceAdd, priorDepth) {
|
||||
|
||||
// applies transform if provided, otherwise returns same value
|
||||
var processPath = typeof transform === 'function' ?
|
||||
transform : function(val) { return val; };
|
||||
|
||||
var emitAdd = function(newPath, stats) {
|
||||
var pp = processPath(newPath);
|
||||
var isDir = stats.isDirectory();
|
||||
var dirObj = this._getWatchedDir(sysPath.dirname(pp));
|
||||
var base = sysPath.basename(pp);
|
||||
|
||||
// ensure empty dirs get tracked
|
||||
if (isDir) this._getWatchedDir(pp);
|
||||
|
||||
if (dirObj.has(base)) return;
|
||||
dirObj.add(base);
|
||||
|
||||
if (!this.options.ignoreInitial || forceAdd === true) {
|
||||
this._emit(isDir ? 'addDir' : 'add', pp, stats);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var wh = this._getWatchHelpers(path);
|
||||
|
||||
// evaluate what is at the path we're being asked to watch
|
||||
fs[wh.statMethod](wh.watchPath, function(error, stats) {
|
||||
if (this._handleError(error) || this._isIgnored(wh.watchPath, stats)) {
|
||||
this._emitReady();
|
||||
return this._emitReady();
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
// emit addDir unless this is a glob parent
|
||||
if (!wh.globFilter) emitAdd(processPath(path), stats);
|
||||
|
||||
// don't recurse further if it would exceed depth setting
|
||||
if (priorDepth && priorDepth > this.options.depth) return;
|
||||
|
||||
// scan the contents of the dir
|
||||
readdirp({
|
||||
root: wh.watchPath,
|
||||
entryType: 'all',
|
||||
fileFilter: wh.filterPath,
|
||||
directoryFilter: wh.filterDir,
|
||||
lstat: true,
|
||||
depth: this.options.depth - (priorDepth || 0)
|
||||
}).on('data', function(entry) {
|
||||
// need to check filterPath on dirs b/c filterDir is less restrictive
|
||||
if (entry.stat.isDirectory() && !wh.filterPath(entry)) return;
|
||||
|
||||
var joinedPath = sysPath.join(wh.watchPath, entry.path);
|
||||
var fullPath = entry.fullPath;
|
||||
|
||||
if (wh.followSymlinks && entry.stat.isSymbolicLink()) {
|
||||
// preserve the current depth here since it can't be derived from
|
||||
// real paths past the symlink
|
||||
var curDepth = this.options.depth === undefined ?
|
||||
undefined : depth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
|
||||
|
||||
this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
|
||||
} else {
|
||||
emitAdd(joinedPath, entry.stat);
|
||||
}
|
||||
}.bind(this)).on('error', function() {
|
||||
// Ignore readdirp errors
|
||||
}).on('end', this._emitReady);
|
||||
} else {
|
||||
emitAdd(wh.watchPath, stats);
|
||||
this._emitReady();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (this.options.persistent && forceAdd !== true) {
|
||||
var initWatch = function(error, realPath) {
|
||||
if (this.closed) return;
|
||||
var closer = this._watchWithFsEvents(
|
||||
wh.watchPath,
|
||||
sysPath.resolve(realPath || wh.watchPath),
|
||||
processPath,
|
||||
wh.globFilter
|
||||
);
|
||||
if (closer) {
|
||||
this._closers[path] = this._closers[path] || [];
|
||||
this._closers[path].push(closer);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
if (typeof transform === 'function') {
|
||||
// realpath has already been resolved
|
||||
initWatch();
|
||||
} else {
|
||||
fs.realpath(wh.watchPath, initWatch);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = FsEventsHandler;
|
||||
module.exports.canUse = canUse;
|
506
node_modules/watchify/node_modules/chokidar/lib/nodefs-handler.js
generated
vendored
Normal file
506
node_modules/watchify/node_modules/chokidar/lib/nodefs-handler.js
generated
vendored
Normal file
@@ -0,0 +1,506 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var readdirp = require('readdirp');
|
||||
var isBinaryPath = require('is-binary-path');
|
||||
|
||||
// fs.watch helpers
|
||||
|
||||
// object to hold per-process fs.watch instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FsWatchInstances = Object.create(null);
|
||||
|
||||
|
||||
// Private function: Instantiates the fs.watch interface
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * options - object, options to be passed to fs.watch
|
||||
// * listener - function, main event handler
|
||||
// * errHandler - function, handler which emits info about errors
|
||||
// * emitRaw - function, handler which emits raw event data
|
||||
|
||||
// Returns new fsevents instance
|
||||
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
||||
var handleEvent = function(rawEvent, evPath) {
|
||||
listener(path);
|
||||
emitRaw(rawEvent, evPath, {watchedPath: path});
|
||||
|
||||
// emit based on events occurring for files from a directory's watcher in
|
||||
// case the file's watcher misses it (and rely on throttling to de-dupe)
|
||||
if (evPath && path !== evPath) {
|
||||
fsWatchBroadcast(
|
||||
sysPath.resolve(path, evPath), 'listeners', sysPath.join(path, evPath)
|
||||
);
|
||||
}
|
||||
};
|
||||
try {
|
||||
return fs.watch(path, options, handleEvent);
|
||||
} catch (error) {
|
||||
errHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Private function: Helper for passing fs.watch event data to a
|
||||
// collection of listeners
|
||||
|
||||
// * fullPath - string, absolute path bound to the fs.watch instance
|
||||
// * type - string, listener type
|
||||
// * val[1..3] - arguments to be passed to listeners
|
||||
|
||||
// Returns nothing
|
||||
function fsWatchBroadcast(fullPath, type, val1, val2, val3) {
|
||||
if (!FsWatchInstances[fullPath]) return;
|
||||
FsWatchInstances[fullPath][type].forEach(function(listener) {
|
||||
listener(val1, val2, val3);
|
||||
});
|
||||
}
|
||||
|
||||
// Private function: Instantiates the fs.watch interface or binds listeners
|
||||
// to an existing one covering the same file system entry
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * fullPath - string, absolute path
|
||||
// * options - object, options to be passed to fs.watch
|
||||
// * handlers - object, container for event listener functions
|
||||
|
||||
// Returns close function
|
||||
function setFsWatchListener(path, fullPath, options, handlers) {
|
||||
var listener = handlers.listener;
|
||||
var errHandler = handlers.errHandler;
|
||||
var rawEmitter = handlers.rawEmitter;
|
||||
var container = FsWatchInstances[fullPath];
|
||||
var watcher;
|
||||
if (!options.persistent) {
|
||||
watcher = createFsWatchInstance(
|
||||
path, options, listener, errHandler, rawEmitter
|
||||
);
|
||||
return watcher.close.bind(watcher);
|
||||
}
|
||||
if (!container) {
|
||||
watcher = createFsWatchInstance(
|
||||
path,
|
||||
options,
|
||||
fsWatchBroadcast.bind(null, fullPath, 'listeners'),
|
||||
errHandler, // no need to use broadcast here
|
||||
fsWatchBroadcast.bind(null, fullPath, 'rawEmitters')
|
||||
);
|
||||
if (!watcher) return;
|
||||
var broadcastErr = fsWatchBroadcast.bind(null, fullPath, 'errHandlers');
|
||||
watcher.on('error', function(error) {
|
||||
container.watcherUnusable = true; // documented since Node 10.4.1
|
||||
// Workaround for https://github.com/joyent/node/issues/4337
|
||||
if (process.platform === 'win32' && error.code === 'EPERM') {
|
||||
fs.open(path, 'r', function(err, fd) {
|
||||
if (!err) fs.close(fd, function(err) {
|
||||
if (!err) broadcastErr(error);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
broadcastErr(error);
|
||||
}
|
||||
});
|
||||
container = FsWatchInstances[fullPath] = {
|
||||
listeners: [listener],
|
||||
errHandlers: [errHandler],
|
||||
rawEmitters: [rawEmitter],
|
||||
watcher: watcher
|
||||
};
|
||||
} else {
|
||||
container.listeners.push(listener);
|
||||
container.errHandlers.push(errHandler);
|
||||
container.rawEmitters.push(rawEmitter);
|
||||
}
|
||||
var listenerIndex = container.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fs.watch
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete container.listeners[listenerIndex];
|
||||
delete container.errHandlers[listenerIndex];
|
||||
delete container.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(container.listeners).length) {
|
||||
if (!container.watcherUnusable) { // check to protect against issue #730
|
||||
container.watcher.close();
|
||||
}
|
||||
delete FsWatchInstances[fullPath];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// fs.watchFile helpers
|
||||
|
||||
// object to hold per-process fs.watchFile instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FsWatchFileInstances = Object.create(null);
|
||||
|
||||
// Private function: Instantiates the fs.watchFile interface or binds listeners
|
||||
// to an existing one covering the same file system entry
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * fullPath - string, absolute path
|
||||
// * options - object, options to be passed to fs.watchFile
|
||||
// * handlers - object, container for event listener functions
|
||||
|
||||
// Returns close function
|
||||
function setFsWatchFileListener(path, fullPath, options, handlers) {
|
||||
var listener = handlers.listener;
|
||||
var rawEmitter = handlers.rawEmitter;
|
||||
var container = FsWatchFileInstances[fullPath];
|
||||
var listeners = [];
|
||||
var rawEmitters = [];
|
||||
if (
|
||||
container && (
|
||||
container.options.persistent < options.persistent ||
|
||||
container.options.interval > options.interval
|
||||
)
|
||||
) {
|
||||
// "Upgrade" the watcher to persistence or a quicker interval.
|
||||
// This creates some unlikely edge case issues if the user mixes
|
||||
// settings in a very weird way, but solving for those cases
|
||||
// doesn't seem worthwhile for the added complexity.
|
||||
listeners = container.listeners;
|
||||
rawEmitters = container.rawEmitters;
|
||||
fs.unwatchFile(fullPath);
|
||||
container = false;
|
||||
}
|
||||
if (!container) {
|
||||
listeners.push(listener);
|
||||
rawEmitters.push(rawEmitter);
|
||||
container = FsWatchFileInstances[fullPath] = {
|
||||
listeners: listeners,
|
||||
rawEmitters: rawEmitters,
|
||||
options: options,
|
||||
watcher: fs.watchFile(fullPath, options, function(curr, prev) {
|
||||
container.rawEmitters.forEach(function(rawEmitter) {
|
||||
rawEmitter('change', fullPath, {curr: curr, prev: prev});
|
||||
});
|
||||
var currmtime = curr.mtime.getTime();
|
||||
if (curr.size !== prev.size || currmtime > prev.mtime.getTime() || currmtime === 0) {
|
||||
container.listeners.forEach(function(listener) {
|
||||
listener(path, curr);
|
||||
});
|
||||
}
|
||||
})
|
||||
};
|
||||
} else {
|
||||
container.listeners.push(listener);
|
||||
container.rawEmitters.push(rawEmitter);
|
||||
}
|
||||
var listenerIndex = container.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fs.watchFile
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete container.listeners[listenerIndex];
|
||||
delete container.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(container.listeners).length) {
|
||||
fs.unwatchFile(fullPath);
|
||||
delete FsWatchFileInstances[fullPath];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// fake constructor for attaching nodefs-specific prototype methods that
|
||||
// will be copied to FSWatcher's prototype
|
||||
function NodeFsHandler() {}
|
||||
|
||||
// Private method: Watch file for changes with fs.watchFile or fs.watch.
|
||||
|
||||
// * path - string, path to file or directory.
|
||||
// * listener - function, to be executed on fs change.
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._watchWithNodeFs =
|
||||
function(path, listener) {
|
||||
var directory = sysPath.dirname(path);
|
||||
var basename = sysPath.basename(path);
|
||||
var parent = this._getWatchedDir(directory);
|
||||
parent.add(basename);
|
||||
var absolutePath = sysPath.resolve(path);
|
||||
var options = {persistent: this.options.persistent};
|
||||
if (!listener) listener = Function.prototype; // empty function
|
||||
|
||||
var closer;
|
||||
if (this.options.usePolling) {
|
||||
options.interval = this.enableBinaryInterval && isBinaryPath(basename) ?
|
||||
this.options.binaryInterval : this.options.interval;
|
||||
closer = setFsWatchFileListener(path, absolutePath, options, {
|
||||
listener: listener,
|
||||
rawEmitter: this.emit.bind(this, 'raw')
|
||||
});
|
||||
} else {
|
||||
closer = setFsWatchListener(path, absolutePath, options, {
|
||||
listener: listener,
|
||||
errHandler: this._handleError.bind(this),
|
||||
rawEmitter: this.emit.bind(this, 'raw')
|
||||
});
|
||||
}
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Watch a file and emit add event if warranted
|
||||
|
||||
// * file - string, the file's path
|
||||
// * stats - object, result of fs.stat
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * callback - function, called when done processing as a newly seen file
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._handleFile =
|
||||
function(file, stats, initialAdd, callback) {
|
||||
var dirname = sysPath.dirname(file);
|
||||
var basename = sysPath.basename(file);
|
||||
var parent = this._getWatchedDir(dirname);
|
||||
// stats is always present
|
||||
var prevStats = stats;
|
||||
|
||||
// if the file is already being watched, do nothing
|
||||
if (parent.has(basename)) return callback();
|
||||
|
||||
// kick off the watcher
|
||||
var closer = this._watchWithNodeFs(file, function(path, newStats) {
|
||||
if (!this._throttle('watch', file, 5)) return;
|
||||
if (!newStats || newStats && newStats.mtime.getTime() === 0) {
|
||||
fs.stat(file, function(error, newStats) {
|
||||
// Fix issues where mtime is null but file is still present
|
||||
if (error) {
|
||||
this._remove(dirname, basename);
|
||||
} else {
|
||||
// Check that change event was not fired because of changed only accessTime.
|
||||
var at = newStats.atime.getTime();
|
||||
var mt = newStats.mtime.getTime();
|
||||
if (!at || at <= mt || mt !== prevStats.mtime.getTime()) {
|
||||
this._emit('change', file, newStats);
|
||||
}
|
||||
prevStats = newStats;
|
||||
}
|
||||
}.bind(this));
|
||||
// add is about to be emitted if file not already tracked in parent
|
||||
} else if (parent.has(basename)) {
|
||||
// Check that change event was not fired because of changed only accessTime.
|
||||
var at = newStats.atime.getTime();
|
||||
var mt = newStats.mtime.getTime();
|
||||
if (!at || at <= mt || mt !== prevStats.mtime.getTime()) {
|
||||
this._emit('change', file, newStats);
|
||||
}
|
||||
prevStats = newStats;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
// emit an add event if we're supposed to
|
||||
if (!(initialAdd && this.options.ignoreInitial)) {
|
||||
if (!this._throttle('add', file, 0)) return;
|
||||
this._emit('add', file, stats);
|
||||
}
|
||||
|
||||
if (callback) callback();
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle symlinks encountered while reading a dir
|
||||
|
||||
// * entry - object, entry object returned by readdirp
|
||||
// * directory - string, path of the directory being read
|
||||
// * path - string, path of this item
|
||||
// * item - string, basename of this item
|
||||
|
||||
// Returns true if no more processing is needed for this entry.
|
||||
NodeFsHandler.prototype._handleSymlink =
|
||||
function(entry, directory, path, item) {
|
||||
var full = entry.fullPath;
|
||||
var dir = this._getWatchedDir(directory);
|
||||
|
||||
if (!this.options.followSymlinks) {
|
||||
// watch symlink directly (don't follow) and detect changes
|
||||
this._readyCount++;
|
||||
fs.realpath(path, function(error, linkPath) {
|
||||
if (dir.has(item)) {
|
||||
if (this._symlinkPaths[full] !== linkPath) {
|
||||
this._symlinkPaths[full] = linkPath;
|
||||
this._emit('change', path, entry.stat);
|
||||
}
|
||||
} else {
|
||||
dir.add(item);
|
||||
this._symlinkPaths[full] = linkPath;
|
||||
this._emit('add', path, entry.stat);
|
||||
}
|
||||
this._emitReady();
|
||||
}.bind(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't follow the same symlink more than once
|
||||
if (this._symlinkPaths[full]) return true;
|
||||
else this._symlinkPaths[full] = true;
|
||||
};
|
||||
|
||||
// Private method: Read directory to add / remove files from `@watched` list
|
||||
// and re-read it on change.
|
||||
|
||||
// * dir - string, fs path.
|
||||
// * stats - object, result of fs.stat
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * depth - int, depth relative to user-supplied path
|
||||
// * target - string, child path actually targeted for watch
|
||||
// * wh - object, common watch helpers for this path
|
||||
// * callback - function, called when dir scan is complete
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._handleDir =
|
||||
function(dir, stats, initialAdd, depth, target, wh, callback) {
|
||||
var parentDir = this._getWatchedDir(sysPath.dirname(dir));
|
||||
var tracked = parentDir.has(sysPath.basename(dir));
|
||||
if (!(initialAdd && this.options.ignoreInitial) && !target && !tracked) {
|
||||
if (!wh.hasGlob || wh.globFilter(dir)) this._emit('addDir', dir, stats);
|
||||
}
|
||||
|
||||
// ensure dir is tracked (harmless if redundant)
|
||||
parentDir.add(sysPath.basename(dir));
|
||||
this._getWatchedDir(dir);
|
||||
|
||||
var read = function(directory, initialAdd, done) {
|
||||
// Normalize the directory name on Windows
|
||||
directory = sysPath.join(directory, '');
|
||||
|
||||
if (!wh.hasGlob) {
|
||||
var throttler = this._throttle('readdir', directory, 1000);
|
||||
if (!throttler) return;
|
||||
}
|
||||
|
||||
var previous = this._getWatchedDir(wh.path);
|
||||
var current = [];
|
||||
|
||||
readdirp({
|
||||
root: directory,
|
||||
entryType: 'all',
|
||||
fileFilter: wh.filterPath,
|
||||
directoryFilter: wh.filterDir,
|
||||
depth: 0,
|
||||
lstat: true
|
||||
}).on('data', function(entry) {
|
||||
var item = entry.path;
|
||||
var path = sysPath.join(directory, item);
|
||||
current.push(item);
|
||||
|
||||
if (entry.stat.isSymbolicLink() &&
|
||||
this._handleSymlink(entry, directory, path, item)) return;
|
||||
|
||||
// Files that present in current directory snapshot
|
||||
// but absent in previous are added to watch list and
|
||||
// emit `add` event.
|
||||
if (item === target || !target && !previous.has(item)) {
|
||||
this._readyCount++;
|
||||
|
||||
// ensure relativeness of path is preserved in case of watcher reuse
|
||||
path = sysPath.join(dir, sysPath.relative(dir, path));
|
||||
|
||||
this._addToNodeFs(path, initialAdd, wh, depth + 1);
|
||||
}
|
||||
}.bind(this)).on('end', function() {
|
||||
var wasThrottled = throttler ? throttler.clear() : false;
|
||||
if (done) done();
|
||||
|
||||
// Files that absent in current directory snapshot
|
||||
// but present in previous emit `remove` event
|
||||
// and are removed from @watched[directory].
|
||||
previous.children().filter(function(item) {
|
||||
return item !== directory &&
|
||||
current.indexOf(item) === -1 &&
|
||||
// in case of intersecting globs;
|
||||
// a path may have been filtered out of this readdir, but
|
||||
// shouldn't be removed because it matches a different glob
|
||||
(!wh.hasGlob || wh.filterPath({
|
||||
fullPath: sysPath.resolve(directory, item)
|
||||
}));
|
||||
}).forEach(function(item) {
|
||||
this._remove(directory, item);
|
||||
}, this);
|
||||
|
||||
// one more time for any missed in case changes came in extremely quickly
|
||||
if (wasThrottled) read(directory, false);
|
||||
}.bind(this)).on('error', this._handleError.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
var closer;
|
||||
|
||||
if (this.options.depth == null || depth <= this.options.depth) {
|
||||
if (!target) read(dir, initialAdd, callback);
|
||||
closer = this._watchWithNodeFs(dir, function(dirPath, stats) {
|
||||
// if current directory is removed, do nothing
|
||||
if (stats && stats.mtime.getTime() === 0) return;
|
||||
|
||||
read(dirPath, false);
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle added file, directory, or glob pattern.
|
||||
// Delegates call to _handleFile / _handleDir after checks.
|
||||
|
||||
// * path - string, path to file or directory.
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * depth - int, depth relative to user-supplied path
|
||||
// * target - string, child path actually targeted for watch
|
||||
// * callback - function, indicates whether the path was found or not
|
||||
|
||||
// Returns nothing
|
||||
NodeFsHandler.prototype._addToNodeFs =
|
||||
function(path, initialAdd, priorWh, depth, target, callback) {
|
||||
if (!callback) callback = Function.prototype;
|
||||
var ready = this._emitReady;
|
||||
if (this._isIgnored(path) || this.closed) {
|
||||
ready();
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
var wh = this._getWatchHelpers(path, depth);
|
||||
if (!wh.hasGlob && priorWh) {
|
||||
wh.hasGlob = priorWh.hasGlob;
|
||||
wh.globFilter = priorWh.globFilter;
|
||||
wh.filterPath = priorWh.filterPath;
|
||||
wh.filterDir = priorWh.filterDir;
|
||||
}
|
||||
|
||||
// evaluate what is at the path we're being asked to watch
|
||||
fs[wh.statMethod](wh.watchPath, function(error, stats) {
|
||||
if (this._handleError(error)) return callback(null, path);
|
||||
if (this._isIgnored(wh.watchPath, stats)) {
|
||||
ready();
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
var initDir = function(dir, target) {
|
||||
return this._handleDir(dir, stats, initialAdd, depth, target, wh, ready);
|
||||
}.bind(this);
|
||||
|
||||
var closer;
|
||||
if (stats.isDirectory()) {
|
||||
closer = initDir(wh.watchPath, target);
|
||||
} else if (stats.isSymbolicLink()) {
|
||||
var parent = sysPath.dirname(wh.watchPath);
|
||||
this._getWatchedDir(parent).add(wh.watchPath);
|
||||
this._emit('add', wh.watchPath, stats);
|
||||
closer = initDir(parent, path);
|
||||
|
||||
// preserve this symlink's target path
|
||||
fs.realpath(path, function(error, targetPath) {
|
||||
this._symlinkPaths[sysPath.resolve(path)] = targetPath;
|
||||
ready();
|
||||
}.bind(this));
|
||||
} else {
|
||||
closer = this._handleFile(wh.watchPath, stats, initialAdd, ready);
|
||||
}
|
||||
|
||||
if (closer) {
|
||||
this._closers[path] = this._closers[path] || [];
|
||||
this._closers[path].push(closer);
|
||||
}
|
||||
callback(null, false);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
module.exports = NodeFsHandler;
|
92
node_modules/watchify/node_modules/chokidar/package.json
generated
vendored
Normal file
92
node_modules/watchify/node_modules/chokidar/package.json
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"_from": "chokidar@^2.1.1",
|
||||
"_id": "chokidar@2.1.8",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
|
||||
"_location": "/watchify/chokidar",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "chokidar@^2.1.1",
|
||||
"name": "chokidar",
|
||||
"escapedName": "chokidar",
|
||||
"rawSpec": "^2.1.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.1.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/watchify"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
|
||||
"_shasum": "804b3a7b6a99358c3c5c61e71d8728f041cff917",
|
||||
"_spec": "chokidar@^2.1.1",
|
||||
"_where": "/home/simon/Documents/lifen-autotest/node_modules/watchify",
|
||||
"author": {
|
||||
"name": "Paul Miller",
|
||||
"url": "https://paulmillr.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/paulmillr/chokidar/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"anymatch": "^2.0.0",
|
||||
"async-each": "^1.0.1",
|
||||
"braces": "^2.3.2",
|
||||
"fsevents": "^1.2.7",
|
||||
"glob-parent": "^3.1.0",
|
||||
"inherits": "^2.0.3",
|
||||
"is-binary-path": "^1.0.0",
|
||||
"is-glob": "^4.0.0",
|
||||
"normalize-path": "^3.0.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"readdirp": "^2.2.1",
|
||||
"upath": "^1.1.1"
|
||||
},
|
||||
"deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.",
|
||||
"description": "A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.",
|
||||
"devDependencies": {
|
||||
"@types/node": "^11.9.4",
|
||||
"chai": "^3.2.0",
|
||||
"coveralls": "^3.0.1",
|
||||
"dtslint": "0.4.1",
|
||||
"graceful-fs": "4.1.4",
|
||||
"mocha": "^5.2.0",
|
||||
"nyc": "^11.8.0",
|
||||
"rimraf": "^2.4.3",
|
||||
"sinon": "^1.10.3",
|
||||
"sinon-chai": "^2.6.0"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"lib/",
|
||||
"types/index.d.ts"
|
||||
],
|
||||
"homepage": "https://github.com/paulmillr/chokidar",
|
||||
"keywords": [
|
||||
"fs",
|
||||
"watch",
|
||||
"watchFile",
|
||||
"watcher",
|
||||
"watching",
|
||||
"file",
|
||||
"fsevents"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "chokidar",
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^1.2.7"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/paulmillr/chokidar.git"
|
||||
},
|
||||
"scripts": {
|
||||
"coveralls": "nyc report --reporter=text-lcov | coveralls",
|
||||
"dtslint": "dtslint types",
|
||||
"test": "nyc mocha --exit"
|
||||
},
|
||||
"types": "./types/index.d.ts",
|
||||
"version": "2.1.8"
|
||||
}
|
191
node_modules/watchify/node_modules/chokidar/types/index.d.ts
generated
vendored
Normal file
191
node_modules/watchify/node_modules/chokidar/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
// TypeScript Version: 3.0
|
||||
|
||||
/// <reference types="node" />
|
||||
|
||||
import * as fs from "fs";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
/**
|
||||
* The object's keys are all the directories (using absolute paths unless the `cwd` option was
|
||||
* used), and the values are arrays of the names of the items contained in each directory.
|
||||
*/
|
||||
export interface WatchedPaths {
|
||||
[directory: string]: string[];
|
||||
}
|
||||
|
||||
export class FSWatcher extends EventEmitter implements fs.FSWatcher {
|
||||
/**
|
||||
* Constructs a new FSWatcher instance with optional WatchOptions parameter.
|
||||
*/
|
||||
constructor(options?: WatchOptions);
|
||||
|
||||
/**
|
||||
* Add files, directories, or glob patterns for tracking. Takes an array of strings or just one
|
||||
* string.
|
||||
*/
|
||||
add(paths: string | string[]): void;
|
||||
|
||||
/**
|
||||
* Stop watching files, directories, or glob patterns. Takes an array of strings or just one
|
||||
* string.
|
||||
*/
|
||||
unwatch(paths: string | string[]): void;
|
||||
|
||||
/**
|
||||
* Returns an object representing all the paths on the file system being watched by this
|
||||
* `FSWatcher` instance. The object's keys are all the directories (using absolute paths unless
|
||||
* the `cwd` option was used), and the values are arrays of the names of the items contained in
|
||||
* each directory.
|
||||
*/
|
||||
getWatched(): WatchedPaths;
|
||||
|
||||
/**
|
||||
* Removes all listeners from watched files.
|
||||
*/
|
||||
close(): void;
|
||||
|
||||
on(event: 'add'|'addDir'|'change', listener: (path: string, stats?: fs.Stats) => void): this;
|
||||
|
||||
on(event: 'all', listener: (eventName: 'add'|'addDir'|'change'|'unlink'|'unlinkDir', path: string, stats?: fs.Stats) => void): this;
|
||||
|
||||
/**
|
||||
* Error occured
|
||||
*/
|
||||
on(event: 'error', listener: (error: Error) => void): this;
|
||||
|
||||
/**
|
||||
* Exposes the native Node `fs.FSWatcher events`
|
||||
*/
|
||||
on(event: 'raw', listener: (eventName: string, path: string, details: any) => void): this;
|
||||
|
||||
/**
|
||||
* Fires when the initial scan is complete
|
||||
*/
|
||||
on(event: 'ready', listener: () => void): this;
|
||||
|
||||
on(event: 'unlink'|'unlinkDir', listener: (path: string) => void): this;
|
||||
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
}
|
||||
|
||||
export interface WatchOptions {
|
||||
/**
|
||||
* Indicates whether the process should continue to run as long as files are being watched. If
|
||||
* set to `false` when using `fsevents` to watch, no more events will be emitted after `ready`,
|
||||
* even if the process continues to run.
|
||||
*/
|
||||
persistent?: boolean;
|
||||
|
||||
/**
|
||||
* ([anymatch](https://github.com/es128/anymatch)-compatible definition) Defines files/paths to
|
||||
* be ignored. The whole relative or absolute path is tested, not just filename. If a function
|
||||
* with two arguments is provided, it gets called twice per path - once with a single argument
|
||||
* (the path), second time with two arguments (the path and the
|
||||
* [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object of that path).
|
||||
*/
|
||||
ignored?: any;
|
||||
|
||||
/**
|
||||
* If set to `false` then `add`/`addDir` events are also emitted for matching paths while
|
||||
* instantiating the watching as chokidar discovers these file paths (before the `ready` event).
|
||||
*/
|
||||
ignoreInitial?: boolean;
|
||||
|
||||
/**
|
||||
* When `false`, only the symlinks themselves will be watched for changes instead of following
|
||||
* the link references and bubbling events through the link's path.
|
||||
*/
|
||||
followSymlinks?: boolean;
|
||||
|
||||
/**
|
||||
* The base directory from which watch `paths` are to be derived. Paths emitted with events will
|
||||
* be relative to this.
|
||||
*/
|
||||
cwd?: string;
|
||||
|
||||
/**
|
||||
* If set to true then the strings passed to .watch() and .add() are treated as literal path
|
||||
* names, even if they look like globs. Default: false.
|
||||
*/
|
||||
disableGlobbing?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to use fs.watchFile (backed by polling), or fs.watch. If polling leads to high CPU
|
||||
* utilization, consider setting this to `false`. It is typically necessary to **set this to
|
||||
* `true` to successfully watch files over a network**, and it may be necessary to successfully
|
||||
* watch files in other non-standard situations. Setting to `true` explicitly on OS X overrides
|
||||
* the `useFsEvents` default.
|
||||
*/
|
||||
usePolling?: boolean;
|
||||
|
||||
/**
|
||||
* Whether to use the `fsevents` watching interface if available. When set to `true` explicitly
|
||||
* and `fsevents` is available this supercedes the `usePolling` setting. When set to `false` on
|
||||
* OS X, `usePolling: true` becomes the default.
|
||||
*/
|
||||
useFsEvents?: boolean;
|
||||
|
||||
/**
|
||||
* If relying upon the [`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) object that
|
||||
* may get passed with `add`, `addDir`, and `change` events, set this to `true` to ensure it is
|
||||
* provided even in cases where it wasn't already available from the underlying watch events.
|
||||
*/
|
||||
alwaysStat?: boolean;
|
||||
|
||||
/**
|
||||
* If set, limits how many levels of subdirectories will be traversed.
|
||||
*/
|
||||
depth?: number;
|
||||
|
||||
/**
|
||||
* Interval of file system polling.
|
||||
*/
|
||||
interval?: number;
|
||||
|
||||
/**
|
||||
* Interval of file system polling for binary files. ([see list of binary extensions](https://gi
|
||||
* thub.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
|
||||
*/
|
||||
binaryInterval?: number;
|
||||
|
||||
/**
|
||||
* Indicates whether to watch files that don't have read permissions if possible. If watching
|
||||
* fails due to `EPERM` or `EACCES` with this set to `true`, the errors will be suppressed
|
||||
* silently.
|
||||
*/
|
||||
ignorePermissionErrors?: boolean;
|
||||
|
||||
/**
|
||||
* `true` if `useFsEvents` and `usePolling` are `false`). Automatically filters out artifacts
|
||||
* that occur when using editors that use "atomic writes" instead of writing directly to the
|
||||
* source file. If a file is re-added within 100 ms of being deleted, Chokidar emits a `change`
|
||||
* event rather than `unlink` then `add`. If the default of 100 ms does not work well for you,
|
||||
* you can override it by setting `atomic` to a custom value, in milliseconds.
|
||||
*/
|
||||
atomic?: boolean | number;
|
||||
|
||||
/**
|
||||
* can be set to an object in order to adjust timing params:
|
||||
*/
|
||||
awaitWriteFinish?: AwaitWriteFinishOptions | boolean;
|
||||
}
|
||||
|
||||
export interface AwaitWriteFinishOptions {
|
||||
/**
|
||||
* Amount of time in milliseconds for a file size to remain constant before emitting its event.
|
||||
*/
|
||||
stabilityThreshold?: number;
|
||||
|
||||
/**
|
||||
* File size polling interval.
|
||||
*/
|
||||
pollInterval?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* produces an instance of `FSWatcher`.
|
||||
*/
|
||||
export function watch(
|
||||
paths: string | string[],
|
||||
options?: WatchOptions
|
||||
): FSWatcher;
|
89
node_modules/watchify/package.json
generated
vendored
Normal file
89
node_modules/watchify/package.json
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"_from": "watchify@3.11.1",
|
||||
"_id": "watchify@3.11.1",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==",
|
||||
"_location": "/watchify",
|
||||
"_phantomChildren": {
|
||||
"anymatch": "2.0.0",
|
||||
"async-each": "1.0.3",
|
||||
"braces": "2.3.2",
|
||||
"fsevents": "1.2.13",
|
||||
"glob-parent": "3.1.0",
|
||||
"inherits": "2.0.4",
|
||||
"is-binary-path": "1.0.1",
|
||||
"is-glob": "4.0.1",
|
||||
"normalize-path": "3.0.0",
|
||||
"path-is-absolute": "1.0.1",
|
||||
"readdirp": "2.2.1",
|
||||
"upath": "1.2.0"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"registry": true,
|
||||
"raw": "watchify@3.11.1",
|
||||
"name": "watchify",
|
||||
"escapedName": "watchify",
|
||||
"rawSpec": "3.11.1",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.11.1"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/@cypress/browserify-preprocessor"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz",
|
||||
"_shasum": "8e4665871fff1ef64c0430d1a2c9d084d9721881",
|
||||
"_spec": "watchify@3.11.1",
|
||||
"_where": "/home/simon/Documents/lifen-autotest/node_modules/@cypress/browserify-preprocessor",
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"bin": {
|
||||
"watchify": "bin/cmd.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/substack/watchify/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"anymatch": "^2.0.0",
|
||||
"browserify": "^16.1.0",
|
||||
"chokidar": "^2.1.1",
|
||||
"defined": "^1.0.0",
|
||||
"outpipe": "^1.1.0",
|
||||
"through2": "^2.0.0",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "watch mode for browserify builds",
|
||||
"devDependencies": {
|
||||
"brfs": "^2.0.1",
|
||||
"mkdirp": "~0.5.1",
|
||||
"split": "^1.0.0",
|
||||
"tape": "^4.2.2",
|
||||
"uglify-js": "^2.5.0",
|
||||
"win-spawn": "^2.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/substack/watchify",
|
||||
"keywords": [
|
||||
"browserify",
|
||||
"browserify-tool",
|
||||
"watch",
|
||||
"bundle",
|
||||
"build",
|
||||
"browser"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "watchify",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/substack/watchify.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js"
|
||||
},
|
||||
"version": "3.11.1"
|
||||
}
|
270
node_modules/watchify/readme.markdown
generated
vendored
Normal file
270
node_modules/watchify/readme.markdown
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
# watchify
|
||||
|
||||
watch mode for [browserify](https://github.com/substack/node-browserify) builds
|
||||
|
||||
[](http://travis-ci.org/substack/watchify)
|
||||
|
||||
Update any source file and your browserify bundle will be recompiled on the
|
||||
spot.
|
||||
|
||||
# example
|
||||
|
||||
```
|
||||
$ watchify main.js -o static/bundle.js
|
||||
```
|
||||
|
||||
Now as you update files, `static/bundle.js` will be automatically
|
||||
incrementally rebuilt on the fly.
|
||||
|
||||
The `-o` option can be a file or a shell command (not available on Windows)
|
||||
that receives piped input:
|
||||
|
||||
``` sh
|
||||
watchify main.js -o 'exorcist static/bundle.js.map > static/bundle.js' -d
|
||||
```
|
||||
|
||||
``` sh
|
||||
watchify main.js -o 'uglifyjs -cm > static/bundle.min.js'
|
||||
```
|
||||
|
||||
You can use `-v` to get more verbose output to show when a file was written and how long the bundling took (in seconds):
|
||||
|
||||
```
|
||||
$ watchify browser.js -d -o static/bundle.js -v
|
||||
610598 bytes written to static/bundle.js (0.23 seconds) at 8:31:25 PM
|
||||
610606 bytes written to static/bundle.js (0.10 seconds) at 8:45:59 PM
|
||||
610597 bytes written to static/bundle.js (0.14 seconds) at 8:46:02 PM
|
||||
610606 bytes written to static/bundle.js (0.08 seconds) at 8:50:13 PM
|
||||
610597 bytes written to static/bundle.js (0.08 seconds) at 8:58:16 PM
|
||||
610597 bytes written to static/bundle.js (0.19 seconds) at 9:10:45 PM
|
||||
```
|
||||
|
||||
# usage
|
||||
|
||||
Use `watchify` with all the same options as `browserify` except that `-o` (or
|
||||
`--outfile`) is mandatory. Additionally, there are also:
|
||||
|
||||
```
|
||||
Standard Options:
|
||||
|
||||
--outfile=FILE, -o FILE
|
||||
|
||||
This option is required. Write the browserify bundle to this file. If
|
||||
the file contains the operators `|` or `>`, it will be treated as a
|
||||
shell command, and the output will be piped to it.
|
||||
|
||||
--verbose, -v [default: false]
|
||||
|
||||
Show when a file was written and how long the bundling took (in
|
||||
seconds).
|
||||
|
||||
--version
|
||||
|
||||
Show the watchify and browserify versions with their module paths.
|
||||
```
|
||||
|
||||
```
|
||||
Advanced Options:
|
||||
|
||||
--delay [default: 100]
|
||||
|
||||
Amount of time in milliseconds to wait before emitting an "update"
|
||||
event after a change.
|
||||
|
||||
--ignore-watch=GLOB, --iw GLOB [default: false]
|
||||
|
||||
Ignore monitoring files for changes that match the pattern. Omitting
|
||||
the pattern will default to "**/node_modules/**".
|
||||
|
||||
--poll=INTERVAL [default: false]
|
||||
|
||||
Use polling to monitor for changes. Omitting the interval will default
|
||||
to 100ms. This option is useful if you're watching an NFS volume.
|
||||
```
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var watchify = require('watchify');
|
||||
```
|
||||
|
||||
## watchify(b, opts)
|
||||
|
||||
watchify is a browserify [plugin](https://github.com/substack/node-browserify#bpluginplugin-opts), so it can be applied like any other plugin.
|
||||
However, when creating the browserify instance `b`, **you MUST set the `cache`
|
||||
and `packageCache` properties**:
|
||||
|
||||
``` js
|
||||
var b = browserify({ cache: {}, packageCache: {} });
|
||||
b.plugin(watchify);
|
||||
```
|
||||
|
||||
```js
|
||||
var b = browserify({
|
||||
cache: {},
|
||||
packageCache: {},
|
||||
plugin: [watchify]
|
||||
});
|
||||
```
|
||||
|
||||
**By default, watchify doesn't display any output, see [events](https://github.com/substack/watchify#events) for more info.**
|
||||
|
||||
`b` continues to behave like a browserify instance except that it caches file
|
||||
contents and emits an `'update'` event when a file changes. You should call
|
||||
`b.bundle()` after the `'update'` event fires to generate a new bundle.
|
||||
Calling `b.bundle()` extra times past the first time will be much faster due
|
||||
to caching.
|
||||
|
||||
**Important:** Watchify will not emit `'update'` events until you've called
|
||||
`b.bundle()` once and completely drained the stream it returns.
|
||||
|
||||
```js
|
||||
var fs = require('fs');
|
||||
var browserify = require('browserify');
|
||||
var watchify = require('watchify');
|
||||
|
||||
var b = browserify({
|
||||
entries: ['path/to/entry.js'],
|
||||
cache: {},
|
||||
packageCache: {},
|
||||
plugin: [watchify]
|
||||
});
|
||||
|
||||
b.on('update', bundle);
|
||||
bundle();
|
||||
|
||||
function bundle() {
|
||||
b.bundle()
|
||||
.on('error', console.error)
|
||||
.pipe(fs.createWriteStream('output.js'))
|
||||
;
|
||||
}
|
||||
```
|
||||
|
||||
### options
|
||||
|
||||
You can to pass an additional options object as a second parameter of
|
||||
watchify. Its properties are:
|
||||
|
||||
`opts.delay` is the amount of time in milliseconds to wait before emitting
|
||||
an "update" event after a change. Defaults to `100`.
|
||||
|
||||
`opts.ignoreWatch` ignores monitoring files for changes. If set to `true`,
|
||||
then `**/node_modules/**` will be ignored. For other possible values see
|
||||
Chokidar's [documentation](https://github.com/paulmillr/chokidar#path-filtering) on "ignored".
|
||||
|
||||
`opts.poll` enables polling to monitor for changes. If set to `true`, then
|
||||
a polling interval of 100ms is used. If set to a number, then that amount of
|
||||
milliseconds will be the polling interval. For more info see Chokidar's
|
||||
[documentation](https://github.com/paulmillr/chokidar#performance) on
|
||||
"usePolling" and "interval".
|
||||
**This option is useful if you're watching an NFS volume.**
|
||||
|
||||
```js
|
||||
var b = browserify({ cache: {}, packageCache: {} });
|
||||
// watchify defaults:
|
||||
b.plugin(watchify, {
|
||||
delay: 100,
|
||||
ignoreWatch: ['**/node_modules/**'],
|
||||
poll: false
|
||||
});
|
||||
```
|
||||
|
||||
## b.close()
|
||||
|
||||
Close all the open watch handles.
|
||||
|
||||
# events
|
||||
|
||||
## b.on('update', function (ids) {})
|
||||
|
||||
When the bundle changes, emit the array of bundle `ids` that changed.
|
||||
|
||||
## b.on('bytes', function (bytes) {})
|
||||
|
||||
When a bundle is generated, this event fires with the number of bytes.
|
||||
|
||||
## b.on('time', function (time) {})
|
||||
|
||||
When a bundle is generated, this event fires with the time it took to create the
|
||||
bundle in milliseconds.
|
||||
|
||||
## b.on('log', function (msg) {})
|
||||
|
||||
This event fires after a bundle was created with messages of the form:
|
||||
|
||||
```
|
||||
X bytes written (Y seconds)
|
||||
```
|
||||
|
||||
with the number of bytes in the bundle X and the time in seconds Y.
|
||||
|
||||
# working with browserify transforms
|
||||
|
||||
If your custom transform for browserify adds new files to the bundle in a non-standard way without requiring.
|
||||
You can inform Watchify about these files by emiting a 'file' event.
|
||||
|
||||
```
|
||||
module.exports = function(file) {
|
||||
return through(
|
||||
function(buf, enc, next) {
|
||||
/*
|
||||
manipulating file content
|
||||
*/
|
||||
|
||||
this.emit("file", absolutePathToFileThatHasToBeWatched);
|
||||
|
||||
next();
|
||||
}
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```
|
||||
$ npm install -g watchify
|
||||
```
|
||||
|
||||
to get the watchify command and:
|
||||
|
||||
```
|
||||
$ npm install watchify
|
||||
```
|
||||
|
||||
to get just the library.
|
||||
|
||||
# troubleshooting
|
||||
|
||||
## rebuilds on OS X never trigger
|
||||
|
||||
It may be related to a bug in `fsevents` (see [#250](https://github.com/substack/watchify/issues/205#issuecomment-98672850)
|
||||
and [stackoverflow](http://stackoverflow.com/questions/26708205/webpack-watch-isnt-compiling-changed-files/28610124#28610124)).
|
||||
Try the `--poll` flag
|
||||
and/or renaming the project's directory - that might help.
|
||||
|
||||
## watchify swallows errors
|
||||
|
||||
To ensure errors are reported you have to add a event listener to your bundle stream. For more information see ([browserify/browserify#1487 (comment)](https://github.com/browserify/browserify/issues/1487#issuecomment-173357516) and [stackoverflow](https://stackoverflow.com/a/22389498/1423220))
|
||||
|
||||
**Example:**
|
||||
```
|
||||
var b = browserify();
|
||||
b.bundle()
|
||||
.on('error', console.error)
|
||||
...
|
||||
;
|
||||
```
|
||||
|
||||
# see also
|
||||
|
||||
- [budo](https://www.npmjs.com/package/budo) – a simple development server built on watchify
|
||||
- [errorify](https://www.npmjs.com/package/errorify) – a plugin to add error handling to watchify development
|
||||
- [watchify-request](https://www.npmjs.com/package/watchify-request) – wraps a `watchify` instance to avoid stale bundles in HTTP requests
|
||||
- [watchify-middleware](https://www.npmjs.com/package/watchify-middleware) – similar to `watchify-request`, but includes some higher-level features
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
44
node_modules/watchify/test/api.js
generated
vendored
Normal file
44
node_modules/watchify/test/api.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var file = path.join(tmpdir, 'main.js');
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(file, 'console.log(555)');
|
||||
|
||||
test('api', function (t) {
|
||||
t.plan(5);
|
||||
var w = watchify(browserify(file, watchify.args));
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '333\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '555\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFile(file, 'console.log(333)', function (err) {
|
||||
t.ifError(err);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
53
node_modules/watchify/test/api_brfs.js
generated
vendored
Normal file
53
node_modules/watchify/test/api_brfs.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
lines: path.join(tmpdir, 'lines.txt')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, [
|
||||
'var fs = require("fs");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase());'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.lines, 'beep\nboop');
|
||||
|
||||
test('api with brfs', function (t) {
|
||||
t.plan(5);
|
||||
var w = watchify(browserify(files.main, watchify.args));
|
||||
w.transform('brfs');
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'ROBO-BOOGIE\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'BEEP\nBOOP\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFile(files.lines, 'rObO-bOOgie', function (err) {
|
||||
t.ifError(err);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
60
node_modules/watchify/test/api_ignore_watch.js
generated
vendored
Normal file
60
node_modules/watchify/test/api_ignore_watch.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch', function (t) {
|
||||
t.plan(4);
|
||||
var w = watchify(browserify(files.main, watchify.args), {
|
||||
ignoreWatch: '**/be*.js'
|
||||
});
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'beep BOOP ROBOT\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'beep boop robot\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
60
node_modules/watchify/test/api_ignore_watch_default.js
generated
vendored
Normal file
60
node_modules/watchify/test/api_ignore_watch_default.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch default', function (t) {
|
||||
t.plan(4);
|
||||
var w = watchify(browserify(files.main, watchify.args), {
|
||||
ignoreWatch: true
|
||||
});
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'BEEP BOOP robot\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'beep boop robot\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
60
node_modules/watchify/test/api_ignore_watch_multiple.js
generated
vendored
Normal file
60
node_modules/watchify/test/api_ignore_watch_multiple.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch multiple paths', function (t) {
|
||||
t.plan(4);
|
||||
var w = watchify(browserify(files.main, watchify.args), {
|
||||
ignoreWatch: ['**/be*.js', '**/robot/*.js']
|
||||
});
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'beep BOOP robot\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'beep boop robot\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
44
node_modules/watchify/test/api_implicit_cache.js
generated
vendored
Normal file
44
node_modules/watchify/test/api_implicit_cache.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var file = path.join(tmpdir, 'main.js');
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(file, 'console.log(555)');
|
||||
|
||||
test('api implicit cache', function (t) {
|
||||
t.plan(5);
|
||||
var w = watchify(browserify(file));
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '333\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '555\n');
|
||||
setTimeout(function () {
|
||||
fs.writeFile(file, 'console.log(333)', function (err) {
|
||||
t.ifError(err);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
52
node_modules/watchify/test/bin.js
generated
vendored
Normal file
52
node_modules/watchify/test/bin.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, 'console.log(555)');
|
||||
|
||||
test('bin', function (t) {
|
||||
t.plan(5);
|
||||
var ps = spawn(cmd, [ files.main, '-o', files.bundle, '-v' ]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '555\n');
|
||||
fs.writeFile(files.main, 'console.log(333)', t.ifError);
|
||||
})
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '333\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
62
node_modules/watchify/test/bin_brfs.js
generated
vendored
Normal file
62
node_modules/watchify/test/bin_brfs.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
lines: path.join(tmpdir, 'lines.txt'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, [
|
||||
'var fs = require("fs");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase());'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.lines, 'beep\nboop');
|
||||
|
||||
test('bin brfs', function (t) {
|
||||
t.plan(5);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'-t', require.resolve('brfs'), '-v',
|
||||
'-o', files.bundle
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'BEEP\nBOOP\n');
|
||||
fs.writeFile(files.lines, 'robo-bOOgie', t.ifError);
|
||||
})
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'ROBO-BOOGIE\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
71
node_modules/watchify/test/bin_ignore_watch.js
generated
vendored
Normal file
71
node_modules/watchify/test/bin_ignore_watch.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch', function (t) {
|
||||
t.plan(4);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'--ignore-watch', '**/be*.js',
|
||||
'-o', files.bundle,
|
||||
'-v'
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'beep boop robot\n');
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
});
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'beep BOOP ROBOT\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
71
node_modules/watchify/test/bin_ignore_watch_default.js
generated
vendored
Normal file
71
node_modules/watchify/test/bin_ignore_watch_default.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch', function (t) {
|
||||
t.plan(4);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'--ignore-watch',
|
||||
'-o', files.bundle,
|
||||
'-v'
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'beep boop robot\n');
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
});
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'BEEP BOOP robot\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
72
node_modules/watchify/test/bin_ignore_watch_multiple.js
generated
vendored
Normal file
72
node_modules/watchify/test/bin_ignore_watch_multiple.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
robot: path.join(tmpdir, 'node_modules', 'robot', 'index.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.dirname(files.robot));
|
||||
fs.writeFileSync(files.main, [
|
||||
'var beep = require("./beep");',
|
||||
'var boop = require("./boop");',
|
||||
'var robot = require("robot");',
|
||||
'console.log(beep + " " + boop + " " + robot);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = "beep";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "boop";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "robot";');
|
||||
|
||||
test('api ignore watch multiple paths', function (t) {
|
||||
t.plan(4);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'--ignore-watch', '**/be*.js',
|
||||
'--ignore-watch', '**/robot/*.js',
|
||||
'-o', files.bundle,
|
||||
'-v'
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'beep boop robot\n');
|
||||
fs.writeFileSync(files.beep, 'module.exports = "BEEP";');
|
||||
fs.writeFileSync(files.boop, 'module.exports = "BOOP";');
|
||||
fs.writeFileSync(files.robot, 'module.exports = "ROBOT";');
|
||||
});
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, 'beep BOOP robot\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
56
node_modules/watchify/test/bin_pipe.js
generated
vendored
Normal file
56
node_modules/watchify/test/bin_pipe.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, 'console.log(num * 2)');
|
||||
|
||||
test('bin with pipe', function (t) {
|
||||
t.plan(5);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'-o', 'uglifyjs - --enclose 11:num > ' + files.bundle,
|
||||
'-v'
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '22\n');
|
||||
fs.writeFile(files.main, 'console.log(num * 3)', t.ifError);
|
||||
});
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '33\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
56
node_modules/watchify/test/bin_plugins_pipelining_multiple_errors.js
generated
vendored
Normal file
56
node_modules/watchify/test/bin_plugins_pipelining_multiple_errors.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
plugin: path.join(tmpdir, 'plugin.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.plugin, [
|
||||
'module.exports = function(b, opts) {',
|
||||
' b.on("file", function (file, id) {',
|
||||
' b.pipeline.emit("error", "bad boop");',
|
||||
' b.pipeline.emit("error", "bad boop");',
|
||||
' });',
|
||||
'};',
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.main, 'boop\nbeep');
|
||||
|
||||
test('bin plugins pipelining multiple errors', function (t) {
|
||||
t.plan(4);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'-p', files.plugin, '-v',
|
||||
'-o', files.bundle
|
||||
]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
t.equal(line, 'bad boop');
|
||||
}
|
||||
if (lineNum === 2) {
|
||||
t.equal(line, 'bad boop');
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(files.main, 'beep\nboop');
|
||||
}, 1000);
|
||||
}
|
||||
if (lineNum === 3) {
|
||||
t.equal(line, 'bad boop');
|
||||
}
|
||||
if (lineNum === 4) {
|
||||
t.equal(line, 'bad boop');
|
||||
ps.kill();
|
||||
}
|
||||
});
|
||||
});
|
52
node_modules/watchify/test/bin_standalone.js
generated
vendored
Normal file
52
node_modules/watchify/test/bin_standalone.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, 'console.log(555)');
|
||||
|
||||
test('bin with standalone', function (t) {
|
||||
t.plan(5);
|
||||
var ps = spawn(cmd, [ files.main, '-o', files.bundle, '-v', '-s', 'XXX' ]);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
lineNum ++;
|
||||
if (lineNum === 1) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '555\n');
|
||||
fs.writeFile(files.main, 'console.log(333)', t.ifError);
|
||||
})
|
||||
}
|
||||
else if (lineNum === 2) {
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, '333\n');
|
||||
ps.kill();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
56
node_modules/watchify/test/errors.js
generated
vendored
Normal file
56
node_modules/watchify/test/errors.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var file = path.join(tmpdir, 'main.js');
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(file, 'console.log(555)');
|
||||
|
||||
test('errors', function (t) {
|
||||
t.plan(5);
|
||||
var w = watchify(browserify(file, watchify.args));
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '555\n');
|
||||
breakTheBuild();
|
||||
});
|
||||
function breakTheBuild() {
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(file, 'console.log(');
|
||||
}, 1000);
|
||||
w.once('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ok(err instanceof Error, 'should be error');
|
||||
fixTheBuild();
|
||||
});
|
||||
});
|
||||
}
|
||||
function fixTheBuild() {
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(file, 'console.log(333)');
|
||||
}, 1000);
|
||||
w.once('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '333\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
83
node_modules/watchify/test/errors_transform.js
generated
vendored
Normal file
83
node_modules/watchify/test/errors_transform.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var through = require('through2');
|
||||
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var main = path.join(tmpdir, 'main.js');
|
||||
var file = path.join(tmpdir, 'dep.jsnum');
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(main, 'require("./dep.jsnum")');
|
||||
fs.writeFileSync(file, 'console.log(555)');
|
||||
|
||||
function someTransform(file) {
|
||||
if (!/\.jsnum$/.test(file)) {
|
||||
return through();
|
||||
}
|
||||
function write (chunk, enc, next) {
|
||||
if (/\d/.test(chunk)) {
|
||||
this.push(chunk);
|
||||
} else {
|
||||
this.emit('error', new Error('No number in this chunk'));
|
||||
}
|
||||
next();
|
||||
}
|
||||
return through(write);
|
||||
}
|
||||
|
||||
test('errors in transform', function (t) {
|
||||
t.plan(6);
|
||||
var b = browserify(main, watchify.args);
|
||||
b.transform(someTransform);
|
||||
var w = watchify(b);
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '555\n');
|
||||
breakTheBuild();
|
||||
});
|
||||
function breakTheBuild() {
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(file, 'console.log()');
|
||||
}, 1000);
|
||||
w.once('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ok(err instanceof Error, 'should be error');
|
||||
t.ok(/^No number in this chunk/.test(err.message));
|
||||
fixTheBuild();
|
||||
});
|
||||
});
|
||||
}
|
||||
function fixTheBuild() {
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(file, 'console.log(333)');
|
||||
}, 1000);
|
||||
var safety = setTimeout(function() {
|
||||
t.fail("gave up waiting");
|
||||
w.close();
|
||||
t.end();
|
||||
}, 5000);
|
||||
w.once('update', function () {
|
||||
clearTimeout(safety);
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), '333\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
72
node_modules/watchify/test/expose.js
generated
vendored
Normal file
72
node_modules/watchify/test/expose.js
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
var test = require('tape');
|
||||
var watchify = require('../');
|
||||
var browserify = require('browserify');
|
||||
var vm = require('vm');
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
||||
var os = require('os');
|
||||
var tmpbase = fs.realpathSync((os.tmpdir || os.tmpDir)());
|
||||
var tmpdir = path.join(tmpbase, 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
beep: path.join(tmpdir, 'beep.js'),
|
||||
boop: path.join(tmpdir, 'boop.js'),
|
||||
abc: path.join(tmpdir, 'lib', 'abc.js'),
|
||||
xyz: path.join(tmpdir, 'lib', 'xyz.js')
|
||||
};
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
mkdirp.sync(path.join(tmpdir, 'lib'));
|
||||
|
||||
fs.writeFileSync(files.main, [
|
||||
'var abc = require("abc");',
|
||||
'var xyz = require("xyz");',
|
||||
'var beep = require("./beep");',
|
||||
'console.log(abc + " " + xyz + " " + beep);'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.beep, 'module.exports = require("./boop");');
|
||||
fs.writeFileSync(files.boop, 'module.exports = require("xyz");');
|
||||
fs.writeFileSync(files.abc, 'module.exports = "abc";');
|
||||
fs.writeFileSync(files.xyz, 'module.exports = "xyz";');
|
||||
|
||||
test('properly caches exposed files', function (t) {
|
||||
t.plan(4);
|
||||
var cache = {};
|
||||
var w = watchify(browserify({
|
||||
entries: [files.main],
|
||||
basedir: tmpdir,
|
||||
cache: cache,
|
||||
packageCache: {}
|
||||
}));
|
||||
|
||||
w.require('./lib/abc', {expose: 'abc'});
|
||||
w.require('./lib/xyz', {expose: 'xyz'});
|
||||
w.on('update', function () {
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'ABC XYZ XYZ\n');
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
w.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
t.equal(run(src), 'abc xyz xyz\n');
|
||||
setTimeout(function () {
|
||||
// If we're incorrectly caching exposed files,
|
||||
// then "files.abc" would be re-read from disk.
|
||||
cache[files.abc].source = 'module.exports = "ABC";';
|
||||
fs.writeFileSync(files.xyz, 'module.exports = "XYZ";');
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
function run (src) {
|
||||
var output = '';
|
||||
function log (msg) { output += msg + '\n' }
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
return output;
|
||||
}
|
101
node_modules/watchify/test/many.js
generated
vendored
Normal file
101
node_modules/watchify/test/many.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
robot: path.join(tmpdir, 'robot.js'),
|
||||
lines: path.join(tmpdir, 'lines.txt'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
var edits = [
|
||||
{ file: 'lines', source: 'robo-boogie' },
|
||||
{ file: 'lines', source: 'dinosaurus rex' },
|
||||
{
|
||||
file: 'robot',
|
||||
source: 'module.exports = function (n) { return n * 111 }',
|
||||
next: true
|
||||
},
|
||||
{ file: 'main', source: [
|
||||
'var fs = require("fs");',
|
||||
'var robot = require("./robot.js");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase() + " " + robot(src.length));'
|
||||
].join('\n') },
|
||||
{ file: 'lines', source: 't-rex' },
|
||||
{
|
||||
file: 'robot',
|
||||
source: 'module.exports = function (n) { return n * 100 }',
|
||||
}
|
||||
];
|
||||
|
||||
var expected = [
|
||||
'BEEP\nBOOP\n',
|
||||
'ROBO-BOOGIE\n',
|
||||
'DINOSAURUS REX\n',
|
||||
'DINOSAURUS REX 1554\n',
|
||||
'T-REX 555\n',
|
||||
'T-REX 500\n'
|
||||
];
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, [
|
||||
'var fs = require("fs");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase());'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.lines, 'beep\nboop');
|
||||
|
||||
test('many edits', function (t) {
|
||||
t.plan(expected.length * 2 + edits.length);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'-t', require.resolve('brfs'), '-v',
|
||||
'-o', files.bundle
|
||||
]);
|
||||
ps.stdout.pipe(process.stdout);
|
||||
ps.stderr.pipe(process.stdout);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
if (line.length === 0) return;
|
||||
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, expected.shift());
|
||||
|
||||
(function next () {
|
||||
if (edits.length === 0) return;
|
||||
var edit = edits.shift();
|
||||
setTimeout(function () {
|
||||
fs.writeFile(files[edit.file], edit.source, function (err) {
|
||||
t.ifError(err);
|
||||
if (edit.next) next();
|
||||
});
|
||||
}, 25);
|
||||
})();
|
||||
})
|
||||
});
|
||||
|
||||
t.on('end', function () {
|
||||
ps.kill();
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
99
node_modules/watchify/test/many_immediate.js
generated
vendored
Normal file
99
node_modules/watchify/test/many_immediate.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
var test = require('tape');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var mkdirp = require('mkdirp');
|
||||
var spawn = require('win-spawn');
|
||||
var split = require('split');
|
||||
|
||||
var cmd = path.resolve(__dirname, '../bin/cmd.js');
|
||||
var os = require('os');
|
||||
var tmpdir = path.join((os.tmpdir || os.tmpDir)(), 'watchify-' + Math.random());
|
||||
|
||||
var files = {
|
||||
main: path.join(tmpdir, 'main.js'),
|
||||
robot: path.join(tmpdir, 'robot.js'),
|
||||
lines: path.join(tmpdir, 'lines.txt'),
|
||||
bundle: path.join(tmpdir, 'bundle.js')
|
||||
};
|
||||
|
||||
var edits = [
|
||||
{ file: 'lines', source: 'robo-boogie' },
|
||||
{ file: 'lines', source: 'dinosaurus rex' },
|
||||
{
|
||||
file: 'robot',
|
||||
source: 'module.exports = function (n) { return n * 111 }',
|
||||
next: true
|
||||
},
|
||||
{ file: 'main', source: [
|
||||
'var fs = require("fs");',
|
||||
'var robot = require("./robot.js");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase() + " " + robot(src.length));'
|
||||
].join('\n') },
|
||||
{ file: 'lines', source: 't-rex' },
|
||||
{
|
||||
file: 'robot',
|
||||
source: 'module.exports = function (n) { return n * 100 }',
|
||||
}
|
||||
];
|
||||
|
||||
var expected = [
|
||||
'BEEP\nBOOP\n',
|
||||
'ROBO-BOOGIE\n',
|
||||
'DINOSAURUS REX\n',
|
||||
'DINOSAURUS REX 1554\n',
|
||||
'T-REX 555\n',
|
||||
'T-REX 500\n'
|
||||
];
|
||||
|
||||
mkdirp.sync(tmpdir);
|
||||
fs.writeFileSync(files.main, [
|
||||
'var fs = require("fs");',
|
||||
'var src = fs.readFileSync(__dirname + "/lines.txt", "utf8");',
|
||||
'console.log(src.toUpperCase());'
|
||||
].join('\n'));
|
||||
fs.writeFileSync(files.lines, 'beep\nboop');
|
||||
|
||||
test('many immediate', function (t) {
|
||||
t.plan(expected.length * 2 + edits.length);
|
||||
var ps = spawn(cmd, [
|
||||
files.main,
|
||||
'-t', require.resolve('brfs'), '-v',
|
||||
'-o', files.bundle
|
||||
]);
|
||||
ps.stdout.pipe(process.stdout);
|
||||
ps.stderr.pipe(process.stdout);
|
||||
var lineNum = 0;
|
||||
ps.stderr.pipe(split()).on('data', function (line) {
|
||||
if (line.length === 0) return;
|
||||
|
||||
run(files.bundle, function (err, output) {
|
||||
t.ifError(err);
|
||||
t.equal(output, expected.shift());
|
||||
|
||||
(function next () {
|
||||
if (edits.length === 0) return;
|
||||
var edit = edits.shift();
|
||||
fs.writeFile(files[edit.file], edit.source, function (err) {
|
||||
t.ifError(err);
|
||||
if (edit.next) next();
|
||||
});
|
||||
})();
|
||||
})
|
||||
});
|
||||
|
||||
t.on('end', function () {
|
||||
ps.kill();
|
||||
});
|
||||
});
|
||||
|
||||
function run (file, cb) {
|
||||
var ps = spawn(process.execPath, [ file ]);
|
||||
var data = [];
|
||||
ps.stdout.on('data', function (buf) { data.push(buf) });
|
||||
ps.stdout.on('end', function () {
|
||||
cb(null, Buffer.concat(data).toString('utf8'));
|
||||
});
|
||||
ps.on('error', cb);
|
||||
return ps;
|
||||
}
|
10
node_modules/watchify/test/zzz.js
generated
vendored
Normal file
10
node_modules/watchify/test/zzz.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
var test = require('tape');
|
||||
|
||||
test('__END__', function (t) {
|
||||
t.on('end', function () {
|
||||
setTimeout(function () {
|
||||
process.exit(0);
|
||||
}, 100)
|
||||
});
|
||||
t.end();
|
||||
});
|
Reference in New Issue
Block a user