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

tv

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tv - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

lib/tv.js

88

lib/index.js
// Load modules
var Os = require('os');
var Fs = require('fs');
var Handlebars = require('handlebars');
var Websocket = require('ws');
var Url = require('url');
var Hoek = require('hoek');
var Defaults = require('./defaults');
var Tv = require('./tv');
// Declare internals

@@ -15,71 +13,55 @@

exports = module.exports = internals.Tv = function (config) {
internals.defaults = {
debugEndpoint: '/debug/console',
queryKey: 'debug'
};
Hoek.assert(this.constructor === internals.Tv, 'Tv must be instantiated using new');
var self = this;
this.settings = Hoek.applyToDefaults(Defaults, config || {});
this._subscribers = {}; // Map: debug session -> [ subscriber ]
exports.register = function (pack, options, next) {
var indexTemplateSource = this.settings.indexTemplate || Fs.readFileSync(this.settings.indexTemplatePath, 'utf8');
this._compiledIndexTemplate = Handlebars.compile(indexTemplateSource);
var settings = Hoek.applyToDefaults(internals.defaults, options || {});
var ws = new Websocket.Server({ host: this.settings.host, port: this.settings.websocketPort });
ws.on('connection', function (socket) {
var tv = new Tv(settings);
var html = tv.getMarkup();
socket.on('message', function (message) {
pack.route({
method: 'GET',
path: settings.debugEndpoint,
config: {
auth: { mode: 'none' }, // In case defaults are set otherwise
handler: function () {
if (message) {
self._subscribers[message] = self._subscribers[message] || [];
if (self._subscribers[message].indexOf(socket) === -1) {
self._subscribers[message].push(socket);
//Log.event('info', 'Debug subscription requested: ' + message);
}
return this.reply(html);
}
});
}
});
};
pack.ext('onRequest', function (request, next) {
internals.Tv.prototype.report = function (session, event) {
var key = settings.queryKey;
if (!request.query[key]) {
return next();
}
var self = this;
request.plugins.tv = { debugId: request.query[key] };
delete request.query[key];
var transmit = function (key) {
delete request.url.search;
delete request.url.query[key];
var subscribers = self._subscribers[key];
request.setUrl(Url.format(request.url));
var valid = [];
if (subscribers) {
for (var i = 0, il = subscribers.length; i < il; ++i) {
try {
if (subscribers[i].readyState === Websocket.OPEN) {
subscribers[i].send(JSON.stringify(event, null, 4));
valid.push(subscribers[i]);
}
}
catch (err) {
// Remove subscriber on any send error
}
}
return next();
});
self._subscribers[key] = valid;
}
};
pack.events.on('log', function (request, report) {
if (session) {
transmit(session);
}
tv.report(report, request.plugins.tv && request.plugins.tv.debugId);
});
transmit('*');
return next();
};
internals.Tv.prototype.getMarkup = function () {
var host = (this.settings.host !== '0.0.0.0') ? this.settings.host : Os.hostname();
var port = this.settings.websocketPort;
var data = {host : host, port : port};
return this._compiledIndexTemplate(data)
};
{
"name": "tv",
"description": "Interactive debug console for hapi",
"version": "0.0.1",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors":[
"Wyatt Preul <wpreul@gmail.com>",
"Van Nguyen <the.gol.effect@gmail.com>",
"Ben Nguyen <benobviate@gmail.com>"
],
"repository": "git://github.com/walmartlabs/tv",
"main": "index",
"keywords": [
"debug",
"console",
"hapi"
],
"engines": {
"node": ">=0.8.0"
},
"dependencies": {
"hoek": "0.4.x",
"ws": "0.4.x",
"handlebars": "1.0.x"
},
"devDependencies": {
"mocha": "1.x.x",
"chai": "1.2.x"
},
"scripts": {
"test": "make test && make unit"
},
"licenses": [
{
"type": "BSD",
"url": "http://github.com/walmartlabs/tv/raw/master/LICENSE"
}
]
"name": "tv",
"description": "Interactive debug console plugin for hapi",
"version": "0.0.2",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors":[
"Wyatt Preul <wpreul@gmail.com>",
"Van Nguyen <the.gol.effect@gmail.com>",
"Ben Nguyen <benobviate@gmail.com>"
],
"repository": "git://github.com/walmartlabs/tv",
"main": "index",
"keywords": [
"debug",
"console",
"hapi",
"plugin"
],
"engines": {
"node": ">=0.8.0"
},
"dependencies": {
"hoek": "0.4.x",
"ws": "0.4.x",
"handlebars": "1.0.x"
},
"peerDependencies": {
"hapi": "0.14.x"
},
"devDependencies": {
"hapi": "0.14.x",
"mocha": "1.x.x",
"chai": "1.x.x",
"blanket": "1.0.x",
"travis-cov": "0.2.x"
},
"scripts": {
"test": "make test && make test-cov",
"blanket": { "pattern": "//^((?!\/node_modules\/)(?!\/test\/).)*$/ig", "onlyCwd": true, "data-cover-flags": { "branchTracking": true } },
"travis-cov": { "threshold": 100 }
},
"licenses": [
{
"type": "BSD",
"url": "http://github.com/walmartlabs/tv/raw/master/LICENSE"
}
]
}

@@ -13,1 +13,13 @@ <a href="https://github.com/walmartlabs/blammo"><img src="https://raw.github.com/walmartlabs/blammo/master/images/from.png" align="right" /></a>

### Debug
To assist in debugging server events related to specific incoming requests, **hapi** includes an optional debug console which is turned _off_ by default.
The debug console is a simple web page in which developers can subscribe to a debug id, and then include that debug id as an extra query parameter in each
request. The server will use WebSocket to stream the subscribed request logs to the web page in real-time. In application using multiple server instances,
only one can enable the debug interface using the default port. To enable the debug console set the `debug` option to _true_ or to an object with custom
configuration:
- `websocketPort` - the port used by the WebSocket connection. Defaults to _3000_.
- `debugEndpoint` - the debug console request path added to the server routes. Defaults to _'/debug/console'_.
- `queryKey` - the name or the request query parameter used to mark requests being debugged. Defaults to _debug_.
// Load modules
var Chai = require('chai');
var Websocket = require('ws');
var Tv = process.env.TEST_COV ? require('../lib-cov') : require('../lib');
var Hapi = require('hapi');
var Ws = require('ws');

@@ -18,137 +18,68 @@

describe('Tv', function() {
describe('Tv', function () {
describe('#constructor', function() {
var server = null;
it('cannot be constructed without new', function(done) {
before(function (done) {
var options = {
permissions: {
ext: true
},
plugin: {
websocketPort: 3007
}
};
var fn = function() {
server = new Hapi.Server();
var tv = Tv();
};
server.route({
method: 'GET',
path: '/',
handler: function () {
expect(fn).to.throw(Error);
done();
return this.reply('1');
}
});
it('can be constructed with new', function(done) {
server.plugin().require('../', options, function (err) {
var fn = function() {
var tv = new Tv({websocketPort: 3001});
};
expect(fn).to.not.throw(Error);
expect(err).to.not.exist;
done();
});
});
it('uses the tv defaults when no config is passed in', function(done) {
it('returns the console html', function (done) {
var tv = new Tv();
server.inject({ method: 'GET', url: '/debug/console' }, function (res) {
expect(tv.settings.host).to.equal('0.0.0.0');
expect(tv.settings.websocketPort).to.equal(3000);
expect(res.result).to.contain('<!DOCTYPE html>');
done();
});
it('uses the passed in config', function(done) {
var tv = new Tv({host: 'localhost', websocketPort: 3002});
expect(tv.settings.host).to.equal('localhost');
expect(tv.settings.websocketPort).to.equal(3002);
done();
});
it('adds message to subscribers list when receiving message', function(done) {
var config = {host: 'localhost', websocketPort: 3010}
var tv = new Tv(config);
var ws = new Websocket("ws://" + config.host + ':' + config.websocketPort);
ws.readyState = Websocket.OPEN;
ws.on('open', function() {
ws.send("test1");
setTimeout(function(){
expect(tv._subscribers["test1"]).to.exist;
done();
}, 1000);
});
});
});
describe('#report', function() {
it('reports a request event', function (done) {
it('sends the data to all subscribers when session is null', function(done) {
var ws = new Ws('ws://localhost:3007');
var tv = new Tv({websocketPort: 3003});
tv._subscribers['*'] = [{
readyState: Websocket.OPEN,
send: function(message) {
ws.on('open', function () {
expect(message).to.exist;
expect(message).to.equal('"test"');
done();
}
}];
ws.send('*');
tv.report(null, 'test');
});
setTimeout(function () {
it('only sends a message to the appropriate subscribers', function(done) {
server.inject({ method: 'GET', url: '/?debug=123' }, function (res) {
var tv = new Tv({websocketPort: 3004});
tv._subscribers['*'] = [{
readyState: Websocket.OPEN,
send: function(message) {
expect(message).to.not.exist;
}
}];
tv._subscribers['test'] = [{
readyState: Websocket.OPEN,
send: function(message) {
expect(message).to.exist;
expect(message).to.equal('"test"');
done();
}
}];
tv.report('test', 'test');
expect(res.result).to.equal('1');
});
}, 100);
});
it('only sends a message when the websocket exists', function(done) {
ws.once('message', function (data, flags) {
var tv = new Tv({websocketPort: 3005});
tv._subscribers['*'] = [{
readyState: 'none',
send: function(message) {
expect(message).to.not.exist;
}
}];
tv.report(null, 'test');
expect(JSON.parse(data).data.agent).to.equal('shot');
done();
});
});
});
describe('#getMarkup', function() {
it('includes the hostname and port in the source', function(done) {
var tv = new Tv({host: 'localhost', websocketPort: 3006});
var html = tv.getMarkup();
expect(html).to.contain('localhost');
expect(html).to.contain('3006');
done();
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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