Commit project

This commit is contained in:
Rodrigo Pedroso 2019-06-19 10:46:14 -04:00
commit 3ac017a5ad
1030 changed files with 94062 additions and 0 deletions

4
node_modules/nodemon/lib/monitor/index.js generated vendored Normal file
View file

@ -0,0 +1,4 @@
module.exports = {
run: require('./run'),
watch: require('./watch').watch,
};

244
node_modules/nodemon/lib/monitor/match.js generated vendored Normal file
View file

@ -0,0 +1,244 @@
var minimatch = require('minimatch');
var path = require('path');
var fs = require('fs');
var utils = require('../utils');
module.exports = match;
module.exports.rulesToMonitor = rulesToMonitor;
function rulesToMonitor(watch, ignore, config) {
var monitor = [];
if (!Array.isArray(ignore)) {
if (ignore) {
ignore = [ignore];
} else {
ignore = [];
}
}
if (!Array.isArray(watch)) {
if (watch) {
watch = [watch];
} else {
watch = [];
}
}
if (watch && watch.length) {
monitor = utils.clone(watch);
}
if (ignore) {
[].push.apply(monitor, (ignore || []).map(function (rule) {
return '!' + rule;
}));
}
var cwd = process.cwd();
// next check if the monitored paths are actual directories
// or just patterns - and expand the rule to include *.*
monitor = monitor.map(function (rule) {
var not = rule.slice(0, 1) === '!';
if (not) {
rule = rule.slice(1);
}
if (rule === '.' || rule === '.*') {
rule = '*.*';
}
var dir = path.resolve(cwd, rule);
try {
var stat = fs.statSync(dir);
if (stat.isDirectory()) {
rule = dir;
if (rule.slice(-1) !== '/') {
rule += '/';
}
rule += '**/*';
// `!not` ... sorry.
if (!not) {
config.dirs.push(dir);
}
} else {
// ensures we end up in the check that tries to get a base directory
// and then adds it to the watch list
throw new Error();
}
} catch (e) {
var base = tryBaseDir(dir);
if (!not && base) {
if (config.dirs.indexOf(base) === -1) {
config.dirs.push(base);
}
}
}
if (rule.slice(-1) === '/') {
// just slap on a * anyway
rule += '*';
}
// if the url ends with * but not **/* and not *.*
// then convert to **/* - somehow it was missed :-\
if (rule.slice(-4) !== '**/*' &&
rule.slice(-1) === '*' &&
rule.indexOf('*.') === -1) {
rule += '*/*';
}
return (not ? '!' : '') + rule;
});
return monitor;
}
function tryBaseDir(dir) {
var stat;
if (/[?*\{\[]+/.test(dir)) { // if this is pattern, then try to find the base
try {
var base = path.dirname(dir.replace(/([?*\{\[]+.*$)/, 'foo'));
stat = fs.statSync(base);
if (stat.isDirectory()) {
return base;
}
} catch (error) {
// console.log(error);
}
} else {
try {
stat = fs.statSync(dir);
// if this path is actually a single file that exists, then just monitor
// that, *specifically*.
if (stat.isFile() || stat.isDirectory()) {
return dir;
}
} catch (e) {}
}
return false;
}
function match(files, monitor, ext) {
// sort the rules by highest specificity (based on number of slashes)
// ignore rules (!) get sorted highest as they take precedent
// TODO actually check separator rules work on windows
var rules = monitor.sort(function (a, b) {
var r = b.split(path.sep).length - a.split(path.sep).length;
var aIsIgnore = a.slice(0, 1) === '!';
var bIsIgnore = b.slice(0, 1) === '!';
if (aIsIgnore || bIsIgnore) {
if (aIsIgnore) {
return -1;
} else {
return 1;
}
}
if (r === 0) {
return b.length - a.length;
}
return r;
}).map(function (s) {
var prefix = s.slice(0, 1);
if (prefix === '!') {
return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1);
} else if (s.slice(0, 2) === '..') {
return path.resolve(process.cwd(), s);
}
return '**' + (prefix !== path.sep ? path.sep : '') + s;
});
var good = [];
var whitelist = []; // files that we won't check against the extension
var ignored = 0;
var watched = 0;
var usedRules = [];
var minimatchOpts = {};
// enable case-insensitivity on Windows
if (utils.isWindows) {
minimatchOpts.nocase = true;
}
files.forEach(function (file) {
var matched = false;
for (var i = 0; i < rules.length; i++) {
if (rules[i].slice(0, 1) === '!') {
if (!minimatch(file, rules[i], minimatchOpts)) {
ignored++;
matched = true;
break;
}
} else {
if (minimatch(file, rules[i], minimatchOpts)) {
watched++;
// don't repeat the output if a rule is matched
if (usedRules.indexOf(rules[i]) === -1) {
usedRules.push(rules[i]);
utils.log.detail('matched rule: ' + rules[i]);
}
// if the rule doesn't match the WATCH EVERYTHING
// but *does* match a rule that ends with *.*, then
// white list it - in that we don't run it through
// the extension check too.
if (rules[i] !== '**' + path.sep + '*.*' &&
rules[i].slice(-3) === '*.*') {
whitelist.push(file);
} else if (path.basename(file) === path.basename(rules[i])) {
// if the file matches the actual rule, then it's put on whitelist
whitelist.push(file);
} else {
good.push(file);
}
matched = true;
break;
}
}
}
if (!matched) {
ignored++;
}
});
// finally check the good files against the extensions that we're monitoring
if (ext) {
if (ext.indexOf(',') === -1) {
ext = '**/*.' + ext;
} else {
ext = '**/*.{' + ext + '}';
}
good = good.filter(function (file) {
// only compare the filename to the extension test
return minimatch(path.basename(file), ext, minimatchOpts);
});
} // else assume *.*
var result = good.concat(whitelist);
if (utils.isWindows) {
// fix for windows testing - I *think* this is okay to do
result = result.map(function (file) {
return file.slice(0, 1).toLowerCase() + file.slice(1);
});
}
return {
result: result,
ignored: ignored,
watched: watched,
total: files.length,
};
}

370
node_modules/nodemon/lib/monitor/run.js generated vendored Normal file
View file

@ -0,0 +1,370 @@
var debug = require('debug')('nodemon');
var utils = require('../utils');
var bus = utils.bus;
var childProcess = require('child_process');
var spawn = childProcess.spawn;
var exec = childProcess.exec;
var watch = require('./watch').watch;
var config = require('../config');
var child = null; // the actual child process we spawn
var killedAfterChange = false;
var noop = function () {};
var restart = null;
var psTree = require('ps-tree');
var hasPS = true;
var path = require('path');
// discover if the OS has `ps`, and therefore can use psTree
exec('ps', function (error) {
if (error) {
hasPS = false;
}
});
function run(options) {
var cmd = config.command.raw;
var runCmd = !options.runOnChangeOnly || config.lastStarted !== 0;
if (runCmd) {
utils.log.status('starting `' + config.command.string + '`');
}
/*jshint validthis:true*/
restart = run.bind(this, options);
run.restart = restart;
config.lastStarted = Date.now();
var stdio = ['pipe', 'pipe', 'pipe'];
if (config.options.stdout) {
stdio = ['pipe',
process.stdout,
process.stderr,];
}
var sh = 'sh';
var shFlag = '-c';
if (utils.isWindows) {
sh = 'cmd';
shFlag = '/c';
}
var executable = cmd.executable;
if (utils.isWindows) {
// under windows if the executable path contains a forward slash, that will
// fail with cmd.exe, so we need to normalize it
if (executable.indexOf('/') !== -1) {
executable = path.normalize(executable);
}
// if the executable path contains a space the whole string must be quoted
// to get windows treat it as 1 argument for cmd.exe
if (executable.indexOf(' ') !== -1 && executable[0] !== '\"'
&& executable[executable.length - 1] !== '\"') {
// remove all quotes from executable (possible backward compat hacks)
executable = executable.replace (/\"/g, '');
}
}
var args = runCmd ? utils.stringify(executable, cmd.args) : ':';
var spawnArgs = [sh, [shFlag, args]];
debug('spawning', args);
if (utils.version.major === 0 && utils.version.minor < 8) {
// use the old spawn args :-\
} else {
spawnArgs.push({
env: utils.merge(options.execOptions.env, process.env),
stdio: stdio,
});
}
child = spawn.apply(null, spawnArgs);
if (config.required) {
var emit = {
stdout: function (data) {
bus.emit('stdout', data);
},
stderr: function (data) {
bus.emit('stderr', data);
},
};
// now work out what to bind to...
if (config.options.stdout) {
child.on('stdout', emit.stdout).on('stderr', emit.stderr);
} else {
child.stdout.on('data', emit.stdout);
child.stderr.on('data', emit.stderr);
bus.stdout = child.stdout;
bus.stderr = child.stderr;
}
}
bus.emit('start');
utils.log.detail('child pid: ' + child.pid);
child.on('error', function (error) {
bus.emit('error', error);
if (error.code === 'ENOENT') {
utils.log.error('unable to run executable: "' + cmd.executable + '"');
process.exit(1);
} else {
utils.log.error('failed to start child process: ' + error.code);
throw error;
}
});
child.on('exit', function (code, signal) {
if (code === 127) {
utils.log.error('failed to start process, "' + cmd.executable +
'" exec not found');
bus.emit('error', code);
process.exit();
}
if (code === 2) {
// something wrong with parsed command
utils.log.error('failed to start process, possible issue with exec ' +
'arguments');
bus.emit('error', code);
process.exit();
}
// In case we killed the app ourselves, set the signal thusly
if (killedAfterChange) {
killedAfterChange = false;
signal = config.signal;
}
// this is nasty, but it gives it windows support
if (utils.isWindows && signal === 'SIGTERM') {
signal = config.signal;
}
if (signal === config.signal || code === 0) {
// this was a clean exit, so emit exit, rather than crash
debug('bus.emit(exit) via ' + config.signal);
bus.emit('exit');
// exit the monitor, but do it gracefully
if (signal === config.signal) {
return restart();
} else if (code === 0) { // clean exit - wait until file change to restart
if (runCmd) {
utils.log.status('clean exit - waiting for changes before restart');
}
child = null;
}
} else {
bus.emit('crash');
if (options.exitcrash) {
utils.log.fail('app crashed');
if (!config.required) {
process.exit(1);
}
} else {
utils.log.fail('app crashed - waiting for file changes before' +
' starting...');
child = null;
}
}
if (config.options.restartable) {
// stdin needs to kick in again to be able to listen to the
// restart command
process.stdin.resume();
}
});
run.kill = function (noRestart, callback) {
// I hate code like this :( - Remy (author of said code)
if (typeof noRestart === 'function') {
callback = noRestart;
noRestart = false;
}
if (!callback) {
callback = noop;
}
if (child !== null) {
// if the stdin piping is on, we need to unpipe, but also close stdin on
// the child, otherwise linux can throw EPIPE or ECONNRESET errors.
if (options.stdin) {
if (process.stdin.unpipe) { // node > 0.8
process.stdin.unpipe(child.stdin);
}
}
if (utils.isWindows) {
// For the on('exit', ...) handler above the following looks like a
// crash, so we set the killedAfterChange flag
killedAfterChange = true;
}
/* Now kill the entire subtree of processes belonging to nodemon */
var oldPid = child.pid;
if (child) {
kill(child, config.signal, function () {
// this seems to fix the 0.11.x issue with the "rs" restart command,
// though I'm unsure why. it seems like more data is streamed in to
// stdin after we close.
if (child && options.stdin && oldPid === child.pid) {
// this is stupid and horrible, but node 0.12 on windows blows up
// with this line, so we'll skip it entirely.
if (!utils.isWindows) {
child.stdin.end();
}
}
callback();
});
}
} else if (!noRestart) {
// if there's no child, then we need to manually start the process
// this is because as there was no child, the child.on('exit') event
// handler doesn't exist which would normally trigger the restart.
bus.once('start', callback);
restart();
} else {
callback();
}
};
// connect stdin to the child process (options.stdin is on by default)
if (options.stdin) {
process.stdin.resume();
// FIXME decide whether or not we need to decide the encoding
// process.stdin.setEncoding('utf8');
process.stdin.pipe(child.stdin);
bus.once('exit', function () {
if (child && process.stdin.unpipe) { // node > 0.8
process.stdin.unpipe(child.stdin);
}
});
}
debug('start watch on: %s', config.options.watch);
if (config.options.watch !== false) {
watch();
}
}
function kill(child, signal, callback) {
if (!callback) {
callback = function () {};
}
if (utils.isWindows) {
// When using CoffeeScript under Windows, child's process is not node.exe
// Instead coffee.cmd is launched, which launches cmd.exe, which starts
// node.exe as a child process child.kill() would only kill cmd.exe, not
// node.exe
// Therefore we use the Windows taskkill utility to kill the process and all
// its children (/T for tree).
// Force kill (/F) the whole child tree (/T) by PID (/PID 123)
exec('taskkill /pid ' + child.pid + ' /T /F');
callback();
} else {
if (hasPS) {
// we use psTree to kill the full subtree of nodemon, because when
// spawning processes like `coffee` under the `--debug` flag, it'll spawn
// it's own child, and that can't be killed by nodemon, so psTree gives us
// an array of PIDs that have spawned under nodemon, and we send each the
// configured signal (defaul: SIGUSR2) signal, which fixes #335
psTree(child.pid, function (err, kids) {
spawn('kill', ['-s', signal, child.pid].concat(kids.map(function (p) {
return p.PID;
}))).on('close', callback);
});
} else {
exec('kill -s ' + signal + ' ' + child.pid, function () {
// ignore if the process has been killed already
callback();
});
}
}
}
// stubbed out for now, filled in during run
run.kill = function (flag, callback) {
if (callback) {
callback();
}
};
run.restart = noop;
bus.on('quit', function onQuit() {
// remove event listener
var exitTimer = null;
var exit = function () {
clearTimeout(exitTimer);
exit = noop; // null out in case of race condition
child = null;
if (!config.required) {
// Execute all other quit listeners.
bus.listeners('quit').forEach(function (listener) {
if (listener !== onQuit) {
listener();
}
});
process.exit(0);
} else {
bus.emit('exit');
}
};
// if we're not running already, don't bother with trying to kill
if (config.run === false) {
return exit();
}
// immediately try to stop any polling
config.run = false;
if (child) {
// give up waiting for the kids after 10 seconds
exitTimer = setTimeout(exit, 10 * 1000);
child.removeAllListeners('exit');
child.once('exit', exit);
kill(child, 'SIGINT');
} else {
exit();
}
});
bus.on('restart', function () {
// run.kill will send a SIGINT to the child process, which will cause it
// to terminate, which in turn uses the 'exit' event handler to restart
run.kill();
});
// remove the flag file on exit
process.on('exit', function () {
utils.log.detail('exiting');
if (child) { child.kill(); }
});
// because windows borks when listening for the SIG* events
if (!utils.isWindows) {
// usual suspect: ctrl+c exit
process.once('SIGINT', function () {
bus.emit('quit');
});
process.once('SIGTERM', function () {
bus.emit('quit');
if (child) { child.kill('SIGTERM'); }
process.exit(0);
});
}
module.exports = run;

175
node_modules/nodemon/lib/monitor/watch.js generated vendored Normal file
View file

@ -0,0 +1,175 @@
module.exports.watch = watch;
module.exports.resetWatchers = resetWatchers;
var debug = require('debug')('nodemon:watch');
var debugRoot = require('debug')('nodemon');
var Promise = require('es6-promise').Promise; // jshint ignore:line
var chokidar = require('chokidar');
var undefsafe = require('undefsafe');
var config = require('../config');
var path = require('path');
var utils = require('../utils');
var bus = utils.bus;
var match = require('./match');
var watchers = [];
var debouncedBus;
bus.on('reset', resetWatchers);
function resetWatchers() {
debug('resetting watchers');
watchers.forEach(function (watcher) {
watcher.close();
});
watchers = [];
}
function watch() {
if (watchers.length) {
debug('early exit on watch, still watching (%s)', watchers.length);
return;
}
var dirs = [].slice.call(config.dirs);
debugRoot('start watch on: %s', dirs.join(', '));
debugRoot('ignore dirs regex(%s)', config.options.ignore.re);
var promises = [];
var watchedFiles = [];
dirs.forEach(function (dir) {
var promise = new Promise(function (resolve) {
var ignored = config.options.ignore.re;
var dotFilePattern = /[\/\\]\./;
// don't ignore dotfiles if explicitly watched.
if (!dir.match(dotFilePattern)) {
ignored = [ignored, dotFilePattern];
}
var watcher = chokidar.watch(dir, {
ignored: ignored,
persistent: true,
usePolling: config.options.legacyWatch || false,
interval: config.options.pollingInterval,
});
watcher.ready = false;
var total = 0;
watcher.on('change', filterAndRestart);
watcher.on('add', function (file) {
if (watcher.ready) {
return filterAndRestart(file);
}
watchedFiles.push(file);
total++;
debug('watching dir: %s', file);
});
watcher.on('ready', function () {
watcher.ready = true;
resolve(total);
debugRoot('watch is complete');
});
watcher.on('error', function (error) {
if (error.code === 'EINVAL') {
utils.log.error('Internal watch failed. Likely cause: too many ' +
'files being watched (perhaps from the root of a drive?\n' +
'See https://github.com/paulmillr/chokidar/issues/229 for details');
} else {
utils.log.error('Internal watch failed: ' + error.message);
process.exit(1);
}
});
watchers.push(watcher);
});
promises.push(promise);
});
return Promise.all(promises).then(function (res) {
var total = res.reduce(function (acc, curr) {
acc += curr;
return acc;
}, 0);
var count = total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
utils.log.detail('watching ' + count + ' files');
return watchedFiles;
});
}
function filterAndRestart(files) {
if (!Array.isArray(files)) {
files = [files];
}
if (files.length) {
if (utils.isWindows) {
// ensure the drive letter is in uppercase (c:\foo -> C:\foo)
files = files.map(function (f) {
return f[0].toUpperCase() + f.slice(1);
});
}
var cwd = process.cwd();
utils.log.detail('files triggering change check: ' +
files.map(function (file) {
return path.relative(cwd, file);
}).join(', '));
var matched = match(
files,
config.options.monitor,
undefsafe(config, 'options.execOptions.ext')
);
utils.log.detail('changes after filters (before/after): ' +
[files.length, matched.result.length].join('/'));
// reset the last check so we're only looking at recently modified files
config.lastStarted = Date.now();
if (matched.result.length) {
if (config.options.delay > 0) {
utils.log.detail('delaying restart for ' + config.options.delay + 'ms');
if (debouncedBus === undefined) {
debouncedBus = debounce(restartBus, config.options.delay);
}
debouncedBus(matched);
} else {
return restartBus(matched);
}
}
}
}
function restartBus(matched) {
utils.log.status('restarting due to changes...');
matched.result.map(function (file) {
utils.log.detail(path.relative(process.cwd(), file));
});
if (config.options.verbose) {
utils.log._log('');
}
bus.emit('restart', matched.result);
}
function debounce(fn, delay) {
var timer = null;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}