Template Upload

This commit is contained in:
SOUTHERNCO\x2mjbyrn
2017-05-17 13:45:25 -04:00
parent 415b9c25f3
commit 7efe7605b8
11476 changed files with 2170865 additions and 34 deletions

86
node_modules/browser-sync/lib/args.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
"use strict";
/**
* The purpose of this function is
* to handle back-backwards compatibility
* @param {Object} args
* @returns {{config: {}, cb: *}}
*/
module.exports = function (args) {
var config = {};
var cb;
switch (args.length) {
case 1 :
if (isFilesArg(args[0])) {
config.files = args[0];
} else if (typeof args[0] === "function") {
cb = args[0];
} else {
config = args[0];
}
break;
case 2 :
// if second is a function, first MUST be config
if (typeof args[1] === "function") {
config = args[0] || {};
cb = args[1];
} else {
if (args[1] === null || args[1] === undefined) {
config = args[0];
} else {
// finally, second arg could be a plain object for config
config = args[1] || {};
if (!config.files) {
config.files = args[0];
}
}
}
break;
case 3 :
config = args[1] || {};
if (!config.files) {
config.files = args[0];
}
cb = args[2];
}
return {
config: config,
cb: cb
};
};
/**
* Files args were only ever strings or arrays
* @param arg
* @returns {*|boolean}
*/
function isFilesArg (arg) {
return Array.isArray(arg) || typeof arg === "string";
}

60
node_modules/browser-sync/lib/async-tasks.js generated vendored Normal file
View File

@ -0,0 +1,60 @@
var async = require("./async");
module.exports = [
{
step: "Finding an empty port",
fn: async.getEmptyPort
},
{
step: "Getting an extra port for Proxy",
fn: async.getExtraPortForProxy
},
{
step: "Checking online status",
fn: async.getOnlineStatus
},
{
step: "Resolve user plugins from options",
fn: async.resolveInlineUserPlugins
},
{
step: "Set Urls and other options that rely on port/online status",
fn: async.setOptions
},
{
step: "Setting Internal Events",
fn: async.setInternalEvents
},
{
step: "Setting file watchers",
fn: async.setFileWatchers
},
{
step: "Merging middlewares from core + plugins",
fn: async.mergeMiddlewares
},
{
step: "Starting the Server",
fn: async.startServer
},
{
step: "Starting the HTTPS Tunnel",
fn: async.startTunnel
},
{
step: "Starting the web-socket server",
fn: async.startSockets
},
{
step: "Starting the UI",
fn: async.startUi
},
{
step: "Merge UI settings",
fn: async.mergeUiSettings
},
{
step: "Init user plugins",
fn: async.initUserPlugins
}
];

323
node_modules/browser-sync/lib/async.js generated vendored Normal file
View File

@ -0,0 +1,323 @@
"use strict";
var _ = require("../lodash.custom");
var Immutable = require("immutable");
var utils = require("./utils");
var pluginUtils = require("./plugins");
var connectUtils = require("./connect-utils");
module.exports = {
/**
* BrowserSync needs at least 1 free port.
* It will check the one provided in config
* and keep incrementing until an available one is found.
* @param {BrowserSync} bs
* @param {Function} done
*/
getEmptyPort: function (bs, done) {
utils.getPorts(bs.options, function (err, port) {
if (err) {
return utils.fail(true, err, bs.cb);
}
bs.debug("Found a free port: {magenta:%s", port);
done(null, {
options: {
port: port
}
});
});
},
/**
* If the running mode is proxy, we'll use a separate port
* for the Browsersync web-socket server. This is to eliminate any issues
* with trying to proxy web sockets through to the users server.
* @param bs
* @param done
*/
getExtraPortForProxy: function (bs, done) {
/**
* An extra port is not needed in snippet/server mode
*/
if (bs.options.get("mode") !== "proxy") {
return done();
}
/**
* Web socket support is disabled by default
*/
if (!bs.options.getIn(["proxy", "ws"])) {
return done();
}
/**
* Use 1 higher than server port by default...
*/
var socketPort = bs.options.get("port") + 1;
/**
* Or use the user-defined socket.port option instead
*/
if (bs.options.hasIn(["socket", "port"])) {
socketPort = bs.options.getIn(["socket", "port"]);
}
utils.getPort(socketPort, null, function (err, port) {
if (err) {
return utils.fail(true, err, bs.cb);
}
done(null, {
optionsIn: [
{
path: ["socket", "port"],
value: port
}
]
});
});
},
/**
* Some features require an internet connection.
* If the user did not provide either `true` or `false`
* for the online option, we will attempt to resolve www.google.com
* as a way of determining network connectivity
* @param {BrowserSync} bs
* @param {Function} done
*/
getOnlineStatus: function (bs, done) {
if (_.isUndefined(bs.options.get("online")) && _.isUndefined(process.env.TESTING)) {
require("dns").resolve("www.google.com", function (err) {
var online = false;
if (err) {
bs.debug("Could not resolve www.google.com, setting {magenta:online: false}");
} else {
bs.debug("Resolved www.google.com, setting {magenta:online: true}");
online = true;
}
done(null, {
options: {
online: online
}
});
});
} else {
done();
}
},
/**
* Try to load plugins that were given in options
* @param {BrowserSync} bs
* @param {Function} done
*/
resolveInlineUserPlugins: function (bs, done) {
var plugins = bs.options
.get("plugins")
.map(pluginUtils.resolvePlugin)
.map(pluginUtils.requirePlugin);
plugins
.forEach(function (plugin) {
if (plugin.get("errors").size) {
return logPluginError(plugin);
}
var jsPlugin = plugin.toJS();
jsPlugin.options = jsPlugin.options || {};
jsPlugin.options.moduleName = jsPlugin.moduleName;
bs.registerPlugin(jsPlugin.module, jsPlugin.options);
});
function logPluginError (plugin) {
utils.fail(true, plugin.getIn(["errors", 0]), bs.cb);
}
done();
},
/**
*
* @param {BrowserSync} bs
* @param {Function} done
*/
setOptions: function (bs, done) {
done(null, {
options: {
urls: utils.getUrlOptions(bs.options),
snippet: connectUtils.scriptTags(bs.options),
scriptPaths: Immutable.fromJS(connectUtils.clientScript(bs.options, true)),
files: bs.pluginManager.hook(
"files:watch",
bs.options.get("files"),
bs.pluginManager.pluginOptions
)
}
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
setInternalEvents: function (bs, done) {
require("./internal-events")(bs);
done();
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
setFileWatchers: function (bs, done) {
done(null, {
instance: {
watchers: bs.pluginManager.get("file:watcher")(bs)
}
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
mergeMiddlewares: function (bs, done) {
done(null, {
options: {
middleware: bs.pluginManager.hook(
"server:middleware",
bs.options.get("middleware")
)
}
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
startServer: function (bs, done) {
var server = bs.pluginManager.get("server")(bs);
done(null, {
instance: {
server: server.server,
app: server.app
}
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
startTunnel: function (bs, done) {
if (bs.options.get("tunnel") && bs.options.get("online")) {
var localTunnel = require("./tunnel");
localTunnel(bs, function (err, tunnel) {
if (err) {
return done(err);
} else {
return done(null, {
optionsIn: [
{
path: ["urls", "tunnel"],
value: tunnel.url
}
],
instance: {
tunnel: tunnel
}
});
}
});
} else {
done();
}
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
startSockets: function (bs, done) {
var clientEvents = bs.pluginManager.hook(
"client:events",
bs.options.get("clientEvents").toJS()
);
// Start the socket, needs an existing server.
var io = bs.pluginManager.get("socket")(
bs.server,
clientEvents,
bs
);
done(null, {
instance: {
io: io
},
options: {
clientEvents: Immutable.fromJS(clientEvents)
}
});
},
/**
*
* @param {BrowserSync} bs
* @param {Function} done
*/
startUi: function (bs, done) {
var PLUGIN_NAME = "UI";
var userPlugins = bs.getUserPlugins();
var ui = bs.pluginManager.get(PLUGIN_NAME);
var uiOpts = bs.options.get("ui");
if (!uiOpts || uiOpts.get("enabled") === false) {
return done();
}
// if user provided a UI, use it instead
if (userPlugins.some(function (item) {
return item.name === PLUGIN_NAME;
})) {
uiOpts = bs.options.get("ui").mergeDeep(Immutable.fromJS(bs.pluginManager.pluginOptions[PLUGIN_NAME]));
}
return ui(uiOpts.toJS(), bs, function (err, ui) {
if (err) {
return done(err);
}
done(null, {
instance: {
ui: ui
}
});
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
mergeUiSettings: function (bs, done) {
if (!bs.ui) {
return done();
}
done(null, {
options: {
urls: bs.options.get("urls").merge(bs.ui.options.get("urls"))
}
});
},
/**
* @param {BrowserSync} bs
* @param {Function} done
*/
initUserPlugins: function (bs, done) {
bs.pluginManager.initUserPlugins(bs);
done(null, {
options: {
userPlugins: bs.getUserPlugins()
}
});
}
};

696
node_modules/browser-sync/lib/browser-sync.js generated vendored Normal file
View File

@ -0,0 +1,696 @@
"use strict";
var hooks = require("./hooks");
var asyncTasks = require("./async-tasks");
var config = require("./config");
var connectUtils = require("./connect-utils");
var utils = require("./utils");
var logger = require("./logger");
var eachSeries = utils.eachSeries;
var _ = require("../lodash.custom");
var EE = require("easy-extender");
/**
* Required internal plugins.
* Any of these can be overridden by deliberately
* causing a name-clash.
*/
var defaultPlugins = {
"logger": logger,
"socket": require("./sockets"),
"file:watcher": require("./file-watcher"),
"server": require("./server"),
"tunnel": require("./tunnel"),
"client:script": require("browser-sync-client"),
"UI": require("browser-sync-ui")
};
/**
* @constructor
*/
var BrowserSync = function (emitter) {
var bs = this;
bs.cwd = process.cwd();
bs.active = false;
bs.paused = false;
bs.config = config;
bs.utils = utils;
bs.events = bs.emitter = emitter;
bs._userPlugins = [];
bs._reloadQueue = [];
bs._cleanupTasks = [];
bs._browserReload = false;
// Plugin management
bs.pluginManager = new EE(defaultPlugins, hooks);
};
/**
* Call a user-options provided callback
* @param name
*/
BrowserSync.prototype.callback = function (name) {
var bs = this;
var cb = bs.options.getIn(["callbacks", name]);
if (_.isFunction(cb)) {
cb.apply(bs.publicInstance, _.toArray(arguments).slice(1));
}
};
/**
* @param {Map} options
* @param {Function} cb
* @returns {BrowserSync}
*/
BrowserSync.prototype.init = function (options, cb) {
/**
* Safer access to `this`
* @type {BrowserSync}
*/
var bs = this;
/**
* Set user-provided callback, or assign a noop
* @type {Function}
*/
bs.cb = cb || utils.defaultCallback;
/**
* Verify provided config.
* Some options are not compatible and will cause us to
* end the process.
*/
if (!utils.verifyConfig(options, bs.cb)) {
return;
}
/**
* Save a reference to the original options
* @type {Map}
* @private
*/
bs._options = options;
/**
* Set additional options that depend on what the
* user may of provided
* @type {Map}
*/
bs.options = require("./options").update(options);
/**
* Kick off default plugins.
*/
bs.pluginManager.init();
/**
* Create a base logger & debugger.
*/
bs.logger = bs.pluginManager.get("logger")(bs.events, bs);
bs.debugger = bs.logger.clone({useLevelPrefixes: true});
bs.debug = bs.debugger.debug;
/**
* Run each setup task in sequence
*/
eachSeries(
asyncTasks,
taskRunner(bs),
tasksComplete(bs)
);
return this;
};
/**
* Run 1 setup task.
* Each task is a pure function.
* They can return options or instance properties to set,
* but they cannot set them directly.
* @param {BrowserSync} bs
* @returns {Function}
*/
function taskRunner (bs) {
return function (item, cb) {
bs.debug("-> {yellow:Starting Step: " + item.step);
/**
* Execute the current task.
*/
item.fn(bs, executeTask);
function executeTask(err, out) {
/**
* Exit early if any task returned an error.
*/
if (err) {
return cb(err);
}
/**
* Act on return values (such as options to be set,
* or instance properties to be set
*/
if (out) {
handleOut(bs, out);
}
bs.debug("+ {green:Step Complete: " + item.step);
cb();
}
};
}
/**
* @param bs
* @param out
*/
function handleOut (bs, out) {
/**
* Set a single/many option.
*/
if (out.options) {
setOptions(bs, out.options);
}
/**
* Any options returned that require path access?
*/
if (out.optionsIn) {
out.optionsIn.forEach(function (item) {
bs.setOptionIn(item.path, item.value);
});
}
/**
* Any instance properties returned?
*/
if (out.instance) {
Object.keys(out.instance).forEach(function (key) {
bs[key] = out.instance[key];
});
}
}
/**
* Update the options Map
* @param bs
* @param options
*/
function setOptions (bs, options) {
/**
* If multiple options were set, act on the immutable map
* in an efficient way
*/
if (Object.keys(options).length > 1) {
bs.setMany(function (item) {
Object.keys(options).forEach(function (key) {
item.set(key, options[key]);
return item;
});
});
} else {
Object.keys(options).forEach(function (key) {
bs.setOption(key, options[key]);
});
}
}
/**
* At this point, ALL async tasks have completed
* @param {BrowserSync} bs
* @returns {Function}
*/
function tasksComplete (bs) {
return function (err) {
if (err) {
bs.logger.setOnce("useLevelPrefixes", true).error(err.message);
}
/**
* Set active flag
*/
bs.active = true;
/**
* @deprecated
*/
bs.events.emit("init", bs);
/**
* This is no-longer needed as the Callback now only resolves
* when everything (including slow things, like the tunnel) is ready.
* It's here purely for backwards compatibility.
* @deprecated
*/
bs.events.emit("service:running", {
options: bs.options,
baseDir: bs.options.getIn(["server", "baseDir"]),
type: bs.options.get("mode"),
port: bs.options.get("port"),
url: bs.options.getIn(["urls", "local"]),
urls: bs.options.get("urls").toJS(),
tunnel: bs.options.getIn(["urls", "tunnel"])
});
/**
* Call any option-provided callbacks
*/
bs.callback("ready", null, bs);
/**
* Finally, call the user-provided callback given as last arg
*/
bs.cb(null, bs);
};
}
/**
* @param module
* @param opts
* @param cb
*/
BrowserSync.prototype.registerPlugin = function (module, opts, cb) {
var bs = this;
bs.pluginManager.registerPlugin(module, opts, cb);
if (module["plugin:name"]) {
bs._userPlugins.push(module);
}
};
/**
* Get a plugin by name
* @param name
*/
BrowserSync.prototype.getUserPlugin = function (name) {
var bs = this;
var items = bs.getUserPlugins(function (item) {
return item["plugin:name"] === name;
});
if (items && items.length) {
return items[0];
}
return false;
};
/**
* @param {Function} [filter]
*/
BrowserSync.prototype.getUserPlugins = function (filter) {
var bs = this;
filter = filter || function () {
return true;
};
/**
* Transform Plugins option
*/
bs.userPlugins = bs._userPlugins.filter(filter).map(function (plugin) {
return {
name: plugin["plugin:name"],
active: plugin._enabled,
opts: bs.pluginManager.pluginOptions[plugin["plugin:name"]]
};
});
return bs.userPlugins;
};
/**
* Get middleware
* @returns {*}
*/
BrowserSync.prototype.getMiddleware = function (type) {
var types = {
"connector": connectUtils.socketConnector(this.options),
"socket-js": require("./snippet").utils.getSocketScript()
};
if (type in types) {
return function (req, res) {
res.setHeader("Content-Type", "text/javascript");
res.end(types[type]);
};
}
};
/**
* Shortcut for pushing a file-serving middleware
* onto the stack
* @param {String} path
* @param {{type: string, content: string}} props
*/
var _serveFileCount = 0;
BrowserSync.prototype.serveFile = function (path, props) {
var bs = this;
var mode = bs.options.get("mode");
var entry = {
handle: function (req, res) {
res.setHeader("Content-Type", props.type);
res.end(props.content);
},
id: "Browsersync - " + _serveFileCount++,
route: path
};
bs._addMiddlewareToStack(entry);
};
/**
* Add middlewares on the fly
* @param {{route: string, handle: function, id?: string}}
*/
BrowserSync.prototype._addMiddlewareToStack = function (entry) {
var bs = this;
if (bs.options.get("mode") === "proxy") {
bs.app.stack.splice(bs.app.stack.length-1, 0, entry);
} else {
bs.app.stack.push(entry);
}
};
var _addMiddlewareCount = 0;
BrowserSync.prototype.addMiddleware = function (route, handle, opts) {
var bs = this;
if (!bs.app) {
return;
}
opts = opts || {};
if (!opts.id) {
opts.id = "bs-mw-" + _addMiddlewareCount++;
}
if (route === "*") {
route = "";
}
var entry = {
id: opts.id,
route: route,
handle: handle
};
if (opts.override) {
entry.override = true;
}
bs.options = bs.options.update("middleware", function (mw) {
if (bs.options.get("mode") === "proxy") {
return mw.insert(mw.size-1, entry);
}
return mw.concat(entry);
});
bs.resetMiddlewareStack();
};
/**
* Remove middlewares on the fly
* @param {String} id
* @returns {Server}
*/
BrowserSync.prototype.removeMiddleware = function (id) {
var bs = this;
if (!bs.app) {
return;
}
bs.options = bs.options.update("middleware", function (mw) {
return mw.filter(function (mw) {
return mw.id !== id;
});
});
bs.resetMiddlewareStack();
};
/**
* Middleware for socket connection (external usage)
* @param opts
* @returns {*}
*/
BrowserSync.prototype.getSocketConnector = function (opts) {
var bs = this;
return function (req, res) {
res.setHeader("Content-Type", "text/javascript");
res.end(bs.getExternalSocketConnector(opts));
};
};
/**
* Socket connector as a string
* @param {Object} opts
* @returns {*}
*/
BrowserSync.prototype.getExternalSocketConnector = function (opts) {
var bs = this;
return connectUtils.socketConnector(
bs.options.withMutations(function (item) {
item.set("socket", item.get("socket").merge(opts));
if (!bs.options.getIn(["proxy", "ws"])) {
item.set("mode", "snippet");
}
})
);
};
/**
* Socket io as string (for embedding)
* @returns {*}
*/
BrowserSync.prototype.getSocketIoScript = function () {
return require("./snippet").utils.getSocketScript();
};
/**
* Callback helper
* @param name
*/
BrowserSync.prototype.getOption = function (name) {
this.debug("Getting option: {magenta:%s", name);
return this.options.get(name);
};
/**
* Callback helper
* @param path
*/
BrowserSync.prototype.getOptionIn = function (path) {
this.debug("Getting option via path: {magenta:%s", path);
return this.options.getIn(path);
};
/**
* @returns {BrowserSync.options}
*/
BrowserSync.prototype.getOptions = function () {
return this.options;
};
/**
* @returns {BrowserSync.options}
*/
BrowserSync.prototype.getLogger = logger.getLogger;
/**
* @param {String} name
* @param {*} value
* @returns {BrowserSync.options|*}
*/
BrowserSync.prototype.setOption = function (name, value, opts) {
var bs = this;
opts = opts || {};
bs.debug("Setting Option: {cyan:%s} - {magenta:%s", name, value.toString());
bs.options = bs.options.set(name, value);
if (!opts.silent) {
bs.events.emit("options:set", {path: name, value: value, options: bs.options});
}
return this.options;
};
/**
* @param path
* @param value
* @param opts
* @returns {Map|*|BrowserSync.options}
*/
BrowserSync.prototype.setOptionIn = function (path, value, opts) {
var bs = this;
opts = opts || {};
bs.debug("Setting Option: {cyan:%s} - {magenta:%s", path.join("."), value.toString());
bs.options = bs.options.setIn(path, value);
if (!opts.silent) {
bs.events.emit("options:set", {path: path, value: value, options: bs.options});
}
return bs.options;
};
/**
* Set multiple options with mutations
* @param fn
* @param opts
* @returns {Map|*}
*/
BrowserSync.prototype.setMany = function (fn, opts) {
var bs = this;
opts = opts || {};
bs.debug("Setting multiple Options");
bs.options = bs.options.withMutations(fn);
if (!opts.silent) {
bs.events.emit("options:set", {options: bs.options.toJS()});
}
return this.options;
};
BrowserSync.prototype.addRewriteRule = function (rule) {
var bs = this;
bs.options = bs.options.update("rewriteRules", function (rules) {
return rules.concat(rule);
});
bs.resetMiddlewareStack();
};
BrowserSync.prototype.removeRewriteRule = function (id) {
var bs = this;
bs.options = bs.options.update("rewriteRules", function (rules) {
return rules.filter(function (rule) {
return rule.id !== id;
});
});
bs.resetMiddlewareStack();
};
BrowserSync.prototype.setRewriteRules = function (rules) {
var bs = this;
bs.options = bs.options.update("rewriteRules", function (_) {
return rules;
});
bs.resetMiddlewareStack();
};
/**
* Add a new rewrite rule to the stack
* @param {Object} rule
*/
BrowserSync.prototype.resetMiddlewareStack = function () {
var bs = this;
var middlewares = require("./server/utils").getMiddlewares(bs, bs.options);
bs.app.stack = middlewares;
};
/**
* @param fn
*/
BrowserSync.prototype.registerCleanupTask = function (fn) {
this._cleanupTasks.push(fn);
};
/**
* Instance Cleanup
*/
BrowserSync.prototype.cleanup = function (cb) {
var bs = this;
if (!bs.active) {
return;
}
// Remove all event listeners
if (bs.events) {
bs.debug("Removing event listeners...");
bs.events.removeAllListeners();
}
// Close any core file watchers
if (bs.watchers) {
Object.keys(bs.watchers).forEach(function (key) {
bs.watchers[key].watchers.forEach(function (watcher) {
watcher.close();
});
});
}
// Run any additional clean up tasks
bs._cleanupTasks.forEach(function (fn) {
if (_.isFunction(fn)) {
fn(bs);
}
});
// Reset the flag
bs.debug("Setting {magenta:active: false");
bs.active = false;
bs.paused = false;
bs.pluginManager.plugins = {};
bs.pluginManager.pluginOptions = {};
bs.pluginManager.defaultPlugins = defaultPlugins;
bs._userPlugins = [];
bs.userPlugins = [];
bs._reloadTimer = undefined;
bs._reloadQueue = [];
bs._cleanupTasks = [];
if (_.isFunction(cb)) {
cb(null, bs);
}
};
module.exports = BrowserSync;

59
node_modules/browser-sync/lib/cli/cli-info.js generated vendored Normal file
View File

@ -0,0 +1,59 @@
"use strict";
var config = require("../config");
var logger = require("../logger").logger;
var fs = require("fs");
var _ = require("../../lodash.custom");
var path = require("path");
var info = {
/**
* Version info
* @param {Object} pjson
* @returns {String}
*/
getVersion: function (pjson) {
console.log(pjson.version);
return pjson.version;
},
/**
* Retrieve the config file
* @returns {*}
* @private
* @param filePath
*/
getConfigFile: function (filePath) {
return require(path.resolve(filePath));
},
/**
* Generate an example Config file.
*/
makeConfig: function (cwd, cb) {
var opts = require(path.join(__dirname, "..", config.configFile));
var userOpts = {};
var ignore = ["excludedFileTypes", "injectFileTypes", "snippetOptions"];
Object.keys(opts).forEach(function (key) {
if (!_.includes(ignore, key)) {
userOpts[key] = opts[key];
}
});
var file = fs.readFileSync(path.join(__dirname, config.template), "utf8");
file = file.replace("//OPTS", JSON.stringify(userOpts, null, 4));
fs.writeFile(path.resolve(cwd, config.userFile), file, function () {
logger.info("Config file created {magenta:%s}", config.userFile);
logger.info(
"To use it, in the same directory run: " +
"{cyan:browser-sync start --config bs-config.js}"
);
cb();
});
}
};
module.exports = info;

317
node_modules/browser-sync/lib/cli/cli-options.js generated vendored Normal file
View File

@ -0,0 +1,317 @@
"use strict";
var path = require("path");
var url = require("url");
var _ = require("../../lodash.custom");
var Immutable = require("immutable");
var isList = Immutable.List.isList;
var isMap = Immutable.Map.isMap;
var defaultConfig = require("../default-config");
var immDefs = Immutable.fromJS(defaultConfig);
var opts = exports;
/**
* @type {{wrapPattern: Function}}
*/
opts.utils = {
/**
* Transform a string arg such as "*.html, css/*.css" into array
* @param string
* @returns {Array}
*/
explodeFilesArg: function (string) {
return string.split(",").map(function (item) {
return item.trim();
});
},
/**
* @param pattern
* @returns {*|string}
* @private
*/
wrapPattern: function (pattern) {
var prefix = "!";
var suffix = "/**";
var lastChar = pattern.charAt(pattern.length - 1);
var extName = path.extname(pattern);
// If there's a file ext, don't append any suffix
if (extName.length) {
suffix = "";
} else {
if (lastChar === "/") {
suffix = "**";
}
if (lastChar === "*") {
suffix = "";
}
}
return [prefix, pattern, suffix].join("");
}
};
opts.callbacks = {
/**
* Merge server options
* @param {String|Boolean|Object} value
* @param [argv]
* @returns {*}
*/
server: function (value, argv) {
if (value === false) {
if (!argv || !argv.server) {
return false;
}
}
var obj = {
baseDir: "./"
};
if (_.isString(value) || isList(value)) {
obj.baseDir = value;
} else {
if (value && value !== true) {
if (value.get("baseDir")) {
return value;
}
}
}
if (argv) {
if (argv.index) {
obj.index = argv.index;
}
if (argv.directory) {
obj.directory = true;
}
}
return Immutable.fromJS(obj);
},
/**
* @param value
* @param argv
* @returns {*}
*/
proxy: function (value) {
var mw;
var target;
if (!value || value === true) {
return false;
}
if (typeof value !== "string") {
target = value.get("target");
mw = value.get("middleware");
} else {
target = value;
value = Immutable.Map({});
}
if (!target.match(/^(https?):\/\//)) {
target = "http://" + target;
}
var parsedUrl = url.parse(target);
if (!parsedUrl.port) {
parsedUrl.port = 80;
}
var out = {
target: parsedUrl.protocol + "//" + parsedUrl.host,
url: Immutable.Map(parsedUrl)
};
if (mw) {
out.middleware = mw;
}
return value.mergeDeep(out);
},
/**
* @param value
* @private
*/
ports: function (value) {
var segs;
var obj = {};
if (typeof value === "string") {
if (~value.indexOf(",")) {
segs = value.split(",");
obj.min = parseInt(segs[0], 10);
obj.max = parseInt(segs[1], 10);
} else {
obj.min = parseInt(value, 10);
obj.max = null;
}
} else {
obj.min = value.get("min");
obj.max = value.get("max") || null;
}
return Immutable.Map(obj);
},
/**
* @param value
* @param argv
* @returns {*}
*/
ghostMode: function (value, argv) {
var trueAll = {
clicks: true,
scroll: true,
forms: {
submit: true,
inputs: true,
toggles: true
}
};
var falseAll = {
clicks: false,
scroll: false,
forms: {
submit: false,
inputs: false,
toggles: false
}
};
if (value === false || value === "false" || argv && argv.ghost === false) {
return Immutable.fromJS(falseAll);
}
if (value === true || value === "true" || argv && argv.ghost === true) {
return Immutable.fromJS(trueAll);
}
if (value.get("forms") === false) {
return value.withMutations(function (map) {
map.set("forms", Immutable.fromJS({
submit: false,
inputs: false,
toggles: false
}));
});
}
if (value.get("forms") === true) {
return value.withMutations(function (map) {
map.set("forms", Immutable.fromJS({
submit: true,
inputs: true,
toggles: true
}));
});
}
return value;
},
/**
* @param value
* @returns {*}
*/
files: function (value) {
var namespaces = {core: {}};
namespaces.core.globs = [];
namespaces.core.objs = [];
var processed = opts.makeFilesArg(value);
if (processed.globs.length) {
namespaces.core.globs = processed.globs;
}
if (processed.objs.length) {
namespaces.core.objs = processed.objs;
}
return Immutable.fromJS(namespaces);
},
/**
* @param value
*/
extensions: function (value) {
if (_.isString(value)) {
var split = opts.utils.explodeFilesArg(value);
if (split.length) {
return Immutable.List(split);
}
}
if (Immutable.List.isList(value)) {
return value;
}
return value;
}
};
/**
* @param {Object} values
* @param {Object} [argv]
* @returns {Map}
*/
opts.merge = function (values, argv) {
return immDefs
.mergeDeep(values)
.withMutations(function (item) {
item.map(function (value, key) {
if (opts.callbacks[key]) {
item.set(key, opts.callbacks[key](value, argv));
}
});
});
};
/**
* @param value
* @returns {{globs: Array, objs: Array}}
*/
opts.makeFilesArg = function (value) {
var globs = [];
var objs = [];
if (_.isString(value)) {
globs = globs.concat(
opts.utils.explodeFilesArg(value)
);
}
if (isList(value) && value.size) {
value.forEach(function (value) {
if (_.isString(value)) {
globs.push(value);
} else {
if (isMap(value)) {
objs.push(value);
}
}
});
}
return {
globs: globs,
objs: objs
};
};

15
node_modules/browser-sync/lib/cli/cli-template.js generated vendored Normal file
View File

@ -0,0 +1,15 @@
/*
|--------------------------------------------------------------------------
| Browser-sync config file
|--------------------------------------------------------------------------
|
| For up-to-date information about the options:
| http://www.browsersync.io/docs/options/
|
| There are more options than you see here, these are just the ones that are
| set internally. See the website for more info.
|
|
*/
module.exports = //OPTS;

15
node_modules/browser-sync/lib/cli/command.init.js generated vendored Normal file
View File

@ -0,0 +1,15 @@
"use strict";
var info = require("./cli-info");
/**
* $ browser-sync init
*
* This command will generate a configuration
* file in the current directory
*
* @param opts
*/
module.exports = function (opts) {
info.makeConfig(process.cwd(), opts.cb);
};

64
node_modules/browser-sync/lib/cli/command.recipe.js generated vendored Normal file
View File

@ -0,0 +1,64 @@
"use strict";
var logger = require("../logger").logger;
/**
* $ browser-sync recipe <name> <options>
*
* This command will copy a recipe into either the current directory
* or one given with the --output flag
*
* @param opts
* @returns {Function}
*/
module.exports = function (opts) {
var path = require("path");
var fs = require("fs-extra");
var input = opts.cli.input.slice(1);
var resolved = require.resolve("bs-recipes");
var dir = path.dirname(resolved);
var logRecipes = function () {
var dirs = fs.readdirSync(path.join(dir, "recipes"));
logger.info("Install one of the following with {cyan:browser-sync recipe <name>\n");
dirs.forEach(function (name) {
console.log(" " + name);
});
};
if (!input.length) {
logger.info("No recipe name provided!");
logRecipes();
return opts.cb();
}
if (opts.cli.input[1] === "ls") {
logRecipes();
return opts.cb();
}
input = input[0];
var flags = opts.cli.flags;
var output = flags.output ? path.resolve(flags.output) : path.join(process.cwd(), input);
var targetDir = path.join(dir, "recipes", input);
if (fs.existsSync(output)) {
return opts.cb(new Error("Target folder exists remove it first and then try again"));
}
if (fs.existsSync(targetDir)) {
fs.copy(targetDir, output, function (err) {
if (err) {
opts.cb(err);
} else {
logger.info("Recipe copied into {cyan:%s}", output);
logger.info("Next, inside that folder, run {cyan:npm i && npm start}");
opts.cb(null);
}
});
} else {
logger.info("Recipe {cyan:%s} not found. The following are available though", input);
logRecipes();
opts.cb();
}
};

44
node_modules/browser-sync/lib/cli/command.reload.js generated vendored Normal file
View File

@ -0,0 +1,44 @@
"use strict";
/**
* $ browser-sync reload <options>
*
* This commands starts the Browsersync servers
* & Optionally UI.
*
* @param opts
* @returns {Function}
*/
module.exports = function (opts) {
var flags = opts.cli.flags;
if (!flags.url) {
flags.url = "http://localhost:" + (flags.port || 3000);
}
var proto = require("../http-protocol");
var scheme = flags.url.match(/^https/) ? "https" : "http";
var args = {method: "reload"};
if (flags.files) {
args.args = flags.files;
}
var url = proto.getUrl(args, flags.url);
if (scheme === "https") {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
}
require(scheme).get(url, function (res) {
res.on("data", function () {
if (res.statusCode === 200) {
opts.cb(null, res);
}
});
}).on("error", function (err) {
if (err.code === "ECONNREFUSED") {
err.message = "Browsersync not running at " + flags.url;
}
return opts.cb(err);
});
};

88
node_modules/browser-sync/lib/cli/command.start.js generated vendored Normal file
View File

@ -0,0 +1,88 @@
"use strict";
var path = require("path");
var fs = require("fs");
var _ = require("../../lodash.custom");
var utils = require("../utils");
var opts = require("./cli-options").utils;
/**
* $ browser-sync start <options>
*
* This commands starts the Browsersync servers
* & Optionally UI.
*
* @param opts
* @returns {Function}
*/
module.exports = function (opts) {
var flags = preprocessFlags(opts.cli.flags);
var maybepkg = path.resolve(process.cwd(), "package.json");
var input = flags;
if (flags.config) {
var maybeconf = path.resolve(process.cwd(), flags.config);
if (fs.existsSync(maybeconf)) {
var conf = require(maybeconf);
input = _.merge({}, conf, flags);
} else {
utils.fail(true, new Error("Configuration file '" + flags.config + "' not found"), opts.cb);
}
} else {
if (fs.existsSync(maybepkg)) {
var pkg = require(maybepkg);
if (pkg["browser-sync"]) {
console.log("> Configuration obtained from package.json");
input = _.merge({}, pkg["browser-sync"], flags);
}
}
}
return require("../../")
.create("cli")
.init(input, opts.cb);
};
/**
* @param flags
* @returns {*}
*/
function preprocessFlags (flags) {
return [
stripUndefined,
legacyFilesArgs
].reduce(function (flags, fn) {
return fn.call(null, flags);
}, flags);
}
/**
* Incoming undefined values are problematic as
* they interfere with Immutable.Map.mergeDeep
* @param subject
* @returns {*}
*/
function stripUndefined (subject) {
return Object.keys(subject).reduce(function (acc, key) {
var value = subject[key];
if (typeof value === "undefined") {
return acc;
}
acc[key] = value;
return acc;
}, {});
}
/**
* @param flags
* @returns {*}
*/
function legacyFilesArgs(flags) {
if (flags.files && flags.files.length) {
flags.files = flags.files.reduce(function (acc, item) {
return acc.concat(opts.explodeFilesArg(item));
}, []);
}
return flags;
}

11
node_modules/browser-sync/lib/cli/help.txt generated vendored Normal file
View File

@ -0,0 +1,11 @@
{cyan:Server Example:}
{gray:---------------}
Use current directory as root & watch CSS files
{gray:$} browser-sync start --server --files="css/*.css"
{cyan:Proxy Example:}
{gray:---------------}
Proxy `localhost:8080` & watch CSS/HTML files
{gray:$} browser-sync start --proxy="localhost:8080" --files="*.html, css/*.css"

1
node_modules/browser-sync/lib/cli/opts.init.json generated vendored Normal file
View File

@ -0,0 +1 @@
{}

6
node_modules/browser-sync/lib/cli/opts.recipe.json generated vendored Normal file
View File

@ -0,0 +1,6 @@
{
"output": {
"alias": "o",
"desc": "Specify an output directory"
}
}

16
node_modules/browser-sync/lib/cli/opts.reload.json generated vendored Normal file
View File

@ -0,0 +1,16 @@
{
"files": {
"desc": "File paths to reload",
"type": "array",
"alias": "f"
},
"port": {
"alias": "p",
"type": "number",
"desc": "Target a running instance by port number"
},
"url": {
"alias": "u",
"desc": "Provide the full the url to the running Browsersync instance"
}
}

120
node_modules/browser-sync/lib/cli/opts.start.json generated vendored Normal file
View File

@ -0,0 +1,120 @@
{
"server": {
"alias": "s",
"desc": "Run a Local server (uses your cwd as the web root)"
},
"serveStatic": {
"type": "array",
"alias": "ss",
"desc": "Directories to serve static files from"
},
"port": {
"type": "number",
"desc": "Specify a port to use"
},
"proxy": {
"alias": "p",
"desc": "Proxy an existing server",
"example": "$0 shane is cool"
},
"ws": {
"type": "boolean",
"desc": "Proxy mode only - enable websocket proxying"
},
"browser": {
"type": "array",
"alias": "b",
"desc": "Choose which browser should be auto-opened"
},
"files": {
"type": "array",
"alias": "f",
"desc": "File paths to watch"
},
"index": {
"type": "string",
"desc": "Specify which file should be used as the index page"
},
"plugins": {
"type": "array",
"desc": "Load Browsersync plugins"
},
"extensions": {
"type": "array",
"desc": "Specify file extension fallbacks"
},
"startPath": {
"type": "string",
"desc": "Specify the start path for the opened browser"
},
"https": {
"desc": "Enable SSL for local development"
},
"directory": {
"type": "boolean",
"desc": "Show a directory listing for the server"
},
"xip": {
"type": "boolean",
"desc": "Use xip.io domain routing"
},
"tunnel": {
"desc": "Use a public URL"
},
"open": {
"type": "string",
"desc": "Choose which URL is auto-opened (local, external or tunnel), or provide a url"
},
"cors": {
"type": "boolean",
"desc": "Add Access Control headers to every request"
},
"config": {
"type": "string",
"alias": "c",
"desc": "Specify a path to a configuration file"
},
"host": {
"desc": "Specify a hostname to use"
},
"logLevel": {
"desc": "Set the logger output level (silent, info or debug)"
},
"reload-delay": {
"type": "number",
"desc": "Time in milliseconds to delay the reload event following file changes"
},
"reload-debounce": {
"type": "number",
"desc": "Restrict the frequency in which browser:reload events can be emitted to connected clients"
},
"ui-port": {
"type": "number",
"desc": "Specify a port for the UI to use"
},
"watchEvents": {
"type": "array",
"desc": "Specify which file events to respond to"
},
"no-notify": {
"desc": "Disable the notify element in browsers"
},
"no-open": {
"desc": "Don't open a new browser window"
},
"no-online": {
"desc": "Force offline usage"
},
"no-ui": {
"desc": "Don't start the user interface"
},
"no-ghost-mode": {
"desc": "Disable Ghost Mode"
},
"no-inject-changes": {
"desc": "Reload on every file change"
},
"no-reload-on-restart": {
"desc": "Don't auto-reload all browsers following a restart"
}
}

31
node_modules/browser-sync/lib/config.js generated vendored Normal file
View File

@ -0,0 +1,31 @@
"use strict";
var path = require("path");
/**
* @type {{controlPanel: {jsFile: string, baseDir: *}, socketIoScript: string, configFile: string, client: {shims: string}}}
*/
module.exports = {
controlPanel: {
jsFile: "/js/app.js",
baseDir: path.join(__dirname, "control-panel")
},
templates: {
scriptTag: path.join(__dirname, "templates/script-tags.tmpl"),
scriptTagSimple: path.join(__dirname, "templates/script-tags-simple.tmpl"),
connector: path.join(__dirname, "templates/connector.tmpl")
},
socketIoScript: "/public/socket.io.min.1.6.0.js",
configFile: "default-config.js",
userFile: "bs-config.js",
template: "cli-template.js",
httpProtocol: {
path: "/__browser_sync__"
},
client: {
shims: "/client/client-shims.js"
},
errors: {
"server+proxy": "Invalid config. You cannot specify both server & proxy options.",
"proxy+https": "Invalid config. You set https: true, but your proxy target doesn't reflect this."
}
};

245
node_modules/browser-sync/lib/connect-utils.js generated vendored Normal file
View File

@ -0,0 +1,245 @@
"use strict";
var _ = require("../lodash.custom");
var fs = require("fs");
var config = require("./config");
function getPath(options, relative, port) {
if (options.get("mode") === "snippet") {
return options.get("scheme") + "://HOST:" + port + relative;
} else {
return "//HOST:" + port + relative;
}
}
var connectUtils = {
/**
* @param {Immutable.Map} options
* @returns {String}
*/
scriptTags: function (options) {
var scriptPath = this.clientScript(options);
var async = options.getIn(["snippetOptions", "async"]);
var scriptDomain = options.getIn(["script", "domain"]);
/**
* Generate the [src] attribute based on user options
*/
var scriptSrc = (function () {
if (options.get("localOnly")) {
return [
options.get("scheme"),
"://localhost:",
options.get("port"),
scriptPath
].join("");
}
/**
* First, was "scriptPath" set? if so the user wanted full control over the
* script tag output
*
*/
if (_.isFunction(options.get("scriptPath"))) {
return options.get("scriptPath").apply(null, getScriptArgs(options, scriptPath));
}
/**
* Next, if "script.domain" was given, allow that + the path to the JS file
* eg:
* script.domain=localhost:3000
* -> localhost:3000/browser-sync/browser-sync-client.js
*/
if (scriptDomain) {
if (_.isFunction(scriptDomain)) {
return scriptDomain.call(null, options) + scriptPath;
}
if (scriptDomain.match(/\{port\}/)) {
return scriptDomain.replace("{port}", options.get("port")) + scriptPath;
}
return scriptDomain + scriptPath;
}
/**
* Now if server or proxy, use dynamic script
* eg:
* browser-sync start --server
* ->
* "HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)
*/
if (options.get("server") || options.get("proxy")) {
return scriptPath;
}
/**
* Final use case is snippet mode
* -> "http://HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)
* -> "//HOST:3000/browser-sync/browser-sync-client.js".replace("HOST", location.hostname)"
*/
return getPath(options, scriptPath, options.get("port"));
})();
/**
* Decide which template shall be used to generate the script tags
*/
var template = (function () {
if (scriptDomain || options.get("localOnly")) {
return config.templates.scriptTagSimple;
}
return config.templates.scriptTag;
})();
/**
* Finally read the template file from disk and replace
* the dynamic values.
*/
return fs.readFileSync(template, "utf8")
.replace("%script%", scriptSrc)
.replace("%async%", async ? "async" : "");
},
/**
* @param {Map} options
* @returns {String}
*/
socketConnector: function (options) {
var socket = options.get("socket");
var template = fs.readFileSync(config.templates.connector, "utf-8");
var url = connectUtils.getConnectionUrl(options);
/**
* ***Backwards compatibility***. While `socket.path` is technically a
* socketIoClientConfig property, it's been documented previously
* as a top-level option, so must stay.
*/
var clientConfig = socket
.get("socketIoClientConfig")
.merge({
path: socket.get("path")
});
template = template
.replace("%config%", JSON.stringify(clientConfig.toJS()))
.replace("%url%", url);
return template;
},
/**
* @param {Object} socketOpts
* @param {Map} options
* @returns {String|Function}
*/
getNamespace: function (socketOpts, options) {
var namespace = socketOpts.namespace;
if (typeof namespace === "function") {
return namespace(options);
}
if (!namespace.match(/^\//)) {
namespace = "/" + namespace;
}
return namespace;
},
/**
* @param {Map} options
* @returns {string}
*/
getConnectionUrl: function (options) {
var socketOpts = options.get("socket").toJS();
var namespace = connectUtils.getNamespace(socketOpts, options);
var protocol = "";
var withHostnamePort = "'{protocol}' + location.hostname + ':{port}{ns}'";
var withHost = "'{protocol}' + location.host + '{ns}'";
var withDomain = "'{domain}{ns}'";
var port = options.get("port");
// default use-case is server/proxy
var string = withHost;
if (options.get("mode") !== "server") {
protocol = options.get("scheme") + "://";
string = withHostnamePort;
}
if (options.get("mode") === "proxy" && options.getIn(["proxy", "ws"])) {
port = options.getIn(["socket", "port"]);
}
/**
* Ensure socket.domain is always a string (for noop replacements later)
*/
socketOpts.domain = (function () {
if (options.get("localOnly")) {
string = withDomain;
return [
options.get("scheme"),
"://localhost:",
options.get("port")
].join("");
}
if (socketOpts.domain) {
string = withDomain;
/**
* User provided a function
*/
if (_.isFunction(socketOpts.domain)) {
return socketOpts.domain.call(null, options);
}
/**
* User provided a string
*/
if (_.isString(socketOpts.domain)) {
return socketOpts.domain;
}
}
return "";
})();
return string
.replace("{protocol}", protocol)
.replace("{port}", port)
.replace("{domain}", socketOpts.domain.replace("{port}", port))
.replace("{ns}", namespace);
},
/**
* @param {Object} [options]
* @param {Boolean} [both]
*/
clientScript: function (options, both) {
var prefix = options.getIn(["socket", "clientPath"]);
var script = prefix + "/browser-sync-client.js";
var versioned = prefix + "/browser-sync-client.js?v=" + options.get("version");
if (both) {
return {
path: script,
versioned: versioned
};
}
return versioned;
}
};
/**
* @param options
* @returns {*[]}
*/
function getScriptArgs (options, scriptPath) {
var abspath = options.get("scheme") + "://HOST:" + options.get("port") + scriptPath;
return [
scriptPath,
options.get("port"),
options.set("absolute", abspath)
];
}
module.exports = connectUtils;

546
node_modules/browser-sync/lib/default-config.js generated vendored Normal file
View File

@ -0,0 +1,546 @@
"use strict";
/**
* @module BrowserSync.options
*/
module.exports = {
/**
* Browsersync includes a user-interface that is accessed via a separate port.
* The UI allows to controls all devices, push sync updates and much more.
* @property ui
* @type Object
* @param {Number} [port=3001]
* @param {Number} [weinre.port=8080]
* @since 2.0.0
* @default false
*/
ui: {
port: 3001,
weinre: {
port: 8080
}
},
/**
* Browsersync can watch your files as you work. Changes you make will either
* be injected into the page (CSS & images) or will cause all browsers to do
* a full-page refresh.
* @property files
* @type Array|String
* @default false
*/
files: false,
/**
* Specify which file events to respond to.
* Available events: `add`, `change`, `unlink`, `addDir`, `unlinkDir`
* @property watchEvents
* @type Array
* @default ["change"]
* @since 2.18.8
*/
watchEvents: ["change"],
/**
* File watching options that get passed along to [Chokidar](https://github.com/paulmillr/chokidar).
* Check their docs for available options
* @property watchOptions
* @type Object
* @default undefined
* @since 2.6.0
*/
watchOptions: {
ignoreInitial: true
/*
persistent: true,
ignored: '*.txt',
followSymlinks: true,
cwd: '.',
usePolling: true,
alwaysStat: false,
depth: undefined,
interval: 100,
ignorePermissionErrors: false,
atomic: true
*/
},
/**
* Use the built-in static server for basic HTML/JS/CSS websites.
* @property server
* @type Object|Boolean
* @default false
*/
server: false,
/**
* Proxy an EXISTING vhost. Browsersync will wrap your vhost with a proxy URL to view your site.
* @property proxy
* @type String|Object|Boolean
* @param {String} [target]
* @param {Boolean} [ws] - Enable websocket proxying
* @param {Function|Array} [middleware]
* @param {Function} [reqHeaders]
* @param {Array} [proxyReq]
* @param {Array} [proxyRes]
* @default false
*/
proxy: false,
/**
* @property port
* @type Number
* @default 3000
*/
port: 3000,
/**
* @property middleware
* @type Function|Array
* @default false
*/
middleware: false,
/**
* Add additional directories from which static
* files should be served. Should only be used in `proxy` or `snippet`
* mode.
* @property serveStatic
* @type Array
* @default []
* @since 2.8.0
*/
serveStatic: [],
/**
* Options that are passed to the serve-static middleware
* when you use the string[] syntax: eg: `serveStatic: ['./app']`. Please see
* [serve-static](https://github.com/expressjs/serve-static) for details
*
* @property serveStaticOptions
* @type Object
* @since 2.17.0
*/
/**
* Enable https for localhost development. **Note** - this is not needed for proxy
* option as it will be inferred from your target url.
* @property https
* @type Boolean
* @default undefined
* @since 1.3.0
*/
/**
* Override http module to allow using 3rd party server modules (such as http2)
* @property httpModule
* @type string
* @default undefined
* @since 2.18.0
*/
/**
* Clicks, Scrolls & Form inputs on any device will be mirrored to all others.
* @property ghostMode
* @param {Boolean} [clicks=true]
* @param {Boolean} [scroll=true]
* @param {Boolean} [location=true]
* @param {Boolean} [forms=true]
* @param {Boolean} [forms.submit=true]
* @param {Boolean} [forms.inputs=true]
* @param {Boolean} [forms.toggles=true]
* @type Object
*/
ghostMode: {
clicks: true,
scroll: true,
location: true,
forms: {
submit: true,
inputs: true,
toggles: true
}
},
/**
* Can be either "info", "debug", "warn", or "silent"
* @property logLevel
* @type String
* @default info
*/
logLevel: "info",
/**
* Change the console logging prefix. Useful if you're creating your
* own project based on Browsersync
* @property logPrefix
* @type String
* @default BS
* @since 1.5.1
*/
logPrefix: "BS",
/**
* @property logConnections
* @type Boolean
* @default false
*/
logConnections: false,
/**
* @property logFileChanges
* @type Boolean
* @default true
*/
logFileChanges: true,
/**
* Log the snippet to the console when you're in snippet mode (no proxy/server)
* @property logSnippet
* @type: Boolean
* @default true
* @since 1.5.2
*/
logSnippet: true,
/**
* You can control how the snippet is injected
* onto each page via a custom regex + function.
* You can also provide patterns for certain urls
* that should be ignored from the snippet injection.
* @property snippetOptions
* @since 2.0.0
* @param {Boolean} [async] - should the script tags have the async attribute?
* @param {Array} [blacklist]
* @param {Array} [whitelist]
* @param {RegExp} [rule.match=/$/]
* @param {Function} [rule.fn=Function]
* @type Object
*/
snippetOptions: {
async: true,
whitelist: [],
blacklist: [],
rule: {
match: /<body[^>]*>/i,
fn: function (snippet, match) {
return match + snippet;
}
}
},
/**
* Add additional HTML rewriting rules.
* @property rewriteRules
* @since 2.4.0
* @type Array
* @default false
*/
rewriteRules: [],
/**
* @property tunnel
* @type String|Boolean
* @default null
*/
/**
* Some features of Browsersync (such as `xip` & `tunnel`) require an internet connection, but if you're
* working offline, you can reduce start-up time by setting this option to `false`
* @property online
* @type Boolean
* @default undefined
*/
/**
* Decide which URL to open automatically when Browsersync starts. Defaults to "local" if none set.
* Can be `true`, `local`, `external`, `ui`, `ui-external`, `tunnel` or `false`
* @property open
* @type Boolean|String
* @default true
*/
open: "local",
/**
* @property browser
* @type String|Array
* @default default
*/
browser: "default",
/**
* Add HTTP access control (CORS) headers to assets served by Browsersync.
* @property cors
* @type boolean
* @default false
* @since 2.16.0
*/
cors: false,
/**
* Requires an internet connection - useful for services such as [Typekit](https://typekit.com/)
* as it allows you to configure domains such as `*.xip.io` in your kit settings
* @property xip
* @type Boolean
* @default false
*/
xip: false,
hostnameSuffix: false,
/**
* Reload each browser when Browsersync is restarted.
* @property reloadOnRestart
* @type Boolean
* @default false
*/
reloadOnRestart: false,
/**
* The small pop-over notifications in the browser are not always needed/wanted.
* @property notify
* @type Boolean
* @default true
*/
notify: true,
/**
* @property scrollProportionally
* @type Boolean
* @default true
*/
scrollProportionally: true,
/**
* @property scrollThrottle
* @type Number
* @default 0
*/
scrollThrottle: 0,
/**
* Decide which technique should be used to restore
* scroll position following a reload.
* Can be `window.name` or `cookie`
* @property scrollRestoreTechnique
* @type String
* @default 'window.name'
*/
scrollRestoreTechnique: "window.name",
/**
* Sync the scroll position of any element
* on the page. Add any amount of CSS selectors
* @property scrollElements
* @type Array
* @default []
* @since 2.9.0
*/
scrollElements: [],
/**
* Sync the scroll position of any element
* on the page - where any scrolled element
* will cause all others to match scroll position.
* This is helpful when a breakpoint alters which element
* is actually scrolling
* @property scrollElementMapping
* @type Array
* @default []
* @since 2.9.0
*/
scrollElementMapping: [],
/**
* Time, in milliseconds, to wait before
* instructing the browser to reload/inject following a
* file change event
* @property reloadDelay
* @type Number
* @default 0
*/
reloadDelay: 0,
/**
* Wait for a specified window of event-silence before
* sending any reload events.
* @property reloadDebounce
* @type Number
* @default 0
* @since 2.6.0
*/
reloadDebounce: 0,
/**
* Emit only the first event during sequential time windows
* of a specified duration.
* @property reloadThrottle
* @type Number
* @default 0
* @since 2.13.0
*/
reloadThrottle: 0,
/**
* User provided plugins
* @property plugins
* @type Array
* @default []
* @since 2.6.0
*/
plugins: [],
/**
* @property injectChanges
* @type Boolean
* @default true
*/
injectChanges: true,
/**
* @property startPath
* @type String|Null
* @default null
*/
startPath: null,
/**
* Whether to minify client script, or not.
* @property minify
* @type Boolean
* @default true
*/
minify: true,
/**
* @property host
* @type String
* @default null
*/
host: null,
/**
* Support environments where dynamic hostnames are not required
* (ie: electron)
* @property localOnly
* @type Boolean
* @default false
* @since 2.14.0
*/
localOnly: false,
/**
* @property codeSync
* @type Boolean
* @default true
*/
codeSync: true,
/**
* @property timestamps
* @type Boolean
* @default true
*/
timestamps: true,
clientEvents: [
"scroll",
"scroll:element",
"input:text",
"input:toggles",
"form:submit",
"form:reset",
"click"
],
/**
* Alter the script path for complete control over where the Browsersync
* Javascript is served from. Whatever you return from this function
* will be used as the script path.
* @property scriptPath
* @default undefined
* @since 1.5.0
* @type Function
*/
/**
* Configure the Socket.IO path and namespace & domain to avoid collisions.
* @property socket
* @param {String} [path="/browser-sync/socket.io"]
* @param {String} [clientPath="/browser-sync"]
* @param {String|Function} [namespace="/browser-sync"]
* @param {String|Function} [domain=undefined]
* @param {String|Function} [port=undefined]
* @param {Object} [clients.heartbeatTimeout=5000]
* @since 1.6.2
* @type Object
*/
socket: {
socketIoOptions: {
log: false
},
socketIoClientConfig: {
reconnectionAttempts: 50
},
path: "/browser-sync/socket.io",
clientPath: "/browser-sync",
namespace: "/browser-sync",
clients: {
heartbeatTimeout: 5000
}
},
/**
* Configure the script domain
* @property script
* @param {String|Function} [domain=undefined]
* @since 2.14.0
* @type Object
*/
tagNames: {
"less": "link",
"scss": "link",
"css": "link",
"jpg": "img",
"jpeg": "img",
"png": "img",
"svg": "img",
"gif": "img",
"js": "script"
},
injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp", "map"],
excludedFileTypes: [
"js",
"css",
"pdf",
"map",
"svg",
"ico",
"woff",
"json",
"eot",
"ttf",
"png",
"jpg",
"jpeg",
"webp",
"gif",
"mp4",
"mp3",
"3gp",
"ogg",
"ogv",
"webm",
"m4a",
"flv",
"wmv",
"avi",
"swf",
"scss"
]
};

120
node_modules/browser-sync/lib/file-event-handler.js generated vendored Normal file
View File

@ -0,0 +1,120 @@
var utils = require("./utils");
/**
* Apply the operators that apply to the 'file:changed' event
* @param {Rx.Observable} subject
* @param options
* @return {Rx.Observable<{type: string, files: Array<any>}>}
*/
function fileChanges(subject, options) {
var operators = [
{
option: "reloadThrottle",
fnName: "throttle"
},
{
option: "reloadDelay",
fnName: "delay"
}
];
var scheduler = options.getIn(["debug", "scheduler"]);
/**
* if the 'reloadDebounce' option was provided, create
* a stream buffered/debounced stream of events
*/
var initial = (function() {
if (options.get("reloadDebounce") > 0) {
return getAggregatedDebouncedStream(subject, options, scheduler);
}
return subject;
})();
return applyOperators(operators, initial, options, scheduler)
.map(function(xs) {
var items = [].concat(xs);
var paths = items.map(function (x) { return x.path });
if (utils.willCauseReload(paths, options.get("injectFileTypes").toJS())) {
return {
type: "reload",
files: items
}
}
return {
type: "inject",
files: items
}
});
}
module.exports.fileChanges = fileChanges;
/**
* Apply the operators that apply to the 'browser:reload' event
* @param {Rx.Observable} subject
* @param options
* @returns {Rx.Observable}
*/
function applyReloadOperators (subject, options) {
var operators = [
{
option: "reloadDebounce",
fnName: "debounce"
},
{
option: "reloadThrottle",
fnName: "throttle"
},
{
option: "reloadDelay",
fnName: "delay"
}
];
return applyOperators(operators, subject, options, options.getIn(["debug", "scheduler"]));
}
module.exports.applyReloadOperators = applyReloadOperators;
/**
* @param items
* @param subject
* @param options
* @param scheduler
*/
function applyOperators (items, subject, options, scheduler) {
return items.reduce(function(subject, item) {
var value = options.get(item.option);
if (value > 0) {
return subject[item.fnName].call(subject, value, scheduler);
}
return subject;
}, subject);
}
/**
* @param subject
* @param options
* @param scheduler
*/
function getAggregatedDebouncedStream (subject, options, scheduler) {
return subject
.filter(function(x) { return options.get("watchEvents").indexOf(x.event) > -1 })
.buffer(subject.debounce(options.get("reloadDebounce"), scheduler))
.map(function(buffered) {
return buffered.reduce(function (acc, item) {
if (!acc[item.path]) acc[item.path] = item;
if (acc[item.path]) acc[item.path] = item;
return acc;
}, {});
})
.map(function(group) {
return Object
.keys(group)
.map(function(key) {
return group[key];
});
})
.filter(function (x) { return x.length })
}

61
node_modules/browser-sync/lib/file-utils.js generated vendored Normal file
View File

@ -0,0 +1,61 @@
"use strict";
var _ = require("../lodash.custom");
var fileUtils = {
/**
* React to file-change events that occur on "core" namespace only
* @param bs
* @param data
*/
changedFile: function (bs, data) {
/**
* If the event property is undefined, infer that it's a 'change'
* event due the fact this handler is for emitter.emit("file:changed")
*/
if (_.isUndefined(data.event)) {
data.event = "change";
}
/**
* Chokidar always sends an 'event' property - which could be
* `add` `unlink` etc etc so we need to check for that and only
* respond to 'change', for now.
*/
if (bs.options.get("watchEvents").indexOf(data.event) > -1) {
if (!bs.paused && data.namespace === "core") {
bs.events.emit("file:reload", fileUtils.getFileInfo(data, bs.options));
}
}
},
/**
* @param data
* @param options
* @returns {{assetFileName: *, fileExtension: String}}
*/
getFileInfo: function (data, options) {
data.ext = require("path").extname(data.path).slice(1);
data.basename = require("path").basename(data.path);
var obj = {
ext: data.ext,
path: data.path,
basename: data.basename,
event: data.event,
type: "inject"
};
// RELOAD page
if (!_.includes(options.get("injectFileTypes").toJS(), obj.ext)) {
obj.url = obj.path;
obj.type = "reload";
}
obj.path = data.path;
obj.log = data.log;
return obj;
}
};
module.exports = fileUtils;

86
node_modules/browser-sync/lib/file-watcher.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
"use strict";
var _ = require("../lodash.custom");
var utils = require("./utils");
var Rx = require("rx");
/**
* Plugin interface
* @returns {*|function(this:exports)}
*/
module.exports.plugin = function (bs) {
var options = bs.options;
var emitter = bs.emitter;
var defaultWatchOptions = options.get("watchOptions").toJS();
return options.get("files").reduce(function (map, glob, namespace) {
/**
* Default CB when not given
* @param event
* @param path
*/
var fn = function (event, path) {
emitter.emit("file:changed", {
event: event,
path: path,
namespace: namespace
});
};
var jsItem = glob.toJS();
if (jsItem.globs.length) {
var watcher = watch(jsItem.globs, defaultWatchOptions, fn);
map[namespace] = {
watchers: [watcher]
};
}
if (jsItem.objs.length) {
jsItem.objs.forEach(function (item) {
if (!_.isFunction(item.fn)) {
item.fn = fn;
}
var watcher = watch(item.match, item.options || defaultWatchOptions, item.fn.bind(bs.publicInstance));
if (!map[namespace]) {
map[namespace] = {
watchers: [watcher]
};
} else {
map[namespace].watchers.push(watcher);
}
});
}
return map;
}, {});
};
/**
* @param patterns
* @param opts
* @param cb
* @returns {*}
*/
function watch (patterns, opts, cb) {
if (typeof opts === "function") {
cb = opts;
opts = {};
}
var watcher = require("chokidar")
.watch(patterns, opts);
if (_.isFunction(cb)) {
watcher.on("all", cb);
}
return watcher;
}
module.exports.watch = watch;

96
node_modules/browser-sync/lib/hooks.js generated vendored Normal file
View File

@ -0,0 +1,96 @@
"use strict";
var _ = require("../lodash.custom");
var Immutable = require("immutable");
var snippetUtils = require("./snippet").utils;
module.exports = {
/**
*
* @this {BrowserSync}
* @returns {String}
*/
"client:js": function (hooks, data) {
var js = snippetUtils.getClientJs(data.port, data.options);
return hooks.reduce(function (joined, hook) {
return joined + hook;
}, js);
},
/**
* @this {BrowserSync}
* @returns {Array}
*/
"client:events": function (hooks, clientEvents) {
hooks.forEach(function (hook) {
var result = hook(this);
if (Array.isArray(result)) {
clientEvents = _.union(clientEvents, result);
} else {
clientEvents.push(result);
}
}, this);
return clientEvents;
},
/**
* @returns {Array}
*/
"server:middleware": function (hooks, initial) {
initial = initial || [];
_.each(hooks, function (hook) {
var result = hook(this);
if (Array.isArray(result)) {
result.forEach(function (res) {
if (_.isFunction(res)) {
initial = initial.push(res);
}
});
} else {
if (_.isFunction(result)) {
initial = initial.push(result);
}
}
}, this);
return initial;
},
/**
* @param {Array} hooks
* @param {Map|List} initial
* @param pluginOptions
* @returns {any}
*/
"files:watch": function (hooks, initial, pluginOptions) {
var opts;
if (pluginOptions) {
opts = Immutable.fromJS(pluginOptions);
opts.forEach(function (value, key) {
if (!value) {
return;
}
var files = value.get("files");
if (files) {
var fileArg = require("./cli/cli-options").makeFilesArg(files);
if (fileArg) {
initial = initial.set(key, Immutable.fromJS(fileArg));
}
}
});
}
return initial;
}
};

69
node_modules/browser-sync/lib/http-protocol.js generated vendored Normal file
View File

@ -0,0 +1,69 @@
"use strict";
var queryString = require("qs");
var proto = exports;
/**
* Use BrowserSync options + querystring to create a
* full HTTP/HTTTPS url.
*
* Eg. http://localhost:3000/__browser_sync__?method=reload
* Eg. http://localhost:3000/__browser_sync__?method=reload&args=core.css
* Eg. http://localhost:3000/__browser_sync__?method=reload&args=core.css&args=core.min
*
* @param args
* @param url
* @returns {string}
*/
proto.getUrl = function (args, url) {
return [
url,
require("./config").httpProtocol.path,
"?",
queryString.stringify(args)
].join("");
};
/**
* Return a middleware for handling the requests
* @param {BrowserSync} bs
* @returns {Function}
*/
proto.middleware = function (bs) {
return function (req, res) {
var params = queryString.parse(req.url.replace(/^.*\?/, ""));
var output;
if (!Object.keys(params).length) {
output = [
"Error: No Parameters were provided.",
"Example: http://localhost:3000/__browser_sync__?method=reload&args=core.css"
];
res.writeHead(500, {"Content-Type": "text/plain"});
res.end(output.join("\n"));
return;
}
try {
require("./public/" + params.method)(bs.events).apply(null, [params.args]);
output = [
"Called public API method `.%s()`".replace("%s", params.method),
"With args: " + JSON.stringify(params.args)
];
res.end(output.join("\n"));
} catch (e) {
res.writeHead(404, {"Content-Type": "text/plain"});
res.write("Public API method `" + params.method + "` not found.");
res.end();
return;
}
};
};

110
node_modules/browser-sync/lib/internal-events.js generated vendored Normal file
View File

@ -0,0 +1,110 @@
"use strict";
var utils = require("./utils");
var fileUtils = require("./file-utils");
var Rx = require("rx");
var fromEvent = Rx.Observable.fromEvent;
var fileHandler = require("./file-event-handler");
module.exports = function (bs) {
var events = {
/**
* File reloads
* @param data
*/
"file:reload": function (data) {
bs.io.sockets.emit("file:reload", data);
},
/**
* Browser Reloads
*/
"browser:reload": function () {
bs.io.sockets.emit("browser:reload");
},
/**
* Browser Notify
* @param data
*/
"browser:notify": function (data) {
bs.io.sockets.emit("browser:notify", data);
},
/**
* Things that happened after the service is running
* @param data
*/
"service:running": function (data) {
var mode = bs.options.get("mode");
var open = bs.options.get("open");
if (mode === "proxy" || mode === "server" || open === "ui" || open === "ui-external") {
utils.openBrowser(data.url, bs.options, bs);
}
// log about any file watching
if (bs.watchers) {
bs.events.emit("file:watching", bs.watchers);
}
},
/**
* Option setting
* @param data
*/
"options:set": function (data) {
if (bs.io) {
bs.io.sockets.emit("options:set", data);
}
},
/**
* Plugin configuration setting
* @param data
*/
"plugins:configure": function (data) {
if (data.active) {
bs.pluginManager.enablePlugin(data.name);
} else {
bs.pluginManager.disablePlugin(data.name);
}
bs.setOption("userPlugins", bs.getUserPlugins());
},
"plugins:opts": function (data) {
if (bs.pluginManager.pluginOptions[data.name]) {
bs.pluginManager.pluginOptions[data.name] = data.opts;
bs.setOption("userPlugins", bs.getUserPlugins());
}
}
};
Object.keys(events).forEach(function (event) {
bs.events.on(event, events[event]);
});
var reloader = fileHandler.applyReloadOperators(fromEvent(bs.events, "_browser:reload"), bs.options)
.subscribe(function() {
bs.events.emit("browser:reload");
});
var coreNamespacedWatchers = fromEvent(bs.events, "file:changed")
.filter(function() { return bs.options.get("codeSync") })
.filter(function(x) { return x.namespace === "core" });
var handler = fileHandler.fileChanges(coreNamespacedWatchers, bs.options)
.subscribe(function (x) {
if (x.type === "reload") {
bs.events.emit("browser:reload");
}
if (x.type === "inject") {
x.files.forEach(function(data) {
if (!bs.paused && data.namespace === "core") {
bs.events.emit("file:reload", fileUtils.getFileInfo(data, bs.options));
}
});
}
});
bs.registerCleanupTask(function() {
handler.dispose();
reloader.dispose();
});
};

288
node_modules/browser-sync/lib/logger.js generated vendored Normal file
View File

@ -0,0 +1,288 @@
"use strict";
var messages = require("./connect-utils");
var utils = require("./utils");
var _ = require("../lodash.custom");
var template = "[{blue:%s}] ";
var logger = require("eazy-logger").Logger({
prefix: template.replace("%s", "BS"),
useLevelPrefixes: false
});
module.exports.logger = logger;
/**
* @param name
* @returns {*}
*/
module.exports.getLogger = function (name) {
return logger.clone(function (config) {
config.prefix = config.prefix + template.replace("%s", name);
return config;
});
};
/**
* Logging Callbacks
*/
module.exports.callbacks = {
/**
* Log when file-watching has started
* @param {BrowserSync} bs
* @param data
*/
"file:watching": function (bs, data) {
if (Object.keys(data).length) {
logger.info("Watching files...");
}
},
/**
* Log when a file changes
* @param {BrowserSync} bs
* @param data
*/
"file:reload": function (bs, data) {
if (canLogFileChange(bs, data)) {
if (data.path[0] === "*") {
return logger.info("{cyan:Reloading files that match: {magenta:%s", data.path);
}
logger.info("{cyan:File event [" + data.event + "] : {magenta:%s", data.path);
}
},
/**
*
*/
"service:exit": function () {
logger.debug("Exiting...");
},
/**
*
*/
"browser:reload": function (bs) {
if (canLogFileChange(bs)) {
logger.info("{cyan:Reloading Browsers...");
}
},
/**
*
*/
"browser:error": function () {
logger.error("Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the {cyan:open} option to {cyan:false})");
},
/**
* @param {BrowserSync} bs
* @param data
*/
"stream:changed": function (bs, data) {
if (canLogFileChange(bs)) {
var changed = data.changed;
logger.info("{cyan:%s %s changed} ({magenta:%s})",
changed.length,
changed.length > 1 ? "files" : "file",
changed.join(", ")
);
}
},
/**
* Client connected logging
* @param {BrowserSync} bs
* @param data
*/
"client:connected": function (bs, data) {
var uaString = utils.getUaString(data.ua);
var msg = "{cyan:Browser Connected: {magenta:%s, version: %s}";
var method = "info";
if (!bs.options.get("logConnections")) {
method = "debug";
}
logger.log(method, msg,
uaString.name,
uaString.version
);
},
/**
* Main logging when the service is running
* @param {BrowserSync} bs
* @param data
*/
"service:running": function (bs, data) {
var type = data.type;
if (type === "server") {
var baseDir = bs.options.getIn(["server", "baseDir"]);
logUrls(bs.options.get("urls").toJS());
if (baseDir) {
if (utils.isList(baseDir)) {
baseDir.forEach(serveFiles);
} else {
serveFiles(baseDir);
}
}
}
if (type === "proxy") {
logger.info("Proxying: {cyan:%s}", bs.options.getIn(["proxy", "target"]));
logUrls(bs.options.get("urls").toJS());
}
if (type === "snippet") {
if (bs.options.get("logSnippet")) {
logger.info(
"{bold:Copy the following snippet into your website, " +
"just before the closing {cyan:</body>} tag"
);
logger.unprefixed("info",
messages.scriptTags(bs.options)
);
}
logUrls(bs.options.get("urls").filter(function (value, key) {
return key.slice(0, 2) === "ui";
}).toJS());
}
function serveFiles (base) {
logger.info("Serving files from: {magenta:%s}", base);
}
}
};
/**
* Plugin interface for BrowserSync
* @param {EventEmitter} emitter
* @param {BrowserSync} bs
* @returns {Object}
*/
module.exports.plugin = function (emitter, bs) {
var logPrefix = bs.options.get("logPrefix");
var logLevel = bs.options.get("logLevel");
// Should set logger level here!
logger.setLevel(logLevel);
if (logPrefix) {
if (_.isFunction(logPrefix)) {
logger.setPrefix(logPrefix);
} else {
logger.setPrefix(template.replace("%s", logPrefix));
}
}
_.each(exports.callbacks, function (func, event) {
emitter.on(event, func.bind(this, bs));
});
return logger;
};
/**
*
* @param urls
*/
function logUrls (urls) {
var keys = Object.keys(urls);
var longestName = 0;
var longesturl = 0;
var offset = 2;
if (!keys.length) {
return;
}
var names = keys.map(function (key) {
if (key.length > longestName) {
longestName = key.length;
}
if (urls[key].length > longesturl) {
longesturl = urls[key].length;
}
return key;
});
var underline = getChars(longestName + offset + longesturl + 1, "-");
var underlined = false;
logger.info("{bold:Access URLs:");
logger.unprefixed("info", "{grey: %s", underline);
keys.forEach(function (key, i) {
var keyname = getKeyName(key);
logger.unprefixed("info", " %s: {magenta:%s}",
getPadding(key.length, longestName + offset) + keyname,
urls[key]
);
if (!underlined && names[i + 1] && names[i + 1].indexOf("ui") > -1) {
underlined = true;
logger.unprefixed("info", "{grey: %s}", underline);
}
});
logger.unprefixed("info", "{grey: %s}", underline);
}
/**
* @param {Number} len
* @param {Number} max
* @returns {string}
*/
function getPadding (len, max) {
return new Array(max - (len + 1)).join(" ");
}
/**
* @param {Number} len
* @param {String} char
* @returns {string}
*/
function getChars (len, char) {
return new Array(len).join(char);
}
/**
* Transform url-key names into something more presentable
* @param key
* @returns {string}
*/
function getKeyName(key) {
if (key.indexOf("ui") > -1) {
if (key === "ui") {
return "UI";
}
if (key === "ui-external") {
return "UI External";
}
}
return key.substr(0, 1).toUpperCase() + key.substring(1);
}
/**
* Determine if file changes should be logged
* @param bs
* @param data
* @returns {boolean}
*/
function canLogFileChange(bs, data) {
if (data && data.log === false) {
return false;
}
return bs.options.get("logFileChanges");
}

250
node_modules/browser-sync/lib/options.js generated vendored Normal file
View File

@ -0,0 +1,250 @@
"use strict";
var _ = require("../lodash.custom");
var Immutable = require("immutable");
var defaultConfig = require("./default-config");
/**
* @param {Map} options
* @returns {Map}
*/
module.exports.update = function (options) {
return options.withMutations(function (item) {
setMode(item);
setScheme(item);
setStartPath(item);
setProxyWs(item);
setServerOpts(item);
setNamespace(item);
fixSnippetOptions(item);
fixRewriteRules(item);
setMiddleware(item);
setOpen(item);
if (item.get("uiPort")) {
item.setIn(["ui", "port"], item.get("uiPort"));
}
});
};
/**
* Move top-level ws options to proxy.ws
* This is to allow it to be set from the CLI
* @param item
*/
function setProxyWs(item) {
if (item.get("ws") && item.get("mode") === "proxy") {
item.setIn(["proxy", "ws"], true);
}
}
/**
* @param item
*/
function setOpen (item) {
var open = item.get("open");
if (item.get("mode") === "snippet") {
if (open !== "ui" && open !== "ui-external") {
item.set("open", false);
}
}
}
/**
* Set the running mode
* @param item
*/
function setMode (item) {
item.set("mode", (function () {
if (item.get("server")) {
return "server";
}
if (item.get("proxy")) {
return "proxy";
}
return "snippet";
})());
}
/**
* @param item
*/
function setScheme (item) {
var scheme = "http";
if (item.getIn(["server", "https"])) {
scheme = "https";
}
if (item.get("https")) {
scheme = "https";
}
if (item.getIn(["proxy", "url", "protocol"])) {
if (item.getIn(["proxy", "url", "protocol"]) === "https:") {
scheme = "https";
}
}
item.set("scheme", scheme);
}
/**
* @param item
*/
function setStartPath (item) {
if (item.get("proxy")) {
var path = item.getIn(["proxy", "url", "path"]);
if (path !== "/") {
item.set("startPath", path);
}
}
}
/**
* @param item
*/
function setNamespace(item) {
var namespace = item.getIn(["socket", "namespace"]);
if (_.isFunction(namespace)) {
item.setIn(["socket", "namespace"], namespace(defaultConfig.socket.namespace));
}
}
/**
* @param item
*/
function setServerOpts(item) {
if (item.get("server")) {
var indexarg = item.get("index") || item.getIn(["server", "index"]) || "index.html";
var optPath = ["server", "serveStaticOptions"];
if (item.get("directory")) {
item.setIn(["server", "directory"], true);
}
if (!item.getIn(optPath)) {
item.setIn(optPath, Immutable.Map({
index: indexarg
}));
} else {
if (!item.hasIn(optPath.concat(["index"]))) {
item.setIn(optPath.concat(["index"]), indexarg);
}
}
// cli extensions
if (item.get("extensions")) {
item.setIn(optPath.concat(["extensions"]), item.get("extensions"));
}
}
}
/**
* Back-compat fixes for rewriteRules being set to a boolean
*/
function fixRewriteRules (item) {
return item.update("rewriteRules", function (rr) {
return Immutable.List([]).concat(rr).filter(Boolean)
});
}
function fixSnippetOptions (item) {
var ignorePaths = item.getIn(["snippetOptions", "ignorePaths"]);
var includePaths = item.getIn(["snippetOptions", "whitelist"]);
if (ignorePaths) {
if (_.isString(ignorePaths)) {
ignorePaths = [ignorePaths];
}
ignorePaths = ignorePaths.map(ensureSlash);
item.setIn(["snippetOptions", "blacklist"], Immutable.List(ignorePaths));
}
if (includePaths) {
includePaths = includePaths.map(ensureSlash);
item.setIn(["snippetOptions", "whitelist"], Immutable.List(includePaths));
}
}
/**
* Enforce paths to begin with a forward slash
*/
function ensureSlash (item) {
if (item[0] !== "/") {
return "/" + item;
}
return item;
}
/**
*
*/
function setMiddleware (item) {
var mw = getMiddlwares(item);
item.set("middleware", mw);
}
/**
* top-level option, or given as part of the proxy/server option
* @param item
* @returns {*}
*/
function getMiddlwares (item) {
var mw = item.get("middleware");
var serverMw = item.getIn(["server", "middleware"]);
var proxyMw = item.getIn(["proxy", "middleware"]);
var list = Immutable.List([]);
if (mw) {
return listMerge(list, mw);
}
if (serverMw) {
return listMerge(list, serverMw);
}
if (proxyMw) {
return listMerge(list, proxyMw);
}
return list;
}
/**
* @param item
* @returns {*}
*/
function isList (item) {
return Immutable.List.isList(item);
}
/**
* @param list
* @param item
* @returns {*}
*/
function listMerge(list, item) {
if (_.isFunction(item)) {
list = list.push(item);
}
if (isList(item) && item.size) {
list = list.merge(item);
}
return list;
}

185
node_modules/browser-sync/lib/plugins.js generated vendored Normal file
View File

@ -0,0 +1,185 @@
var Immutable = require("immutable");
var Map = Immutable.Map;
var isMap = Immutable.Map.isMap;
var List = Immutable.List;
var qs = require("qs");
var path = require("path");
var fs = require("fs");
var Plugin = Immutable.Record({
moduleName: "",
name: "",
active: true,
module: undefined,
options: Map({}),
via: "inline",
dir: process.cwd(),
init: undefined,
errors: List([])
});
/**
* Accept a string/object
* and resolve it into the plugin format above
* @param item
* @returns {*}
*/
function resolvePlugin(item) {
/**
* Handle when string was given, such as plugins: ['bs-html-injector']
*/
if (typeof item === "string") {
return getFromString(item);
}
if (!isMap(item)) {
return new Plugin().mergeDeep({errors: [new Error("Plugin not supported in this format")]});
}
if (item.has("module")) {
var nameOrObj = item.get("module");
var options = item.get("options");
/**
* The 'module' key can be a string, this allows
* inline plugin references, but with options
* eg:
*
* bs.init({
* plugins: [
* {
* module: './myjs-file.js'
* options: {
* files: "*.html"
* }
* }
* ]
* });
*/
if (typeof nameOrObj === "string") {
return getFromString(nameOrObj)
.mergeDeep({
options: options
});
}
/**
* If the plugin was given completely inline (because it needs options)
* eg:
*
* bs.init({
* plugins: [
* {
* module: {
* plugin: function() {
* console.log('My plugin code')
* }
* },
* options: {
* files: "*.html"
* }
* }
* ]
* })
*/
if (Immutable.Map.isMap(nameOrObj)) {
return new Plugin({
module: nameOrObj,
options: options
});
}
}
/**
* If a module was given directly. For example, ater calling require.
*
* eg:
* var myplugin = require('./some-js');
* bs.init({plugins: [myplugin]});
*/
if (item.has("plugin")) {
return new Plugin({
module: item
})
}
/**
* If we reach here, the plugin option was used incorrectly
*/
return new Plugin().mergeDeep({errors: [new Error("Plugin was not configured correctly")]})
}
module.exports.resolvePlugin = resolvePlugin;
/**
* Load a plugin from disk
* @param item
* @returns {*}
*/
function requirePlugin (item) {
/**
* if the "module" property already exists and
* is not a string, then we bail and don't bother looking
* for the file
*/
if (item.get("module") && typeof item.get("module") !== "string") {
return item;
}
try {
/**
* Try a raw node require() call - this will be how
* regular "npm installed" plugins wil work
*/
var maybe = path.resolve(process.cwd(), "node_modules", item.get("name"));
return item.set("module", require(maybe));
} catch (e) {
/**
* If require threw an MODULE_NOT_FOUND error, try again
* by resolving from cwd. This is needed since cli
* users will not add ./ to the front of a path (which
* node requires to resolve from cwd)
*/
if (e.code === "MODULE_NOT_FOUND") {
var maybe = path.resolve(process.cwd(), item.get("name"));
if (fs.existsSync(maybe)) {
return item.set("module", require(maybe));
} else {
/**
* Finally return a plugin that contains the error
* this will be picked up later and discarded
*/
return item.update("errors", function (errors) {
return errors.concat(e);
});
}
}
throw e;
}
}
module.exports.requirePlugin = requirePlugin;
function getFromString(string) {
/**
* We allow query strings for plugins, so always split on ?
*/
var split = string.split("?");
var outGoing = new Plugin({
moduleName: split[0],
name: split[0]
});
if (split.length > 1) {
return outGoing.update("options", function (opts) {
return opts.mergeDeep(qs.parse(split[1]));
});
}
return outGoing;
}

17
node_modules/browser-sync/lib/public/exit.js generated vendored Normal file
View File

@ -0,0 +1,17 @@
"use strict";
/**
* @param {BrowserSync} browserSync
* @returns {Function}
*/
module.exports = function (browserSync) {
function exit() {
if (browserSync.active) {
browserSync.events.emit("service:exit");
browserSync.cleanup();
}
}
return exit;
};

32
node_modules/browser-sync/lib/public/init.js generated vendored Normal file
View File

@ -0,0 +1,32 @@
"use strict";
var _ = require("../../lodash.custom");
var merge = require("../cli/cli-options").merge;
/**
* @param {BrowserSync} browserSync
* @param {String} [name] - instance name
* @param {Object} pjson
* @returns {Function}
*/
module.exports = function (browserSync, name, pjson) {
return function () {
/**
* Handle new + old signatures for init.
*/
var args = require("../args")(_.toArray(arguments));
/**
* If the current instance is already running, just return an error
*/
if (browserSync.active) {
return args.cb(new Error("Instance: " + name + " is already running!"));
}
args.config.version = pjson.version;
return browserSync.init(merge(args.config), args.cb);
};
};

19
node_modules/browser-sync/lib/public/notify.js generated vendored Normal file
View File

@ -0,0 +1,19 @@
"use strict";
/**
* @param {BrowserSync} browserSync
* @returns {Function}
*/
module.exports = function (browserSync) {
return function (msg, timeout) {
if (msg) {
browserSync.events.emit("browser:notify", {
message: msg,
timeout: timeout || 2000,
override: true
});
}
};
};

12
node_modules/browser-sync/lib/public/pause.js generated vendored Normal file
View File

@ -0,0 +1,12 @@
"use strict";
/**
* @param {BrowserSync} browserSync
* @returns {Function}
*/
module.exports = function (browserSync) {
return function () {
browserSync.paused = true;
};
};

65
node_modules/browser-sync/lib/public/public-utils.js generated vendored Normal file
View File

@ -0,0 +1,65 @@
"use strict";
var _ = require("../../lodash.custom");
module.exports = {
/**
* Emit the internal `file:change` event
* @param {EventEmitter} emitter
* @param {string} path
* @param {boolean} [log]
*/
emitChangeEvent: function emitChangeEvent (emitter, path, log) {
emitter.emit("file:changed", {
path: path,
log: log,
namespace: "core",
event: "change"
});
},
/**
* Emit the internal `browser:reload` event
* @param {EventEmitter} emitter
*/
emitBrowserReload: function emitChangeEvent (emitter) {
emitter.emit("_browser:reload");
},
/**
* Emit the internal `stream:changed` event
* @param {EventEmitter} emitter
* @param {Array} changed
*/
emitStreamChangedEvent: function (emitter, changed) {
emitter.emit("stream:changed", {changed: changed});
},
/**
* This code handles the switch between .reload & .stream
* since 2.6.0
* @param name
* @param args
* @returns {boolean}
*/
isStreamArg: function (name, args) {
if (name === "stream") {
return true;
}
if (name !== "reload") {
return false;
}
var firstArg = args[0];
/**
* If here, it's reload with args
*/
if (_.isObject(firstArg)) {
if (!Array.isArray(firstArg) && Object.keys(firstArg).length) {
return firstArg.stream === true;
}
}
return false;
}
};

67
node_modules/browser-sync/lib/public/reload.js generated vendored Normal file
View File

@ -0,0 +1,67 @@
"use strict";
var utils = require("../utils");
var publicUtils = require("./public-utils");
var _ = require("../../lodash.custom");
var defaultConfig = require("../default-config");
var stream = require("./stream");
/**
* @param emitter
* @returns {Function}
*/
module.exports = function (emitter) {
/**
* Inform browsers about file changes.
*
* eg: reload("core.css")
*/
function browserSyncReload (opts) {
/**
* BACKWARDS COMPATIBILITY:
* Passing an object as the only arg to the `reload`
* method with at *least* the key-value pair of {stream: true},
* was only ever used for streams support - so it's safe to check
* for that signature here and defer to the
* dedicated `.stream()` method instead.
*/
if (_.isObject(opts)) {
if (!Array.isArray(opts) && Object.keys(opts).length) {
if (opts.stream === true) {
return stream(emitter)(opts);
}
}
}
/**
* Handle single string paths such as
* reload("core.css")
*/
if (typeof opts === "string" && opts !== "undefined") {
return publicUtils.emitChangeEvent(emitter, opts, true);
}
/**
* Handle an array of file paths such as
* reload(["core.css, "ie.css"])
*/
if (Array.isArray(opts)) {
return opts.forEach(function (filepath) {
publicUtils.emitChangeEvent(emitter, filepath, true);
});
}
/**
* At this point the argument given was neither an object,
* array or string so we simply perform a reload. This is to
* allow the following syntax to work as expected
*
* reload();
*/
return publicUtils.emitBrowserReload(emitter);
}
return browserSyncReload;
};

12
node_modules/browser-sync/lib/public/resume.js generated vendored Normal file
View File

@ -0,0 +1,12 @@
"use strict";
/**
* @param {BrowserSync} browserSync
* @returns {Function}
*/
module.exports = function (browserSync) {
return function () {
browserSync.paused = false;
};
};

File diff suppressed because one or more lines are too long

98
node_modules/browser-sync/lib/public/stream.js generated vendored Normal file
View File

@ -0,0 +1,98 @@
"use strict";
var path = require("path");
var micromatch = require("micromatch");
var utils = require("./public-utils");
/**
* @param emitter
* @returns {Function}
*/
module.exports = function (emitter) {
/**
* Return a transform/through stream that listens to file
* paths and fires internal Browsersync events.
* @param {{once: boolean, match: string|array}} [opts]
* @returns {Stream.Transform}
*/
function browserSyncThroughStream (opts) {
opts = opts || {};
var emitted = false;
var Transform = require("stream").Transform;
var reload = new Transform({objectMode: true});
var changed = [];
reload._transform = function (file, encoding, next) {
var stream = this;
/**
* End is always called to send the current file down
* stream. Browsersync never acts upon a stream,
* we only `listen` to it.
*/
function end () {
stream.push(file); // always send the file down-stream
next();
}
/**
* If {match: <pattern>} was provided, test the
* current filepath against it
*/
if (opts.match) {
if (!micromatch(file.path, opts.match, {dot: true}).length) {
return end();
}
}
/**
* if {once: true} provided, emit the reload event for the
* first file only
*/
if (opts.once === true && !emitted) {
utils.emitBrowserReload(emitter);
emitted = true;
} else { // handle multiple
if (opts.once === true && emitted) {
} else {
if (file.path) {
emitted = true;
utils.emitChangeEvent(emitter, file.path, false);
changed.push(path.basename(file.path));
}
}
}
end();
};
/**
* When this current operation has finished, emit the
* steam:changed event so that any loggers can pick up it
* @param next
* @private
*/
reload._flush = function (next) {
if (changed.length) {
utils.emitStreamChangedEvent(emitter, changed);
}
next();
};
return reload;
}
return browserSyncThroughStream;
};

Binary file not shown.

6
node_modules/browser-sync/lib/server/certs/gen.sh generated vendored Normal file
View File

@ -0,0 +1,6 @@
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
cp server.key server.key.copy
openssl rsa -in server.key.copy -out server.key
rm server.key.copy

19
node_modules/browser-sync/lib/server/certs/server.crt generated vendored Normal file
View File

@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAe4CCQCir/8eGDIE/jANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJH
QjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE3MDQxMDExNDcyNloXDTI3MDQwODExNDcyNlowRTELMAkG
A1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AMRLR2crKB4X/9pM3gR641iDscZWW3aqo70nUDxzo5Bhk8uupqz0EfdRoCLCUeQi
xVp3HJ1HqnilMW7dETGGkDHKdxJRjrkBrYHhE3Kw/LCC4tEb400F6Ikm6OudVPIB
P+CuwfNAw70KHSx/CtIrbTz0HhDC6XN0azp39pDLRBnWWluz3iU+rFLMx7YT2Q8k
1nQAwcXkzLjeU7txAt2pYGQUgvBQETO5RI7QQ0CmwaV4gfHWGABBTX34WQun7g1Q
YukrG3/4fVeNLzGW787FKCvL07BTymJTwXXbTTPXg4chw9p+YkLLPrr+AOVe/PF1
MJppDT3gKdKMHFo3vMycUf0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAEVmUYRrT
fCQmBDox3evqj4n8dJVStjgdw/7BPkm49SmGtaxsST/eUSGwT7dTvZBLov6BK/OW
+arhHZIvUY/DXlsV4NfCM4TK8KVefrwgd8ZsfQJW73L+FB0IOAY/6s+YKHm/wQGF
ptSOycJvEltsqfIegtYcvvD6c6SkSOvqApaF+Ai10+yiLe20KyOvM3PefZLV7mFE
0zCNyglZ75HftvHHV0wh82T2Et/R+txH+6dTwh065Dd6rrDzljtcAd2HC7B26ERK
dA2zJd9Y4eMz8osacmG/afVuR9rqtFGwdyZ1Kb5xQRzGWlrjvSmAFUx9W9iA4Ilv
3+56a5njSTFYKw==
-----END CERTIFICATE-----

17
node_modules/browser-sync/lib/server/certs/server.csr generated vendored Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICoTCCAYkCAQAwRTELMAkGA1UEBhMCR0IxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMRLR2crKB4X/9pM3gR641iDscZWW3aqo70nUDxz
o5Bhk8uupqz0EfdRoCLCUeQixVp3HJ1HqnilMW7dETGGkDHKdxJRjrkBrYHhE3Kw
/LCC4tEb400F6Ikm6OudVPIBP+CuwfNAw70KHSx/CtIrbTz0HhDC6XN0azp39pDL
RBnWWluz3iU+rFLMx7YT2Q8k1nQAwcXkzLjeU7txAt2pYGQUgvBQETO5RI7QQ0Cm
waV4gfHWGABBTX34WQun7g1QYukrG3/4fVeNLzGW787FKCvL07BTymJTwXXbTTPX
g4chw9p+YkLLPrr+AOVe/PF1MJppDT3gKdKMHFo3vMycUf0CAwEAAaAXMBUGCSqG
SIb3DQEJBzEIDAYxMjM0NTYwDQYJKoZIhvcNAQELBQADggEBABlVUaWK/UUovgPZ
+rqNG8/j6aggSCCye9CkauLB/WqhQFfLl9lWTYdUVmWweNU0SJwDU9lWF/TngipF
RZs6501DkXKxaDT9/3JYg4lRz6zHLy+a77pavJOeN0+cFAPZZuGyxZvYHFYPVSVH
EeJL6bO/nZ/ARgIp0YNkQblDarxq1ARj7YT1Z24D5KgO1kQ55+fCY/wtct8TLGk9
ujvWBbFEBSrJCDjRQeSctlP5qG8yfeJqZwZzo4PQMUwABhNLGUz0z0ceK8W1QnOm
T+nCN5Fni04wO4dAZvYPp6wmU0Gpi2XBihbFl9CT3B5AmJmM8hQVpuQlmXeXT0FO
pOZFpko=
-----END CERTIFICATE REQUEST-----

27
node_modules/browser-sync/lib/server/certs/server.key generated vendored Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAxEtHZysoHhf/2kzeBHrjWIOxxlZbdqqjvSdQPHOjkGGTy66m
rPQR91GgIsJR5CLFWnccnUeqeKUxbt0RMYaQMcp3ElGOuQGtgeETcrD8sILi0Rvj
TQXoiSbo651U8gE/4K7B80DDvQodLH8K0ittPPQeEMLpc3RrOnf2kMtEGdZaW7Pe
JT6sUszHthPZDyTWdADBxeTMuN5Tu3EC3algZBSC8FARM7lEjtBDQKbBpXiB8dYY
AEFNffhZC6fuDVBi6Ssbf/h9V40vMZbvzsUoK8vTsFPKYlPBddtNM9eDhyHD2n5i
Qss+uv4A5V788XUwmmkNPeAp0owcWje8zJxR/QIDAQABAoIBADbeT/wvnQwkazkL
CXg5HXltfnDRTMmz0wcZiR0MueiuzdA+ZoqrwqXeJCPzK07YxU+PQelY0fbdPh8e
HiM42O+CB5yQPZPLO0O1tWj2vftc6qfG4tdx0lkcDjlmBguLe96DGuWy8cPSousA
K/cpemRyXEEVKopCPYLfa4V3u/Z4be2U/39KNjVkHFhSdSYQl6ferhEfUPwTPi7O
7l1/QUBabqN5FzNc2TeMVhhcJkXtYqF3RxGsaRfT0lK/j2hpbX7Bn2T0CfA/40jY
2OCERqFPfZWx/ShTT52b3fyX/FEua7Nukq/MZdYZou63dDIjCQQyTJSflX6lVojO
SuUoumECgYEA6CSkLiKcRLlTfec3LkjqkWtXR5ibL33g/H1fsZEQKFOyMbIXpUkX
Hybpku8NGeetjKynO3yRirp+NiBHGPn3cHc9WJ5GGG1ew9hRQ9QzyC3Tit15TDbu
J8i50/MaQHZSiUCnPQ/ceIZCNz8STcsEz87o/7utRLJKOvIIAPj+/8kCgYEA2Hd/
v5oUroMRbtzPtMJDMHiGEQyNxEGDNqcuxgXSmiEEqPLfk2qR3yLffzA9UQOg4wkX
/dSXsyomPriKWTvADXu1lNdkPGmW/1tk+onnHu6qgOalva30ZKhtteVjUqxEJEke
mHhNHyIVuj6lExLw9LZhVvzoOi+aj4AD+DRS4pUCgYBEtuveOCJ3eUAMiY9c5PqB
9vsL11FAOouJUXcs8VqOBVA+w4+aPktYzkTfWGFRZLGLbWPHCPVv0gof7Wf+Laef
o7wF6junaWBeqj5LzJlTTLVMaohIFg5iuli/Mzt3D08ZD4kxWuuQxXT+M24wlsKi
3IU9hYkhR4EPd6sE1q9seQKBgEpQRBAgModywbJgpgH1SyHBzqzdtXGx1/0USg97
gkCdoz7pGm4+gNOs4jOE+Rft+fbXcWAX8vh0OOsBaaWWyKkYVk9B3syKp2cFFlaY
rzrETs6v4CiNJsDDvd5bYMzKDR6z54gKjNdqWTE2Pm+c6hHo5uP5MTSAkTxAg5xb
QjU9AoGAaYPXlm3IKVO12FgNg/ffduooi0PKa1yRNJGnhpQKNvBQXs8eV+CQ83aK
kQHUExuJDrOfsC2iwF/2ZywXhEfbhL7ar0aw5zrhV+r7qvYFWxu/YoLoNVMDByw5
wAN0oIbsGWYmtIIti8+b9IcacTbAZ79ctlTLb1HCyPMosHxDkv8=
-----END RSA PRIVATE KEY-----

95
node_modules/browser-sync/lib/server/index.js generated vendored Normal file
View File

@ -0,0 +1,95 @@
"use strict";
var enableDestroy = require("server-destroy");
var _ = require("../../lodash.custom");
/**
* Browsersync server
* Three available modes: Snippet, Server or Proxy
*/
module.exports.plugin = function (bs) {
var debug = bs.debug;
var proxy = bs.options.get("proxy");
var type = bs.options.get("mode");
var bsServer = createServer(bs);
if (type === "server" || type === "snippet") {
debug("Static Server running ({magenta:%s}) ...", bs.options.get("scheme"));
}
if (proxy) {
debug("Proxy running, proxing: {magenta:%s}", proxy.get("target"));
}
if (bsServer) {
/**
* Allow server to be destroyed gracefully
*/
enableDestroy(bsServer.server);
/**
* Listen on the available port
*/
bsServer.server.listen(bs.options.get("port"));
/**
* Hack to deal with https://github.com/socketio/socket.io/issues/1602#issuecomment-224270022
*/
bs.registerCleanupTask(function () {
if (bs.io && bs.io.sockets) {
setCloseReceived(bs.io.sockets);
}
if (bs.ui && bs.ui.socket) {
setCloseReceived(bs.ui.socket);
}
});
/**
* Destroy the server on cleanup
*/
bs.registerCleanupTask(function () {
bsServer.server.destroy();
});
}
function setCloseReceived(io) {
Object.keys(io.sockets).forEach(function (key) {
_.set(io.sockets[key], "conn.transport.socket._closeReceived", true);
});
}
debug("Running mode: %s", type.toUpperCase());
return {
server: bsServer.server,
app: bsServer.app
};
};
/**
* Launch the server for serving the client JS plus static files
* @param {BrowserSync} bs
* @returns {{staticServer: (http.Server), proxyServer: (http.Server)}}
*/
function createServer (bs) {
var proxy = bs.options.get("proxy");
var server = bs.options.get("server");
if (!proxy && !server) {
return require("./snippet-server")(bs);
}
if (proxy) {
return require("./proxy-server")(bs);
}
if (server) {
return require("./static-server")(bs);
}
}
module.exports.createServer = createServer;

195
node_modules/browser-sync/lib/server/proxy-server.js generated vendored Normal file
View File

@ -0,0 +1,195 @@
"use strict";
var httpProxy = require("http-proxy");
var utils = require("./utils");
var proxyUtils = require("./proxy-utils");
var Immutable = require("immutable");
var Map = require("immutable").Map;
var List = require("immutable").List;
/**
* Default options that are passed along to http-proxy
*/
var defaultHttpProxyOptions = Map({
/**
* This ensures targets are more likely to
* accept each request
*/
changeOrigin: true,
/**
* This handles redirects
*/
autoRewrite: true,
/**
* This allows our self-signed certs to be used for development
*/
secure: false,
ws: true
});
var defaultCookieOptions = Map({
stripDomain: true
});
var ProxyOption = Immutable.Record({
route: "",
target: "",
rewriteRules: true,
/**
* Functions to be called on proxy request
* with args [proxyReq, req, res, options]
*/
proxyReq: List([]),
/**
* Functions to be called on proxy response
* with args [proxyRes, req, res]
*/
proxyRes: List([]),
/**
* Functions to be called on proxy response
* with args [proxyReq, req, socket, options, head]
*/
proxyReqWs: List([]),
errHandler: undefined,
url: Map({}),
proxyOptions: Map(defaultHttpProxyOptions),
cookies: Map(defaultCookieOptions),
ws: false,
middleware: List([]),
reqHeaders: undefined
});
/**
* @param {BrowserSync} bs
* @param {String} scripts
* @returns {*}
*/
module.exports = function createProxyServer (bs) {
var opt = new ProxyOption().mergeDeep(bs.options.get("proxy"));
var proxy = httpProxy.createProxyServer(opt.get("proxyOptions").set("target", opt.get("target")).toJS());
var target = opt.get("target");
var proxyReq = getProxyReqFunctions(opt.get("proxyReq"), opt, bs);
var proxyRes = getProxyResFunctions(opt.get("proxyRes"), opt);
var proxyResWs = opt.get("proxyReqWs");
bs.options = bs.options.update("middleware", function (mw) {
return mw.concat({
id: "Browsersync Proxy",
route: opt.get("route"),
handle: function (req, res) {
proxy.web(req, res, {
target: target
});
}
});
});
var app = utils.getBaseApp(bs);
/**
* @type {*|{server, app}}
*/
var browserSyncServer = utils.getServer(app, bs.options);
browserSyncServer.proxy = proxy;
if (opt.get("ws")) {
// debug(`+ ws upgrade for: ${x.get("target")}`);
browserSyncServer.server.on("upgrade", function (req, socket, head) {
proxy.ws(req, socket, head);
});
}
/**
* Add any user provided functions for proxyReq, proxyReqWs and proxyRes
*/
applyFns("proxyReq", proxyReq);
applyFns("proxyRes", proxyRes);
applyFns("proxyReqWs", proxyResWs);
/**
* Handle Proxy errors
*/
proxy.on("error", function (err) {
if (typeof opt.get("errHandler") === "function") {
opt.get("errHandler").call(null, err);
}
});
/**
* Apply functions to proxy events
* @param {string} name - the name of the http-proxy event
* @param {Array} fns - functions to call on each event
*/
function applyFns (name, fns) {
if (!List.isList(fns)) fns = [fns];
proxy.on(name, function () {
var args = arguments;
fns.forEach(function(fn) {
if (typeof fn === "function") {
fn.apply(null, args);
}
});
});
}
return browserSyncServer;
};
/**
* @param resFns
* @returns {*}
*/
function getProxyResFunctions (resFns, opt) {
if (opt.getIn(["cookies", "stripDomain"])) {
return resFns.push(proxyUtils.checkCookies);
}
return resFns;
}
/**
* @param reqFns
* @returns {*}
*/
function getProxyReqFunctions (reqFns, opt, bs) {
var reqHeaders = opt.getIn(["reqHeaders"]);
if (!reqHeaders) {
return reqFns;
}
/**
* Back-compat for old `reqHeaders` option here a
* function was given that returned an object
* where key:value was header-name:header-value
* This didn't really work as it clobbered all other headers,
* but it remains for the unlucky few who used it.
*/
if (typeof reqHeaders === "function") {
var output = reqHeaders.call(bs, opt.toJS());
if (Object.keys(output).length) {
return reqFns.concat(function (proxyReq) {
Object.keys(output).forEach(function (key) {
proxyReq.setHeader(key, output[key]);
});
});
}
}
/**
* Now, if {key:value} given, set the each header
*
* eg: reqHeaders: {
* 'is-dev': 'true'
* }
*/
if (Map.isMap(reqHeaders)) {
return reqFns.concat(function (proxyReq) {
reqHeaders.forEach(function (value, key) {
proxyReq.setHeader(key, value);
});
});
}
return reqFns;
}

138
node_modules/browser-sync/lib/server/proxy-utils.js generated vendored Normal file
View File

@ -0,0 +1,138 @@
var url = require("url");
module.exports.rewriteLinks = function (userServer) {
var host = userServer.hostname;
var string = host;
var port = userServer.port;
if (host && port) {
if (parseInt(port, 10) !== 80) {
string = host + ":" + port;
}
}
return {
match: new RegExp("https?:\\\\/\\\\/" + string + "|('|\")\\\/\\\/" + string + "|https?://" + string + "(\/)?|('|\")(https?://|/|\\.)?" + string + "(\/)?(.*?)(?=[ ,'\"\\s])", "g"),
//match: new RegExp("https?:\\\\/\\\\/" + string + "|https?://" + string + "(\/)?|('|\")(https?://|/|\\.)?" + string + "(\/)?(.*?)(?=[ ,'\"\\s])", "g"),
//match: new RegExp("https?:\\\\?/\\\\?/" + string + "(\/)?|('|\")(https?://|\\\\?/|\\.)?" + string + "(\/)?(.*?)(?=[ ,'\"\\s])", "g"),
//match: new RegExp('https?://' + string + '(\/)?|(\'|")(https?://|/|\\.)?' + string + '(\/)?(.*?)(?=[ ,\'"\\s])', 'g'),
//match: new RegExp("https?:\\\\/\\\\/" + string, "g"),
fn: function (req, res, match) {
var proxyUrl = req.headers["host"];
/**
* Reject subdomains
*/
if (match[0] === ".") {
return match;
}
var captured = match[0] === "'" || match[0] === "\"" ? match[0] : "";
/**
* allow http https
* @type {string}
*/
var pre = "//";
if (match[0] === "'" || match[0] === "\"") {
match = match.slice(1);
}
/**
* parse the url
* @type {number|*}
*/
var out = url.parse(match);
/**
* If host not set, just do a simple replace
*/
if (!out.host) {
string = string.replace(/^(\/)/, "");
return captured + match.replace(string, proxyUrl);
}
/**
* Only add trailing slash if one was
* present in the original match
*/
if (out.path === "/") {
if (match.slice(-1) === "/") {
out.path = "/";
} else {
out.path = "";
}
}
/**
* Finally append all of parsed url
*/
return [
captured,
pre,
proxyUrl,
out.path || "",
out.hash || ""
].join("");
}
};
};
/**
* Remove 'domain' from any cookies
* @param {Object} res
*/
module.exports.checkCookies = function checkCookies (res) {
if (typeof(res.headers["set-cookie"]) !== "undefined") {
res.headers["set-cookie"] = res.headers["set-cookie"].map(function (item) {
return rewriteCookies(item);
});
}
};
/**
* Remove the domain from any cookies.
* @param rawCookie
* @returns {string}
*/
function rewriteCookies (rawCookie) {
var objCookie = (function () {
// simple parse function (does not remove quotes)
var obj = {};
var pairs = rawCookie.split(/; */);
pairs.forEach( function( pair ) {
var eqIndex = pair.indexOf("=");
// skip things that don't look like key=value
if (eqIndex < 0) {
return;
}
var key = pair.substr(0, eqIndex).trim();
obj[key] = pair.substr(eqIndex + 1, pair.length).trim();
});
return obj;
})();
var pairs = Object.keys(objCookie)
.filter(function (item) {
return item !== "domain";
})
.map(function (key) {
return key + "=" + objCookie[key];
});
if (rawCookie.match(/httponly/i)) {
pairs.push("HttpOnly");
}
return pairs.join("; ");
}
module.exports.rewriteCookies = rewriteCookies;

16
node_modules/browser-sync/lib/server/snippet-server.js generated vendored Normal file
View File

@ -0,0 +1,16 @@
"use strict";
var connect = require("connect");
var serverUtils = require("./utils.js");
/**
* Create a server for the snippet
* @param {BrowserSync} bs
* @param scripts
* @returns {*}
*/
module.exports = function createSnippetServer (bs, scripts) {
var app = serverUtils.getBaseApp(bs, bs.options, scripts);
return serverUtils.getServer(app, bs.options);
};

79
node_modules/browser-sync/lib/server/static-server.js generated vendored Normal file
View File

@ -0,0 +1,79 @@
"use strict";
var connect = require("connect");
var serverUtils = require("./utils.js");
var resolve = require("path").resolve;
var utils = require("../utils.js");
var serveStatic = require("serve-static");
var serveIndex = require("serve-index");
/**
* @param {BrowserSync} bs
* @param scripts
* @returns {*}
*/
module.exports = function createServer (bs) {
var options = bs.options;
var server = options.get("server");
var basedirs = utils.arrayify(server.get("baseDir"));
var serveStaticOptions = server.get("serveStaticOptions").toJS(); // passed to 3rd party
var _serveStatic = 0;
var _routes = 0;
bs.options = bs.options
/**
* Add directory Middleware if given in server.directory
*/
.update("middleware", function (mw) {
if (!server.get("directory")) {
return mw;
}
return mw.concat({
route: "",
handle: serveIndex(resolve(basedirs[0]), {icons:true}),
id: "Browsersync Server Directory Middleware"
});
})
/**
* Add middleware for server.baseDir Option
*/
.update("middleware", function (mw) {
return mw.concat(basedirs.map(function (root) {
return {
route: "",
id: "Browsersync Server ServeStatic Middleware - " + _serveStatic++,
handle: serveStatic(resolve(root), serveStaticOptions)
}
}));
})
/**
* Add middleware for server.routes
*/
.update("middleware", function (mw) {
if (!server.get("routes")) {
return mw;
}
return mw.concat(server.get("routes").map(function (root, urlPath) {
// strip trailing slash
if (urlPath[urlPath.length - 1] === "/") {
urlPath = urlPath.slice(0, -1);
}
return {
route: urlPath,
id: "Browsersync Server Routes Middleware - " + _routes++,
handle: serveStatic(resolve(root))
}
}));
});
var app = serverUtils.getBaseApp(bs);
/**
* Finally, return the server + App
*/
return serverUtils.getServer(app, bs.options);
};

453
node_modules/browser-sync/lib/server/utils.js generated vendored Normal file
View File

@ -0,0 +1,453 @@
"use strict";
var fs = require("fs");
var path = require("path");
var join = require("path").join;
var connect = require("connect");
var Immutable = require("immutable");
var http = require("http");
var https = require("https");
var Map = require("immutable").Map;
var fromJS = require("immutable").fromJS;
var List = require("immutable").List;
var snippet = require("./../snippet").utils;
var _ = require("./../../lodash.custom");
var serveStatic = require("serve-static");
var logger = require("../logger");
var snippetUtils = require("../snippet").utils;
var lrSnippet = require("resp-modifier");
var utils = require("../utils");
function getCa (options) {
var caOption = options.getIn(["https", "ca"]);
// if not provided, use Browsersync self-signed
if (typeof caOption === "undefined") {
return fs.readFileSync(join(__dirname, "certs", "server.csr"));
}
// if a string was given, read that file from disk
if (typeof caOption === "string") {
return fs.readFileSync(caOption);
}
// if an array was given, read all
if (List.isList(caOption)) {
return caOption.toArray().map(function (x) {
return fs.readFileSync(x);
});
}
}
function getKey(options) {
return fs.readFileSync(options.getIn(["https", "key"]) || join(__dirname, "certs", "server.key"));
}
function getCert(options) {
return fs.readFileSync(options.getIn(["https", "cert"]) || join(__dirname, "certs", "server.crt"));
}
function getHttpsServerDefaults (options) {
return fromJS({
key: getKey(options),
cert: getCert(options),
ca: getCa(options),
passphrase: ""
});
}
function getPFXDefaults (options) {
return fromJS({
pfx: fs.readFileSync(options.getIn(["https", "pfx"]))
});
}
var serverUtils = {
/**
* @param options
* @returns {{key, cert}}
*/
getHttpsOptions: function (options) {
var userOption = options.get("https");
if (Map.isMap(userOption)) {
if (userOption.has("pfx")) {
return userOption.mergeDeep(getPFXDefaults(options));
}
return userOption.mergeDeep(getHttpsServerDefaults(options));
}
return getHttpsServerDefaults(options);
},
/**
* Get either http or https server
* or use the httpModule provided in options if present
*/
getServer: function (app, options) {
return {
server: (function () {
var httpModule = serverUtils.getHttpModule(options);
if (options.get("scheme") === "https") {
var opts = serverUtils.getHttpsOptions(options);
return httpModule.createServer(opts.toJS(), app);
}
return httpModule.createServer(app);
})(),
app: app
};
},
getHttpModule: function (options) {
/**
* Users may provide a string to be used by nodes
* require lookup.
*/
var httpModule = options.get("httpModule");
if (typeof httpModule === "string") {
/**
* Note, this could throw, but let that happen as
* the error message good enough.
*/
var maybe = path.resolve(process.cwd(), "node_modules", httpModule);
return require(maybe);
}
if (options.get("scheme") === "https") {
return https;
}
return http;
},
getMiddlewares: function (bs) {
var clientJs = bs.pluginManager.hook("client:js", {
port: bs.options.get("port"),
options: bs.options
});
var scripts = bs.pluginManager.get("client:script")(
bs.options.toJS(),
clientJs,
"middleware"
);
var defaultMiddlewares = [
{
id: "Browsersync HTTP Protocol",
route: require("../config").httpProtocol.path,
handle: require("../http-protocol").middleware(bs)
},
{
id: "Browsersync IE8 Support",
route: "",
handle: snippet.isOldIe(bs.options.get("excludedFileTypes").toJS())
},
{
id: "Browsersync Response Modifier",
route: "",
handle: serverUtils.getSnippetMiddleware(bs)
},
{
id: "Browsersync Client - versioned",
route: bs.options.getIn(["scriptPaths", "versioned"]),
handle: scripts
},
{
id: "Browsersync Client",
route: bs.options.getIn(["scriptPaths", "path"]),
handle: scripts
}
];
/**
* Add cors middleware to the front of the stack
* if a user provided a 'cors' flag
*/
if (bs.options.get("cors")) {
defaultMiddlewares.unshift({
id: "Browsersync CORS support",
route: "",
handle: serverUtils.getCorsMiddlewware()
})
}
/**
* Add serve static middleware
*/
if (bs.options.get("serveStatic")) {
var ssMiddlewares = serverUtils.getServeStaticMiddlewares(bs.options.get("serveStatic"), bs.options.get("serveStaticOptions", Immutable.Map({})).toJS());
var withErrors = ssMiddlewares.filter(function(x) { return x.get("errors").size > 0 });
var withoutErrors = ssMiddlewares.filter(function(x) { return x.get("errors").size === 0 });
if (withErrors.size) {
withErrors.forEach(function (item) {
logger.logger.error("{red:Warning!} %s", item.getIn(["errors", 0, "data", "message"]));
});
}
if (withoutErrors.size) {
withoutErrors.forEach(function (item) {
defaultMiddlewares.push.apply(defaultMiddlewares, item.get("items").toJS());
});
}
}
/**
* Add user-provided middlewares
*/
var userMiddlewares = bs.options.get("middleware").map(normaliseMiddleware).toArray();
var beforeMiddlewares = userMiddlewares.filter(function (x) { return x.override; });
var afterMiddlewares = userMiddlewares.filter(function (x) { return !x.override; });
return [].concat(beforeMiddlewares, defaultMiddlewares, afterMiddlewares);
function normaliseMiddleware(item) {
/**
* Object given in options, which
* ended up being a Map
*/
if (Map.isMap(item)) {
return item.toJS();
}
/**
* Single function
*/
if (typeof item === "function") {
return {
route: "",
handle: item
}
}
/**
* Plain obj
*/
if ((item.route !== undefined) && item.handle) {
return item;
}
}
},
getBaseApp: function (bs) {
var app = connect();
var middlewares = serverUtils.getMiddlewares(bs);
/**
* Add all internal middlewares
*/
middlewares.forEach(function (item) {
app.stack.push(item);
});
return app;
},
getSnippetMiddleware: function (bs) {
var rules = [];
var blacklist = List([])
.concat(bs.options.getIn(["snippetOptions", "ignorePaths"]))
.concat(bs.options.getIn(["snippetOptions", "blacklist"]))
.filter(Boolean);
var whitelist = List([])
.concat(bs.options.getIn(["snippetOptions", "whitelist"]));
// Snippet
rules.push(snippetUtils.getRegex(bs.options.get("snippet"), bs.options.get("snippetOptions")));
// User
bs.options.get("rewriteRules").forEach(function (rule) {
if (Map.isMap(rule)) {
rules.push(rule.toJS());
}
if (_.isPlainObject(rule)) {
rules.push(rule);
}
});
// Proxy
if (bs.options.get("proxy")) {
var proxyRule = require("./proxy-utils").rewriteLinks(bs.options.getIn(["proxy", "url"]).toJS());
rules.push(proxyRule);
}
var lr = lrSnippet.create({
rules: rules,
blacklist: blacklist.toArray(),
whitelist: whitelist.toArray()
});
return lr.middleware;
},
getCorsMiddlewware: function () {
return function (req, res, next) {
// Website you wish to allow to connect
res.setHeader("Access-Control-Allow-Origin", "*");
// Request methods you wish to allow
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
// Request headers you wish to allow
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With,content-type");
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader("Access-Control-Allow-Credentials", true);
next();
}
},
/**
* @param ssOption
* @param serveStaticOptions
* @returns {*}
*/
getServeStaticMiddlewares: function (ssOption, serveStaticOptions) {
return ssOption.map(function (dir, i) {
/**
* When a user gives a plain string only, eg:
* serveStatic: ['./temp']
* ->
* This means a middleware will be created with
* route: ''
* handle: serveStatic('./temp', options)
*/
if (_.isString(dir)) {
return getFromString(dir)
}
/**
* If a user gave an object eg:
* serveStatic: [{route: "", dir: ["test", "./tmp"]}]
* ->
* This means we need to create a middle for each route + dir combo
*/
if (Immutable.Map.isMap(dir)) {
return getFromMap(dir, i);
}
/**
* At this point, an item in the serveStatic array was not a string
* or an object so we return an error that can be logged
*/
return fromJS({
items: [],
errors: [{
type: "Invalid Type",
data: {
message: "Only strings and Objects (with route+dir) are supported for the ServeStatic option"
}
}]
})
});
/**
* @param {string} x
* @returns {string}
*/
function getRoute (x) {
if (x === "") return "";
return x[0] === "/" ? x : "/" + x;
}
/**
* @param dir
* @returns {Map}
*/
function getFromString(dir) {
return fromJS({
items: [
{
route: "",
handle: serveStatic(dir, serveStaticOptions)
}
],
errors: []
})
}
/**
* @param dir
* @returns {Map}
*/
function getFromMap(dir) {
var ssOptions = (function () {
if (dir.get("options")) {
return dir.get("options").toJS();
}
return {}
})();
var route = Immutable.List([]).concat(dir.get("route")).filter(_.isString);
var _dir = Immutable.List([]).concat(dir.get("dir")).filter(_.isString);
if (_dir.size === 0) {
return fromJS({
items: [],
errors: [{
type: "Invalid Object",
data: {
message: "Serve Static requires a 'dir' property when using an Object"
}
}]
})
}
var ssItems = (function () {
/**
* iterate over every 'route' item
* @type {Immutable.List<any>|Immutable.List<*>|Immutable.List<any>|*}
*/
var routeItems = (function () {
/**
* If no 'route' was given, assume we want to match all
* paths
*/
if (route.size === 0) {
return _dir.map(function (dirString) {
return Map({
route: "",
dir: dirString
});
});
}
return route.reduce(function (acc, routeString) {
/**
* For each 'route' item, also iterate through 'dirs'
* @type {Immutable.Iterable<K, M>}
*/
var perDir = _dir.map(function (dirString) {
return Map({
route: getRoute(routeString),
dir: dirString
})
});
return acc.concat(perDir);
}, List([]));
})();
/**
* Now create a serverStatic Middleware for each item
*/
return routeItems.map(function (routeItem) {
return routeItem.merge({
handle: serveStatic(routeItem.get("dir"), ssOptions)
});
});
})();
return fromJS({
items: ssItems,
errors: []
});
}
}
};
module.exports = serverUtils;

106
node_modules/browser-sync/lib/snippet.js generated vendored Normal file
View File

@ -0,0 +1,106 @@
"use strict";
var connectUtils = require("./connect-utils");
var config = require("./config");
var lrSnippet = require("resp-modifier");
var path = require("path");
var _ = require("../lodash.custom");
var utils = require("./utils");
var fs = require("fs");
/**
* Utils for snippet injection
*/
var snippetUtils = {
/**
* @param {String} url
* @param {Array} excludeList
* @returns {boolean}
*/
isExcluded: function (url, excludeList) {
var extension = path.extname(url);
if (extension) {
if (~url.indexOf("?")) {
return true;
}
extension = extension.slice(1);
return _.includes(excludeList, extension);
}
return false;
},
/**
* @param {String} snippet
* @param {Object} options
* @returns {{match: RegExp, fn: Function}}
*/
getRegex: function (snippet, options) {
var fn = options.getIn(["rule", "fn"]);
return {
match: options.getIn(["rule", "match"]),
fn: function (req, res, match) {
return fn.apply(null, [snippet, match]);
},
once: true,
id: "bs-snippet"
};
},
getSnippetMiddleware: function (snippet, options, rewriteRules) {
return lrSnippet.create(snippetUtils.getRules(snippet, options, rewriteRules));
},
getRules: function (snippet, options, rewriteRules) {
var rules = [snippetUtils.getRegex(snippet, options)];
if (rewriteRules) {
rules = rules.concat(rewriteRules);
}
return {
rules: rules,
blacklist: utils.arrayify(options.get("blacklist")),
whitelist: utils.arrayify(options.get("whitelist"))
};
},
/**
* @param {Object} req
* @param {Array} [excludeList]
* @returns {Object}
*/
isOldIe: function (excludeList) {
return function (req, res, next) {
var ua = req.headers["user-agent"];
var match = /MSIE (\d)\.\d/.exec(ua);
if (match) {
if (parseInt(match[1], 10) < 9) {
if (!snippetUtils.isExcluded(req.url, excludeList)) {
req.headers["accept"] = "text/html";
}
}
}
next();
}
},
/**
* @param {Number} port
* @param {BrowserSync.options} options
* @returns {String}
*/
getClientJs: function (port, options) {
var socket = snippetUtils.getSocketScript();
var noConflictJs = "window.___browserSync___oldSocketIo = window.io;";
return noConflictJs + socket + ";" + connectUtils.socketConnector(options);
},
/**
* @returns {String}
*/
getSocketScript: function () {
return fs.readFileSync(path.join(__dirname, config.socketIoScript), "utf-8");
}
};
module.exports.utils = snippetUtils;

100
node_modules/browser-sync/lib/sockets.js generated vendored Normal file
View File

@ -0,0 +1,100 @@
"use strict";
var socket = require("socket.io");
var utils = require("./server/utils");
var Steward = require("emitter-steward");
/**
* Plugin interface
* @returns {*|function(this:exports)}
*/
module.exports.plugin = function (server, clientEvents, bs) {
return exports.init(server, clientEvents, bs);
};
/**
* @param {http.Server} server
* @param clientEvents
* @param {BrowserSync} bs
*/
module.exports.init = function (server, clientEvents, bs) {
var emitter = bs.events;
var socketConfig = bs.options
.get("socket")
.toJS();
if (bs.options.get("mode") === "proxy" && bs.options.getIn(["proxy", "ws"])) {
server = utils.getServer(null, bs.options).server;
server.listen(bs.options.getIn(["socket", "port"]));
bs.registerCleanupTask(function () {
server.close();
});
}
var socketIoConfig = socketConfig.socketIoOptions;
socketIoConfig.path = socketConfig.path;
var io = socket(server, socketIoConfig);
// Override default namespace.
io.sockets = io.of(socketConfig.namespace);
io.set("heartbeat interval", socketConfig.clients.heartbeatTimeout);
var steward = new Steward(emitter);
bs.registerCleanupTask(steward.destroy.bind(steward));
/**
* Listen for new connections
*/
io.sockets.on("connection", handleConnection);
/**
* Handle each new connection
* @param {Object} client
*/
function handleConnection (client) {
// set ghostmode callbacks
if (bs.options.get("ghostMode")) {
addGhostMode(client);
}
client.emit("connection", bs.options.toJS()); //todo - trim the amount of options sent to clients
emitter.emit("client:connected", {
ua: client.handshake.headers["user-agent"]
});
}
/**
* @param {string} event
* @param {Socket.client} client
* @param {Object} data
*/
function handleClientEvent(event, client, data) {
if (steward.valid(client.id)) {
client.broadcast.emit(event, data);
}
}
/**
* @param client
*/
function addGhostMode (client) {
clientEvents.forEach(addEvent);
function addEvent(event) {
client.on(event, handleClientEvent.bind(null, event, client));
}
}
return io;
};

10
node_modules/browser-sync/lib/templates/connector.tmpl generated vendored Normal file
View File

@ -0,0 +1,10 @@
window.___browserSync___ = {};
___browserSync___.io = window.io;
window.io = window.___browserSync___oldSocketIo;
window.___browserSync___oldSocketIo=undefined;
___browserSync___.socketConfig = %config%;
___browserSync___.url = %url%;
if (location.protocol == "https:" && /^http:/.test(___browserSync___.url)) {
___browserSync___.url = ___browserSync___.url.replace(/^http:/, "https:");
}
___browserSync___.socket = ___browserSync___.io(___browserSync___.url, ___browserSync___.socketConfig);

View File

@ -0,0 +1 @@
<script %async% id="__bs_script__" src="%script%"></script>

View File

@ -0,0 +1,3 @@
<script id="__bs_script__">//<![CDATA[
document.write("<script %async% src='%script%'><\/script>".replace("HOST", location.hostname));
//]]></script>

35
node_modules/browser-sync/lib/tunnel.js generated vendored Normal file
View File

@ -0,0 +1,35 @@
"use strict";
var _ = require("../lodash.custom");
var utils = require("util");
/**
* @param {BrowserSync} bs
* @param {Function} cb
*/
module.exports = function (bs, cb) {
var opts = {};
var options = bs.options;
var port = options.get("port");
if (_.isString(options.get("tunnel"))) {
opts.subdomain = options.get("tunnel");
}
bs.debug("Requesting a tunnel connection on port: {magenta:%s}", port);
bs.debug("Requesting a tunnel connection with options: {magenta:%s}", utils.inspect(opts));
require("localtunnel")(port, opts, function (err, tunnel) {
if (err) {
return cb(err);
}
tunnel.on("error", function (err) {
bs.logger.info("Localtunnel issue: " + err.message);
bs.logger.info("Oops! The localtunnel appears to have disconnected. Reconnecting...");
});
return cb(null, tunnel);
});
};

310
node_modules/browser-sync/lib/utils.js generated vendored Normal file
View File

@ -0,0 +1,310 @@
"use strict";
var _ = require("../lodash.custom");
var devIp = require("dev-ip")();
var Immutable = require("immutable");
var portScanner = require("portscanner");
var path = require("path");
var List = require("immutable").List;
var UAParser = require("ua-parser-js");
var parser = new UAParser();
var utils = {
/**
* @param {Object} options
* @returns {String|boolean} - the IP address
* @param devIp
*/
getHostIp: function (options, devIp) {
if (options) {
var host = options.get("host");
if (host && host !== "localhost") {
return host;
}
if (options.get("detect") === false || !devIp.length) {
return false;
}
}
return devIp.length ? devIp[0] : false;
},
/**
* Set URL Options
*/
getUrlOptions: function (options) {
var scheme = options.get("scheme");
var port = options.get("port");
var urls = {};
if (options.get("online") === false) {
urls.local = utils.getUrl(scheme + "://localhost:" + port, options);
return Immutable.fromJS(urls);
}
var external = utils.xip(utils.getHostIp(options, devIp), options);
var localhost = "localhost";
if (options.get("xip")) {
localhost = "127.0.0.1";
}
localhost = utils.xip(localhost, options);
return Immutable.fromJS(utils.getUrls(external, localhost, scheme, options));
},
/**
* Append a start path if given in options
* @param {String} url
* @param {Object} options
* @returns {String}
*/
getUrl: function (url, options) {
var prefix = "/";
var startPath = options.get("startPath");
if (startPath) {
if (startPath.charAt(0) === "/") {
prefix = "";
}
url = url + prefix + startPath;
}
return url;
},
/**
* @param {String} external
* @param {String} local
* @param {String} scheme
* @param {Object} options
* @returns {{local: string, external: string}}
*/
getUrls: function (external, local, scheme, options) {
var urls = {
local: utils.getUrl(utils._makeUrl(scheme, local, options.get("port")), options)
};
if (external !== local) {
urls.external = utils.getUrl(utils._makeUrl(scheme, external, options.get("port")), options);
}
return urls;
},
/**
* @param {String} scheme
* @param {String} host
* @param {Number} port
* @returns {String}
* @private
*/
_makeUrl: function (scheme, host, port) {
return scheme + "://" + host + ":" + port;
},
/**
* Get ports
* @param {Object} options
* @param {Function} cb
*/
getPorts: function (options, cb) {
var port = options.get("port");
var ports = options.get("ports"); // backwards compatibility
var max;
if (ports) {
port = ports.get("min");
max = ports.get("max") || null;
}
utils.getPort(port, max, cb);
},
getPort: function (port, max, cb) {
portScanner.findAPortNotInUse(port, max, {
host: "localhost",
timeout: 1000
}, cb);
},
/**
* @param {String} ua
* @returns {Object}
*/
getUaString: function (ua) {
return parser.setUA(ua).getBrowser();
},
/**
* Open the page in browser
* @param {String} url
* @param {Object} options
* @param {BrowserSync} bs
*/
openBrowser: function (url, options, bs) {
var open = options.get("open");
var browser = options.get("browser");
if (_.isString(open)) {
if (options.getIn(["urls", open])) {
url = options.getIn(["urls", open]);
}
}
if (open) {
if (browser !== "default") {
if (utils.isList(browser)) {
browser.forEach(function (browser) {
utils.open(url, browser, bs);
});
} else {
utils.open(url, browser, bs); // single
}
} else {
utils.open(url, null, bs);
}
}
},
/**
* Wrapper for opn module
* @param url
* @param name
* @param bs
*/
open: function (url, name, bs) {
var options = (function () {
if (_.isString(name)) {
return {app: name};
}
if (Immutable.Map.isMap(name)) {
return name.toJS();
}
return {};
})();
var opn = require("opn");
opn(url, options).catch(function() {
bs.events.emit("browser:error");
});
},
/**
* @param {Boolean} kill
* @param {String|Error} [errMessage]
* @param {Function} [cb]
*/
fail: function (kill, errMessage, cb) {
if (kill) {
if (_.isFunction(cb)) {
if (errMessage.message) { // Is this an error object?
cb(errMessage);
} else {
cb(new Error(errMessage));
}
}
process.exit(1);
}
},
/**
* Add support for xip.io urls
* @param {String} host
* @param {Object} options
* @returns {String}
*/
xip: function (host, options) {
var suffix = options.get("hostnameSuffix");
if (options.get("xip")) {
return host + ".xip.io";
}
if (suffix) {
return host + suffix;
}
return host;
},
/**
* Determine if an array of file paths will cause a full page reload.
* @param {Array} needles - filepath such as ["core.css", "index.html"]
* @param {Array} haystack
* @returns {Boolean}
*/
willCauseReload: function (needles, haystack) {
return needles.some(function (needle) {
return !_.includes(haystack, path.extname(needle).replace(".", ""));
});
},
isList: Immutable.List.isList,
isMap: Immutable.List.isMap,
/**
* @param {Map} options
* @returns {Array}
*/
getConfigErrors: function (options) {
var messages = require("./config").errors;
var errors = [];
if (options.get("server") && options.get("proxy")) {
errors.push(messages["server+proxy"]);
}
return errors;
},
/**
* @param {Map} options
* @param {Function} [cb]
*/
verifyConfig: function (options, cb) {
var errors = utils.getConfigErrors(options);
if (errors.length) {
utils.fail(true, errors.join("\n"), cb);
return false;
}
return true;
},
/**
* @param err
*/
defaultCallback: function (err) {
if (err && err.message) {
console.error(err.message);
}
},
eachSeries: function (arr, iterator, callback) {
callback = callback || function () {};
var completed = 0;
var iterate = function () {
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function () {};
} else {
++completed;
if (completed >= arr.length) {
callback();
} else {
iterate();
}
}
});
};
iterate();
},
/**
* @param {Immutable.List|Array|String} incoming
* @returns {Array}
*/
arrayify: function (incoming) {
if (List.isList(incoming)) {
return incoming.toArray();
}
return [].concat(incoming).filter(Boolean);
}
};
module.exports = utils;
module.exports.portscanner = portScanner;
module.exports.UAParser = UAParser;
module.exports.connect = require("connect");
module.exports.devIp = devIp;
module.exports.serveStatic = require("serve-static");
module.exports.easyExtender = require("easy-extender");