diff --git a/.gitignore b/.gitignore
index 301f74a..9497d32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
+# Playground
+/dev.js
+
/node_modules
/npm-debug.log
-/package-lock.json
/benchmark
diff --git a/README.md b/README.md
index 91f4f82..ca5c4a9 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
# Huejay - Philips Hue client for Node.js
@@ -36,6 +36,7 @@ Philips Hue API version supported: **1.19.0**
- [Bridge Discovery](#bridge-discovery)
- [Errors](#errors)
- [Client Usage](#client-usage)
+ - [Remote API](#using-the-remote-api)
- [Users](#users)
- [Bridge](#bridge)
- [Portal](#portal)
@@ -133,6 +134,78 @@ client commands.
The *timeout* option applies to bridge commands. The default value is 15000
milliseconds (or 15 seconds).
+### Using the Remote API
+
+Philips provides a hosted API with an identical interface to that of the local bridge API. Using the Remote API allows for bridges and the devices controlling them to be on seperate networks.
+
+To use it, an OAuth token must be generated first.
+
+After [adding a new Remote Hue API app](https://developers.meethue.com/my-apps/), open
+
+`https://api.meethue.com/oauth2/auth?clientid=&appid=&deviceid=&devicename=&state=&response_type=code`
+
+in your browser to generate an authentication code.
+
+Parameters:
+
+| Parameter | Meaning |
+|-------------|------------------------------------------------------------|
+| client-id | Your app's client ID |
+| app-id | Your app ID |
+| device-id | Anything you want |
+| device-name | Your app's name |
+| state | Anything you want, will be passed back in the redirect URL |
+
+Once a code has been generated, run
+
+```javascript
+const huejay = require('huejay');
+
+(async () => {
+ const token = new huejay.OAuthToken({
+ clientId: 'your-client-id',
+ clientSecret: 'your-client-secret'
+ });
+
+ await token.getByCode('your-auth-code');
+
+ console.log(JSON.stringify(token)) // => your OAuth token
+})();
+```
+
+to generate an OAuth token.
+
+You can then use the OAuth token in future requests like so:
+
+```javascript
+const huejay = require('huejay');
+
+(async () => {
+ const token = new huejay.OAuthToken({
+ clientId: 'your-client-id',
+ clientSecret: 'your-client-secret',
+ accessToken: 'your-access-token',
+ refreshToken: 'your-refresh-token'
+ });
+
+ const client = new huejay.Client({
+ remote: true,
+ oauthToken: token,
+ username: 'your-bridge-username'
+ });
+
+ // Refresh the access token
+ await token.refresh();
+
+ // Turn light `1` on
+ const light = await client.lights.getById(1);
+
+ light.on = true;
+
+ await client.lights.save(light);
+})();
+```
+
### Users
Huejay provides several commands for managing users on Philips Hue bridges.
@@ -413,7 +486,7 @@ client.portal.get()
### Software Update
Occasionally, Philips releases new updates for the bridge, lights, and devices.
-You can use Huejay to facilitate downloading and installation of updates.
+You can use Huejay to facilitate downloading and installation of updates.
#### client.softwareUpdate.get - Get software update details
@@ -1930,7 +2003,7 @@ Get bridge resource limits and timezones.
Retrieve bridge light limits with the command `client.capabilities.lights`.
This command will eventually return an object describe the limits of the bridge
-around the light resource.
+around the light resource.
```js
client.capabilities.lights()
diff --git a/lib/Action/ChangeGroupAction.js b/lib/Action/ChangeGroupAction.js
index 8ef7411..9947f5c 100644
--- a/lib/Action/ChangeGroupAction.js
+++ b/lib/Action/ChangeGroupAction.js
@@ -63,7 +63,7 @@ class ChangeGroupAction extends AbstractAction {
}
if (!!withUsername) {
- address = `/api/${client.username}${address}`;
+ address = `${client.username}${address}`;
}
return {
diff --git a/lib/Action/ChangeLightState.js b/lib/Action/ChangeLightState.js
index 4b639fe..9a25985 100644
--- a/lib/Action/ChangeLightState.js
+++ b/lib/Action/ChangeLightState.js
@@ -62,7 +62,7 @@ class ChangeLightState extends AbstractAction {
}
if (!!withUsername) {
- address = `/api/${client.username}${address}`;
+ address = `${client.username}${address}`;
}
return {
diff --git a/lib/Action/ChangeSensorState.js b/lib/Action/ChangeSensorState.js
index 094ea1a..4313de8 100644
--- a/lib/Action/ChangeSensorState.js
+++ b/lib/Action/ChangeSensorState.js
@@ -46,7 +46,7 @@ class ChangeSensorState extends AbstractAction {
}
if (!!withUsername) {
- address = `/api/${client.username}${address}`;
+ address = `${client.username}${address}`;
}
return {
diff --git a/lib/Client.js b/lib/Client.js
index 23e26b1..ee285c0 100644
--- a/lib/Client.js
+++ b/lib/Client.js
@@ -1,10 +1,14 @@
'use strict';
+const OAuthToken = require('./OAuthToken');
+
const DEFAULT_CONFIG = {
- host: undefined,
- port: 80,
- username: undefined,
- timeout: 15000,
+ host: undefined,
+ port: 80,
+ remote: false,
+ oauthToken: new OAuthToken(),
+ username: undefined,
+ timeout: 15000,
};
/**
@@ -59,6 +63,42 @@ class Client {
this.config.port = Number(port);
}
+ /**
+ * Get remote
+ *
+ * @return {boolean} Remote
+ */
+ get remote() {
+ return this.config.remote;
+ }
+
+ /**
+ * Set remote
+ *
+ * @param {boolean} remote Remote
+ */
+ set remote(remote) {
+ this.config.remote = Boolean(remote);
+ }
+
+ /**
+ * Get OAuthToken
+ *
+ * @return {string} OAuthToken
+ */
+ get oauthToken() {
+ return this.config.oauthToken;
+ }
+
+ /**
+ * Set OAuthToken
+ *
+ * @param {string} oauthToken OAuthToken
+ */
+ set oauthToken(token) {
+ this.config.oauthToken = token;
+ }
+
/**
* Get username
*
@@ -223,7 +263,7 @@ class Client {
/**
* Get capabilities accessor
- *
+ *
* @return {mixed} Capabilities accessor
*/
get capabilities() {
diff --git a/lib/Command/Bridge/EnableLinkButton.js b/lib/Command/Bridge/EnableLinkButton.js
index 6797d42..ba7466c 100644
--- a/lib/Command/Bridge/EnableLinkButton.js
+++ b/lib/Command/Bridge/EnableLinkButton.js
@@ -16,7 +16,7 @@ class EnableLinkButton {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/config`,
+ url: `${client.username}/config`,
data: {
'linkbutton': true
}
diff --git a/lib/Command/Bridge/EnableTouchlink.js b/lib/Command/Bridge/EnableTouchlink.js
index 7318049..1a650b8 100644
--- a/lib/Command/Bridge/EnableTouchlink.js
+++ b/lib/Command/Bridge/EnableTouchlink.js
@@ -16,7 +16,7 @@ class EnableTouchlink {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/config`,
+ url: `${client.username}/config`,
data: {
'touchlink': true
}
diff --git a/lib/Command/Bridge/GetBridge.js b/lib/Command/Bridge/GetBridge.js
index 87a72bc..d90d75e 100644
--- a/lib/Command/Bridge/GetBridge.js
+++ b/lib/Command/Bridge/GetBridge.js
@@ -18,8 +18,8 @@ class GetBridge {
invoke(client) {
let options = {
url: client.username !== undefined
- ? `api/${client.username}/config`
- : 'api/config'
+ ? `${client.username}/config`
+ : 'config'
};
return client.getTransport()
diff --git a/lib/Command/Bridge/IsAuthenticated.js b/lib/Command/Bridge/IsAuthenticated.js
index 954e45f..3a1fb6b 100644
--- a/lib/Command/Bridge/IsAuthenticated.js
+++ b/lib/Command/Bridge/IsAuthenticated.js
@@ -16,7 +16,7 @@ class IsAuthenticated {
invoke(client) {
let options = {
// Time zone retrieval as it requires user and not resource intensive
- url: `api/${client.username}/info/timezones`
+ url: `${client.username}/info/timezones`
};
return client.getTransport()
diff --git a/lib/Command/Bridge/Ping.js b/lib/Command/Bridge/Ping.js
index 3db67d9..4ed5124 100644
--- a/lib/Command/Bridge/Ping.js
+++ b/lib/Command/Bridge/Ping.js
@@ -15,7 +15,7 @@ class Ping {
*/
invoke(client) {
let options = {
- url: 'api/config'
+ url: 'config'
};
return client.getTransport()
diff --git a/lib/Command/Bridge/SaveBridge.js b/lib/Command/Bridge/SaveBridge.js
index 6e24db8..fe4dc8a 100644
--- a/lib/Command/Bridge/SaveBridge.js
+++ b/lib/Command/Bridge/SaveBridge.js
@@ -76,7 +76,7 @@ class SaveBridge {
saveBridgeAttribute(client, attribute, value) {
let options = {
method: 'PUT',
- url: `api/${client.username}/config`,
+ url: `${client.username}/config`,
data: {}
};
diff --git a/lib/Command/Capability/GetGroups.js b/lib/Command/Capability/GetGroups.js
index def535b..452ff37 100644
--- a/lib/Command/Capability/GetGroups.js
+++ b/lib/Command/Capability/GetGroups.js
@@ -15,7 +15,7 @@ class GetGroups {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetLights.js b/lib/Command/Capability/GetLights.js
index f0096a7..7ecbdd8 100644
--- a/lib/Command/Capability/GetLights.js
+++ b/lib/Command/Capability/GetLights.js
@@ -15,7 +15,7 @@ class GetLights {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetResourceLinks.js b/lib/Command/Capability/GetResourceLinks.js
index 76754f1..0be85fa 100644
--- a/lib/Command/Capability/GetResourceLinks.js
+++ b/lib/Command/Capability/GetResourceLinks.js
@@ -15,7 +15,7 @@ class GetResourceLinks {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetRules.js b/lib/Command/Capability/GetRules.js
index 94870a2..f3f81fc 100644
--- a/lib/Command/Capability/GetRules.js
+++ b/lib/Command/Capability/GetRules.js
@@ -15,7 +15,7 @@ class GetRules {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetScenes.js b/lib/Command/Capability/GetScenes.js
index 67e74e5..a032759 100644
--- a/lib/Command/Capability/GetScenes.js
+++ b/lib/Command/Capability/GetScenes.js
@@ -15,7 +15,7 @@ class GetScenes {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetSchedules.js b/lib/Command/Capability/GetSchedules.js
index 3d4c760..6480d33 100644
--- a/lib/Command/Capability/GetSchedules.js
+++ b/lib/Command/Capability/GetSchedules.js
@@ -15,7 +15,7 @@ class GetSchedules {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetSensors.js b/lib/Command/Capability/GetSensors.js
index 38f9b4d..e3a90b8 100644
--- a/lib/Command/Capability/GetSensors.js
+++ b/lib/Command/Capability/GetSensors.js
@@ -15,7 +15,7 @@ class GetSensors {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Capability/GetTimeZones.js b/lib/Command/Capability/GetTimeZones.js
index fee122b..7f13869 100644
--- a/lib/Command/Capability/GetTimeZones.js
+++ b/lib/Command/Capability/GetTimeZones.js
@@ -15,7 +15,7 @@ class GetTimeZones {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/capabilities`,
+ url: `${client.username}/capabilities`,
raw: true
};
diff --git a/lib/Command/Group/CreateGroup.js b/lib/Command/Group/CreateGroup.js
index d2ef001..e8e1e21 100644
--- a/lib/Command/Group/CreateGroup.js
+++ b/lib/Command/Group/CreateGroup.js
@@ -36,7 +36,7 @@ class CreateGroup {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/groups`,
+ url: `${client.username}/groups`,
data: {}
};
diff --git a/lib/Command/Group/DeleteGroup.js b/lib/Command/Group/DeleteGroup.js
index 4ad424b..7d53bf8 100644
--- a/lib/Command/Group/DeleteGroup.js
+++ b/lib/Command/Group/DeleteGroup.js
@@ -25,7 +25,7 @@ class DeleteGroup {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/groups/${this.groupId}`
+ url: `${client.username}/groups/${this.groupId}`
};
return client.getTransport()
diff --git a/lib/Command/Group/GetGroup.js b/lib/Command/Group/GetGroup.js
index 39fd236..2647274 100644
--- a/lib/Command/Group/GetGroup.js
+++ b/lib/Command/Group/GetGroup.js
@@ -26,7 +26,7 @@ class GetGroup {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/groups/${this.groupId}`
+ url: `${client.username}/groups/${this.groupId}`
};
return client.getTransport()
diff --git a/lib/Command/Group/GetGroups.js b/lib/Command/Group/GetGroups.js
index 5c63695..fc517b3 100644
--- a/lib/Command/Group/GetGroups.js
+++ b/lib/Command/Group/GetGroups.js
@@ -17,7 +17,7 @@ class GetGroups {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/groups`
+ url: `${client.username}/groups`
};
return client.getTransport()
diff --git a/lib/Command/Group/SaveGroup.js b/lib/Command/Group/SaveGroup.js
index aa3bc36..aec677f 100644
--- a/lib/Command/Group/SaveGroup.js
+++ b/lib/Command/Group/SaveGroup.js
@@ -34,7 +34,7 @@ class SaveGroup {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/groups/${this.group.id}`,
+ url: `${client.username}/groups/${this.group.id}`,
data: {}
};
diff --git a/lib/Command/Group/SaveGroupAction.js b/lib/Command/Group/SaveGroupAction.js
index ffba11f..ec313cf 100644
--- a/lib/Command/Group/SaveGroupAction.js
+++ b/lib/Command/Group/SaveGroupAction.js
@@ -47,7 +47,7 @@ class SaveGroupAction {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/groups/${this.group.id}/action`,
+ url: `${client.username}/groups/${this.group.id}/action`,
data: {},
multi: true
};
diff --git a/lib/Command/InternetServices/GetInternetServices.js b/lib/Command/InternetServices/GetInternetServices.js
index 340c56a..2708fb0 100644
--- a/lib/Command/InternetServices/GetInternetServices.js
+++ b/lib/Command/InternetServices/GetInternetServices.js
@@ -17,7 +17,7 @@ class GetInternetServices {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/config`
+ url: `${client.username}/config`
};
return client.getTransport()
diff --git a/lib/Command/Light/DeleteLight.js b/lib/Command/Light/DeleteLight.js
index f9e209a..94a5a2c 100644
--- a/lib/Command/Light/DeleteLight.js
+++ b/lib/Command/Light/DeleteLight.js
@@ -25,7 +25,7 @@ class DeleteLight {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/lights/${this.lightId}`
+ url: `${client.username}/lights/${this.lightId}`
};
return client.getTransport()
diff --git a/lib/Command/Light/GetLight.js b/lib/Command/Light/GetLight.js
index 249e43d..80094de 100644
--- a/lib/Command/Light/GetLight.js
+++ b/lib/Command/Light/GetLight.js
@@ -26,7 +26,7 @@ class GetLight {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/lights/${this.lightId}`
+ url: `${client.username}/lights/${this.lightId}`
};
return client.getTransport()
diff --git a/lib/Command/Light/GetLights.js b/lib/Command/Light/GetLights.js
index 339c3ae..9a63570 100644
--- a/lib/Command/Light/GetLights.js
+++ b/lib/Command/Light/GetLights.js
@@ -17,7 +17,7 @@ class GetLights {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/lights`
+ url: `${client.username}/lights`
};
return client.getTransport()
diff --git a/lib/Command/Light/GetNewLights.js b/lib/Command/Light/GetNewLights.js
index 8d75b01..ba5c4b8 100644
--- a/lib/Command/Light/GetNewLights.js
+++ b/lib/Command/Light/GetNewLights.js
@@ -17,7 +17,7 @@ class GetNewLights {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/lights/new`
+ url: `${client.username}/lights/new`
};
return client.getTransport()
diff --git a/lib/Command/Light/SaveLight.js b/lib/Command/Light/SaveLight.js
index f778f24..990fa22 100644
--- a/lib/Command/Light/SaveLight.js
+++ b/lib/Command/Light/SaveLight.js
@@ -66,7 +66,7 @@ class SaveLight {
saveLightAttribute(client, attribute, value) {
let options = {
method: 'PUT',
- url: `api/${client.username}/lights/${this.light.id}`,
+ url: `${client.username}/lights/${this.light.id}`,
data: {}
};
diff --git a/lib/Command/Light/SaveLightState.js b/lib/Command/Light/SaveLightState.js
index b28da89..7fb5273 100644
--- a/lib/Command/Light/SaveLightState.js
+++ b/lib/Command/Light/SaveLightState.js
@@ -46,7 +46,7 @@ class SaveLightState {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/lights/${this.light.id}/state`,
+ url: `${client.username}/lights/${this.light.id}/state`,
data: {},
multi: true
};
diff --git a/lib/Command/Light/StartLightScan.js b/lib/Command/Light/StartLightScan.js
index 036f133..3865176 100644
--- a/lib/Command/Light/StartLightScan.js
+++ b/lib/Command/Light/StartLightScan.js
@@ -16,7 +16,7 @@ class StartLightScan {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/lights`
+ url: `${client.username}/lights`
};
return client.getTransport()
diff --git a/lib/Command/Portal/GetPortal.js b/lib/Command/Portal/GetPortal.js
index fab9b6a..131b3ac 100644
--- a/lib/Command/Portal/GetPortal.js
+++ b/lib/Command/Portal/GetPortal.js
@@ -17,7 +17,7 @@ class GetPortal {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/config`
+ url: `${client.username}/config`
};
return client.getTransport()
diff --git a/lib/Command/ResourceLinks/CreateResourceLink.js b/lib/Command/ResourceLinks/CreateResourceLink.js
index ef82f13..3b2bab6 100644
--- a/lib/Command/ResourceLinks/CreateResourceLink.js
+++ b/lib/Command/ResourceLinks/CreateResourceLink.js
@@ -37,7 +37,7 @@ class CreateResourceLink {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/resourcelinks`,
+ url: `${client.username}/resourcelinks`,
data: {}
};
diff --git a/lib/Command/ResourceLinks/DeleteResourceLink.js b/lib/Command/ResourceLinks/DeleteResourceLink.js
index 2946b22..f628ab2 100644
--- a/lib/Command/ResourceLinks/DeleteResourceLink.js
+++ b/lib/Command/ResourceLinks/DeleteResourceLink.js
@@ -25,7 +25,7 @@ class DeleteResourceLink {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/resourcelinks/${this.resourceLinkId}`
+ url: `${client.username}/resourcelinks/${this.resourceLinkId}`
};
return client.getTransport()
diff --git a/lib/Command/ResourceLinks/GetResourceLink.js b/lib/Command/ResourceLinks/GetResourceLink.js
index de61993..f33184b 100644
--- a/lib/Command/ResourceLinks/GetResourceLink.js
+++ b/lib/Command/ResourceLinks/GetResourceLink.js
@@ -26,7 +26,7 @@ class GetResourceLink {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/resourcelinks/${this.resourceLinkId}`
+ url: `${client.username}/resourcelinks/${this.resourceLinkId}`
};
return client.getTransport()
diff --git a/lib/Command/ResourceLinks/GetResourceLinks.js b/lib/Command/ResourceLinks/GetResourceLinks.js
index b77f014..fc6332e 100644
--- a/lib/Command/ResourceLinks/GetResourceLinks.js
+++ b/lib/Command/ResourceLinks/GetResourceLinks.js
@@ -17,7 +17,7 @@ class GetResourceLinks {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/resourcelinks`
+ url: `${client.username}/resourcelinks`
};
return client.getTransport()
diff --git a/lib/Command/ResourceLinks/SaveResourceLink.js b/lib/Command/ResourceLinks/SaveResourceLink.js
index 31ee87b..358e77c 100644
--- a/lib/Command/ResourceLinks/SaveResourceLink.js
+++ b/lib/Command/ResourceLinks/SaveResourceLink.js
@@ -35,7 +35,7 @@ class SaveResourceLink {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/resourcelinks/${this.resourceLink.id}`,
+ url: `${client.username}/resourcelinks/${this.resourceLink.id}`,
data: {}
};
diff --git a/lib/Command/Rule/CreateRule.js b/lib/Command/Rule/CreateRule.js
index 2974e2e..e04fef5 100644
--- a/lib/Command/Rule/CreateRule.js
+++ b/lib/Command/Rule/CreateRule.js
@@ -36,7 +36,7 @@ class CreateRule {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/rules`,
+ url: `${client.username}/rules`,
data: {}
};
diff --git a/lib/Command/Rule/DeleteRule.js b/lib/Command/Rule/DeleteRule.js
index 391f350..550688b 100644
--- a/lib/Command/Rule/DeleteRule.js
+++ b/lib/Command/Rule/DeleteRule.js
@@ -25,7 +25,7 @@ class DeleteRule {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/rules/${this.ruleId}`
+ url: `${client.username}/rules/${this.ruleId}`
};
return client.getTransport()
diff --git a/lib/Command/Rule/GetRule.js b/lib/Command/Rule/GetRule.js
index 4cb2656..5ee6d3b 100644
--- a/lib/Command/Rule/GetRule.js
+++ b/lib/Command/Rule/GetRule.js
@@ -26,7 +26,7 @@ class GetRule {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/rules/${this.ruleId}`
+ url: `${client.username}/rules/${this.ruleId}`
};
return client.getTransport()
diff --git a/lib/Command/Rule/GetRules.js b/lib/Command/Rule/GetRules.js
index 010f729..51d35c7 100644
--- a/lib/Command/Rule/GetRules.js
+++ b/lib/Command/Rule/GetRules.js
@@ -17,7 +17,7 @@ class GetRules {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/rules`
+ url: `${client.username}/rules`
};
return client.getTransport()
diff --git a/lib/Command/Rule/SaveRule.js b/lib/Command/Rule/SaveRule.js
index 3d78f77..04af5d2 100644
--- a/lib/Command/Rule/SaveRule.js
+++ b/lib/Command/Rule/SaveRule.js
@@ -36,7 +36,7 @@ class SaveRule {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/rules/${this.rule.id}`,
+ url: `${client.username}/rules/${this.rule.id}`,
data: {}
};
diff --git a/lib/Command/Scene/CreateScene.js b/lib/Command/Scene/CreateScene.js
index a124498..e4fc436 100644
--- a/lib/Command/Scene/CreateScene.js
+++ b/lib/Command/Scene/CreateScene.js
@@ -37,7 +37,7 @@ class CreateScene {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/scenes`,
+ url: `${client.username}/scenes`,
data: {}
};
@@ -71,7 +71,7 @@ class CreateScene {
reloadSceneAttributes(client) {
return client.getTransport()
.sendRequest({
- url: `api/${client.username}/scenes/${this.scene.id}`
+ url: `${client.username}/scenes/${this.scene.id}`
})
.then(result => {
this.scene.attributes.replace(
diff --git a/lib/Command/Scene/DeleteScene.js b/lib/Command/Scene/DeleteScene.js
index 4ec44c1..057c248 100644
--- a/lib/Command/Scene/DeleteScene.js
+++ b/lib/Command/Scene/DeleteScene.js
@@ -25,7 +25,7 @@ class DeleteScene {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/scenes/${this.sceneId}`
+ url: `${client.username}/scenes/${this.sceneId}`
};
return client.getTransport()
diff --git a/lib/Command/Scene/GetSceneById.js b/lib/Command/Scene/GetSceneById.js
index c897c67..e1c9bde 100644
--- a/lib/Command/Scene/GetSceneById.js
+++ b/lib/Command/Scene/GetSceneById.js
@@ -26,7 +26,7 @@ class GetSceneById {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/scenes/${this.sceneId}`
+ url: `${client.username}/scenes/${this.sceneId}`
};
return client.getTransport()
diff --git a/lib/Command/Scene/GetScenes.js b/lib/Command/Scene/GetScenes.js
index 2ce0d30..b7dcb0b 100644
--- a/lib/Command/Scene/GetScenes.js
+++ b/lib/Command/Scene/GetScenes.js
@@ -17,7 +17,7 @@ class GetScenes {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/scenes`
+ url: `${client.username}/scenes`
};
return client.getTransport()
diff --git a/lib/Command/Scene/RecallScene.js b/lib/Command/Scene/RecallScene.js
index 1c7014c..e774805 100644
--- a/lib/Command/Scene/RecallScene.js
+++ b/lib/Command/Scene/RecallScene.js
@@ -25,7 +25,7 @@ class RecallScene {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/groups/0/action`,
+ url: `${client.username}/groups/0/action`,
data: {
scene: this.sceneId
}
diff --git a/lib/Command/Scene/SaveScene.js b/lib/Command/Scene/SaveScene.js
index 583f43c..08ea7a9 100644
--- a/lib/Command/Scene/SaveScene.js
+++ b/lib/Command/Scene/SaveScene.js
@@ -38,7 +38,7 @@ class SaveScene {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/scenes/${this.scene.id}`,
+ url: `${client.username}/scenes/${this.scene.id}`,
data: {}
};
@@ -68,7 +68,7 @@ class SaveScene {
reloadSceneAttributes(client) {
return client.getTransport()
.sendRequest({
- url: `api/${client.username}/scenes/${this.scene.id}`
+ url: `${client.username}/scenes/${this.scene.id}`
})
.then(result => {
this.scene.attributes.replace(
diff --git a/lib/Command/Scene/SaveSceneLightState.js b/lib/Command/Scene/SaveSceneLightState.js
index f4bc72d..de87359 100644
--- a/lib/Command/Scene/SaveSceneLightState.js
+++ b/lib/Command/Scene/SaveSceneLightState.js
@@ -65,7 +65,7 @@ class SaveSceneLightState {
saveLightState(client, lightId, state) {
let options = {
method: 'PUT',
- url: `api/${client.username}/scenes/${this.scene.id}/lightstates/${lightId}`,
+ url: `${client.username}/scenes/${this.scene.id}/lightstates/${lightId}`,
data: {}
};
diff --git a/lib/Command/Schedule/CreateSchedule.js b/lib/Command/Schedule/CreateSchedule.js
index a8e0e5d..5c8a065 100644
--- a/lib/Command/Schedule/CreateSchedule.js
+++ b/lib/Command/Schedule/CreateSchedule.js
@@ -38,7 +38,7 @@ class CreateSchedule {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/schedules`,
+ url: `${client.username}/schedules`,
data: {}
};
diff --git a/lib/Command/Schedule/DeleteSchedule.js b/lib/Command/Schedule/DeleteSchedule.js
index 62b5e15..5181802 100644
--- a/lib/Command/Schedule/DeleteSchedule.js
+++ b/lib/Command/Schedule/DeleteSchedule.js
@@ -25,7 +25,7 @@ class DeleteSchedule {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/schedules/${this.scheduleId}`
+ url: `${client.username}/schedules/${this.scheduleId}`
};
return client.getTransport()
diff --git a/lib/Command/Schedule/GetSchedule.js b/lib/Command/Schedule/GetSchedule.js
index 81d6fde..3fc08b6 100644
--- a/lib/Command/Schedule/GetSchedule.js
+++ b/lib/Command/Schedule/GetSchedule.js
@@ -26,7 +26,7 @@ class GetSchedule {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/schedules/${this.scheduleId}`
+ url: `${client.username}/schedules/${this.scheduleId}`
};
return client.getTransport()
diff --git a/lib/Command/Schedule/GetSchedules.js b/lib/Command/Schedule/GetSchedules.js
index 1f9a257..ba45ab7 100644
--- a/lib/Command/Schedule/GetSchedules.js
+++ b/lib/Command/Schedule/GetSchedules.js
@@ -17,7 +17,7 @@ class GetSchedules {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/schedules`
+ url: `${client.username}/schedules`
};
return client.getTransport()
diff --git a/lib/Command/Schedule/SaveSchedule.js b/lib/Command/Schedule/SaveSchedule.js
index c938fde..8c85821 100644
--- a/lib/Command/Schedule/SaveSchedule.js
+++ b/lib/Command/Schedule/SaveSchedule.js
@@ -38,7 +38,7 @@ class SaveSchedule {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/schedules/${this.schedule.id}`,
+ url: `${client.username}/schedules/${this.schedule.id}`,
data: {}
};
diff --git a/lib/Command/Sensor/CreateSensor.js b/lib/Command/Sensor/CreateSensor.js
index 002cce6..db117be 100644
--- a/lib/Command/Sensor/CreateSensor.js
+++ b/lib/Command/Sensor/CreateSensor.js
@@ -38,7 +38,7 @@ class CreateSensor {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/sensors`,
+ url: `${client.username}/sensors`,
data: {
config: this.sensor.config.attributes.getAll(),
state: this.sensor.state.attributes.getAll()
diff --git a/lib/Command/Sensor/DeleteSensor.js b/lib/Command/Sensor/DeleteSensor.js
index 85f4ea5..28a0ec5 100644
--- a/lib/Command/Sensor/DeleteSensor.js
+++ b/lib/Command/Sensor/DeleteSensor.js
@@ -25,7 +25,7 @@ class DeleteSensor {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/sensors/${this.sensorId}`
+ url: `${client.username}/sensors/${this.sensorId}`
};
return client.getTransport()
diff --git a/lib/Command/Sensor/GetNewSensors.js b/lib/Command/Sensor/GetNewSensors.js
index 570ddea..30edfcd 100644
--- a/lib/Command/Sensor/GetNewSensors.js
+++ b/lib/Command/Sensor/GetNewSensors.js
@@ -17,7 +17,7 @@ class GetNewSensors {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/sensors/new`
+ url: `${client.username}/sensors/new`
};
return client.getTransport()
diff --git a/lib/Command/Sensor/GetSensor.js b/lib/Command/Sensor/GetSensor.js
index 6d60058..d6491fb 100644
--- a/lib/Command/Sensor/GetSensor.js
+++ b/lib/Command/Sensor/GetSensor.js
@@ -26,7 +26,7 @@ class GetSensor {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/sensors/${this.sensorId}`
+ url: `${client.username}/sensors/${this.sensorId}`
};
return client.getTransport()
diff --git a/lib/Command/Sensor/GetSensors.js b/lib/Command/Sensor/GetSensors.js
index f608185..d2bdb18 100644
--- a/lib/Command/Sensor/GetSensors.js
+++ b/lib/Command/Sensor/GetSensors.js
@@ -17,7 +17,7 @@ class GetSensors {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/sensors`
+ url: `${client.username}/sensors`
};
return client.getTransport()
diff --git a/lib/Command/Sensor/SaveSensor.js b/lib/Command/Sensor/SaveSensor.js
index f906bf9..8c1880d 100644
--- a/lib/Command/Sensor/SaveSensor.js
+++ b/lib/Command/Sensor/SaveSensor.js
@@ -62,7 +62,7 @@ class SaveSensor {
saveSensorAttribute(client, attribute, value) {
let options = {
method: 'PUT',
- url: `api/${client.username}/sensors/${this.sensor.id}`,
+ url: `${client.username}/sensors/${this.sensor.id}`,
data: {}
};
diff --git a/lib/Command/Sensor/SaveSensorConfig.js b/lib/Command/Sensor/SaveSensorConfig.js
index ddf6224..937a396 100644
--- a/lib/Command/Sensor/SaveSensorConfig.js
+++ b/lib/Command/Sensor/SaveSensorConfig.js
@@ -29,7 +29,7 @@ class SaveSensorConfig {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/sensors/${this.sensor.id}/config`,
+ url: `${client.username}/sensors/${this.sensor.id}/config`,
data: this.sensor.config.attributes.getChanged()
};
diff --git a/lib/Command/Sensor/SaveSensorState.js b/lib/Command/Sensor/SaveSensorState.js
index 9aadea6..b0d5e9d 100644
--- a/lib/Command/Sensor/SaveSensorState.js
+++ b/lib/Command/Sensor/SaveSensorState.js
@@ -29,7 +29,7 @@ class SaveSensorState {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/sensors/${this.sensor.id}/state`,
+ url: `${client.username}/sensors/${this.sensor.id}/state`,
data: this.sensor.state.attributes.getChanged()
};
diff --git a/lib/Command/Sensor/StartSensorScan.js b/lib/Command/Sensor/StartSensorScan.js
index 9e30550..6e10d23 100644
--- a/lib/Command/Sensor/StartSensorScan.js
+++ b/lib/Command/Sensor/StartSensorScan.js
@@ -16,7 +16,7 @@ class StartSensorScan {
invoke(client) {
let options = {
method: 'POST',
- url: `api/${client.username}/sensors`
+ url: `${client.username}/sensors`
};
return client.getTransport()
diff --git a/lib/Command/SoftwareUpdate/CheckForSoftwareUpdates.js b/lib/Command/SoftwareUpdate/CheckForSoftwareUpdates.js
index 37a7628..22d22df 100644
--- a/lib/Command/SoftwareUpdate/CheckForSoftwareUpdates.js
+++ b/lib/Command/SoftwareUpdate/CheckForSoftwareUpdates.js
@@ -16,7 +16,7 @@ class CheckForSoftwareUpdates {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/config`,
+ url: `${client.username}/config`,
data: {
'swupdate': {
'checkforupdate': true
diff --git a/lib/Command/SoftwareUpdate/DisableInstallNotification.js b/lib/Command/SoftwareUpdate/DisableInstallNotification.js
index e3ad24a..7c25096 100644
--- a/lib/Command/SoftwareUpdate/DisableInstallNotification.js
+++ b/lib/Command/SoftwareUpdate/DisableInstallNotification.js
@@ -16,7 +16,7 @@ class DisableInstallNotification {
invoke(client) {
let options = {
method: 'PUT',
- url: `api/${client.username}/config`,
+ url: `${client.username}/config`,
data: {
'swupdate': {
'notify': false
diff --git a/lib/Command/SoftwareUpdate/GetSoftwareUpdate.js b/lib/Command/SoftwareUpdate/GetSoftwareUpdate.js
index b746f9e..ccefc9c 100644
--- a/lib/Command/SoftwareUpdate/GetSoftwareUpdate.js
+++ b/lib/Command/SoftwareUpdate/GetSoftwareUpdate.js
@@ -17,7 +17,7 @@ class GetSoftwareUpdate {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/config`
+ url: `${client.username}/config`
};
return client.getTransport()
diff --git a/lib/Command/SoftwareUpdate/InstallSoftwareUpdates.js b/lib/Command/SoftwareUpdate/InstallSoftwareUpdates.js
index ffc7197..66491e0 100644
--- a/lib/Command/SoftwareUpdate/InstallSoftwareUpdates.js
+++ b/lib/Command/SoftwareUpdate/InstallSoftwareUpdates.js
@@ -16,7 +16,7 @@ class InstallSoftwareUpdates {
invoke(client) {
let options = {
method: 'PUT',
- url : `api/${client.username}/config`,
+ url : `${client.username}/config`,
data: {
'swupdate': {
'updatestate': 3
diff --git a/lib/Command/User/CreateUser.js b/lib/Command/User/CreateUser.js
index bc1aacc..08e44c2 100644
--- a/lib/Command/User/CreateUser.js
+++ b/lib/Command/User/CreateUser.js
@@ -30,7 +30,7 @@ class CreateUser {
invoke(client) {
let options = {
method: 'POST',
- url: 'api',
+ url: '',
data: {
'devicetype': this.user.deviceType
}
diff --git a/lib/Command/User/DeleteUser.js b/lib/Command/User/DeleteUser.js
index 4d7b46a..7c40921 100644
--- a/lib/Command/User/DeleteUser.js
+++ b/lib/Command/User/DeleteUser.js
@@ -25,7 +25,7 @@ class DeleteUser {
invoke(client) {
let options = {
method: 'DELETE',
- url: `api/${client.username}/config/whitelist/${this.username}`
+ url: `${client.username}/config/whitelist/${this.username}`
};
return client.getTransport()
diff --git a/lib/Command/User/GetUser.js b/lib/Command/User/GetUser.js
index 99a1daf..3b08b5c 100644
--- a/lib/Command/User/GetUser.js
+++ b/lib/Command/User/GetUser.js
@@ -27,7 +27,7 @@ class GetUser {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/config`
+ url: `${client.username}/config`
};
return client.getTransport()
diff --git a/lib/Command/User/GetUsers.js b/lib/Command/User/GetUsers.js
index c0fa586..3074125 100644
--- a/lib/Command/User/GetUsers.js
+++ b/lib/Command/User/GetUsers.js
@@ -17,7 +17,7 @@ class GetUsers {
*/
invoke(client) {
let options = {
- url: `api/${client.username}/config`
+ url: `${client.username}/config`
};
return client.getTransport()
diff --git a/lib/Huejay.js b/lib/Huejay.js
index c24b80b..370a6b9 100644
--- a/lib/Huejay.js
+++ b/lib/Huejay.js
@@ -1,8 +1,9 @@
'use strict';
module.exports = {
- version: require('../package.json').version,
- discover: require('./Discovery').discoverBridges,
- Client: require('./Client'),
- Error: require('./Error')
+ version: require('../package.json').version,
+ discover: require('./Discovery').discoverBridges,
+ Client: require('./Client'),
+ OAuthToken: require('./OAuthToken'),
+ Error: require('./Error')
};
diff --git a/lib/OAuthToken.js b/lib/OAuthToken.js
new file mode 100644
index 0000000..a464a34
--- /dev/null
+++ b/lib/OAuthToken.js
@@ -0,0 +1,154 @@
+'use strict';
+
+const axios = require('axios');
+const qs = require('querystring');
+const HuejayError = require('./Error');
+
+const DEFAULT_CONFIG = {
+ clientId: undefined,
+ clientSecret: undefined,
+ accessToken: undefined,
+ refreshToken: undefined,
+ accessTokenExpiryDate: undefined,
+ refreshTokenExpiryDate: undefined
+};
+
+/**
+ * OAuthToken
+ *
+ * Stores an OAuthToken to use when
+ * querying the remote API.
+ */
+class OAuthToken {
+ /**
+ * Constructor
+ *
+ * @param {Object} config Configuration
+ */
+ constructor(config) {
+ this.config = Object.assign({}, DEFAULT_CONFIG, config);
+ }
+
+ _expiresInSecondsToDate(seconds) {
+ return new Date(new Date().getTime() + Number(seconds) * 1000);
+ }
+
+ _setTokenFromResponse(data) {
+ this.accessToken = data.access_token;
+ this.refreshToken = data.refresh_token;
+
+ this.accessTokenExpiryDate = this._expiresInSecondsToDate(data.access_token_expires_in);
+ this.refreshTokenExpiryDate = this._expiresInSecondsToDate(data.refresh_token_expires_in);
+ }
+
+ toJSON() {
+ return this.config;
+ }
+
+ async refresh() {
+ try {
+ const res = await axios.post(
+ 'https://api.meethue.com/oauth2/refresh',
+ qs.stringify({
+ refresh_token: this.config.refreshToken
+ }),
+ {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ auth: {
+ username: this.config.clientId,
+ password: this.config.clientSecret
+ },
+ params: {
+ grant_type: 'refresh_token'
+ }
+ }
+ );
+
+ this._setTokenFromResponse(res.data);
+
+ return this;
+ } catch (error) {
+ throw new HuejayError({
+ message: error.message
+ });
+ }
+ }
+
+ async getByCode(code) {
+ try {
+ const res = await axios.post(
+ 'https://api.meethue.com/oauth2/token', {},
+ {
+ auth: {
+ username: this.config.clientId,
+ password: this.config.clientSecret
+ },
+ params: {
+ grant_type: 'authorization_code',
+ code
+ }
+ }
+ );
+
+ this._setTokenFromResponse(res.data);
+
+ return this;
+ } catch (error) {
+ throw new HuejayError({
+ message: error.message
+ });
+ }
+ }
+
+ get clientId() {
+ return this.config.clientId;
+ }
+
+ set clientId(clientId) {
+ this.config.clientId = String(clientId);
+ }
+
+ get clientSecret() {
+ return this.config.clientSecret;
+ }
+
+ set clientSecret(clientSecret) {
+ this.config.clientSecret = String(clientSecret);
+ }
+
+ get accessToken() {
+ return this.config.accessToken;
+ }
+
+ set accessToken(token) {
+ this.config.accessToken = String(token);
+ }
+
+ get refreshToken() {
+ return this.config.refreshToken;
+ }
+
+ set refreshToken(token) {
+ this.config.refreshToken = String(token);
+ }
+
+ get accessTokenExpiryDate() {
+ return this.config.accessTokenExpiryDate;
+ }
+
+ set accessTokenExpiryDate(date) {
+ this.config.accessTokenExpiryDate = new Date(date);
+ }
+
+ get refreshTokenExpiryDate() {
+ return this.config.refreshTokenExpiryDate;
+ }
+
+ set refreshTokenExpiryDate(date) {
+ this.config.refreshTokenExpiryDate = new Date(date);
+ }
+}
+
+module.exports = OAuthToken;
diff --git a/lib/Transport.js b/lib/Transport.js
index 1d0b568..4e3bfeb 100644
--- a/lib/Transport.js
+++ b/lib/Transport.js
@@ -1,7 +1,6 @@
'use strict';
let axios = require('axios');
-let path = require('path');
let HuejayError = require('./Error');
/**
@@ -25,8 +24,8 @@ class Transport {
* @return {mixed} Axios http client
*/
getHttpClient() {
- let httpClient = axios.create({
- baseURL: `http://${this.client.host}:${this.client.port}/`,
+ const clientOptions = {
+ baseURL: `http://${this.client.host}:${this.client.port}/api/`,
headers: {
'Content-Type': 'application/json'
},
@@ -37,9 +36,16 @@ class Transport {
}
],
responseType: 'json',
- });
+ };
- return httpClient;
+ if (this.client.remote) {
+ clientOptions.baseURL = `https://api.meethue.com/bridge/`;
+
+ // Add authorization header
+ clientOptions.headers.Authorization = `Bearer ${this.client.oauthToken.accessToken}`;
+ }
+
+ return axios.create(clientOptions);
}
/**
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..fc0d588
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1194 @@
+{
+ "name": "huejay",
+ "version": "1.9.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@sinonjs/commons": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz",
+ "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/formatio": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz",
+ "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^3.1.0"
+ }
+ },
+ "@sinonjs/samsam": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz",
+ "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.0.2",
+ "array-from": "^2.1.1",
+ "lodash": "^4.17.11"
+ }
+ },
+ "@sinonjs/text-encoding": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
+ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "dev": true
+ },
+ "ansi-colors": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ }
+ }
+ },
+ "array-from": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
+ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=",
+ "dev": true
+ },
+ "assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true
+ },
+ "axios": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
+ "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
+ "requires": {
+ "follow-redirects": "1.5.10",
+ "is-buffer": "^2.0.2"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chai": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+ "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+ "dev": true,
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "pathval": "^1.1.0",
+ "type-detect": "^4.0.5"
+ }
+ },
+ "chai-as-promised": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
+ "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==",
+ "dev": true,
+ "requires": {
+ "check-error": "^1.0.2"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "es-abstract": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
+ "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "is-callable": "^1.1.4",
+ "is-regex": "^1.0.4",
+ "object-keys": "^1.0.12"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+ "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "flat": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
+ "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "~2.0.3"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+ "dev": true
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "invert-kv": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
+ "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw=="
+ },
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
+ "dev": true
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-symbol": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+ "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "just-extend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz",
+ "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==",
+ "dev": true
+ },
+ "lcid": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ }
+ },
+ "lolex": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz",
+ "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==",
+ "dev": true
+ },
+ "map-age-cleaner": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+ "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+ "dev": true,
+ "requires": {
+ "p-defer": "^1.0.0"
+ }
+ },
+ "mem": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+ "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
+ "dev": true,
+ "requires": {
+ "map-age-cleaner": "^0.1.1",
+ "mimic-fn": "^2.0.0",
+ "p-is-promise": "^2.0.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "mocha": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz",
+ "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "3.2.3",
+ "browser-stdout": "1.3.1",
+ "debug": "3.2.6",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "find-up": "3.0.0",
+ "glob": "7.1.3",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "3.13.1",
+ "log-symbols": "2.2.0",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "ms": "2.1.1",
+ "node-environment-flags": "1.0.5",
+ "object.assign": "4.1.0",
+ "strip-json-comments": "2.0.1",
+ "supports-color": "6.0.0",
+ "which": "1.3.1",
+ "wide-align": "1.1.3",
+ "yargs": "13.2.2",
+ "yargs-parser": "13.0.0",
+ "yargs-unparser": "1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "mockery": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz",
+ "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==",
+ "dev": true
+ },
+ "moment": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "nise": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.1.tgz",
+ "integrity": "sha512-edFWm0fsFG2n318rfEnKlTZTkjlbVOFF9XIA+fj+Ed+Qz1laYW2lobwavWoMzGrYDHH1EpiNJgDfvGnkZztR/g==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/formatio": "^3.2.1",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "lolex": "^4.1.0",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node-environment-flags": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
+ "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==",
+ "dev": true,
+ "requires": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.5.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-locale": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "lcid": "^2.0.0",
+ "mem": "^4.0.0"
+ }
+ },
+ "p-defer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+ "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+ "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+ "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ },
+ "pathval": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+ "dev": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "sinon": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.1.tgz",
+ "integrity": "sha512-7s9buHGHN/jqoy/v4bJgmt0m1XEkCEd/tqdHXumpBp0JSujaT4Ng84JU5wDdK4E85ZMq78NuDe0I3NAqXY8TFg==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.4.0",
+ "@sinonjs/formatio": "^3.2.1",
+ "@sinonjs/samsam": "^3.3.2",
+ "diff": "^3.5.0",
+ "lolex": "^4.2.0",
+ "nise": "^1.5.1",
+ "supports-color": "^5.5.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+ "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
+ "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "os-locale": "^3.1.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
+ "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "yargs-unparser": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz",
+ "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==",
+ "dev": true,
+ "requires": {
+ "flat": "^4.1.0",
+ "lodash": "^4.17.11",
+ "yargs": "^12.0.5"
+ },
+ "dependencies": {
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "12.0.5",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+ "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^3.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1 || ^4.0.0",
+ "yargs-parser": "^11.1.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
+ "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index d97e3fe..146f73b 100644
--- a/package.json
+++ b/package.json
@@ -23,8 +23,9 @@
"test": "mocha"
},
"dependencies": {
- "moment": "^2.24.0",
"axios": "^0.18.0",
+ "moment": "^2.24.0",
+ "querystring": "^0.2.0",
"sprintf-js": "^1.1.2"
},
"devDependencies": {