324 lines
8.9 KiB
JavaScript
324 lines
8.9 KiB
JavaScript
"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()
|
|
}
|
|
});
|
|
}
|
|
};
|