style Dashboard

This commit is contained in:
Lieu Le
2019-09-13 11:27:52 +07:00
parent 558fb07261
commit 07322c9084
17151 changed files with 1686347 additions and 103 deletions

View File

@@ -0,0 +1,63 @@
/*
* grunt-contrib-watch
* http://gruntjs.com/
*
* Copyright (c) 2018 "Cowboy" Ben Alman, contributors
* Licensed under the MIT license.
*/
'use strict';
var tinylr = require('tiny-lr');
var _ = require('lodash');
// Holds the servers out of scope in case watch is reloaded
var servers = Object.create(null);
module.exports = function(grunt) {
var defaults = {port: 35729};
function LR(options) {
if (options === true) {
options = defaults;
} else if (typeof options === 'number') {
options = {port: options};
} else {
options = _.defaults(options, defaults);
}
var host = (options.host || '*') + ':' + options.port;
if (servers[host]) {
this.server = servers[host];
} else {
this.server = tinylr(options);
this.server.server.removeAllListeners('error');
this.server.server.on('error', function(err) {
if (err.code === 'EADDRINUSE') {
grunt.fatal('Port ' + options.port + ' is already in use by another process.');
} else {
grunt.fatal(err);
}
process.exit(1);
});
this.server.listen(options.port, options.host, function(err) {
if (err) {
return grunt.fatal(err);
}
grunt.log.verbose.writeln('Live reload server started on ' + host);
});
servers[host] = this.server;
}
}
LR.prototype.trigger = function(files) {
grunt.log.verbose.writeln('Live reloading ' + grunt.log.wordlist(files) + '...');
this.server.changed({body: {files: files}});
};
return function(options) {
return new LR(options);
};
};

110
node_modules/grunt-contrib-watch/tasks/lib/taskrun.js generated vendored Normal file
View File

@@ -0,0 +1,110 @@
/*
* grunt-contrib-watch
* http://gruntjs.com/
*
* Copyright (c) 2018 "Cowboy" Ben Alman, contributors
* Licensed under the MIT license.
*/
'use strict';
module.exports = function(grunt) {
// Create a TaskRun on a target
function TaskRun(target) {
this.name = target.name || 0;
this.files = target.files || [];
this._getConfig = target._getConfig;
this.options = target.options;
this.startedAt = false;
this.spawned = null;
this.changedFiles = Object.create(null);
this.spawnTaskFailure = false;
this.livereloadOnError = true;
if (typeof this.options.livereloadOnError !== 'undefined') {
this.livereloadOnError = this.options.livereloadOnError;
}
}
var getErrorCount = function() {
if (typeof grunt.fail.forever_warncount !== 'undefined') {
return grunt.fail.forever_warncount + grunt.fail.forever_errorcount;
} else {
return grunt.fail.warncount + grunt.fail.errorcount;
}
};
// Run it
TaskRun.prototype.run = function(done) {
var self = this;
// Dont run if already running
if (self.startedAt !== false) {
return;
}
// Start this task run
self.startedAt = Date.now();
// reset before each run
self.spawnTaskFailure = false;
self.errorsAndWarningsCount = getErrorCount();
// pull the tasks here in case they were changed by a watch event listener
self.tasks = self._getConfig('tasks') || [];
if (typeof self.tasks === 'string') {
self.tasks = [self.tasks];
}
// If no tasks just call done to trigger potential livereload
if (self.tasks.length < 1) {
return done();
}
if (self.options.spawn === false || self.options.nospawn === true) {
grunt.task.run(self.tasks);
done();
} else {
self.spawned = grunt.util.spawn({
// Spawn with the grunt bin
grunt: true,
// Run from current working dir and inherit stdio from process
opts: {
cwd: self.options.cwd.spawn,
stdio: 'inherit'
},
// Run grunt this process uses, append the task to be run and any cli options
args: self.tasks.concat(self.options.cliArgs || [])
}, function(err, res, code) {
self.spawnTaskFailure = (code !== 0);
if (self.options.interrupt !== true || (code !== 130 && code !== 1)) {
// Spawn is done
self.spawned = null;
done();
}
});
}
};
// When the task run has completed
TaskRun.prototype.complete = function() {
var time = Date.now() - this.startedAt;
this.startedAt = false;
if (this.spawned) {
this.spawned.kill('SIGINT');
this.spawned = null;
}
var taskFailed = this.spawnTaskFailure || (getErrorCount() > this.errorsAndWarningsCount);
this.errorsAndWarningsCount = getErrorCount();
// Trigger livereload if necessary
if (this.livereload && (this.livereloadOnError || !taskFailed)) {
this.livereload.trigger(Object.keys(this.changedFiles));
this.changedFiles = Object.create(null);
}
return time;
};
return TaskRun;
};

View File

@@ -0,0 +1,387 @@
/*
* grunt-contrib-watch
* http://gruntjs.com/
*
* Copyright (c) 2018 "Cowboy" Ben Alman, contributors
* Licensed under the MIT license.
*/
'use strict';
var path = require('path');
var EE = require('events').EventEmitter;
var util = require('util');
var _ = require('lodash');
var async = require('async');
// Track which targets to run after reload
var reloadTargets = [];
// A default target name for config where targets are not used (keep this unique)
var defaultTargetName = '_$_default_$_';
module.exports = function(grunt) {
var TaskRun = require('./taskrun')(grunt);
var livereload = require('./livereload')(grunt);
function Runner() {
EE.call(this);
// Name of the task
this.name = 'watch';
// Options for the runner
this.options = {};
// Function to close the task
this.done = function() {};
// Targets available to task run
this.targets = Object.create(null);
// The queue of task runs
this.queue = [];
// Whether we're actively running tasks
this.running = false;
// If a nospawn task has ran (and needs the watch to restart)
this.nospawn = false;
// Set to true before run() to reload task
this.reload = false;
// For re-queuing arguments with the task that originally ran this
this.nameArgs = [];
// A list of changed files to feed to task runs for livereload
this.changedFiles = Object.create(null);
}
util.inherits(Runner, EE);
// Init a task for taskrun
Runner.prototype.init = function init(name, defaults, done) {
var self = this;
self.name = name || grunt.task.current.name || 'watch';
self.options = self._options(grunt.config([self.name, 'options']) || {}, defaults || {});
self.reload = false;
self.nameArgs = grunt.task.current.nameArgs ? grunt.task.current.nameArgs : self.name;
// Normalize cwd option
if (typeof self.options.cwd === 'string') {
self.options.cwd = {files: self.options.cwd, spawn: self.options.cwd};
}
// Function to call when closing the task
self.done = done || grunt.task.current.async();
// If a default livereload server for all targets
// Use task level unless target level overrides
var taskLRConfig = grunt.config([self.name, 'options', 'livereload']);
if (self.options.target && taskLRConfig) {
var targetLRConfig = grunt.config([self.name, self.options.target, 'options', 'livereload']);
if (targetLRConfig) {
// Dont use task level as target level will be used instead
taskLRConfig = false;
}
}
if (taskLRConfig) {
self.livereload = livereload(taskLRConfig);
}
// Return the targets normalized
var targets = self._getTargets(self.name);
if (self.running) {
// If previously running, complete the last run
self.complete();
} else if (reloadTargets.length > 0) {
// If not previously running but has items in the queue, needs run
self.queue = reloadTargets;
reloadTargets = [];
self.run();
} else {
if (!self.hadError) {
// Check whether target's tasks should run at start w/ atBegin option
self.queue = targets.filter(function(tr) {
return tr.options.atBegin === true && tr.tasks.length > 0;
}).map(function(tr) {
return tr.name;
});
} else {
// There was an error in atBegin task, we can't re-run it, as this would
// create an infinite loop of failing tasks
// See https://github.com/gruntjs/grunt-contrib-watch/issues/169
self.queue = [];
self.hadError = false;
}
if (self.queue.length > 0) {
self.run();
}
}
return targets;
};
// Normalize targets from config
Runner.prototype._getTargets = function _getTargets(name) {
var self = this;
grunt.task.current.requiresConfig(name);
var config = grunt.config(name);
var onlyTarget = self.options.target ? self.options.target : false;
var targets = (onlyTarget ? [onlyTarget] : Object.keys(config)).filter(function(key) {
if (key === 'options') {
return false;
}
return typeof config[key] !== 'string' && !Array.isArray(config[key]);
}).map(function(target) {
// Fail if any required config properties have been omitted
grunt.task.current.requiresConfig([name, target, 'files']);
var cfg = grunt.config([name, target]);
cfg.name = target;
cfg.options = self._options(cfg.options || {}, self.options);
self.add(cfg);
return cfg;
}, self);
// Allow "basic" non-target format
if (typeof config.files === 'string' || Array.isArray(config.files)) {
var cfg = {
files: config.files,
tasks: config.tasks,
name: defaultTargetName,
options: self._options(config.options || {}, self.options)
};
targets.push(cfg);
self.add(cfg);
}
return targets;
};
// Default options
Runner.prototype._options = function _options() {
var args = Array.prototype.slice.call(arguments).concat({
// The cwd to spawn within
cwd: process.cwd(),
// Additional cli args to append when spawning
cliArgs: _.without.apply(null, [[].slice.call(process.argv, 2)].concat(grunt.cli.tasks)),
interrupt: false,
nospawn: false,
spawn: true,
atBegin: false,
event: ['all'],
target: null
});
return _.defaults.apply(_, args);
};
// Run the current queue of task runs
Runner.prototype.run = _.debounce(function run() {
var self = this;
if (self.queue.length < 1) {
self.running = false;
return;
}
// Re-grab task options in case they changed between runs
self.options = self._options(grunt.config([self.name, 'options']) || {}, self.options);
// If we should interrupt
if (self.running === true) {
var shouldInterrupt = true;
self.queue.forEach(function(name) {
var tr = self.targets[name];
if (tr && tr.options.interrupt !== true) {
shouldInterrupt = false;
return false;
}
});
if (shouldInterrupt === true) {
self.interrupt();
} else {
// Dont interrupt the tasks running
return;
}
}
// If we should reload
if (self.reload) {
return self.reloadTask();
}
// Trigger that tasks runs have started
self.emit('start');
self.running = true;
// Run each target
var shouldComplete = true;
async.forEachSeries(self.queue, function(name, next) {
var tr = self.targets[name];
if (!tr) {
return next();
}
// Re-grab options in case they changed between runs
tr.options = self._options(grunt.config([self.name, name, 'options']) || {}, tr.options, self.options);
if (tr.options.spawn === false || tr.options.nospawn === true) {
shouldComplete = false;
}
tr.run(next);
}, function() {
if (shouldComplete) {
self.complete();
} else {
grunt.task.mark().run(self.nameArgs);
self.done();
}
});
}, 250);
// Push targets onto the queue
Runner.prototype.add = function add(target) {
var self = this;
if (!this.targets[target.name || 0]) {
// Private method for getting latest config for a watch target
target._getConfig = function(name) {
var cfgPath = [self.name];
if (target.name !== defaultTargetName) {
cfgPath.push(target.name);
}
if (name) {
cfgPath.push(name);
}
return grunt.config(cfgPath);
};
// Create a new TaskRun instance
var tr = new TaskRun(target);
// Add livereload to task runs
// Get directly from config as task level options are merged.
// We only want a single default LR server and then
// allow each target to override their own.
var lrconfig = grunt.config([this.name, target.name || 0, 'options', 'livereload']);
if (lrconfig) {
tr.livereload = livereload(lrconfig);
} else if (this.livereload && lrconfig !== false) {
tr.livereload = this.livereload;
}
return this.targets[tr.name] = tr;
}
return false;
};
// Do this when queued task runs have completed/scheduled
Runner.prototype.complete = function complete() {
var self = this;
if (self.running === false) {
return;
}
self.running = false;
var time = 0;
for (var i = 0, len = self.queue.length; i < len; ++i) {
var name = self.queue[i];
var target = self.targets[name];
if (!target) {
return;
}
if (target.startedAt !== false) {
time += target.complete();
self.queue.splice(i--, 1);
len--;
// if we're just livereloading and no tasks
// it can happen too fast and we dont report it
if (target.options.livereload && target.tasks.length < 1) {
time += 0.0001;
}
}
}
var elapsed = (time > 0) ? Number(time / 1000) : 0;
self.changedFiles = Object.create(null);
self.emit('end', elapsed);
};
// Run through completing every target in the queue
Runner.prototype._completeQueue = function _completeQueue() {
var self = this;
self.queue.forEach(function(name) {
var target = self.targets[name];
if (!target) {
return;
}
target.complete();
});
};
// Interrupt the running tasks
Runner.prototype.interrupt = function interrupt() {
var self = this;
self._completeQueue();
grunt.task.clearQueue();
self.emit('interrupt');
};
// Attempt to make this task run forever
Runner.prototype.forever = function forever() {
var self = this;
function rerun() {
// Clear queue and rerun to prevent failing
self._completeQueue();
grunt.task.clearQueue();
grunt.task.run(self.nameArgs);
self.running = false;
// Mark that there was an error and we needed to rerun
self.hadError = true;
}
grunt.fail.forever_warncount = 0;
grunt.fail.forever_errorcount = 0;
grunt.warn = grunt.fail.warn = function(e) {
grunt.fail.forever_warncount ++;
var message = typeof e === 'string' ? e : e.message;
grunt.log.writeln(('Warning: ' + message).yellow);
if (!grunt.option('force')) {
rerun();
}
};
grunt.fatal = grunt.fail.fatal = function(e) {
grunt.fail.forever_errorcount ++;
var message = typeof e === 'string' ? e : e.message;
grunt.log.writeln(('Fatal error: ' + message).red);
rerun();
};
};
// Clear the require cache for all passed filepaths.
Runner.prototype.clearRequireCache = function() {
// If a non-string argument is passed, it's an array of filepaths, otherwise
// each filepath is passed individually.
var filepaths = typeof arguments[0] !== 'string' ? arguments[0] : Array.prototype.slice(arguments);
// For each filepath, clear the require cache, if necessary.
filepaths.forEach(function(filepath) {
var abspath = path.resolve(filepath);
if (require.cache[abspath]) {
grunt.verbose.write('Clearing require cache for "' + filepath + '" file...').ok();
delete require.cache[abspath];
}
});
};
// Reload this watch task, like when a Gruntfile is edited
Runner.prototype.reloadTask = function() {
var self = this;
// Which targets to run after reload
reloadTargets = self.queue;
self.emit('reload', reloadTargets);
// Re-init the watch task config
grunt.task.init([self.name]);
// Complete all running tasks
self._completeQueue();
// Run the watch task again
grunt.task.run(self.nameArgs);
self.done();
};
return new Runner();
};

191
node_modules/grunt-contrib-watch/tasks/watch.js generated vendored Normal file
View File

@@ -0,0 +1,191 @@
/*
* grunt-contrib-watch
* http://gruntjs.com/
*
* Copyright (c) 2018 "Cowboy" Ben Alman, contributors
* Licensed under the MIT license.
*/
'use strict';
var path = require('path');
var Gaze = require('gaze').Gaze;
var _ = require('lodash');
var waiting = 'Waiting...';
var changedFiles = Object.create(null);
var watchers = [];
module.exports = function(grunt) {
var taskrun = require('./lib/taskrunner')(grunt);
// Default date format logged
var dateFormat = function(time) {
grunt.log.writeln(String(
'Completed in ' +
time.toFixed(3) +
's at ' +
(new Date()).toString()
).cyan + ' - ' + waiting);
};
// When task runner has started
taskrun.on('start', function() {
Object.keys(changedFiles).forEach(function(filepath) {
// Log which file has changed, and how.
grunt.log.ok('File "' + filepath + '" ' + changedFiles[filepath] + '.');
});
// Reset changedFiles
changedFiles = Object.create(null);
});
// When task runner has ended
taskrun.on('end', function(time) {
if (time > 0) {
dateFormat(time);
}
});
// When a task run has been interrupted
taskrun.on('interrupt', function() {
grunt.log.writeln('').write('Scheduled tasks have been interrupted...'.yellow);
});
// When taskrun is reloaded
taskrun.on('reload', function() {
taskrun.clearRequireCache(Object.keys(changedFiles));
grunt.log.writeln('').writeln('Reloading watch config...'.cyan);
});
grunt.registerTask('watch', 'Run predefined tasks whenever watched files change.', function(target) {
var self = this;
var name = self.name || 'watch';
// Close any previously opened watchers
watchers.forEach(function(watcher) {
watcher.close();
});
watchers = [];
// Never gonna give you up, never gonna let you down
if (grunt.config([name, 'options', 'forever']) !== false) {
taskrun.forever();
}
// If a custom dateFormat function
var df = grunt.config([name, 'options', 'dateFormat']);
if (typeof df === 'function') {
dateFormat = df;
}
if (taskrun.running === false) {
grunt.log.writeln(waiting);
}
// Initialize taskrun
var targets = taskrun.init(name, {target: target});
targets.forEach(function(target) {
if (typeof target.files === 'string') {
target.files = [target.files];
}
// Process into raw patterns
var patterns = _.chain(target.files).flatten().map(function(pattern) {
return grunt.config.process(pattern);
}).value();
// Validate the event option
if (typeof target.options.event === 'string') {
target.options.event = [target.options.event];
}
var eventCwd = process.cwd();
if (target.options.cwd && target.options.cwd.event) {
eventCwd = target.options.cwd.event;
}
// Set cwd if options.cwd.file is set
if (typeof target.options.cwd !== 'string' && target.options.cwd.files) {
target.options.cwd = target.options.cwd.files;
}
// Create watcher per target
watchers.push(new Gaze(patterns, target.options, function(err) {
if (err) {
if (typeof err === 'string') {
err = new Error(err);
}
grunt.log.writeln('ERROR'.red);
grunt.fatal(err);
return taskrun.done();
}
// Log all watched files with --verbose set
if (grunt.option('verbose')) {
var watched = this.watched();
Object.keys(watched).forEach(function(watchedDir) {
watched[watchedDir].forEach(function(watchedFile) {
grunt.log.writeln('Watching ' + path.relative(process.cwd(), watchedFile) + ' for changes.');
});
});
}
// On changed/added/deleted
this.on('all', function(status, filepath) {
// Skip events not specified
if (!_.includes(target.options.event, 'all') &&
!_.includes(target.options.event, status)) {
return;
}
filepath = path.relative(eventCwd, filepath);
// Skip empty filepaths
if (filepath === '') {
return;
}
// If Gruntfile.js changed, reload self task
if (target.options.reload || /gruntfile\.(js|coffee)/i.test(filepath)) {
taskrun.reload = true;
}
// Emit watch events if anyone is listening
if (grunt.event.listeners('watch').length > 0) {
grunt.event.emit('watch', status, filepath, target.name);
}
// Group changed files only for display
changedFiles[filepath] = status;
// Add changed files to the target
if (taskrun.targets[target.name]) {
if (!taskrun.targets[target.name].changedFiles) {
taskrun.targets[target.name].changedFiles = Object.create(null);
}
taskrun.targets[target.name].changedFiles[filepath] = status;
}
// Queue the target
if (taskrun.queue.indexOf(target.name) === -1) {
taskrun.queue.push(target.name);
}
// Run the tasks
taskrun.run();
});
// On watcher error
this.on('error', function(err) {
if (typeof err === 'string') {
err = new Error(err);
}
grunt.log.error(err.message);
});
}));
});
});
};