Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

browser-sync

Package Overview
Dependencies
Maintainers
1
Versions
300
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

browser-sync - npm Package Compare versions

Comparing version 0.9.1 to 1.0.0

.idea/jsLinters/jshint.xml

26

example.js
var browserSync = require("./lib/index");
var lr = require("./live-reload");

@@ -8,8 +7,7 @@ console.time("init");

var files = ["test/fixtures/assets/*", "test/fixtures/*.html"];
files = ["/Users/shakyshane/Sites/swoon-static/assets/css/**"]
var options = {
server: {
baseDir: ["test/fixtures"]
},
// server: {
// baseDir: ["test/fixtures"]
// },
// proxy: "swoon.static/store-home.php",

@@ -21,8 +19,14 @@ ghostMode: {

},
// tunnel: true,
ports: {
min: 4000,
max: 4003
},
open: true,
logConnections: false,
minify: false,
minify: true,
// host: ,
notify: true,
xip: true,
browser: ["google chrome", "safari"]
xip: false,
browser: ["google chrome"]
};

@@ -38,5 +42,5 @@

console.timeEnd("init");
setTimeout(function () {
browserSync.notify("5 Seconds have passed!");
}, 5000);
// setTimeout(function () {
// browserSync.notify("5 Seconds have passed!");
// }, 5000);
});

@@ -1,22 +0,24 @@

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var contribs = require('gulp-contribs');
var sass = require('gulp-sass');
var rubySass = require('gulp-ruby-sass');
var browserSync = require('./lib/index');
"use strict";
gulp.task('lint', function () {
gulp.src(['test/specs/**/*.js', '!test/fixtures/**', 'lib/*'])
.pipe(jshint('test/specs/.jshintrc'))
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'))
var gulp = require("gulp");
var jshint = require("gulp-jshint");
var contribs = require("gulp-contribs");
var sass = require("gulp-sass");
var rubySass = require("gulp-ruby-sass");
var browserSync = require("./lib/index");
gulp.task("lint", function () {
gulp.src(["test/specs/**/*.js", "!test/fixtures/**", "lib/*"])
.pipe(jshint("test/specs/.jshintrc"))
.pipe(jshint.reporter("default"))
.pipe(jshint.reporter("fail"));
});
gulp.task('contribs', function () {
gulp.src('README.md')
gulp.task("contribs", function () {
gulp.src("README.md")
.pipe(contribs())
.pipe(gulp.dest("./"))
.pipe(gulp.dest("./"));
});
gulp.task('default', ['lint']);
gulp.task("default", ["lint"]);

@@ -29,3 +31,3 @@ var paths = {

gulp.task('sass', function () {
gulp.task("sass", function () {
browserSync.notify("Compiling SCSS files... Please Wait");

@@ -41,3 +43,3 @@ gulp.src(paths.scss)

*/
gulp.task('browser-sync', function () {
gulp.task("browser-sync", function () {

@@ -56,2 +58,6 @@ // var clientScript = require("/Users/shakyshane/Sites/browser-sync-modules/browser-sync-client/index");

});
setTimeout(function () {
browserSync.exit();
}, 3000);
});

@@ -62,3 +68,3 @@

*/
gulp.task('bs-reload', function () {
gulp.task("bs-reload", function () {
browserSync.reload();

@@ -70,6 +76,6 @@ });

*/
gulp.task('watch', ['browser-sync'], function () {
gulp.watch(paths.scss, ['sass']);
gulp.watch(paths.html, ['bs-reload']);
gulp.task("watch", ["browser-sync"], function () {
gulp.watch(paths.scss, ["sass"]);
gulp.watch(paths.html, ["bs-reload"]);
});

@@ -8,6 +8,7 @@ "use strict";

var config = require("./config");
var tunnel = require("./tunnel");
var messages = require("./messages");
var utils = require("./utils").utils;
var fileWatcher = require("./file-watcher");
var bsControlPanel = require("browser-sync-control-panel");
var bsClient = require("browser-sync-client");

@@ -22,4 +23,3 @@ var _ = require("lodash");

"plugin:socket": socket.plugin,
"plugin:logger": logger.plugin,
"plugin:controlpanel": bsControlPanel.plugin
"plugin:logger": logger.plugin
};

@@ -32,3 +32,2 @@

this.cwd = process.cwd();
this.minPorts = 2;
this.events = new events.EventEmitter();

@@ -99,2 +98,3 @@ this.events.setMaxListeners(20);

this.loadPlugins();
this.getPlugin("logger")(this.events, options);

@@ -104,20 +104,15 @@

if (options.server && options.proxy) {
err = "Invalid config. You cannot specify both a server & proxy option.";
this.callback(err);
utils.fail(err, options, true);
utils.fail(messages.configError(err), options, true);
}
var success = function (ports) {
services.init(this)(ports, files, options);
}.bind(this);
var error = function (err) {
this.callback(err);
utils.fail(err, options, true);
}.bind(this);
utils.getPorts(options)
.then(this.handleSuccess.bind(this, options))
.catch(this.handleError.bind(this, options));
utils.getPorts(options, this.minPorts)
.then(success)
.catch(error);
return this;

@@ -127,2 +122,52 @@ };

/**
* @param options
* @param err
*/
BrowserSync.prototype.handleError = function (options, err) {
this.callback(err);
utils.fail(err, options, true);
};
/**
* @param options
* @param ports
*/
BrowserSync.prototype.handleSuccess = function (options, ports) {
var that = this;
var debug = this.debug = utils.getDebugger(options);
function init() {
services.init(that)(ports[0], options.files || [], options);
}
if (typeof options.online === "undefined") {
debug("Checking if there's an internet connection...");
require("dns").resolve("www.google.com", function(err) {
if (err) {
debug("Could not resolve www.google.com, setting online: false");
options.online = false;
} else {
debug("Resolved, setting online: true");
options.online = true;
}
init();
});
} else {
init();
}
};
/**
* Callback helper

@@ -156,2 +201,9 @@ * @param err

this.io.sockets.emit("browser:notify", data);
},
"service:running": function (data) {
utils.openBrowser(data.url, options);
},
"msg:debug": function (data) {
var debug = utils.getDebugger(options);
debug(data.msg, data.vars || "", options);
}

@@ -201,40 +253,71 @@ };

* @param {String} host
* @param {Object} ports
* @param {Number} port
* @param {Object} options
* @param {Object} io
* @returns {*|http.Server}
* @param {String|Function} scripts
* @returns {Boolean|http.Server}
*/
BrowserSync.prototype.initServer = function (host, ports, options, io) {
BrowserSync.prototype.initServer = function (host, port, options, scripts) {
var proxy = options.proxy || false;
var server = options.server || false;
var proxy = options.proxy || false;
var server = options.server || false;
var debug = utils.getDebugger(options);
var snippet = (!server && !proxy);
var baseDir = utils.getBaseDir(server.baseDir || "./");
var type = false;
var type = "snippet";
var events = this.events;
var servers = serverModule.launchServer(host, ports, options, io);
var servers = serverModule.launchServer(host, port, options, scripts);
if (server) {
if (server || snippet) {
if (servers.staticServer) {
servers.staticServer.listen(ports.server);
servers.staticServer.listen(port);
debug("Static Server runnning...");
}
type = "server";
type = server ? "server" : "snippet";
}
if (proxy) {
if (servers.proxyServer) {
servers.proxyServer.listen(ports.proxy);
servers.proxyServer.listen(port);
debug("Proxy running, proxing: %s", options.proxy.target);
}
type = "proxy";
}
options.url = utils.getUrl(utils._makeUrl(host, ports[type]), options);
debug("Running mode: %s", type.toUpperCase());
options.url = utils.getUrl(utils._makeUrl(host, port), options);
if (type && (server || proxy)) {
utils.openBrowser(options.url, options);
if (options.tunnel && options.online) {
this.events.emit("open", {
tunnel.init(this, port, emitEvent);
} else {
emitEvent(options.urls.local);
}
} else {
emitEvent("n/a");
}
function emitEvent(url, tunnel) {
events.emit("service:running", {
type: type,
baseDir: baseDir || null,
port: ports[type]
port: port,
url: url,
tunnel: tunnel ? url : false
});

@@ -241,0 +324,0 @@ }

@@ -15,143 +15,4 @@ /*

/*
|--------------------------------------------------------------------------
| Files to watch
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-files
*/
files: [],
/*
|--------------------------------------------------------------------------
| Directories or files to exclude
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-exclude
*/
exclude: false,
/*
|--------------------------------------------------------------------------
| Server
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-server
*/
server: false,
/*
|--------------------------------------------------------------------------
| Proxy
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-proxy
*/
proxy: false,
/*
|--------------------------------------------------------------------------
| Start path
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-startPath
*/
startPath: null,
/*
|--------------------------------------------------------------------------
| Ghost Mode
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-ghostmode
*/
ghostMode: {
clicks: true,
links: true,
forms: true,
scroll: true
},
/*
|--------------------------------------------------------------------------
| Open (true|false)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-open
*/
open: true,
/*
|--------------------------------------------------------------------------
| xip (true|false)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-xip
*/
xip: false,
/*
|--------------------------------------------------------------------------
| Timestamps (true|false)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-timestamps
*/
timestamps: true,
/*
|--------------------------------------------------------------------------
| File Timeout (milliseconds)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-filetimeout
*/
fileTimeout: 1000,
/*
|--------------------------------------------------------------------------
| Inject Changes
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-injectchanges
*/
injectChanges: true,
/*
|--------------------------------------------------------------------------
| Scroll Proportionally (true|false)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-scrollproportionally
*/
scrollProportionally: true,
/*
|--------------------------------------------------------------------------
| Scroll Throttle (milliseconds)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-scrollthrottle
*/
scrollThrottle: 0,
/*
|--------------------------------------------------------------------------
| Notify (true|false)
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-notify
*/
notify: true,
/*
|--------------------------------------------------------------------------
| Host
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-host
*/
host: null,
/*
|--------------------------------------------------------------------------
| Excluded File Types
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-excludedfiletypes
*/
excludedFileTypes: [],
/*
|--------------------------------------------------------------------------
| Reload Delay
|--------------------------------------------------------------------------
| https://github.com/shakyShane/browser-sync/wiki/options#wiki-reloadDelay
*/
reloadDelay: 0
// options here
};
"use strict";
var messages = require("./messages");
var config = require("./config");
var messages = require("./messages");
var config = require("./config");
var defaultConfig = require("./default-config");
var fs = require("fs");
var fs = require("fs");
var path = require("path");

@@ -23,14 +25,14 @@ module.exports = {

getDefaultConfigFile: function () {
var defaultPath = process.cwd() + config.configFile;
return this._getConfigFile(defaultPath);
return defaultConfig;
},
/**
* Retrieve the config file
* @param {String} path
* @returns {*}
* @private
* @param filePath
*/
_getConfigFile: function (path) {
if (fs.existsSync(path)) {
return require(fs.realpathSync(path));
_getConfigFile: function (filePath) {
var relPath = path.resolve(process.cwd() + "/" + filePath);
if (fs.existsSync(relPath)) {
return require(relPath);
}

@@ -37,0 +39,0 @@ return false;

@@ -8,3 +8,3 @@ "use strict";

var program = require("commander");
var _ = require("lodash");
var merge = require("opt-merger").merge;

@@ -14,45 +14,2 @@ module.exports.allowedOptions = ["host", "server", "proxy"];

/**
* @param {String} string
* @returns {string}
*/
function ucfirst(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* Template for creating a method name
* @param {String} key
* @returns {String}
*/
module.exports.methodName = function (key) {
return "_merge%sOption".replace("%s", ucfirst(key));
};
/**
* @param {Object} obj
* @param {String} key
* @param {Object} args
* @returns {Object}
*/
module.exports.transformOption = function (obj, key, args) {
if (args[key] && typeof obj[key] !== "undefined") {
obj[key] = cliOptions[exports.methodName(key)](obj[key], args[key], args);
}
return obj;
};
/**
* @param {Object} defaultConfig
* @param {Object} args
* @param {Array} allowedOptions
* @returns {Object}
*/
module.exports.mergeOptions = function (defaultConfig, args, allowedOptions) {
return allowedOptions
.reduce(function (obj, key) {
return exports.transformOption(obj, key, args);
}, defaultConfig);
};
/**
* Handle command-line usage with 'start'

@@ -64,3 +21,2 @@ * @param args

var options = {};
var userConfig;

@@ -71,22 +27,6 @@

userConfig = info._getConfigFile(args.config);
} else {
userConfig = info.getDefaultConfigFile();
}
if (args.xip) {
defaultConfig.xip = true;
}
var options = merge(defaultConfig, userConfig || {}, cliOptions.callbacks);
if (args.open === false) {
defaultConfig.open = false;
}
if (userConfig) {
options = _.merge(defaultConfig, userConfig);
options = exports.mergeOptions(defaultConfig, options, exports.allowedOptions);
} else {
options = exports.mergeOptions(defaultConfig, args, exports.allowedOptions);
options.files = cliOptions._mergeFilesOption(args.files, options.exclude);
}
cb(null, {

@@ -101,3 +41,3 @@ files: options.files || [],

* @param {Object} args - optimist object
* @param {Object} argv - process.argv
* @param {Object} argv
* @param {Function} cb

@@ -110,10 +50,16 @@ */

.usage("<command> [options]")
.option("--files", "File paths to watch")
.option("--server", "Run a Local server (uses your cwd as the web root)")
.option("--files", "File paths to watch")
.option("--exclude", "File patterns to ignore")
.option("--server", "Run a Local server (uses your cwd as the web root)")
.option("--directory", "Show a directory listing for the server")
.option("--proxy", "Proxy an existing server")
.option("--xip", "Use xip.io domain routing")
.option("--no-open", "Don't open a new browser window")
.option("--config", "Specify a path to a bs-config.js file")
.option("--host", "Specify a hostname to use");
.option("--proxy", "Proxy an existing server")
.option("--xip", "Use xip.io domain routing")
.option("--tunnel", "Use a public URL")
.option("--config", "Specify a path to a bs-config.js file")
.option("--host", "Specify a hostname to use")
.option("--logLevel", "Set the logger output level (silent, info or debug)")
.option("--port", "Specify a port to use")
.option("--no-open", "Don't open a new browser window")
.option("--no-ghost", "Disable Ghost Mode")
.option("--no-online", "Force offline usage");

@@ -120,0 +66,0 @@ program

"use strict";
var path = require("path");
var _ = require("lodash");
module.exports = {
var utils = {
/**
* Merge Server Options
* @param {Object} defaultValue
* @param {String} arg
* @param {Object} [argv] - process.argv
* @returns {{baseDir: string}}
* @param pattern
* @returns {*|string}
* @private
*/
_mergeServerOption: function (defaultValue, arg, args) {
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("");
}
};
module.exports.utils = utils;
module.exports.callbacks = {
/**
* Merge server options
* @param defaultValue
* @param newValue
* @param args
* @returns {*}
*/
server: function (defaultValue, newValue, args) {
// Return if object or array given
if (arg.baseDir) {
return arg;
if (typeof newValue === "undefined") {
return defaultValue;
}
if (newValue.baseDir) {
return newValue;
}
var obj = {

@@ -25,10 +63,12 @@ baseDir: "./"

if (arg !== true) {
obj.baseDir = arg;
if (newValue !== true) {
obj.baseDir = newValue;
}
if (args) {
if (args.index) {
obj.index = args.index;
}
if (args.directory) {

@@ -43,11 +83,11 @@ obj.directory = true;

* @param defaultValue
* @param arg
* @param newValue
* @param args
* @param config
* @returns {*}
* @private
*/
_mergeProxyOption: function (defaultValue, arg) {
proxy: function (defaultValue, newValue, args, config) {
var protocol = "http";
var host = "localhost";
var target = "";
var port = 80;

@@ -58,7 +98,7 @@ var segs;

if (typeof arg !== "string") {
if (typeof newValue !== "string") {
return false;
}
var url = arg.replace(/^(https?):\/\//, function (match, solo) {
var url = newValue.replace(/^(https?):\/\//, function (match, solo) {
protocol = solo;

@@ -97,9 +137,9 @@ return "";

* @param {Object} defaultValue
* @param {String} arg
* @param {String} newValue
* @returns {String}
* @private
*/
_mergeHostOption: function (defaultValue, arg) {
if (arg && typeof arg === "string") {
return arg;
host: function (defaultValue, newValue) {
if (newValue && typeof newValue === "string") {
return newValue;
}

@@ -110,6 +150,6 @@ return null;

* @param defaultValue
* @param arg
* @param newValue
* @private
*/
_mergePortsOption: function (defaultValue, arg) {
ports: function (defaultValue, newValue) {

@@ -119,10 +159,10 @@ var segs;

if (typeof arg === "string") {
if (typeof newValue === "string") {
if (~arg.indexOf(",")) {
segs = arg.split(",");
if (~newValue.indexOf(",")) {
segs = newValue.split(",");
obj.min = parseInt(segs[0], 10);
obj.max = parseInt(segs[1], 10);
} else {
obj.min = parseInt(arg, 10);
obj.min = parseInt(newValue, 10);
obj.max = null;

@@ -135,4 +175,4 @@ }

return {
min: arg.min,
max: arg.max || null
min: newValue.min,
max: newValue.max || null
};

@@ -142,27 +182,55 @@ }

/**
* @private
* @param defaultValue
* @param newValue
* @returns {*}
*/
_mergeGhostModeOption: function (defaultValue, arg) {
if (!arg || arg === "false") {
ghostMode: function (defaultValue, newValue) {
var def = _.cloneDeep(defaultValue);
if (newValue === "false" || newValue === false) {
return false;
}
return arg;
if (newValue === "true" || newValue === true) {
def.location = true;
return def;
}
if (newValue && typeof newValue.forms !== "undefined") {
if (newValue.forms === false) {
newValue.forms = {};
_.each(def.forms, function (value, key) {
newValue.forms[key] = false;
});
}
if (newValue.forms === true) {
delete newValue.forms;
}
}
return _.merge(def, newValue);
},
/**
*
* @param {String|Array} files
* @param {String|Array} [exclude]
* @returns {Array}
* @private
* @param defaultValue
* @param newValue
* @param args
* @param config
* @returns {*}
*/
_mergeFilesOption: function (files, exclude) {
files: function (defaultValue, newValue, args, config) {
var merged;
var split;
var exclude = config && config.exclude ? config.exclude : false;
if (files) {
if (typeof files === "string") {
if (newValue) {
if (typeof newValue === "string") {
merged = [];
if (~files.indexOf(",")) {
split = files.split(",");
if (~newValue.indexOf(",")) {
split = newValue.split(",");
merged = merged.concat(split.map(function (item) {

@@ -172,6 +240,6 @@ return item.trim();

} else {
merged.push(files);
merged.push(newValue);
}
} else {
merged = files;
merged = newValue;
}

@@ -181,7 +249,10 @@ }

if (typeof exclude === "string") {
merged.push(this._wrapPattern(exclude));
merged.push(utils.wrapPattern(exclude));
} else {
if (Array.isArray(exclude)) {
exclude.forEach(function (pattern) {
merged.push(this._wrapPattern(pattern));
merged.push(utils.wrapPattern(pattern));
}, this);

@@ -192,30 +263,3 @@ }

return merged;
},
/**
* @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("");
}
};
module.exports = {
debugInfo: true,
files: false,
injectFileTypes: ["css", "png", "jpg", "jpeg", "svg", "gif", "webp"],

@@ -11,3 +12,4 @@ minify: true,

clicks: true,
links: false,
scroll: true,
location: false,
forms: {

@@ -17,12 +19,8 @@ submit: true,

toggles: true
},
scroll: true,
location: false
}
},
logLevel: "info",
server: false,
proxy: false,
ports: {
min: 3000,
max: 4000
},
port: 3000,
open: true,

@@ -29,0 +27,0 @@ browser: "default",

"use strict";
var fs = require("fs");
var fs = require("fs");
var Gaze = require("gaze").Gaze;
var _ = require("lodash");
var _ = require("lodash");

@@ -7,0 +7,0 @@ /**

#! /usr/bin/env node
"use strict";
var pjson = require("../package.json");
var BrowserSync = require("./browser-sync");
var pjson = require("../package.json");
var defaultConfig = require("./default-config");
var utils = require("./utils");

@@ -11,3 +11,2 @@ var cli = require("./cli");

var info = cli.info;
var options = cli.options;

@@ -17,6 +16,4 @@ var args = require("optimist").argv;

var _ = require("lodash");
var browserSync = new BrowserSync();
var browserSync = new BrowserSync();
/**

@@ -26,2 +23,3 @@ * @param {Array|Null} files

* @param {Function} [cb]
* @returns {BrowserSync}
*/

@@ -36,3 +34,5 @@ module.exports.start = function (files, config, cb) {

if (require.main === module) {
init.parse(pjson.version, args, argv, function (err, data) {
if (err) {

@@ -45,3 +45,3 @@ utils.fail(err, {}, true);

if (data.configFile) {
info.makeConfig(argv);
info.makeConfig();
}

@@ -56,84 +56,20 @@ });

*/
module.exports.reload = function (arg) {
module.exports.reload = require("./public/reload")(browserSync);
function emitReload(path) {
browserSync.events.emit("file:changed", {
path: path
});
}
function emitBrowserReload() {
browserSync.events.emit("browser:reload");
}
if (typeof arg === "string") {
return emitReload(arg);
}
if (Array.isArray(arg)) {
return arg.forEach(emitReload);
}
if (arg && arg.stream === true) {
// Handle Streams here...
var emitted = false;
var once = arg.once || false;
var Transform = require("stream").Transform;
var reload = new Transform({objectMode:true});
reload._transform = function(file, encoding, next) {
if (once === true && !emitted) {
emitBrowserReload();
emitted = true;
this.push(file);
return next();
} else {
if (once === true && emitted) {
return;
}
if (file.path) {
emitted = true;
emitReload(file.path);
}
}
this.push(file);
next();
};
return reload;
}
return emitBrowserReload();
};
/**
* @param {string} msg
* Exposed helper method for browser notifications
* @param {String} msg
*/
module.exports.notify = function (msg) {
if (msg) {
browserSync.events.emit("browser:notify", {
message: msg
});
}
};
module.exports.notify = require("./public/notify")(browserSync);
/**
* Handle External usage.
* @param {Array} [userFiles]
* @param {Object} [userConfig]
* Handle External API usage.
* @param {Object} [config]
* @param {Function} [cb]
* @returns {exports.EventEmitter}
* @returns {BrowserSync}
*/
module.exports.init = function (userFiles, userConfig, cb) {
var config = _.merge(defaultConfig, userConfig, function (a, b) {
return _.isArray(a) ? _.union(a, b) : undefined;
});
var files = options._mergeFilesOption(userFiles, config.exclude);
config = init.mergeOptions(defaultConfig, config, init.allowedOptions);
return exports.start(files, config, cb);
};
module.exports.init = require("./public/init")(exports.start);
/**
* Allow plugins to be registered/overridden
* @param {String} name

@@ -147,2 +83,6 @@ * @param {Function} func

/**
* Export the emitter
* @type {BrowserSync.events}
*/
module.exports.emitter = browserSync.events;

@@ -5,2 +5,3 @@ "use strict";

var utils = require("./utils").utils;
var log = utils.log;

@@ -14,31 +15,45 @@ var _ = require("lodash");

module.exports.callbacks = {
"file:watching": function (options, data) {
if (data.watcher._patterns) {
utils.log(messages.files.watching(data.watcher._patterns), options);
log("info", messages.files.watching(data.watcher._patterns), options);
}
},
"file:reload": function (options, data) {
utils.log(messages.files.changed(utils.resolveRelativeFilePath(data.path, data.cwd)), options);
utils.log(messages.browser[data.type](), options);
log("info", messages.files.changed(utils.resolveRelativeFilePath(data.path, data.cwd)), options);
log("info", messages.browser[data.type](), options);
},
"client:connected": function (options, data) {
var msg = messages.browser.connection(utils.getUaString(data.ua));
if (options.logConnections) {
var msg = messages.browser.connection(utils.getUaString(data.ua));
utils.log(msg, options, false);
log("info", msg, options, false);
} else {
log("debug", msg, options, false);
}
},
"open": function (options, data) {
"service:running": function (options, data) {
var type = data.type;
var msg;
if (data.tunnel) {
options.urls.tunnel = data.tunnel;
}
if (type === "server") {
msg = messages.initServer(options.host, data.port, data.baseDir);
msg = messages.initServer(options);
}
if (type === "proxy") {
msg = messages.initProxy(options.urls.local, options.urls.remote, options.proxy.target);
msg = messages.initProxy(options, options.proxy.target, data.tunnel);
}
utils.log(msg, options, false);
},
"snippet": function (options, data) {
var msg = messages.init(data.ports, options);
utils.log(msg, options, false);
if (type === "snippet") {
msg = messages.initSnippet(data.port, options);
}
log("info", msg, options, false);
}

@@ -45,0 +60,0 @@ };

@@ -6,15 +6,17 @@ "use strict";

var path = require("path");
var config = require("./config");
var _ = require("lodash");
var utils = require("./utils").utils;
module.exports = {
/**
* @param {Object} ports
* @param {Object} port
* @param {Object} options
* @returns {String}
*/
init: function (ports, options) {
initSnippet: function (port, options) {
var template = "{green:Copy the following snippet into your website, just before the closing} </body> {green:tag}\n{:tags:}";
var params = {
tags: this.scriptTags(ports, options)
tags: this.scriptTags(port, options)
};

@@ -24,2 +26,11 @@

},
tunnel: function (url) {
var templates = [
"{green:Tunnel running...}",
"{green:You can access it through the following address:}\n",
">>> {magenta:{:url:}}"
];
return prefixed(templates, {url: url});
},
server: {

@@ -36,37 +47,24 @@ /**

/**
* @param {String} host
* @param {String|Number} port
* @param {String} baseDir
* @param {Object} options
* @returns {String}
*/
initServer: function (host, port, baseDir) {
initServer: function (options) {
var output = "";
var base = baseDir;
var baseDir = options.server ? options.server.baseDir : undefined;
var templates = [
"{green:Server running...}",
"{green:You can access it through the following addresses:}\n",
"{green:Local (this machine):}",
">>> {magenta:{:local:}}",
"{green:External (other devices etc):}",
">>> {magenta:{:remote:}}\n"
];
output += this.getUrls(options.urls);
var params = {
local: this._makeUrl("localhost", port, "http:"),
remote: this._makeUrl(host, port, "http:")
};
if (baseDir) {
if (Array.isArray(baseDir)) {
_.each(baseDir, addBase);
} else {
addBase(baseDir);
}
}
output += prefixed(templates, params);
var template = "{green:Serving files from:} {magenta:{: baseDir :}}";
if (Array.isArray(baseDir)) {
baseDir.forEach(function (item, i) {
var prefix = (i ? "\n" : "");
output += prefix + prefixed(template, {baseDir: item});
function addBase (value) {
output += prefixed("{green:Serving files from:} {magenta:{: baseDir :}}\n", {
baseDir: value
});
} else {
output += prefixed(template, {baseDir: baseDir});
}

@@ -77,31 +75,24 @@

/**
* @param {String} host
* @param {String|Number} port
* @param {Object} options
* @returns {String}
*/
initProxy: function (local, external, proxyUrl) {
initProxy: function (options) {
var output = "";
var output = "";
var target = options.proxy.target;
var templates = [
"{green:Proxying:} {:proxy:}",
"{green:Now you can access your site through the following addresses:}\n",
"{green:Local (this machine):}",
">>> {magenta:{:local:}}",
"{green:External (other devices etc):}",
">>> {magenta:{:remote:}}\n"
"{green:Now you can access your site through the following addresses:}\n"
];
var params = {
proxy: proxyUrl,
local: local,
remote: external
};
output += prefixed(templates, {proxy: target});
output += prefixed(templates, params);
output += this.getUrls(options.urls);
return output;
},
plugin: {
error: function (name) {
error: function () {
return "Your plugin must be a function";

@@ -128,4 +119,3 @@ }

/**
* @param {String} hostIp
* @param {Object} ports
* @param {number} port
* @param {Object} options

@@ -135,20 +125,18 @@ * @param {String} [env]

*/
scriptTags: function (ports, options, env) {
scriptTags: function (port, options, env) {
var template = [
"\n<script type='text/javascript'>//<![CDATA[\n;",
"document.write(\"<script defer src='//HOST:{:socket:}/socket.io/socket.io.js'><\\/script>",
"<script defer src='//HOST:{:custom:}'><\\/script>",
"\".replace(/HOST/g, location.hostname));",
"document.write(\"<script async src='{:custom:}'><\\/script>\".replace(/HOST/g, location.hostname));",
"\n//]]></script>"
];
if (env === "controlPanel") {
template.splice(2, 1);
var script = "//HOST:" + port + this.clientScript(options);
if (options.tunnel) {
script = this.clientScript(options);
}
var params = {
socket: ports.socket,
custom: ports.controlPanel + this.clientScript(options),
connector: this.socketConnector(ports.socket)
custom: script
};

@@ -202,3 +190,3 @@

var template1 = "Config file created ({cyan:{:path:}})";
var template2 = "To use it, in the same directory run: {green:browser-sync}";
var template2 = "To use it, in the same directory run: {green:browser-sync start --config bs-config.js}";

@@ -280,8 +268,13 @@ var params = {

/**
* @param {String|Number} port
* @param {number} port
* @param {Object} options
* @returns {String}
*/
socketConnector: function (port) {
var string = "var ___socket___ = io.connect('http://' + location.hostname + ':' + '{:port:}');";
socketConnector: function (port, options) {
var string = "var ___socket___ = io.connect(location.hostname + ':{:port:}');";
var tunnel = "var ___socket___ = io.connect(location.hostname);";
var template = options.tunnel ?
tunnel : string;
var params = {

@@ -291,3 +284,3 @@ port: port

return compile(string, params);
return compile(template, params);
},

@@ -300,4 +293,4 @@ /**

var script = "/client/browser-sync-client.js";
var template = "/client/browser-sync-client.{:version:}.js";
var script = "/browser-sync-client.js";
var template = "/browser-sync-client.{:version:}.js";

@@ -322,3 +315,25 @@ if (!options || !options.version) {

return compiled;
},
getUrls: function (urls) {
var output = "";
_.each(urls, function (value, key) {
output += prefixed("{green:{:name:}:} >>> {magenta:{:url:}}\n", {
name: utils.ucfirst(key),
url: value
});
});
return output;
},
tunnelFail: function (err) {
return prefixed(["The following is a Tunnel error:", this.getErr(err)]);
},
configError: function (msg) {
return prefixed("{red:CONFIG ERROR: %s }".replace("%s", msg));
},
getErr: function (msg) {
return "{red:%s }".replace("%s", msg);
},
getDebug: function (msg) {
return prefixed("{cyan:DEBUG: %s }".replace("%s", msg));
}
};
"use strict";
var proxyModule = require("./proxy");
var messages = require("./messages");

@@ -10,2 +9,3 @@ var snippetUtils = require("./snippet").utils;

var filePath = require("path");
var foxy = require("foxy");

@@ -111,3 +111,5 @@ var utils = {

} else {
app.use(connect.static(filePath.resolve(base), { index: index }));
if ("string" === typeof base) {
app.use(connect.static(filePath.resolve(base), { index: index }));
}
}

@@ -120,3 +122,6 @@ },

addDirectory: function (app, base) {
app.use(connect.directory(base, {icons:true}));
if (Array.isArray(base)) {
base = base[0];
}
app.use(connect.directory(filePath.resolve(base), {icons:true}));
}

@@ -129,30 +134,48 @@ };

* @param {String} host
* @param {{socket: (Number), controlPanel: (Number)}} ports
* @param {Number} port
* @param {Object} options
* @param {socket} io
* @param {string|} scripts
* @returns {{staticServer: (http.Server), proxyServer: (http.Server)}|Boolean}
*/
module.exports.launchServer = function (host, ports, options, io) {
module.exports.launchServer = function (host, port, options, scripts) {
var app;
var proxy = options.proxy || false;
var server = options.server || false;
var snippet = false;
if (!proxy && !server) {
snippet = true;
}
var scriptTags = options.snippet = messages.scriptTags(port, options);
var scriptPaths = messages.clientScript(options, true);
var scriptPath = options.scriptPath = scriptPaths.versioned;
var staticServer;
var proxyServer;
var navCallback = utils.navigateCallback(io, options);
var scriptTags = options.snippet = messages.scriptTags(ports, options);
var app;
if (proxy) {
proxyServer = proxyModule.createProxy(host, ports, options, navCallback);
proxyServer = foxy.init(
options.proxy,
{
host: host,
port: port
},
snippetUtils.getRegex(scriptTags),
snippetUtils.getProxyMiddleware(scripts, scriptPath)
);
}
if (server) {
if (server || snippet) {
var baseDir = server.baseDir;
var index = server.index || "index.html";
var directory = server.directory;
var baseDir, index, directory;
if (server) {
baseDir = server.baseDir;
index = server.index || "index.html";
directory = server.directory;
}
app = connect();
if (server.middleware) {
if (server && server.middleware) {
utils.addMiddleware(app, server.middleware);

@@ -162,13 +185,18 @@ }

app.use(function (req, res, next) {
req = snippetUtils.isOldIe(req);
snippetUtils.isOldIe(req);
return next();
})
.use(navCallback)
.use(snippetUtils.getSnippetMiddleware(scriptTags));
.use(scriptPath, scripts)
.use(scriptPaths.path, scripts);
utils.addBaseDir(app, baseDir, index);
if (server) {
if (directory) {
utils.addDirectory(app, baseDir);
if (directory) {
utils.addDirectory(app, baseDir);
}
app.use(snippetUtils.getSnippetMiddleware(scriptTags));
utils.addBaseDir(app, baseDir, index);
}

@@ -175,0 +203,0 @@

"use strict";
var controlPanel = require("./control-panel");
var messages = require("./messages");
var api = require("./api");
var utils = require("./utils").utils;
var utils = require("./utils").utils;
var snippetUtils = require("./snippet").utils;

@@ -17,8 +15,7 @@ /**

*/
return function (ports, files, options) {
return function (port, files, options) {
var servers;
this.options = options;
this.options.port = port;
this.io = this.getPlugin("socket")(ports.socket, this.clientEvents, options, this.events);
// register internal events

@@ -28,3 +25,3 @@ this.registerInternalEvents(options);

// Set global URL options
utils.setUrlOptions(ports, options);
options.urls = utils.setUrlOptions(port, options);

@@ -34,29 +31,16 @@ // Start file watcher

// launch the server/proxy
servers = this.initServer(options.host, ports, options, this.io);
// Get the Client JS
var clientJs = snippetUtils.getClientJs(port, options);
if (!servers) {
this.events.emit("snippet", {ports: ports});
}
// Start the server
var servers = this.servers = this.initServer(
options.host,
port,
options,
this.getPlugin("client:script")(options, clientJs, options.proxy ? "file" : "middleware")
);
// Always Launch the control panel (which contains client script);
var snippet = messages.scriptTags(ports, options, "controlPanel");
var connector = messages.socketConnector(ports.socket);
// Start the socket, needs an existing server.
this.io = this.getPlugin("socket")(servers.staticServer || servers.proxyServer, this);
var cpPlugin = this.getPlugin("controlpanel");
var cp;
if (cpPlugin) {
cp = cpPlugin(options, snippet, connector, this);
}
controlPanel
.launchControlPanel(options, this.getPlugin("client:script")(options, connector), cp)
.listen(ports.controlPanel);
this.options = options;
// get/emit the api
this.api = api.getApi(ports, options, servers);
this.events.emit("init", this);

@@ -63,0 +47,0 @@

"use strict";
var messages = require("./messages");
var lrSnippet = require("resp-modifier");
var path = require("path");
var _ = require("lodash");
var fs = require("fs");
/**
* Utils for snippet injection
* @type {{excludeList: string[], bodyExists: bodyExists, isExcluded: isExcluded}}
*/

@@ -41,3 +43,3 @@ var utils = {

/**
* @param {string} snippet
* @param {String} snippet
* @returns {{match: RegExp, fn: Function}}

@@ -64,5 +66,22 @@ */

return lrSnippet({rules:rules});
return lrSnippet({rules: rules});
},
/**
* @param {String} scripts - the clientside JS
* @param {String} scriptPath - the URL to match
* @returns {Function}
*/
getProxyMiddleware: function (scripts, scriptPath) {
return function (req, res, next) {
if (req.url.indexOf(scriptPath) > -1) {
res.writeHead(200, { "Content-Type": "text/javascript" });
res.write(scripts);
res.end();
return next(true);
} else {
return next(false);
}
};
},
/**
* @param {Object} req

@@ -83,4 +102,15 @@ * @param {Array} [excludeList]

return req;
},
/**
* @param {number} port
* @param {BrowserSync.options} options
* @returns {String}
*/
getClientJs: function (port, options) {
var js = fs.readFileSync(path.resolve(__dirname + "/public/socket.io.js"), "utf-8") + ";";
return js += messages.socketConnector(port, options);
}
};
module.exports.utils = utils;
"use strict";
var socket = require("socket.io");
var socket = require("socket.io");
var Steward = require("./steward");

@@ -10,34 +11,36 @@ /**

module.exports.plugin = function () {
return function (port, events, options, emitter) {
return exports.init(port, events, options, emitter);
return function (server, bs) {
return exports.init(server, bs);
};
};
/**
* @param client
* @param event
*/
module.exports.clientEvent = function (client, event) {
client.on(event, function (data) {
client.broadcast.emit(event, data);
});
};
/**
* @param {Array} events
* @param {Object} options
* @param {Socket} io
* @param {EventEmitter} emitter
* @param {http.Server} server
* @param {BrowserSync} bs
*/
module.exports.socketConnection = function (events, options, io, emitter) {
module.exports.init = function (server, bs) {
var ua;
var events = bs.clientEvents;
var options = bs.options;
var emitter = bs.events;
io.sockets.on("connection", function (client) {
var io = socket.listen(server, {log: false});
var steward = new Steward(emitter);
/**
* Listen for new connections
*/
io.sockets.on("connection", handleConnection);
/**
* Handle each new connection
* @param {Object} client
*/
function handleConnection (client) {
// set ghostmode callbacks
if (options.ghostMode) {
events.forEach(function (evt) {
exports.clientEvent(client, evt);
});
addGhostMode(client);
}

@@ -47,26 +50,35 @@

ua = client.handshake.headers["user-agent"];
emitter.emit("client:connected", {
ua: client.handshake.headers["user-agent"]
});
}
emitter.emit("client:connected", {ua: ua});
});
};
/**
* @param {string} event
* @param {Socket.client} client
* @param {Object} data
*/
function handleClientEvent(event, client, data) {
/**
* @param {Number} port
* @param {Array} events
* @param {Object} options
* @param {EventEmitter} emitter
* @returns {http.Server}
*/
module.exports.init = function (port, events, options, emitter) {
var io = socket.listen(port, {log: false});
io.set("log level", 0);
if (options.minify) {
io.set("browser client minification", true);
if (process.platform !== "win32") {
io.set("browser client gzip", true);
if (steward.valid(client.id)) {
client.broadcast.emit(event, data);
}
}
exports.socketConnection(events, options, io, emitter);
/**
* @param client
*/
function addGhostMode (client) {
events.forEach(addEvent);
function addEvent(event) {
client.on(event, handleClientEvent.bind(null, event, client));
}
}
return io;
};
"use strict";
var devIp = require("dev-ip");

@@ -9,2 +10,3 @@ var open = require("opn");

var UAParser = require("ua-parser-js");
var parser = new UAParser();

@@ -15,15 +17,14 @@

* @param {Object} options
* @returns {String} - the IP address
* @returns {String|boolean} - the IP address
*/
getHostIp: function (options) {
var fallback = "0.0.0.0";
var returnValue = devIp.getIp(null);
if (options) {
if (options.host) {
if (options.host && options.host !== "localhost") {
return options.host;
}
if (options.detect === false || !devIp) {
return fallback;
return false;
}

@@ -36,8 +37,8 @@ }

return returnValue || fallback;
return returnValue || false;
},
/**
* Take the path provided in options & transform into CWD for serving files
* @param {string} [baseDir]
* @returns {string}
* @param {String} [baseDir]
* @returns {String}
*/

@@ -72,6 +73,13 @@ getBaseDir: function (baseDir) {

*/
setUrlOptions: function (ports, opts) {
setUrlOptions: function (port, opts) {
var port = ports.server || ports.proxy;
var urls = {};
if (!opts.online) {
urls.local = "http://localhost:" + port;
return urls;
}
var external = utils.xip(utils.getHostIp(opts), opts);
var localhost = "localhost";

@@ -87,11 +95,9 @@

if (port) {
opts.urls = utils.getUrls(external, local, port, opts);
}
return utils.getUrls(external, local, port, opts);
},
/**
* Append a start path if given in options
* @param {string} url
* @param {object} options
* @returns {string}
* @param {String} url
* @param {Object} options
* @returns {String}
*/

@@ -117,13 +123,19 @@ getUrl: function (url, options) {

/**
* @param {string} external
* @param {String} external
* @param {number|string} port
* @param {object} options
* @param {string} local
* @returns {{local: string, remote: string}}
* @param {Object} options
* @param {String} local
* @returns {{local: string, external: string}}
*/
getUrls: function (external, local, port, options) {
return {
local: utils.getUrl(utils._makeUrl(local, port), options),
remote: utils.getUrl(utils._makeUrl(external, port), options)
var urls = {
local: utils.getUrl(utils._makeUrl(local, port), options)
};
if (external !== local) {
urls.external = utils.getUrl(utils._makeUrl(external, port), options);
}
return urls;
},

@@ -133,3 +145,3 @@ /**

* @param {Number} port
* @returns {string}
* @returns {String}
* @private

@@ -142,23 +154,17 @@ */

* Get ports
* @param {object} options
* @param {number} minCount
* @param {Object} options
* @returns {Q.promise}
*/
getPorts: function (options, minCount) {
getPorts: function (options) {
var minPorts = (options.server || options.proxy) ? 3 : minCount;
var minPortRange = options.ports && options.ports.min;
var maxPortRange = options.ports && options.ports.max;
var port = options.port;
var ports = options.ports; // backwards compatibility
var max;
var names = ["socket", "controlPanel"];
if (options.server) {
names.push("server");
if (ports) {
port = ports.min;
max = ports.max;
}
if (options.proxy) {
names.push("proxy");
}
return portScanner.getPorts(minPorts, minPortRange, maxPortRange, names);
return portScanner.getPorts(1, port, max);
},

@@ -173,5 +179,5 @@ /**

/**
* @param {string} filepath
* @param {string} cwd
* @returns {string}
* @param {String} filepath
* @param {String} cwd
* @returns {String}
*/

@@ -182,4 +188,4 @@ resolveRelativeFilePath: function (filepath, cwd) {

/**
* @param {string} path
* @returns {string}
* @param {String} path
* @returns {String}
*/

@@ -191,4 +197,4 @@ getFileExtension: function (path) {

* Open the page in browser
* @param {string} url
* @param {object} options
* @param {String} url
* @param {Object} options
*/

@@ -216,20 +222,60 @@ openBrowser: function (url, options) {

* Log a message to the console
* @param {string} msg
* @param {object} options
* @param {boolean} override
* @param {String} level
* @param {String} msg
* @param {Object} options
* @returns {boolean}
*/
log: function (msg, options, override) {
if (!options.debugInfo && !override) {
log: function (level, msg, options) {
var msgs = require("./messages");
/** Backwards compat **/
if (options && (options.logLevel === "silent" || options.debugInfo === false)) {
return false;
}
return console.log(msg);
if (options.logLevel === "debug") {
if (level === "debug") {
console.log(msgs.getDebug(msg));
} else {
console.log(msg);
}
} else {
if (level === "info") {
return console.log(msg);
}
}
},
/**
* @param {Object} options
* @returns {Function}
*/
getDebugger: function (options) {
return function (msg, vars) {
utils.log("debug", msg.replace("%s", vars), options);
};
},
/**
* @param {String} msg
* @param {*} vars
* @param {Object} options
*/
debug: function (msg, vars, options) {
utils.log("debug", msg.replace("%s", vars), options);
},
/**
* @param {String} msg
* @param {*} vars
* @param {Object} options
*/
warn: function (msg, vars, options) {
utils.log("warn", msg.replace("%s", vars), options);
},
/**
* @param {String} msg
* @param {Object} options
* @param {Boolean} kill
*/
fail: function (msg, options, kill) {
this.log(msg, options, false);
this.log("info", msg, options);
if (kill) {

@@ -253,2 +299,5 @@ process.exit(1);

return host;
},
ucfirst: function (string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

@@ -255,0 +304,0 @@ };

{
"name": "browser-sync",
"description": "Live CSS Reload & Browser Syncing",
"version": "0.9.1",
"version": "1.0.0",
"homepage": "https://github.com/shakyshane/browser-sync",

@@ -31,6 +31,4 @@ "author": {

"portscanner-plus": "0.1.0",
"path": "~0.4.9",
"url": "~0.7.9",
"lodash": "~2.2.1",
"socket.io": "~0.8.0",
"socket.io": "1.0.4",
"connect": "~2.13.0",

@@ -44,10 +42,13 @@ "ua-parser-js": "~0.6.2",

"resp-modifier": "0.0.4",
"browser-sync-client": "^0.1.7",
"browser-sync-client": "0.2.1",
"commander": "~2.1.0",
"browser-sync-control-panel": "0.0.5",
"opn": "^0.1.1"
"opn": "^0.1.1",
"foxy": "0.1.2",
"localtunnel": "^1.3.0",
"opt-merger": "^0.1.2"
},
"devDependencies": {
"optimist": "~0.6.0",
"socket.io-client": "~0.9.16",
"socket.io-client": "1.0.4",
"cli-color": "~0.2.3",

@@ -54,0 +55,0 @@ "chai": "~1.8.1",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc