From a230abb65dd922023fb9c20e237c04664c1efbd1 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Thu, 16 Mar 2017 01:35:16 -0700 Subject: [PATCH] boatload of API docs --- .eslintrc.yml | 17 +- .gitignore | 1 + esdoc.json | 26 +++ package.json | 7 +- src/codes.js | 82 +++++--- src/index.js | 53 ++++- src/nextion.js | 57 +++++- src/protocol.js | 176 +++++++++++++--- src/system.js | 90 ++++++-- src/uart.js | 221 +++++++++++--------- src/util.js | 45 +++- test/.eslintrc.yml | 3 + test/unit/util.spec.js | 13 ++ yarn.lock | 452 +++++++++++++++++++++++++++++++++++++++-- 14 files changed, 1027 insertions(+), 216 deletions(-) create mode 100644 esdoc.json create mode 100644 test/unit/util.spec.js diff --git a/.eslintrc.yml b/.eslintrc.yml index 7d9a553..9a623b0 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,9 +1,16 @@ extends: - - semistandard - - plugin:lodash-fp/recommended +- semistandard +- plugin:lodash-fp/recommended plugins: - - lodash-fp +- lodash-fp rules: strict: - - error - - safe + - error + - safe + valid-jsdoc: error + require-jsdoc: + - error + - require: + FunctionDeclaration: true + MethodDefinition: true + ClassDeclaration: true diff --git a/.gitignore b/.gitignore index 1204254..2f35f86 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ jspm_packages .yarn-integrity dist/ minimal/ +doc/ diff --git a/esdoc.json b/esdoc.json new file mode 100644 index 0000000..ec5f896 --- /dev/null +++ b/esdoc.json @@ -0,0 +1,26 @@ +{ + "source": "./src", + "destination": "./doc", + "experimentalProposal": { + "classProperties": true, + "objectRestSpread": true, + "decorators": true, + "doExpressions": true, + "functionBind": true, + "asyncGenerators": true, + "exportExtensions": true, + "dynamicImport": true + }, + "coverage": false, + "test": { + "type": "mocha", + "source": "./test/unit", + "includes": ["\\.spec\\.js$"] + }, + "plugins": [ + { + "name": "esdoc-node" + } + ], + "unexportIdentifier": true +} diff --git a/package.json b/package.json index 005465f..e9492d9 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,10 @@ "build:watch": "concurrently \"babel --watch --source-maps --out-dir dist src\" \"cross-env BABEL_ENV=production webpack --watch\"", "prepublish": "npm run build", "pretest": "eslint '*.js' test src", - "test": "nyc --require babel-register mocha --require test/harness.js 'test/unit/*.spec.js'", + "test": "nyc -a --include src --require babel-register mocha --require test/harness.js 'test/unit/*.spec.js'", "test:e2e": "mocha --require babel-register --require test/harness.js 'test/e2e/**/*.spec.js'", - "preversion": "npm test" + "preversion": "npm test", + "docs": "esdoc" }, "devDependencies": { "babel-cli": "^6.24.0", @@ -53,6 +54,8 @@ "babili-webpack-plugin": "^0.0.11", "concurrently": "^3.4.0", "cross-env": "^3.2.3", + "esdoc": "^0.5.2", + "esdoc-node": "^1.0.1", "eslint": "^3.17.1", "eslint-config-semistandard": "^8.0.0", "eslint-config-standard": "^7.0.1", diff --git a/src/codes.js b/src/codes.js index aa6873e..503c125 100644 --- a/src/codes.js +++ b/src/codes.js @@ -1,38 +1,54 @@ import _ from 'lodash/fp'; -const executionCodes = { - 0x00: 'invalidInstruction', - 0x01: 'success', - 0x02: 'invalidComponentID', - 0x03: 'invalidPageID', - 0x04: 'invalidPictureID', - 0x05: 'invalidFontID', - 0x11: 'invalidBaudRate', - 0x12: 'invalidCurveControl', - 0x1a: 'invalidVariableName', - 0x1b: 'invalidVariableOperation', - 0x1c: 'assignmentFailure', - 0x1d: 'eepromFailure', - 0x1e: 'invalidParameterQuantity', - 0x1f: 'ioOperationFailure', - 0x20: 'undefinedEscapeCharacter', - 0x23: 'variableNameTooLong' +/** + * Maps of instruction codes, namespaced by type. + * @private + */ +const codes = { + responseCodes: { + 0x00: 'invalidInstruction', + 0x01: 'success', + 0x02: 'invalidComponentID', + 0x03: 'invalidPageID', + 0x04: 'invalidPictureID', + 0x05: 'invalidFontID', + 0x11: 'invalidBaudRate', + 0x12: 'invalidCurveControl', + 0x1a: 'invalidVariableName', + 0x1b: 'invalidVariableOperation', + 0x1c: 'assignmentFailure', + 0x1d: 'eepromFailure', + 0x1e: 'invalidParameterQuantity', + 0x1f: 'ioOperationFailure', + 0x20: 'undefinedEscapeCharacter', + 0x23: 'variableNameTooLong' + }, + eventCodes: { + 0x65: 'touchEvent', + 0x66: 'pageId', + 0x67: 'touchCoordinate', + 0x68: 'touchCoordinateOnWake', + 0x70: 'stringData', + 0x71: 'numericData', + 0x86: 'autoSleep', + 0x87: 'autoWake', + 0x88: 'startup', + 0x89: 'cardUpgrade', + 0xfd: 'transmitFinished', + 0xfe: 'transmitReady' + } }; -const eventCodes = { - 0x65: 'touchEvent', - 0x66: 'pageId', - 0x67: 'touchCoordinate', - 0x68: 'touchCoordinateOnWake', - 0x70: 'stringData', - 0x71: 'numericData', - 0x86: 'autoSleep', - 0x87: 'autoWake', - 0x88: 'startup', - 0x89: 'cardUpgrade', - 0xfd: 'transmitFinished', - 0xfe: 'transmitReady' -}; +/** + * Map of "event" instruction codes + * @private + * @type {Map} + */ +export const eventCodeMap = new Map(_.toPairs(codes.eventCodes)); -export const eventCodeMap = new Map(_.toPairs(eventCodes)); -export const responseCodeMap = new Map(_.toPairs(executionCodes)); +/** + * Map of "response" instruction codes + * @private + * @type {Map} + */ +export const responseCodeMap = new Map(_.toPairs(codes.responseCodes)); diff --git a/src/index.js b/src/index.js index f243f6f..19fdb16 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,38 @@ import {Nextion} from './nextion'; import {NextionProtocol} from './protocol'; import {UART} from './uart'; +/** + * @external {EventEmitter} https://nodejs.org/api/events.html#events_class_eventemitter + */ + +/** + * @external {Duplex} https://nodejs.org/api/stream.html#stream_class_stream_duplex + */ + +/** + * @external {Serialport} https://npmjs.com/package/serialport + */ + +/** + * @external {Buffer} https://nodejs.org/api/buffer.html#buffer_class_buffer + */ + +/** + * Valid options to supply a {@link Nextion} or {@link UART} constructor. + * All options are optional. + * @typedef {Object} NextionOptions + * @property {string} [port] - Name (e.g. "COM3") or path (e.g. "/dev/ttyUSB0") + * @property {number} [baudRate=9600] - Baud rate of Nextion device. + */ + +/** + * Instantiates a Nextion instance and fulfills a Promise + * when it's listening for data. + * @param {UART} uart - UART instance + * @param {NextionOptions} [opts] - Extra options + * @private + * @returns {Promise} New Nextion instance + */ function instantiate (uart, opts) { return new Promise(resolve => { const nextion = new Nextion(uart, opts, () => { @@ -10,12 +42,31 @@ function instantiate (uart, opts) { }); } -Nextion.from = Nextion.create = (port, opts) => UART.from(port, opts) +/** + * Create a Nextion instance. + * @param {string|Object} [port] - Name of port (`COM1`, `/dev/tty.usbserial`, etc.), `Serialport` instance or `Duplex` stream. Omit for autodetection. + * @param {NextionOptions} [opts] - Options + * @returns {Promise} - Nextion instance + */ +Nextion.from = (port, opts) => UART.from(port, opts) .then(instantiate); +Nextion.create = Nextion.from; +/** + * Create a Nextion instance using an existing connected `Serialport` instance or `Duplex` stream. + * @param {string} serialPort - `Serialport` instance, `Duplex` stream, etc. + * @param {NextionOptions} [opts] - Options + * @returns {Promise} - Nextion instance + */ Nextion.fromSerial = (serialPort, opts) => UART.fromSerial(serialPort, opts) .then(instantiate); +/** + * Create a Nextion instance, optionally specifying a port name. + * @param {string} [portName] - Name of port (`COM1`, `/dev/tty.usbserial`, etc.). Omit for autodetection. + * @param {NextionOptions} [opts] - Options + * @returns {Promise} - Nextion instance + */ Nextion.fromPort = (portName, opts) => UART.fromPort(portName, opts) .then(instantiate); diff --git a/src/nextion.js b/src/nextion.js index 76f3e57..3d75d65 100644 --- a/src/nextion.js +++ b/src/nextion.js @@ -3,24 +3,40 @@ import {System} from './system'; import debug_ from 'debug'; import _ from 'lodash/fp'; +/** + * @ignore + */ const debug = debug_('nextion:Nextion'); +/** + * Applies defaults to an object + * @param {NextionOptions} obj - Defaults are applied to this object + * @returns {NextionOptions} Options w/ defaults applied + * @function + * @private + */ const applyDefaults = _.defaults({ // XXX: does nothing yet enhanced: true }); +/** + * High-level abstraction for interacting with a Nextion device. + * @extends {EventEmitter} + */ export class Nextion extends EventEmitter { /** - * - * @param {UART} uart - UART instance (serial port wrapper) + * Begins listening for data via a {@link UART} instance. + * @param {UART} uart - {@link UART} instance * @param {Object|Function} [opts] - Options or `connectListener` * @param {Function} [connectListener] - Callback to run when listening for * Nextion data + * @emits {error} When binding via `uart` fails + * @throws {ReferenceError} When `uart` is missing */ constructor (uart, opts = {}, connectListener = _.noop) { if (!uart) { - throw new Error( + throw new ReferenceError( 'Invalid parameters; Use Nextion.from(), Nextion.fromSerial(), or Nextion.fromPort()'); } @@ -36,7 +52,18 @@ export class Nextion extends EventEmitter { connectListener(); }); + /** + * Options + * @type {Object} + * @private + */ this.opts = applyDefaults(opts); + + /** + * Internal UART instance + * @type {UART} + * @private + */ this.uart = uart; // when a Nextion event occurs, re-emit it with event name @@ -55,25 +82,39 @@ export class Nextion extends EventEmitter { this.emit('error', err); }); + /** + * System-level Nextion commands + * @type {System} + */ this.system = new System(uart); debug('Instantiated'); } /** - * Sets a variable on the current page to a value + * Sets a local or global variable on the current page to a value * @param {string} name - Name of variable - * @param {*} [value] - Value to set variable to - * @returns {Promise.<*>} + * @param {*} [value] - New variable value + * @returns {Promise} Result */ setValue (name, value) { return this.uart.setValue(name, value); } - setComponentValue (componentName, value) { - return this.setVariableValue(`${componentName}.val`, value); + /** + * Sets a the value of a local component + * @param {string} name - Name of component + * @param {*} [value] - New component value + * @returns {Promise} Result + */ + setComponentValue (name, value) { + return this.setVariableValue(`${name}.val`, value); } + /** + * Closes connection to Nextion device. + * @returns {Promise} This instance + */ close () { return this.uart.unbind() .then(() => { diff --git a/src/protocol.js b/src/protocol.js index 7b62f07..4b6efc4 100644 --- a/src/protocol.js +++ b/src/protocol.js @@ -2,12 +2,19 @@ import {createProtocol} from 'bin-protocol'; import {eventCodeMap, responseCodeMap} from './codes'; import _ from 'lodash/fp'; import debug_ from 'debug'; -import {hexStr} from './util'; +import {toHex} from './util'; + +/** + * @ignore + */ const debug = debug_('nextion:protocol'); -const NextionProtocol = createProtocol(function () { +/** + * @ignore + * @todo document + */ +const NextionProtocolClass = createProtocol(function () { // this is mostly here for the convenience of a 3p consumer. - // TODO: document const reset = this.reader.reset; this.reader.reset = function (buf) { if (buf.slice(buf.length - 3) @@ -18,6 +25,28 @@ const NextionProtocol = createProtocol(function () { }; }); +/** + * A [bin-protocol](https://npmjs.com/package/bin-protocol) `Protocol` class + * which decodes Nextion-speak. + * Does not handle response codes! + * @see https://npmjs.com/package/bin-protocol + * @example + * const protocolInstance = new NextionProtocol(); + */ +class NextionProtocol { + /** + * Constructs a {@link NextionProtocol} instance. + */ + constructor () { + return new NextionProtocolClass(); + } +} + +/** + * Namespace of "read" functions which are supported by {@link NextionProtocol}. + * @todo Document the shape of the event data + * @private + */ const readers = { byte (name) { this.UInt8(name); @@ -60,47 +89,136 @@ const readers = { Object.keys(readers) .forEach(name => { - NextionProtocol.define(name, { + NextionProtocolClass.define(name, { read: readers[name] }); }); -export function read (data) { - const code = data.readUInt8(0); - debug('Code:', hexStr(code)); - let name = responseCodeMap.get(String(code)); - if (name) { - return { - name, - codeByte: hexStr(code), - code, - type: 'response' - }; +/** + * Generic response or event from Nextion device. + * @public + * @abstract + * @example + * const result = new Result(0x01); // success + */ +class Result { + /** + * Creates a {@link Result}. + * @param {number} code - Decimal instruction code + */ + constructor (code) { + /** + * Decimal representation of instruction code. + * @type {number} + */ + this.code = code; + } + + /** + * Hexadecimal representation of instruction code. + * @type {string} + */ + get hex () { + return toHex(this.code); + } +} + +/** + * An "event" from a Nextion device. + * @public + */ +class EventResult extends Result { + /** + * Creates an EventResult. + * @param {number} code - Decimal instruction code + * @param {*} [data] - Any other data returned by result + */ + constructor (code, data) { + super(code); + + /** + * Human-readable short name of this event. + * @type {string} + */ + this.name = eventCodeMap.get(String(code)); + + /** + * Any other data returned by result + * @type {*|void} + */ + this.data = data; } - name = eventCodeMap.get(String(code)); - if (name) { - const result = { - name, - codeByte: hexStr(code), - code, - type: 'event' - }; - const reader = nextionProtocol.read(data.slice(1)); - if (_.isFunction(reader[name])) { - result.data = reader[name]().result; +} + +/** + * A response, either success or an error, from a command. + * @public + */ +class ResponseResult extends Result { + /** + * Creates a ResponseResult. + * @param {number} code - Decimal instruction code + */ + constructor (code) { + super(code); + + /** + * Human-readable short name of this response. + * @type {string} + */ + this.name = responseCodeMap.get(String(code)); + } +} + +/** + * Parse an event or response from a Nextion device. + * @param {Buffer} buf - Raw `Buffer` from Nextion device + * @returns {Result} - Parsed result + * @throws {TypeError} When unknown data received from device + * @private + */ +export function read (buf) { + const code = buf.readUInt8(0); + debug('Code:', toHex(code)); + if (responseCodeMap.has(String(code))) { + return new ResponseResult(code); + } + + if (eventCodeMap.has(String(code))) { + const eventResult = new EventResult(code); + const reader = nextionProtocol.read(buf.slice(1)); + if (_.isFunction(reader[eventResult.name])) { + eventResult.data = reader[eventResult.name]().result; } - return result; + return eventResult; } - throw new Error(`Unknown data received: ${data.toString()}`); + + throw new TypeError(`Unknown data received: ${buf.toString()}`); } +/** + * This instance is used internally. + * @type {NextionProtocol} + * @private + */ export const nextionProtocol = new NextionProtocol(); -export {NextionProtocol}; +export {NextionProtocolClass as NextionProtocol}; +/** + * This is the byte delimiter all Nextion data ends with. + * @type {number[]} + * @private + */ export const delimiter = [ 0xff, 0xff, 0xff ]; + +/** + * Buffer wrapper of {@link delimiter}. + * @private + * @type {Buffer} + */ export const delimiterBuffer = Buffer.from(delimiter); diff --git a/src/system.js b/src/system.js index 8e8f302..bc4d39f 100644 --- a/src/system.js +++ b/src/system.js @@ -1,77 +1,123 @@ import _ from 'lodash/fp'; import {EventEmitter} from 'events'; +import {isUnsignedInteger, MAX_INT} from './util'; -const isUnsignedInteger = _.overEvery([ - _.isNumber, - _.isFinite, - _.gte(0) -]); - +/** + * These are the names of the internal system variables. + * @type {string[]} + * @private + */ export const SYSTEM_VARIABLES = [ 'sys0', 'sys1', 'sys2' ]; +/** + * System-level Nextion device functionality. + * @extends {EventEmitter} + */ export class System extends EventEmitter { + /** + * Creates a {@link System} instance. + * @param {UART} uart - UART instance. + */ constructor (uart) { super(); this.uart = uart; } + /** + * Sets value of system variable. + * @param {string} name - Name of system variable; either `sys0`, `sys1`, or + * `sys2`. + * @param {number} value - Must be an unsigned integer less than or equal to + * `4294967295`. + * @returns {Promise} Response or {@link TypeError} + * if invalid `name` or `value` + */ setSystemVariable (name, value) { return Promise.resolve() .then(() => { if (!_.includes(name, SYSTEM_VARIABLES)) { - throw new Error( - `"name" must be one of: ${SYSTEM_VARIABLES.join(', ')}, but found "${name}"`); + throw new TypeError(`"name" must be one of: ${SYSTEM_VARIABLES.join( + ', ')}, but found "${name}"`); } if (!isUnsignedInteger(value)) { - throw new Error('"value" must be an unsigned integer <= 4294967295'); + throw new TypeError( + `"value" must be an unsigned integer <= ${MAX_INT}`); } return this.uart.setValue(name, value); }); } - setRandomRange (min, max) { + /** + * Sets the range of results returned by {@link System#random}. + * @param {number} [min=0] - Unsigned integer; no greater than `max` + * @param {number} [max=4294967295] - Unsigned integer; no less than `min` + * @returns {Promise.} Response or {@link + * TypeError} if invalid `min` or `max` value + */ + setRandomRange (min = 0, max = 1) { return Promise.resolve() .then(() => { if (!isUnsignedInteger(min)) { - throw new Error('"min" must be an unsigned integer <= 4294967295'); + throw new TypeError( + `"min" must be an unsigned integer <= ${MAX_INT}`); } if (!isUnsignedInteger(max)) { - throw new Error('"max" must be an unsigned integer <= 4294967295'); + throw new TypeError( + `"max" must be an unsigned integer <= ${MAX_INT}`); + } + if (min > max) { + throw new TypeError('"min" cannot be greater than "max"'); } return this.uart.request(`ranset ${min},${max}`); }); } + /** + * Gets a random value, optionally setting the allowed range via {@link System#setRandomRange}. + * @param {number} [min=0] - Unsigned integer; no greater than `max` + * @param {number} [max=0] - Unsigned integer; no less than `min` + * @returns {Promise} Result or error if invalid range supplied + */ random (min = 0, max = 0) { return Promise.resolve(() => { - if (max < min) { - throw new Error('"max" cannot be less than "min"'); - } - if (min < 0 || max < 0) { - throw new Error('only positive integers allowed'); - } - if (min > 0 || max > 0) { + if (min || max) { return this.setRandomRange(min, max); } }) .then(() => this.uart.request('rand')); } + /** + * Set sleep timer when not touched. + * @param {number} ms - Sleep after `ms` milliseconds of no touching. Rounded to closest second. + * @returns {Promise.} Result + */ setNoTouchSleepTimer (ms = 0) { return this.uart.setValue('thsp', Math.floor(ms / 1000)); } - sleep () { - return this.uart.setValue('sleep', true); + /** + * Puts Nextion to sleep. + * @see {@link System#wake} + * @param {boolean} [shouldSleep=true] Sleep if `true`; wake if `false`. + * @returns {Promise.} Result + */ + sleep (shouldSleep = true) { + return this.uart.setValue('sleep', shouldSleep); } + /** + * Wakes Nextion from sleep. + * @see {@link System#sleep} + * @returns {Promise.} Result + */ wake () { - return this.uart.setValue('sleep', false); + return this.sleep(false); } } diff --git a/src/uart.js b/src/uart.js index 1885000..4f4bae4 100644 --- a/src/uart.js +++ b/src/uart.js @@ -1,40 +1,63 @@ import {EventEmitter} from 'events'; import Serialport from 'serialport'; import _ from 'lodash/fp'; -import {delimiter, delimiterBuffer, read} from './protocol'; -import debug_ from 'debug'; import pMapSeries from 'p-map-series'; import pify from 'pify'; +import debug_ from 'debug'; + +import {delimiter, delimiterBuffer, read} from './protocol'; +import {isValidPort} from './util'; /** * Factory default baud rate of Nextion is 9600 + * @private * @type {number} */ export const DEFAULT_BAUD_RATE = 9600; /** * This tells the Nextion to return a command result even if command succeeded + * @private * @type {string} */ export const DEFAULT_RETURN_COMMAND_RESULT = 'always'; /** * Timeout in ms we should wait for response from Nextion for various requests + * @private * @type {number} */ export const REQUEST_TIMEOUT = 1000; +/** + * We use this to find a reasonable serial port + * @private + * @type {RegExp} + */ const PORT_GUESS_REGEX = /usb|acm|^com/i; + +/** + * @ignore + */ const txDebug = debug_('nextion:UART:TX'); + +/** + * @ignore + */ const rxDebug = debug_('nextion:UART:RX'); -const debug = debug_('nextion:UART'); -const isValidPort = _.allPass([ - _.isObject, - _.pipe(_.property('on'), _.isFunction), - _.pipe(_.property('write'), _.isFunction) -]); +/** + * @ignore + */ +const debug = debug_('nextion:UART'); +/** + * Applies defaults to an object + * @param {NextionOptions} obj - Defaults are applied to this object + * @returns {NextionOptions} Options w/ defaults applied + * @function + * @private + */ const applyDefaults = _.defaults({ returnCommandResult: DEFAULT_RETURN_COMMAND_RESULT, baudRate: DEFAULT_BAUD_RATE @@ -44,28 +67,22 @@ const applyDefaults = _.defaults({ * Whether or not to expect the Nextion device to return success/failure codes * after each serial command. Defaults to "always". * @typedef {string|boolean|number} ReturnCommandResultValue - */ - -/** - * Options for creating a UART option. Some properties may be ignored if a - * Serialport or similar object has been provided when calling the factory - * functions. - * @typedef {Object} UARTOptions - * @property {ReturnCommandResultValue} returnCommandResult - Value - * @property {string} port - Name (e.g. "COM3") or path (e.g. "/dev/ttyUSB0") - * @property {number} baudRate - Defaults to 9600 - * @property {Function} parser - Serialport parser; defaults to byte delimiter + * @private */ /** * Wraps a SerialPort or similar object; provides convenience methods for * interaction with a Nextion over UART. + * @emits {error} When {@link UART#port} emits `error` or is unexpectedly + * disconnected, or when we receive unknown data from the device. + * @emits {close} When {@link UART#close} successfully completes + * @extends {EventEmitter} */ export class UART extends EventEmitter { /** * Sets some default options - * @param {events.EventEmitter|stream.Duplex} port - Serial port interface - * @param {UARTOptions} [opts={}] - Options + * @param {EventEmitter|Duplex} port - Serial port interface + * @param {NextionOptions} [opts={}] - Options */ constructor (port, opts = {}) { super(); @@ -74,9 +91,26 @@ export class UART extends EventEmitter { throw new TypeError('"port" must be a Serialport-like object'); } + /** + * Options + * @type {NextionOptions} + * @private + */ this.opts = applyDefaults(opts); + + /** + * Internal serial port object + * @type {Serialport|Duplex|*} + * @private + */ this.port = port; + /** + * `true` once we've successfully began listening via {@link UART#bind}. + * @type {boolean} + */ + this.ready = false; + this.on('data', data => { try { const result = read(data); @@ -91,35 +125,28 @@ export class UART extends EventEmitter { } catch (err) { this.emit('error', err); } - }); - - // Is there a better way to do this? - const waitForReadiness = () => { - this.ready = new Promise(resolve => { - this.once('connected', () => { - debug('UART ready!'); - this.once('disconnect', () => { - debug('UART disconnected!'); - waitForReadiness(); - }); - }); - resolve(); + }) + .on('connect', () => { + this.ready = true; + }) + .on('close', () => { + this.ready = false; }); - }; - - waitForReadiness(); } /** * Set variable `variableName` to value `value`. - * Corrects booleans to 0/1. + * Boolean values `true` and `false` become `1` and `0`, respectively. * @param {string} variableName - Name of variable, component, system var, * page, etc. * @param {*} [value] - Will be coerced to a string. - * @returns {Promise<*>} - * @public + * @returns {Promise} Result of setting value, or + * {@link Error} if device is not ready. */ setValue (variableName, value) { + if (!this.ready) { + return Promise.reject(new Error('Device not ready!')); + } return this.ready.then(() => { if (value === true) { value = 1; @@ -131,15 +158,16 @@ export class UART extends EventEmitter { } /** - * Wraps serial port's write() in a Promise + * Wraps port's `write()` in a {@link Promise} * @param {Buffer} data - Data to write - * @returns {Promise} UART instance + * @returns {Promise} UART instance, or {@link TypeError} if + * `data` is not a {@link Buffer}. * @private */ write (data) { return new Promise((resolve, reject) => { if (!Buffer.isBuffer(data)) { - return reject(new Error('Expected Buffer')); + return reject(new TypeError('Expected Buffer')); } txDebug('Writing:', data); this.port.write(data, err => { @@ -164,7 +192,7 @@ export class UART extends EventEmitter { * Sends a raw command; does not wait for response. * @param {string} [command] - Raw ASCII command, or nothing at all * @private - * @returns {Promise} + * @returns {Promise} This UART instance */ send (command = '') { txDebug('Sending:', command); @@ -180,35 +208,37 @@ export class UART extends EventEmitter { /** * Makes a request to a Nextion device, expecting a response. - * @param {Array|string} commands - Command(s) to execute - * @public - * @returns {Promise<*>} Result or array of results + * @param {string[]|string} commands - Command(s) to execute + * @param {number} [timeout=1000] - How long to wait for response (in ms) + * @returns {Promise} Result or array + * of results, or {@link Error} if device is not ready. */ - request (commands = []) { - return this.ready.then(() => { - commands = [].concat(commands); - return pMapSeries(commands, command => { - txDebug('Beginning request'); - return new Promise((resolve, reject) => { - const handler = result => { - rxDebug('Received', result); - clearTimeout(t); - return resolve(result); - }; - - this.once('response', handler); - - const t = setTimeout(() => { + request (commands = [], timeout = REQUEST_TIMEOUT) { + if (!this.ready) { + return Promise.reject(new Error('Device not ready!')); + } + commands = [].concat(commands); + return pMapSeries(commands, command => { + txDebug('Beginning request'); + return new Promise((resolve, reject) => { + const handler = result => { + rxDebug('Received', result); + clearTimeout(t); + return resolve(result); + }; + + this.once('response', handler); + + const t = setTimeout(() => { + this.removeListener('response', handler); + reject(new Error(`Timeout of ${timeout}ms exceeded`)); + }, timeout); + + this.send(command) + .catch(err => { this.removeListener('response', handler); - reject(new Error(`Timeout of ${REQUEST_TIMEOUT}ms exceeded`)); - }, REQUEST_TIMEOUT); - - this.send(command) - .catch(err => { - this.removeListener('response', handler); - reject(err); - }); - }); + reject(err); + }); }); }) .then(results => commands.length === 1 @@ -222,10 +252,9 @@ export class UART extends EventEmitter { * human-readable name will be emitted, along with any extra data, if * present. * Errors bubble up from the serial port object thru the UART instance. - * @param {events.EventEmitter|stream.Duplex} [port] - `Serialport`-like + * @param {EventEmitter|Duplex} [port] - `Serialport`-like * object to listen for data and errors on. Defaults to {@link UART#port}. - * @public - * @returns {Promise} + * @returns {Promise} This UART instance */ bind (port) { port = port || this.port; @@ -266,7 +295,7 @@ export class UART extends EventEmitter { return this.send('sleep=0') .then(() => this.setReturnCommandResult(this.opts.returnCommandResult)) .then(() => { - this.emit('connected'); + this.emit('connect'); return this; }); } @@ -274,11 +303,11 @@ export class UART extends EventEmitter { /** * Tell the Nextion device to wait (default) or not wait for responses when * requests are made. - * @param {string|number|boolean} [value='always'] - false, 0 or "none" to - * disable waiting for responses; true, 1 or "always" to enable waiting for - * responses. + * @param {string|number|boolean} [value='always'] - `false`, `0` or `'none'` + * to disable waiting for responses; `true`, `1` or `'always'` to enable + * waiting for responses. * @private - * @returns {Promise} + * @returns {Promise} This UART instance */ setReturnCommandResult (value = 'always') { let commandValue; @@ -309,8 +338,9 @@ export class UART extends EventEmitter { /** * Stops listening on the serial port, closes it, destroys the reference, * kills a kitten, etc. - * @returns {Promise} - * @public + * Use {@link Nextion#close} instead. + * @returns {Promise} This UART instance + * @private */ unbind () { const port = this.port; @@ -329,12 +359,10 @@ export class UART extends EventEmitter { /** * Given a {@link Serialport}-like object, create a {@link UART} wrapper. - * Returns a `Promise` for consistency. - * @param {events.EventEmitter|stream.Duplex} serialPort - Serial port - * interface - * @param {UARTOptions} [opts={}] - Options - * @public - * @returns {Promise.} + * Synchronous, but returns a {@link Promise} for consistency. + * @param {Serialport|Duplex|*} serialPort - {@link Serialport}-like object + * @param {NextionOptions} [opts={}] - Options + * @returns {Promise} New {@link UART} instance */ static fromSerial (serialPort, opts = {}) { return Promise.resolve(new UART(serialPort, opts)); @@ -342,14 +370,12 @@ export class UART extends EventEmitter { /** * Given a serial port name or path, or object containing one, create a - * `Serialport` instance, open the serial port, then return a `UART` - * instance. - * If no port name is present, we'll try to detect the port. - * @param {string|UARTOptions} [portName] - Serial port name or path, or + * {@link Serialport} instance, open the serial port, then return a {@link + * UART} instance. If no port name is present, we'll try to autodetect the port. + * @param {string|NextionOptions} [portName] - Serial port name or path, or * options - * @param {UARTOptions} [opts={}] - Options - * @public - * @returns {Promise.} + * @param {NextionOptions} [opts={}] - Options + * @returns {Promise} New {@link UART} instance */ static fromPort (portName, opts = {}) { if (_.isObject(portName)) { @@ -386,10 +412,9 @@ export class UART extends EventEmitter { /** * Convenience wrapper of {@link UART.fromPort} and {@link UART.fromSerial}. - * @param {string|events.EventEmitter|stream.Duplex|UARTOptions} [port] - Port - * @param {UARTOptions} [opts] - Options - * @public - * @returns {Promise} + * @param {string|Duplex|Serialport} [port] - Port name or object + * @param {NextionOptions} [opts] - Options + * @returns {Promise} New {@link UART} instance */ static from (port, opts = {}) { return isValidPort(port) diff --git a/src/util.js b/src/util.js index 3b887d7..dad00b3 100644 --- a/src/util.js +++ b/src/util.js @@ -1,5 +1,44 @@ import _ from 'lodash/fp'; -export function hexStr (num) { - return _.padCharsStart('0x0', 4, num.toString(16)); -} +/** + * Largest unsigned integer Nextion can handle (I think) + * @type {number} + * @private + */ +export const MAX_INT = 4294967295; + +/** + * Converts decimal to a string hexadecimal representation beginning with `0x`. + * @param {number} num - Number to convert + * @type {Function} + * @private + * @returns {string} Hexadecimal representation of number + */ +export const toHex = _.pipe(num => num.toString(16), _.padCharsStart('0x0', 4)); + +/** + * Returns `true` if `value` quacks like a {@link Serialport} object. + * @type {Function} + * @param {*} value - Value to test + * @private + * @returns {boolean} Result + */ +export const isValidPort = _.allPass([ + _.isObject, + _.pipe(_.property('on'), _.isFunction), + _.pipe(_.property('write'), _.isFunction), + _.pipe(_.property('drain'), _.isFunction) +]); + +/** + * Returns `true` if unsigned integer and <= 4294967295. + * @param {*} value - Value to test + * @private + * @returns {boolean} Result + */ +export const isUnsignedInteger = _.overEvery([ + _.isNumber, + _.isFinite, + _.gte(0), + _.lte(MAX_INT) +]); diff --git a/test/.eslintrc.yml b/test/.eslintrc.yml index 46572f4..3605016 100644 --- a/test/.eslintrc.yml +++ b/test/.eslintrc.yml @@ -3,3 +3,6 @@ env: globals: sinon: true expect: true +rules: + require-jsdoc: off + valid-jsdoc: off diff --git a/test/unit/util.spec.js b/test/unit/util.spec.js new file mode 100644 index 0000000..7105fa0 --- /dev/null +++ b/test/unit/util.spec.js @@ -0,0 +1,13 @@ +import * as util from '../../src/util'; + +describe('utility methods', function () { + describe('toHex()', function () { + it('should return a hexadecimal representation of a number', function () { + expect(util.toHex(255), 'to be', '0xff'); + }); + + it('should pad the hexadecimal representation', function () { + expect(util.toHex(1), 'to be', '0x01'); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 3c4f844..f27b95f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +abab@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d" + abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -12,6 +16,12 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" +acorn-globals@^1.0.4: + version "1.0.9" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf" + dependencies: + acorn "^2.1.0" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -22,6 +32,10 @@ acorn@4.0.4, acorn@^4.0.3, acorn@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" +acorn@^2.1.0, acorn@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" + acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" @@ -228,7 +242,7 @@ babel-cli@^6.24.0: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: +babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" dependencies: @@ -260,6 +274,17 @@ babel-core@^6.23.1, babel-core@^6.24.0: slash "^1.0.0" source-map "^0.5.0" +babel-generator@6.11.4: + version "6.11.4" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.11.4.tgz#14f6933abb20c62666d27e3b7b9f5b9dc0712a9a" + dependencies: + babel-messages "^6.8.0" + babel-runtime "^6.9.0" + babel-types "^6.10.2" + detect-indent "^3.0.1" + lodash "^4.2.0" + source-map "^0.5.0" + babel-generator@^6.18.0, babel-generator@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" @@ -411,7 +436,7 @@ babel-loader@^6.4.0: mkdirp "^0.5.1" object-assign "^4.0.1" -babel-messages@^6.23.0: +babel-messages@^6.23.0, babel-messages@^6.8.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" dependencies: @@ -839,7 +864,7 @@ babel-register@^6.24.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0: +babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.9.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: @@ -856,6 +881,20 @@ babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0: babylon "^6.11.0" lodash "^4.2.0" +babel-traverse@6.12.0: + version "6.12.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.12.0.tgz#f22f54fa0d6eeb7f63585246bab6e637858f5d94" + dependencies: + babel-code-frame "^6.8.0" + babel-messages "^6.8.0" + babel-runtime "^6.9.0" + babel-types "^6.9.0" + babylon "^6.7.0" + debug "^2.2.0" + globals "^8.3.0" + invariant "^2.2.0" + lodash "^4.2.0" + babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: version "6.23.1" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" @@ -870,7 +909,7 @@ babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-tr invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: +babel-types@^6.10.2, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0, babel-types@^6.9.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" dependencies: @@ -887,7 +926,11 @@ babili-webpack-plugin@^0.0.11: babel-preset-babili "^0.0.12" webpack-sources "^0.1.4" -babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: +babylon@6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" + +babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0, babylon@^6.7.0: version "6.15.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e" @@ -921,6 +964,10 @@ binary-extensions@^1.0.0: version "1.8.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" +bindings@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11" + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -931,6 +978,10 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" @@ -1103,6 +1154,39 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +cheerio@0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.20.0.tgz#5c710f2bab95653272842ba01c6ea61b3545ec35" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "~3.8.1" + lodash "^4.1.0" + optionalDependencies: + jsdom "^7.0.2" + +cheerio@0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.0" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash.assignin "^4.0.9" + lodash.bind "^4.1.4" + lodash.defaults "^4.0.1" + lodash.filter "^4.4.0" + lodash.flatten "^4.2.0" + lodash.foreach "^4.3.0" + lodash.map "^4.4.0" + lodash.merge "^4.4.0" + lodash.pick "^4.2.1" + lodash.reduce "^4.4.0" + lodash.reject "^4.4.0" + lodash.some "^4.4.0" + chokidar@^1.4.3, chokidar@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" @@ -1166,6 +1250,10 @@ color-diff@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/color-diff/-/color-diff-0.1.7.tgz#6db78cd9482a8e459d40821eaf4b503283dcb8e2" +color-logger@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/color-logger/-/color-logger-0.0.3.tgz#d9b22dd1d973e166b18bf313f9f481bba4df2018" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -1309,6 +1397,29 @@ crypto-browserify@^3.11.0: public-encrypt "^4.0.0" randombytes "^2.0.0" +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" + +cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" + +"cssstyle@>= 0.2.29 < 0.3.0": + version "0.2.37" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + dependencies: + cssom "0.3.x" + d@^0.1.1, d@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" @@ -1339,7 +1450,7 @@ debug@2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" -debug@^2.1.1, debug@^2.2.0, debug@^2.6.3: +debug@^2.1.1, debug@^2.2.0, debug@^2.3.2, debug@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" dependencies: @@ -1363,6 +1474,13 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -1390,7 +1508,7 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -detect-indent@3.0.1: +detect-indent@3.0.1, detect-indent@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75" dependencies: @@ -1427,10 +1545,38 @@ doctrine@^1.2.2: esutils "^2.0.2" isarray "^1.0.0" +dom-serializer@0, dom-serializer@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" + dependencies: + domelementtype "~1.1.1" + entities "~1.1.1" + domain-browser@^1.1.1: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" +domelementtype@1, domelementtype@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" + +domelementtype@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" + +domhandler@2.3, domhandler@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" + dependencies: + domelementtype "1" + +domutils@1.5, domutils@1.5.1, domutils@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + dependencies: + dom-serializer "0" + domelementtype "1" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -1472,6 +1618,14 @@ enhanced-resolve@^3.0.0: object-assign "^4.0.1" tapable "^0.2.5" +entities@1.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" + +entities@^1.1.1, entities@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" + errno@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" @@ -1536,10 +1690,25 @@ es6-weak-map@^2.0.1: es6-iterator "2" es6-symbol "3" +escape-html@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@^1.6.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" @@ -1549,6 +1718,26 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +esdoc-node@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esdoc-node/-/esdoc-node-1.0.1.tgz#b300315763ab1bbb89b819b05dff17ea97e7fd06" + +esdoc@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/esdoc/-/esdoc-0.5.2.tgz#cbfd0b20e3d1cacc23c93c328eed987e21ba0067" + dependencies: + babel-generator "6.11.4" + babel-traverse "6.12.0" + babylon "6.14.1" + cheerio "0.22.0" + color-logger "0.0.3" + escape-html "1.0.3" + fs-extra "1.0.0" + ice-cap "0.0.4" + marked "0.3.6" + minimist "1.2.0" + taffydb "2.7.2" + eslint-ast-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-ast-utils/-/eslint-ast-utils-1.0.0.tgz#4acb86a0a018de08492f922a05b05928809472f4" @@ -1627,6 +1816,10 @@ espree@^3.4.0: acorn "4.0.4" acorn-jsx "^3.0.0" +esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -1638,6 +1831,10 @@ esrecurse@^4.1.0: estraverse "~4.1.0" object-assign "^4.0.1" +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1763,6 +1960,10 @@ for-own@^0.1.4: dependencies: for-in "^0.1.5" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + foreground-child@^1.3.3, foreground-child@^1.5.3: version "1.5.6" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" @@ -1788,6 +1989,14 @@ formatio@1.1.1: dependencies: samsam "~1.1" +fs-extra@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + fs-readdir-recursive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" @@ -1820,6 +2029,10 @@ fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + gauge@~2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" @@ -1892,6 +2105,10 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^8.3.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-8.18.0.tgz#93d4a62bdcac38cfafafc47d6b034768cb0ffcb4" + globals@^9.0.0, globals@^9.14.0: version "9.16.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80" @@ -1907,7 +2124,7 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2000,6 +2217,27 @@ hosted-git-info@^2.1.4: version "2.2.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" +htmlparser2@^3.9.1: + version "3.9.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" + dependencies: + domelementtype "^1.3.0" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^2.0.2" + +htmlparser2@~3.8.1: + version "3.8.3" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" + dependencies: + domelementtype "1" + domhandler "2.3" + domutils "1.5" + entities "1.0" + readable-stream "1.1" + http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -2012,6 +2250,13 @@ https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" +ice-cap@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ice-cap/-/ice-cap-0.0.4.tgz#8a6d31ab4cac8d4b56de4fa946df3352561b6e18" + dependencies: + cheerio "0.20.0" + color-logger "0.0.3" + ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" @@ -2020,6 +2265,10 @@ ignore@^3.2.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.4.tgz#4055e03596729a8fabe45a43c100ad5ed815c4e8" +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2200,6 +2449,10 @@ is-windows@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.0.tgz#c61d61020c3ebe99261b781bd3d1622395f547f8" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2287,6 +2540,26 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jsdom@^7.0.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-7.2.2.tgz#40b402770c2bda23469096bee91ab675e3b1fc6e" + dependencies: + abab "^1.0.0" + acorn "^2.4.0" + acorn-globals "^1.0.4" + cssom ">= 0.3.0 < 0.4.0" + cssstyle ">= 0.2.29 < 0.3.0" + escodegen "^1.6.1" + nwmatcher ">= 1.3.7 < 2.0.0" + parse5 "^1.5.1" + request "^2.55.0" + sax "^1.1.4" + symbol-tree ">= 3.1.0 < 4.0.0" + tough-cookie "^2.2.0" + webidl-conversions "^2.0.0" + whatwg-url-compat "~0.6.5" + xml-name-validator ">= 2.0.1 < 3.0.0" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -2325,6 +2598,12 @@ json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -2347,6 +2626,12 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.0.2" +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + optionalDependencies: + graceful-fs "^4.1.9" + lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" @@ -2368,6 +2653,12 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lie@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + dependencies: + immediate "~3.0.5" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -2414,6 +2705,14 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" +lodash.assignin@^4.0.9: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + +lodash.bind@^4.1.4: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" + lodash.create@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" @@ -2422,6 +2721,22 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" +lodash.defaults@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + +lodash.filter@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.foreach@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + lodash.get@^4.3.0, lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -2446,7 +2761,27 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.some@^4.6.0: +lodash.map@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + +lodash.merge@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" + +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + +lodash.reduce@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" + +lodash.reject@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" + +lodash.some@^4.4.0, lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" @@ -2487,6 +2822,10 @@ magicpen@5.10.0: color-diff "0.1.7" supports-color "1.2.0" +marked@0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.6.tgz#b2c6c618fccece4ef86c4fc6cb8a7cbf5aeda8d7" + md5-hex@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" @@ -2563,7 +2902,7 @@ minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.0, minimist@^1.2.0: +minimist@1.2.0, minimist@^1.1.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -2601,7 +2940,7 @@ mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" -nan@^2.3.0: +nan@^2.3.0, nan@^2.4.0: version "2.5.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" @@ -2637,7 +2976,7 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" -node-pre-gyp@^0.6.29: +node-pre-gyp@^0.6.29, node-pre-gyp@^0.6.32: version "0.6.33" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" dependencies: @@ -2679,10 +3018,20 @@ npmlog@^4.0.1: gauge "~2.7.1" set-blocking "~2.0.0" +nth-check@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" + dependencies: + boolbase "~1.0.0" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" +"nwmatcher@>= 1.3.7 < 2.0.0": + version "1.3.9" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.3.9.tgz#8bab486ff7fa3dfd086656bbe8b17116d3692d2a" + nyc@^10.1.2: version "10.1.2" resolved "https://registry.yarnpkg.com/nyc/-/nyc-10.1.2.tgz#ea7acaa20a235210101604f4e7d56d28453b0274" @@ -2723,6 +3072,18 @@ object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@^1.0.10, object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object.assign@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc" + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.0" + object-keys "^1.0.10" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -2753,7 +3114,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -2829,6 +3190,10 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse5@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" + path-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -2990,6 +3355,15 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" +readable-stream@1.1: + version "1.1.13" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.0, readable-stream@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" @@ -3102,7 +3476,7 @@ req-all@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/req-all/-/req-all-0.1.0.tgz#130051e2ace58a02eacbfc9d448577a736a9273a" -request@^2.79.0: +request@^2.55.0, request@^2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: @@ -3201,10 +3575,26 @@ samsam@1.1.2, samsam@~1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" +sax@^1.1.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" +serialport@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/serialport/-/serialport-4.0.7.tgz#421c618a8a612bd40cfa461b4a46154daf2229a5" + dependencies: + bindings "1.2.1" + commander "^2.9.0" + debug "^2.3.2" + lie "^3.1.0" + nan "^2.4.0" + node-pre-gyp "^0.6.32" + object.assign "^4.0.3" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -3296,6 +3686,12 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, sour version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + dependencies: + amdefine ">=0.0.4" + spawn-command@^0.0.2-1: version "0.0.2" resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" @@ -3434,6 +3830,10 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: dependencies: has-flag "^1.0.0" +"symbol-tree@>= 3.1.0 < 4.0.0": + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + table@^3.7.8: version "3.8.3" resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" @@ -3445,6 +3845,10 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" +taffydb@2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.2.tgz#7bf8106a5c1a48251b3e3bc0a0e1732489fd0dc8" + tapable@^0.2.5, tapable@~0.2.5: version "0.2.6" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" @@ -3502,12 +3906,16 @@ to-fast-properties@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" -tough-cookie@~2.3.0: +tough-cookie@^2.2.0, tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" dependencies: punycode "^1.4.1" +tr46@~0.0.1: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + tree-kill@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.1.0.tgz#c963dcf03722892ec59cba569e940b71954d1729" @@ -3650,6 +4058,10 @@ watchpack@^1.2.0: chokidar "^1.4.3" graceful-fs "^4.1.2" +webidl-conversions@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-2.0.1.tgz#3bf8258f7d318c7443c36f2e169402a1a6703506" + webpack-node-externals@^1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.5.4.tgz#ea05ba17108a23e776c35c42e7bb0e86c225be00" @@ -3686,6 +4098,12 @@ webpack@^2.2.1: webpack-sources "^0.1.4" yargs "^6.0.0" +whatwg-url-compat@~0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz#00898111af689bb097541cd5a45ca6c8798445bf" + dependencies: + tr46 "~0.0.1" + which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" @@ -3743,6 +4161,10 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +"xml-name-validator@>= 2.0.1 < 3.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" + xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"