obs-websocket-js
Advanced tools
Comparing version 0.5.0 to 0.5.2
# Change Log | ||
## [v0.5.2](https://github.com/haganbmj/obs-websocket-js/tree/v0.5.2) (2017-05-03) | ||
[Full Changelog](https://github.com/haganbmj/obs-websocket-js/compare/v0.5.1...v0.5.2) | ||
**Implemented enhancements:** | ||
- \[API\] Convert AuthHashing from a Class to a Function [\#44](https://github.com/haganbmj/obs-websocket-js/issues/44) | ||
- \[API\] Standardize internal emits [\#42](https://github.com/haganbmj/obs-websocket-js/issues/42) | ||
**Fixed bugs:** | ||
- \[API\] Binding multiple events results in duplicate callbacks [\#46](https://github.com/haganbmj/obs-websocket-js/issues/46) | ||
**Merged pull requests:** | ||
- \[CI\] Set up Coveralls [\#45](https://github.com/haganbmj/obs-websocket-js/pull/45) ([haganbmj](https://github.com/haganbmj)) | ||
## [v0.5.1](https://github.com/haganbmj/obs-websocket-js/tree/v0.5.1) (2017-04-29) | ||
[Full Changelog](https://github.com/haganbmj/obs-websocket-js/compare/v0.5.0...v0.5.1) | ||
**Implemented enhancements:** | ||
- \[API\] Revise send method [\#41](https://github.com/haganbmj/obs-websocket-js/pull/41) ([haganbmj](https://github.com/haganbmj)) | ||
**Closed issues:** | ||
- Update Bower Release [\#43](https://github.com/haganbmj/obs-websocket-js/issues/43) | ||
## [v0.5.0](https://github.com/haganbmj/obs-websocket-js/tree/v0.5.0) (2017-04-27) | ||
@@ -15,2 +42,3 @@ [Full Changelog](https://github.com/haganbmj/obs-websocket-js/compare/v0.4.0...v0.5.0) | ||
- \[API\] Rejects when no Socket Connection Exists [\#34](https://github.com/haganbmj/obs-websocket-js/issues/34) | ||
- Fix webpack distributable [\#38](https://github.com/haganbmj/obs-websocket-js/pull/38) ([haganbmj](https://github.com/haganbmj)) | ||
@@ -17,0 +45,0 @@ - \[API\] Fix errors caused when .disconnect is called at the wrong time [\#37](https://github.com/haganbmj/obs-websocket-js/pull/37) ([Lange](https://github.com/Lange)) |
@@ -11,3 +11,3 @@ module.exports = function (grunt) { | ||
' * Repository: <%= pkg.repoUrl %>\n' + | ||
' * Build SHA: <%= pkg.sha %>\n' + | ||
' * Commit SHA: <%= pkg.sha %>\n' + | ||
' * Build Timestamp: <%= pkg.timestamp %>\n' + | ||
@@ -26,8 +26,2 @@ ' */\n\n', | ||
}, | ||
// Jsdoc2md: { | ||
// docs: { | ||
// src: ['lib/OBSWebSocket.js', 'lib/OBSScene.js', 'lib/OBSSource.js', 'lib/Core.js', 'lib/Socket.js', 'lib/Requests.js', 'lib/Events.js'], | ||
// dest: 'dist/DOCUMENTATION.md' | ||
// } | ||
// }, | ||
clean: { | ||
@@ -34,0 +28,0 @@ dist: 'dist' |
const API = require('./API'); | ||
const debug = require('debug')('obs-websocket-js:api'); | ||
const logAmbiguousError = require('./util/logAmbiguousError'); | ||
const eventCallbacks = {}; | ||
function iterateEventCallbacks(callbacks, err, data) { | ||
for (const callback in callbacks) { | ||
if (typeof callbacks[callback] === 'function') { | ||
if (err) { | ||
logAmbiguousError(debug, 'Callback error:', err); | ||
} | ||
callbacks[callback](err, data); | ||
} | ||
} | ||
} | ||
function methodBinding(OBSWebSocket) { | ||
@@ -36,14 +21,4 @@ // Bind each request command to a function of the same name. | ||
if (!eventCallbacks[event]) { | ||
eventCallbacks[event] = []; | ||
} | ||
eventCallbacks[event].push(callback); | ||
// TODO: Determine if having err in the callback is even possible/necessary. | ||
this.on(event, msg => { | ||
const err = msg.error ? msg : null; | ||
const data = msg.error ? null : msg; | ||
iterateEventCallbacks(eventCallbacks[event], err, data); | ||
this.on(event, (err, data) => { | ||
this._doCallback(callback, err, data); | ||
}); | ||
@@ -50,0 +25,0 @@ }; |
@@ -23,46 +23,47 @@ const Socket = require('./Socket'); | ||
send(requestType, args = {}, callback) { | ||
// TODO: Improve this to ensure args is an object, not a function or primitive or something. | ||
args = args || {}; | ||
return new Promise((resolve, reject) => { | ||
if (!this._connected) { | ||
debug('[send] %s', Status.NOT_CONNECTED.description); | ||
this._doCallback(callback, Status.NOT_CONNECTED, null); | ||
reject(Status.NOT_CONNECTED); | ||
return; | ||
} | ||
const messageId = generateMessageId(); | ||
let rejectReason; | ||
if (!requestType) { | ||
debug('[send] %s', Status.REQUEST_TYPE_NOT_SPECIFIED.description); | ||
this._doCallback(callback, Status.REQUEST_TYPE_NOT_SPECIFIED, null); | ||
reject(Status.REQUEST_TYPE_NOT_SPECIFIED); | ||
return; | ||
rejectReason = Status.REQUEST_TYPE_NOT_SPECIFIED; | ||
} | ||
// Assign the core message details. | ||
args['request-type'] = requestType; | ||
const messageId = args['message-id'] = generateMessageId(); // eslint-disable-line no-multi-assign | ||
// Submit the request to the websocket. | ||
debug('[send] %s %s %o', messageId, requestType, args); | ||
try { | ||
this._socket.send(JSON.stringify(args)); | ||
} catch (e) { | ||
reject(e); | ||
if (!this._connected) { | ||
rejectReason = Status.NOT_CONNECTED; | ||
} | ||
// Assign a temporary event listener for this particular messageId to uniquely identify the response. | ||
this.once('obs:internal:message:id-' + messageId, message => { | ||
// TODO: Do additional stuff with the msg to determine errors, marshaling, etc. | ||
// message = API.marshalResponse(requestType, message); | ||
this.once('obs:internal:message:id-' + messageId, (err, data) => { | ||
this._doCallback(callback, err, data); | ||
if (message.status === 'error') { | ||
debug('[send:reject] %o', message); | ||
this._doCallback(callback, message, null); | ||
reject(message); | ||
if (err) { | ||
debug('[send:reject] %o', err); | ||
reject(err); | ||
} else { | ||
debug('[send:resolve] %o', message); | ||
this._doCallback(callback, null, message); | ||
resolve(message); | ||
debug('[send:resolve] %o', data); | ||
resolve(data); | ||
} | ||
}); | ||
if (!rejectReason) { | ||
args['request-type'] = requestType; | ||
args['message-id'] = messageId; | ||
// Submit the request to the websocket. | ||
debug('[send] %s %s %o', messageId, requestType, args); | ||
try { | ||
this._socket.send(JSON.stringify(args)); | ||
} catch (e) { | ||
// TODO: Consider inspecting the exception thrown to gleam some relevant info and pass that on. | ||
rejectReason = Status.SOCKET_EXCEPTION; | ||
} | ||
} | ||
if (rejectReason) { | ||
this.emit('obs:internal:message:id-' + messageId, rejectReason); | ||
} | ||
}); | ||
@@ -69,0 +70,0 @@ } |
const WebSocket = require('ws'); | ||
const EventEmitter = require('events'); | ||
const AuthHashing = require('./AuthHashing'); | ||
const hash = require('./util/authenticationHashing'); | ||
const Status = require('./Status'); | ||
@@ -12,8 +12,2 @@ const debug = require('debug')('obs-websocket-js:Socket'); | ||
let AUTH = { | ||
required: true, | ||
salt: undefined, | ||
challenge: undefined | ||
}; | ||
function camelCaseKeys(obj) { | ||
@@ -43,3 +37,4 @@ obj = obj || {}; | ||
this.emit = function () { | ||
debug('[emit] %s %o', arguments[0], arguments[1]); | ||
// Log every emit to debug. Could be a bit noisy. | ||
debug('[emit] %s err: %o data: %o', arguments[0], arguments[1], arguments[2]); | ||
originalEmit.apply(this, arguments); | ||
@@ -80,11 +75,22 @@ }; | ||
this._socket.onmessage = msg => { | ||
debug('[OnMessage]: %o', msg); | ||
const data = camelCaseKeys(JSON.parse(msg.data)); | ||
// eslint-disable-next-line capitalized-comments | ||
// debug('[OnMessage]: %o', msg); | ||
const message = camelCaseKeys(JSON.parse(msg.data)); | ||
let err; | ||
let data; | ||
// Emit the message with ID if available, otherwise default to a non-messageId driven event. | ||
if (data.messageId) { | ||
this.emit('obs:internal:message:id-' + data.messageId, data); | ||
if (message.status === 'error') { | ||
err = message; | ||
} else { | ||
this.emit('obs:internal:event', data); | ||
data = message; | ||
} | ||
// Emit the message with ID if available, otherwise try to find a non-messageId driven event. | ||
if (message.messageId) { | ||
this.emit('obs:internal:message:id-' + message.messageId, err, data); | ||
} else if (message.updateType) { | ||
this.emit(message.updateType, err, data); | ||
} else { | ||
logAmbiguousError(debug, 'Unrecognized Socket Message:', message); | ||
} | ||
}; | ||
@@ -97,7 +103,7 @@ | ||
debug('Connection closed: %s', address); | ||
this.emit('obs:internal:event', {updateType: 'ConnectionClosed'}); | ||
this.emit('ConnectionClosed'); | ||
}; | ||
debug('Connection opened: %s', address); | ||
this.emit('obs:internal:event', {updateType: 'ConnectionOpened'}); | ||
this.emit('ConnectionOpened'); | ||
this._doCallback(callback); | ||
@@ -161,11 +167,6 @@ } catch (err) { | ||
.then(data => { | ||
AUTH = { | ||
required: data.authRequired, | ||
salt: data.salt, | ||
challenge: data.challenge | ||
}; | ||
// Return early if authentication is not necessary. | ||
if (!AUTH.required) { | ||
this.emit('obs:internal:event', {updateType: 'AuthenticationSuccess'}); | ||
if (!data.authRequired) { | ||
debug('Authentication not Required'); | ||
this.emit('AuthenticationSuccess'); | ||
return Promise.resolve(Status.AUTH_NOT_REQUIRED); | ||
@@ -175,6 +176,6 @@ } | ||
return this.send('Authenticate', { | ||
auth: new AuthHashing(AUTH.salt, AUTH.challenge).hash(password) | ||
auth: hash(data.salt, data.challenge, password) | ||
}).then(() => { | ||
debug('Authentication Success.'); | ||
this.emit('obs:internal:event', {updateType: 'AuthenticationSuccess'}); | ||
this.emit('AuthenticationSuccess'); | ||
}); | ||
@@ -181,0 +182,0 @@ }); |
module.exports = { | ||
NOT_CONNECTED: { | ||
code: 'Not Connected', | ||
status: 'error', | ||
description: 'There is no Socket connection available.', | ||
error: this.description | ||
description: 'There is no Socket connection available.' | ||
}, | ||
SOCKET_EXCEPTION: { | ||
status: 'error', | ||
description: 'An exception occurred from the underlying WebSocket.' | ||
}, | ||
AUTH_NOT_REQUIRED: { | ||
code: 'Auth Not Required', | ||
status: 'ok', | ||
@@ -14,7 +15,21 @@ description: 'Authentication is not required.' | ||
REQUEST_TYPE_NOT_SPECIFIED: { | ||
code: 'Request Type Not Spcecified', | ||
status: 'error', | ||
description: 'A Request Type was not specified.', | ||
error: this.description | ||
description: 'A Request Type was not specified.' | ||
}, | ||
init() { | ||
for (const key in this) { | ||
if ({}.hasOwnProperty.call(this, key)) { | ||
// Assign a value to 'code' identified by the status' key. | ||
this[key].code = key; | ||
// Assign a value to 'error' if one is not already defined. | ||
if (this[key].status === 'error' && !this[key].error) { | ||
this[key].error = this[key].description; | ||
} | ||
} | ||
} | ||
delete this.init; | ||
return this; | ||
} | ||
}; | ||
}.init(); |
{ | ||
"name": "obs-websocket-js", | ||
"version": "0.5.0", | ||
"description": "OBS Websocket API in Javascript", | ||
"version": "0.5.2", | ||
"description": "OBS Websocket API in Javascript, consume @Palakis/obs-websocket", | ||
"main": "index.js", | ||
@@ -9,7 +9,8 @@ "repository": "haganbmj/obs-websocket-js", | ||
"scripts": { | ||
"test": "npm run static && nyc ava", | ||
"report": "nyc report --reporter=html", | ||
"grunt": "grunt", | ||
"build": "grunt", | ||
"watch": "grunt watch", | ||
"test": "npm run static && nyc ava", | ||
"report": "nyc report --reporter=text-lcov", | ||
"node-coveralls": "npm run report | coveralls", | ||
"static": "eslint ." | ||
@@ -27,8 +28,9 @@ }, | ||
"dependencies": { | ||
"debug": "^2.6.4", | ||
"debug": "^2.6.6", | ||
"sha.js": "^2.4.8", | ||
"ws": "^1.1.1" | ||
"ws": "^2.3.1" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.19.1", | ||
"coveralls": "^2.13.1", | ||
"eslint": "^3.19.0", | ||
@@ -40,6 +42,5 @@ "eslint-config-xo-space": "^0.16.0", | ||
"grunt-contrib-concat": "^1.0.1", | ||
"grunt-jsdoc-to-markdown": "^2.0.0", | ||
"grunt-webpack": "^2.0.1", | ||
"load-grunt-tasks": "^3.5.2", | ||
"nyc": "^10.2.0", | ||
"nyc": "^10.3.0", | ||
"webpack": "^2.2.1" | ||
@@ -51,4 +52,4 @@ }, | ||
"homepage": "https://github.com/haganbmj/obs-websocket-js#readme", | ||
"sha": "5380d20831fa2d05c3044e939a2fcb729777ce87", | ||
"timestamp": "2017-04-27 06:21:54+00:00", | ||
"sha": "69b167e90dcea1d7b451f7f4144a0785e6c23730", | ||
"timestamp": "2017-05-03 01:57:14+00:00", | ||
"eslintConfig": { | ||
@@ -55,0 +56,0 @@ "extends": "xo-space/esnext" |
# obs-websocket-js | ||
*OBSWebSocket.JS allows Javascript-based connections to [obs-websocket][link-obswebsocket].* | ||
*OBSWebSocket.JS allows Javascript-based connections to the Open Broadcaster plugin [obs-websocket][link-obswebsocket].* | ||
[![Build Status][badge-build-status]][link-Travis-CI] [![Latest release][badge-release]][link-releases] [![Latest Tag][badge-tag]][link-tags] | ||
[![Build Status][badge-build-status]][link-Travis-CI] | ||
[![Coverage Status][badge-coveralls]][link-Coveralls] | ||
[![Latest Tag][badge-tag]][link-tags] | ||
[![Latest release][badge-release]][link-releases] | ||
![Downloads][badge-npm-downloads] | ||
@@ -10,8 +14,8 @@ ##### [Download][link-download] | [Samples][link-samples] | [Changelog][link-changelog] | ||
## Installation | ||
```sh | ||
npm install obs-websocket-js --save | ||
bower install obs-websocket-js --save | ||
``` | ||
```html | ||
<script type='text/javascript' src='./dist/obs-websocket.js'></script> | ||
``` | ||
@@ -21,4 +25,9 @@ ## Usage | ||
The web distributable exposes a global named `OBSWebSocket`. | ||
In node.js, import the project using the following. | ||
```html | ||
<script type='text/javascript' src='./dist/obs-websocket.js'></script> | ||
``` | ||
In node... | ||
```js | ||
@@ -112,3 +121,4 @@ const OBSWebSocket = require('obs-websocket-js'); | ||
To enable debug logging, set the `DEBUG` environment variable: | ||
```bash | ||
```sh | ||
# Enables debug logging for all modules of osb-websocket-js | ||
@@ -122,3 +132,4 @@ DEBUG=obs-websocket-js:* | ||
If you have multiple libraries or application which use the `DEBUG` environment variable, they can be joined with commas: | ||
```bash | ||
```sh | ||
DEBUG=foo,bar:*,obs-websocket-js:* | ||
@@ -131,3 +142,4 @@ | ||
Browser debugging uses `localStorage` | ||
``` | ||
```js | ||
localStorage.debug = 'obs-websocket-js:*'; | ||
@@ -152,11 +164,14 @@ | ||
[link-obswebsocket]: https://github.com/Palakis/obs-websocket "OBS WebSocket Plugin" | ||
[link-Travis-CI]: https://travis-ci.org/haganbmj/obs-websocket-js "Travis CI" | ||
[badge-build-status]: https://img.shields.io/travis/haganbmj/obs-websocket-js/master.svg?style=flat "Travis Status" | ||
[badge-tag]: https://img.shields.io/github/tag/haganbmj/obs-websocket-js.svg?style=flat "Latest Tag" | ||
[badge-release]: https://img.shields.io/github/release/haganbmj/obs-websocket-js.svg?style=flat "Latest Release" | ||
[badge-coveralls]: https://coveralls.io/repos/github/haganbmj/obs-websocket-js/badge.svg?branch=master "Coveralls Status" | ||
[badge-npm-downloads]: https://img.shields.io/npm/dt/obs-websocket-js.svg "NPM Downloads" | ||
[link-obswebsocket]: https://github.com/Palakis/obs-websocket "OBS WebSocket Plugin" | ||
[link-Travis-CI]: https://travis-ci.org/haganbmj/obs-websocket-js "Travis CI" | ||
[link-Coveralls]: ]https://coveralls.io/github/haganbmj/obs-websocket-js?branch=master "Coveralls" | ||
[link-releases]: https://github.com/haganbmj/obs-websocket-js/releases "obs-websocket-js Releases" | ||
[link-tags]: https://github.com/haganbmj/obs-websocket-js/tags "obs-websocket-js Tags" | ||
[link-download]: https://github.com/haganbmj/obs-websocket-js/blob/gh-pages/dist/obs-websocket.js "Download" | ||
[link-download]: https://raw.githubusercontent.com/haganbmj/obs-websocket-js/gh-pages/dist/obs-websocket.js "Download" | ||
[link-documentation]: https://github.com/haganbmj/obs-websocket-js/blob/gh-pages/DOCUMENTATION.md "Documentation" | ||
@@ -163,0 +178,0 @@ [link-samples]: https://github.com/haganbmj/obs-websocket-js/tree/master/samples "Samples" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
176
133509
16
3675
+ Addedsafe-buffer@5.0.1(transitive)
+ Addedultron@1.1.1(transitive)
+ Addedws@2.3.1(transitive)
- Removedoptions@0.0.6(transitive)
- Removedultron@1.0.2(transitive)
- Removedws@1.1.5(transitive)
Updateddebug@^2.6.6
Updatedws@^2.3.1