Comparing version 0.3.0 to 0.3.1
@@ -0,1 +1,7 @@ | ||
# Version 0.3.1 - 2017/12/02 | ||
- Create generic connect function to allow users to define their own connectors | ||
- Documentation updates | ||
- Added more WeVibe names | ||
# Version 0.3.0 - 2017/10/29 | ||
@@ -2,0 +8,0 @@ |
{ | ||
"name": "buttplug", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "Javascript library for accessing buttplug servers via node.js or web sockets", | ||
@@ -25,2 +25,3 @@ "repository": { | ||
"build:main": "tsc -p tsconfig.json && yarn build:copy-schema", | ||
"build:doc": "typedoc --options typedoc.json --out doc .", | ||
"tslint": "tslint -c tslint.json \"src/**/*.ts\" \"tests/**/*.ts\"", | ||
@@ -49,7 +50,9 @@ "tslint:fix": "tslint -c tslint.json --fix semicolon,comma,no-var-keyword,ordered-imports \"src/**/*.ts\" \"tests/**/*.ts\"", | ||
"mock-socket": "^7.0.0", | ||
"nyc": "^11.2.1", | ||
"nyc": "^11.3.0", | ||
"trash": "^4.1.0", | ||
"trash-cli": "^1.4.0", | ||
"ts-node": "^3.3.0", | ||
"tslint": "^5.8.0", | ||
"typescript": "^2.5.3", | ||
"typedoc": "^0.9.0", | ||
"typescript": "^2.6.1", | ||
"yarn": "^1.2.1" | ||
@@ -77,4 +80,5 @@ }, | ||
"instrument": true, | ||
"all": true | ||
"all": true, | ||
"cache": false | ||
} | ||
} |
@@ -6,4 +6,4 @@ "use strict"; | ||
import { IButtplugConnector } from "./IButtplugConnector"; | ||
import { ButtplugWebsocketConnector } from "./ButtplugWebsocketConnector"; | ||
import { ButtplugBrowserConnector } from "./ButtplugBrowserConnector"; | ||
import { ButtplugBrowserWebsocketConnector } from "./ButtplugBrowserWebsocketConnector"; | ||
import { ButtplugBrowserServerConnector } from "./ButtplugBrowserServerConnector"; | ||
import * as Messages from "../core/Messages"; | ||
@@ -14,3 +14,3 @@ import { CheckMessage } from "../core/MessageUtils"; | ||
protected _pingTimer: NodeJS.Timer; | ||
private _connector: IButtplugConnector | null = null; | ||
protected _connector: IButtplugConnector | null = null; | ||
private _devices: Map<number, Device> = new Map(); | ||
@@ -27,13 +27,12 @@ private _counter: number = 1; | ||
public ConnectWebsocket = async (aAddress: string) => { | ||
const connector = new ButtplugWebsocketConnector(); | ||
await connector.Connect(aAddress); | ||
this._connector = connector; | ||
this._connector.addListener("message", this.ParseMessages); | ||
await this.InitializeConnection(); | ||
await this.Connect(new ButtplugBrowserWebsocketConnector(aAddress)); | ||
} | ||
public ConnectLocal = async () => { | ||
const connector = new ButtplugBrowserConnector(); | ||
await connector.Connect(); | ||
this._connector = connector; | ||
await this.Connect(new ButtplugBrowserServerConnector()); | ||
} | ||
public Connect = async (aConnector: IButtplugConnector) => { | ||
await aConnector.Connect(); | ||
this._connector = aConnector; | ||
this._connector.addListener("message", this.ParseMessages); | ||
@@ -40,0 +39,0 @@ await this.InitializeConnection(); |
@@ -5,3 +5,3 @@ import { ButtplugMessage } from "../core/Messages"; | ||
export interface IButtplugConnector extends EventEmitter { | ||
Connect: (aUrl: string) => Promise<void>; | ||
Connect: () => Promise<void>; | ||
Disconnect: () => void; | ||
@@ -8,0 +8,0 @@ Send: (aMsg: ButtplugMessage) => void; |
"use strict"; | ||
import * as Messages from "./Messages"; | ||
/** | ||
* Represents an abstract device, capable of taking certain kinds of messages. | ||
*/ | ||
export class Device { | ||
@@ -11,23 +14,32 @@ public static fromMsg(aMsg: Messages.DeviceAdded | Messages.DeviceInfo): Device { | ||
constructor(private _index: number, | ||
private _name: string, | ||
private _allowedMessages: string[]) { | ||
/** | ||
* @param _index Index of the device, as created by the device manager. | ||
* @param _name Name of the device. | ||
* @param _allowedMsgs Buttplug messages the device can receive. | ||
*/ | ||
constructor(private index: number, | ||
private name: string, | ||
private allowedMsgs: string[]) { | ||
} | ||
/** | ||
* Return the name of the device. | ||
*/ | ||
public get Name(): string { | ||
return this._name; | ||
return this.name; | ||
} | ||
/** | ||
* Return the index of the device. | ||
*/ | ||
public get Index(): number { | ||
return this._index; | ||
return this.index; | ||
} | ||
/** | ||
* Return a list of message types the device accepts. | ||
*/ | ||
public get AllowedMessages(): string[] { | ||
return this._allowedMessages; | ||
return this.allowedMsgs; | ||
} | ||
public newMessage(allowedMsg: number): Messages.ButtplugMessage { | ||
const msg = this._allowedMessages[allowedMsg]; | ||
return Messages[msg]; | ||
} | ||
} |
import { EventEmitter } from "events"; | ||
import * as Messages from "./Messages"; | ||
// Log levels must match order and name in Buttplug spec | ||
/** | ||
* Enumeration of log levels for LogMessage message types. Log levels must match | ||
* order and name specified in LogMessage portion of the Buttplug protocol spec. | ||
*/ | ||
export enum LogLevel { | ||
@@ -15,7 +18,21 @@ Off, | ||
/** | ||
* Representation of log messages for the internal logging utility. | ||
*/ | ||
export class LogMessage { | ||
private _timestamp: string; | ||
/** Timestamp for the log message */ | ||
private timestamp: string; | ||
public constructor(private _logMessage: string, | ||
private _logLevel: LogLevel) { | ||
/** Log Message */ | ||
private logMessage: string; | ||
/** Log Level */ | ||
private logLevel: LogLevel; | ||
/** | ||
* @param logMessage Log message. | ||
* @param logLevel: Log severity level. | ||
*/ | ||
public constructor(logMessage: string, | ||
logLevel: LogLevel) { | ||
const a = new Date(); | ||
@@ -25,37 +42,68 @@ const hour = a.getHours(); | ||
const sec = a.getSeconds(); | ||
this._timestamp = `${hour}:${min}:${sec}`; | ||
this.timestamp = `${hour}:${min}:${sec}`; | ||
this.logMessage = logMessage; | ||
this.logLevel = logLevel; | ||
} | ||
/** | ||
* Returns the log message. | ||
*/ | ||
public get Message() { | ||
return this._logMessage; | ||
return this.logMessage; | ||
} | ||
/** | ||
* Returns the log message level. | ||
*/ | ||
public get LogLevel() { | ||
return this._logLevel; | ||
return this.logLevel; | ||
} | ||
/** | ||
* Returns the log message timestamp. | ||
*/ | ||
public get Timestamp() { | ||
return this._timestamp; | ||
return this.timestamp; | ||
} | ||
/** | ||
* Returns a formatted string with timestamp, level, and message. | ||
*/ | ||
public get FormattedMessage() { | ||
return `${LogLevel[this._logLevel]} : ${this._timestamp} : ${this._logMessage}`; | ||
return `${LogLevel[this.logLevel]} : ${this.timestamp} : ${this.logMessage}`; | ||
} | ||
} | ||
/** | ||
* Simple, global logging utility for the Buttplug client and server. Keeps an | ||
* internal static reference to an instance of itself (singleton pattern, | ||
* basically), and allows message logging throughout the module. | ||
*/ | ||
export class ButtplugLogger extends EventEmitter { | ||
protected static _sLogger: ButtplugLogger | null = null; | ||
protected _logMessages: LogMessage[] = []; | ||
protected _shouldTimestamp: boolean = true; | ||
protected _logLimit: number = 1000; | ||
protected _logToConsole: boolean = false; | ||
protected _maximumLogLevel: LogLevel = LogLevel.Off; | ||
/** Singleton instance for the logger */ | ||
protected static sLogger: ButtplugLogger | undefined = undefined; | ||
/** Array of stored log messages */ | ||
protected logMessages: LogMessage[] = []; | ||
/** Size limit of logMessages array */ | ||
protected logLimit: number = 1000; | ||
/** If true, call console.log on all new log messages */ | ||
protected logToConsole: boolean = false; | ||
/** If logToConsole is true, sets maximum log level to log to console */ | ||
protected maximumLogLevel: LogLevel = LogLevel.Off; | ||
/** | ||
* Returns the stored static instance of the logger, creating one if it | ||
* doesn't currently exist. | ||
*/ | ||
public static get Logger(): ButtplugLogger { | ||
if (ButtplugLogger._sLogger === null) { | ||
ButtplugLogger._sLogger = new ButtplugLogger(); | ||
if (ButtplugLogger.sLogger === undefined) { | ||
ButtplugLogger.sLogger = new ButtplugLogger(); | ||
} | ||
return this._sLogger!; | ||
return this.sLogger!; | ||
} | ||
/** | ||
* Constructor. Can only be called internally since we regulate ButtplugLogger | ||
* ownership. | ||
*/ | ||
protected constructor() { | ||
@@ -65,10 +113,21 @@ super(); | ||
public get LogLevel() { | ||
return this._maximumLogLevel; | ||
/** | ||
* Set the maximum log level to output to console. | ||
*/ | ||
public get MaximumLogLevel() { | ||
return this.maximumLogLevel; | ||
} | ||
public set LogLevel(aLogLevel: LogLevel) { | ||
this._maximumLogLevel = aLogLevel; | ||
/** | ||
* Get the maximum log level to output to console. | ||
*/ | ||
public set MaximumLogLevel(aLogLevel: LogLevel) { | ||
this.maximumLogLevel = aLogLevel; | ||
} | ||
/** | ||
* Log a message, then create a Error buttplug message with the log message. | ||
* Used when an operation has errored out and status needs to be both logged | ||
* and returned to the client as an Error Message type. | ||
*/ | ||
public LogAndError(aMsg: string, aErrorClass: Messages.ErrorClass, aMsgId: number): Messages.ButtplugMessage { | ||
@@ -79,6 +138,12 @@ this.Error(aMsg); | ||
/** | ||
* Sets whether log messages are logged to the web console. | ||
*/ | ||
public SetConsoleLogging(aShouldLog: boolean) { | ||
this._logToConsole = aShouldLog; | ||
this.logToConsole = aShouldLog; | ||
} | ||
/** | ||
* Log new message at Fatal level. | ||
*/ | ||
public Fatal(aMsg: string) { | ||
@@ -88,2 +153,5 @@ this.AddLogMessage(aMsg, LogLevel.Fatal); | ||
/** | ||
* Log new message at Error level. | ||
*/ | ||
public Error(aMsg: string) { | ||
@@ -93,2 +161,5 @@ this.AddLogMessage(aMsg, LogLevel.Error); | ||
/** | ||
* Log new message at Warn level. | ||
*/ | ||
public Warn(aMsg: string) { | ||
@@ -98,2 +169,5 @@ this.AddLogMessage(aMsg, LogLevel.Warn); | ||
/** | ||
* Log new message at Info level. | ||
*/ | ||
public Info(aMsg: string) { | ||
@@ -103,2 +177,5 @@ this.AddLogMessage(aMsg, LogLevel.Info); | ||
/** | ||
* Log new message at Debug level. | ||
*/ | ||
public Debug(aMsg: string) { | ||
@@ -108,2 +185,5 @@ this.AddLogMessage(aMsg, LogLevel.Debug); | ||
/** | ||
* Log new message at Trace level. | ||
*/ | ||
public Trace(aMsg: string) { | ||
@@ -113,16 +193,20 @@ this.AddLogMessage(aMsg, LogLevel.Trace); | ||
/** | ||
* Checks to see if message should be logged, and if so, adds message to the | ||
* log buffer. May also print message and emit event. | ||
*/ | ||
protected AddLogMessage(aMsg: string, aLevel: LogLevel) { | ||
if (aLevel > this._maximumLogLevel) { | ||
if (aLevel > this.maximumLogLevel) { | ||
return; | ||
} | ||
if (this._logMessages.length > this._logLimit) { | ||
this._logMessages.shift(); | ||
if (this.logMessages.length > this.logLimit) { | ||
this.logMessages.shift(); | ||
} | ||
const msg = new LogMessage(aMsg, aLevel); | ||
if (this._logToConsole) { | ||
if (this.logToConsole) { | ||
console.log(msg.FormattedMessage); | ||
} | ||
this._logMessages.push(new LogMessage(aMsg, aLevel)); | ||
this.logMessages.push(new LogMessage(aMsg, aLevel)); | ||
this.emit("log", msg); | ||
} | ||
} |
@@ -7,3 +7,4 @@ import { BluetoothDeviceInfo } from "../BluetoothDeviceInfo"; | ||
export class WeVibe extends ButtplugBluetoothDevice { | ||
public static readonly DeviceInfo = new BluetoothDeviceInfo(["4 Plus", "Ditto", "Nova", "Wish", "Pivot", "Verge"], | ||
public static readonly DeviceInfo = new BluetoothDeviceInfo(["4 Plus", "Ditto", "Nova", "Wish", | ||
"Pivot", "Verge", "Cougar"], | ||
["f000bb03-0451-4000-b000-000000000000"], | ||
@@ -10,0 +11,0 @@ { tx: "f000c000-0451-4000-b000-000000000000", |
@@ -9,3 +9,4 @@ import { DeviceAdded } from "../../core/Messages"; | ||
export class WebBluetoothDeviceManager extends EventEmitter implements IDeviceSubtypeManager { | ||
public StartScanning() { | ||
public async StartScanning() { | ||
// Form scanning filters | ||
@@ -24,7 +25,27 @@ const info = BluetoothDevices.GetDeviceInfo(); | ||
(((navigator as any).bluetooth) as Bluetooth).requestDevice(filters).then(async (device) => { | ||
// At some point, we should use navigator.bluetooth.getAvailability() to | ||
// check whether we have a radio to use. However, no browser currently | ||
// implements this. Instead, see if requestDevice throws; | ||
let device: BluetoothDevice; | ||
try { | ||
device = await (((navigator as any).bluetooth) as Bluetooth).requestDevice(filters); | ||
} catch (e) { | ||
this.emit("scanningfinished"); | ||
// This is the only way we have to check whether the user cancelled out of | ||
// the dialog versus bluetooth radio not being available, as both errors | ||
// are thrown as DOMExcpetion. Kill me. | ||
if (e.message.indexOf("User cancelled") !== -1) { | ||
return; | ||
} | ||
throw new Error("Bluetooth scanning interrupted. " + | ||
"Either user cancelled out of dialog, or bluetooth radio is not available. Exception: " + e); | ||
} | ||
try { | ||
await this.OpenDevice(device); | ||
} catch (e) { | ||
this.emit("scanningfinished"); | ||
}).catch(() => this.emit("scanningfinished")); | ||
return true; | ||
throw new Error(`Cannot open device ${device.name}: ${e}`); | ||
} | ||
this.emit("scanningfinished"); | ||
} | ||
@@ -31,0 +52,0 @@ |
@@ -27,3 +27,3 @@ import * as Messages from "../core/Messages"; | ||
super(); | ||
this._logger.LogLevel = LogLevel.Debug; | ||
this._logger.MaximumLogLevel = LogLevel.Debug; | ||
this._logger.SetConsoleLogging(true); | ||
@@ -57,2 +57,4 @@ this._logger.Info(`Starting Buttplug Server: ${this._serverName}`); | ||
case "RequestLog": | ||
// TODO: If requested log level is higher than what we have specified, | ||
// what happens? | ||
const logmsg: Messages.RequestLog = aMessage as Messages.RequestLog; | ||
@@ -59,0 +61,0 @@ if (logmsg.LogLevel === LogLevel[LogLevel.Off]) { |
@@ -46,3 +46,7 @@ import * as Messages from "../core/Messages"; | ||
if (!manager.IsScanning()) { | ||
manager.StartScanning(); | ||
try { | ||
await manager.StartScanning(); | ||
} catch (e) { | ||
return new Messages.Error((e as Error).message, Messages.ErrorClass.ERROR_DEVICE, id); | ||
} | ||
} | ||
@@ -49,0 +53,0 @@ } |
{ | ||
"compilerOptions" : { | ||
"lib": ["ES2015", "dom"], | ||
"lib": ["es2015", "dom"], | ||
"target": "es5", | ||
@@ -5,0 +5,0 @@ "module": "commonjs", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
192765
18
49
2254
1
1