From 2387e8ad33180b6fd96b70c52c95ef094810ccc6 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 08:09:20 -0500 Subject: [PATCH 01/14] minor syntax fix --- main.js | 4 ++-- test/server.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/main.js b/main.js index e760e1a..9e3377e 100755 --- a/main.js +++ b/main.js @@ -29,9 +29,9 @@ function collect(val, memo) { const defaultCacheModule = config.get("Cache.defaultModule"); const processorOptions = config.get("Cache.options.processor"); -if(Array.isArray(processorOptions.putWhitelist) && processorOptions.putWhitelist.length){ +if(Array.isArray(processorOptions.putWhitelist) && processorOptions.putWhitelist.length) { helpers.log(consts.LOG_INFO, `PUT whitelist: ${processorOptions.putWhitelist}`); -}; +} program.description("Unity Cache Server") .version(VERSION) diff --git a/test/server.js b/test/server.js index f2e7672..d792c4f 100644 --- a/test/server.js +++ b/test/server.js @@ -72,8 +72,8 @@ describe("Server common", function() { const ipv6Server = new CacheServer(cache, {port: 0, allowIpv6: true}); before(function () { - var interfaces = os.networkInterfaces(); - var ipv6Available = false; + const interfaces = os.networkInterfaces(); + let ipv6Available = false; Object.keys(interfaces).forEach(function (interfaceName){ interfaces[interfaceName].forEach(function (address){ if(address.family === "IPv6"){ @@ -95,7 +95,7 @@ describe("Server common", function() { }); it("should bind to ipv6 when allowed", function(done) { - var serverAddress = ipv6Server._server.address(); + const serverAddress = ipv6Server._server.address(); assert.strictEqual(serverAddress.family, "IPv6"); done(); }); @@ -113,7 +113,7 @@ describe("Server common", function() { }); it("should bind to ipv4 when ipv6 not allowed", function(done) { - var serverAddress = ipv4Server._server.address(); + const serverAddress = ipv4Server._server.address(); assert.strictEqual(serverAddress.family, "IPv4"); done(); }); From 247c77a7ba22248bb00dad7d5ea2dfcbe6b556a3 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 08:15:50 -0500 Subject: [PATCH 02/14] Updated .gitignore rules --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3010568..68baad0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ node_modules/ coverage/ local-production.yml .cache*/ +Dockerfile* +.dockerignore \ No newline at end of file From 50887a926fe531dc886a2d684bf90b10205a20e7 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 08:10:20 -0500 Subject: [PATCH 03/14] Skip DNS resolution if addresses are already in IP format --- lib/helpers.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/helpers.js b/lib/helpers.js index ceb06d9..d660a15 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -3,6 +3,7 @@ const consts = require("./constants"); const dns = require('dns'); const path = require('path'); const fs = require('fs-extra'); +const ip = require('ip'); let logLevel = consts.LOG_TEST; @@ -94,10 +95,14 @@ exports.isBuffer = function(obj) { exports.parseAndValidateAddressString = function(address, defaultPort) { // eslint-disable-next-line prefer-const let [host, port] = address.split(':'); + port = port || defaultPort; port = parseInt(port); if(!port) port = defaultPort; + if(ip.isV4Format(address) || ip.isV6Format(address)) + return Promise.resolve({ host: address, port: port }); + return new Promise((resolve, reject) => { dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, address) => { if(err) return reject(err); From 554ef626df26aee6a8b3e4f837e72cf4d3c86468 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 08:13:21 -0500 Subject: [PATCH 04/14] Fix variable naming and incorrect variable references --- lib/helpers.js | 8 ++++---- lib/server/transaction_mirror.js | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/helpers.js b/lib/helpers.js index d660a15..5b7b762 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -100,13 +100,13 @@ exports.parseAndValidateAddressString = function(address, defaultPort) { port = parseInt(port); if(!port) port = defaultPort; - if(ip.isV4Format(address) || ip.isV6Format(address)) - return Promise.resolve({ host: address, port: port }); + if(ip.isV4Format(host) || ip.isV6Format(host)) + return Promise.resolve({ host: host, port: port }); return new Promise((resolve, reject) => { - dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, address) => { + dns.lookup(host, {family: 4, hints: dns.ADDRCONFIG}, (err, ip) => { if(err) return reject(err); - resolve({ host: address, port: port }); + resolve({ host: ip, port: port }); }); }); }; diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js index 7fa10b0..2fd4c0b 100644 --- a/lib/server/transaction_mirror.js +++ b/lib/server/transaction_mirror.js @@ -23,10 +23,10 @@ class TransactionMirror { this._processing = false; this._queueProcessDelay = TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS; - const address = connectOptions.address; + const host = connectOptions.host; const port = connectOptions.port; const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS; - this._client = new Client(address, port, {idleTimeout: idleTimeout}); + this._client = new Client(host, port, {idleTimeout: idleTimeout}); } static get options() { @@ -38,6 +38,7 @@ class TransactionMirror { } _connect() { + helpers.log(consts.LOG_INFO, `[TransactionMirror] Connecting to ${this._connectOptions.host}:${this._connectOptions.port}`); return this._client.connect(); } From 266c934bb64026ab95ca3cdedc2175bf5d6ecefe Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 08:14:28 -0500 Subject: [PATCH 05/14] Skip mirroring if mirror IP matches source transaction IP --- lib/server/server.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/server/server.js b/lib/server/server.js index 4d2628f..5d6a00d 100644 --- a/lib/server/server.js +++ b/lib/server/server.js @@ -61,12 +61,13 @@ class CacheServer { const cmdProc = new CommandProcessor(self.cache); - // TODO: Prune mirror list to exclude the incoming socket address, to prevent looping transactions const mirrors = self._mirrors; - if(mirrors.length > 0) { cmdProc.on('onTransactionEnd', (trx) => { - mirrors.forEach(m => m.queueTransaction(trx)); + mirrors.forEach(m => { + if(m.address !== socket.remoteAddress) + m.queueTransaction(trx); + }); }); } From 441938819c2f8bb1598b2e1e85e8b3f8258c1dbf Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 10:20:48 -0500 Subject: [PATCH 06/14] Print startup log message for configured transaction mirrors --- lib/server/transaction_mirror.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js index 2fd4c0b..4f3ab58 100644 --- a/lib/server/transaction_mirror.js +++ b/lib/server/transaction_mirror.js @@ -27,6 +27,7 @@ class TransactionMirror { const port = connectOptions.port; const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS; this._client = new Client(host, port, {idleTimeout: idleTimeout}); + helpers.log(consts.LOG_INFO, `[TransactionMirror] Mirroring transactions to ${host}:${port}`); } static get options() { From 0e8d48768dcc7cafd481208ff1672891b6a60e74 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Sun, 16 Sep 2018 15:55:56 -0500 Subject: [PATCH 07/14] Updated node to latest LTS release; updated package dependencies; bumped version to 6.1.2-beta.0 --- .nvmrc | 2 +- package-lock.json | 1218 ++++++++++++++++++++++----------------------- package.json | 4 +- 3 files changed, 612 insertions(+), 612 deletions(-) diff --git a/.nvmrc b/.nvmrc index 41c4217..368fe85 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v8.11.3 +v8.12.0 diff --git a/package-lock.json b/package-lock.json index 0527420..840a102 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "unity-cache-server", - "version": "6.1.1", + "version": "6.1.2-beta.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -19,10 +19,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ansi-styles": { @@ -30,7 +30,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "argparse": { @@ -38,7 +38,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "asn1": { @@ -84,7 +84,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "bluebird": { @@ -99,7 +99,7 @@ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", "dev": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "brace-expansion": { @@ -108,7 +108,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -129,9 +129,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.4.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "cli-cursor": { @@ -139,7 +139,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "requires": { - "restore-cursor": "2.0.0" + "restore-cursor": "^2.0.0" } }, "cli-spinners": { @@ -158,7 +158,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "requires": { - "color-name": "1.1.3" + "color-name": "^1.1.1" } }, "color-name": { @@ -172,7 +172,7 @@ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -191,7 +191,7 @@ "resolved": "https://registry.npmjs.org/config/-/config-1.31.0.tgz", "integrity": "sha512-Ep/l9Rd1J9IPueztJfpbOqVzuKHQh4ZODMNt9xqTYdBBNRXbV4oTu34kCkkfdRVcDq0ohtpaeXGgb+c0LQxFRA==", "requires": { - "json5": "1.0.1" + "json5": "^1.0.1" }, "dependencies": { "json5": { @@ -199,7 +199,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } } } @@ -216,12 +216,12 @@ "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", "dev": true, "requires": { - "growl": "1.10.3", - "js-yaml": "3.12.0", - "lcov-parse": "0.0.10", - "log-driver": "1.2.7", - "minimist": "1.2.0", - "request": "2.85.0" + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.85.0" } }, "cryptiles": { @@ -230,7 +230,7 @@ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", "dev": true, "requires": { - "boom": "5.2.0" + "boom": "5.x.x" }, "dependencies": { "boom": { @@ -239,7 +239,7 @@ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", "dev": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } } } @@ -250,7 +250,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "debug": { @@ -281,7 +281,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "escape-string-regexp": { @@ -335,9 +335,9 @@ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "^2.1.12" } }, "fs-extra": { @@ -345,9 +345,9 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs.realpath": { @@ -362,7 +362,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -371,12 +371,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "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" } }, "graceful-fs": { @@ -402,8 +402,8 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has-flag": { @@ -417,10 +417,10 @@ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", "dev": true, "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" } }, "he": { @@ -441,9 +441,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "inflight": { @@ -452,8 +452,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -490,8 +490,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { @@ -524,7 +524,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsprim": { @@ -573,7 +573,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "requires": { - "chalk": "2.4.1" + "chalk": "^2.0.1" } }, "lokijs": { @@ -599,7 +599,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.33.0" } }, "mimic-fn": { @@ -613,7 +613,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -659,7 +659,7 @@ "dependencies": { "commander": { "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, @@ -700,11 +700,11 @@ "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "just-extend": "1.1.27", - "lolex": "2.4.1", - "path-to-regexp": "1.7.0", - "text-encoding": "0.6.4" + "@sinonjs/formatio": "^2.0.0", + "just-extend": "^1.1.27", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" } }, "nyc": { @@ -713,33 +713,33 @@ "integrity": "sha512-w8OdJAhXL5izerzZMdqzYKMj/pgHJyY3qEPYBjLLxrhcVoHEY9pU5ENIiZyCgG9OR7x3VcUMoD40o6PtVpfR4g==", "dev": true, "requires": { - "archy": "1.0.0", - "arrify": "1.0.1", - "caching-transform": "1.0.1", - "convert-source-map": "1.5.1", - "debug-log": "1.0.1", - "default-require-extensions": "1.0.0", - "find-cache-dir": "0.1.1", - "find-up": "2.1.0", - "foreground-child": "1.5.6", - "glob": "7.1.2", - "istanbul-lib-coverage": "1.2.0", - "istanbul-lib-hook": "1.1.0", - "istanbul-lib-instrument": "1.10.1", - "istanbul-lib-report": "1.1.3", - "istanbul-lib-source-maps": "1.2.3", - "istanbul-reports": "1.4.0", - "md5-hex": "1.3.0", - "merge-source-map": "1.1.0", - "micromatch": "3.1.10", - "mkdirp": "0.5.1", - "resolve-from": "2.0.0", - "rimraf": "2.6.2", - "signal-exit": "3.0.2", - "spawn-wrap": "1.4.2", - "test-exclude": "4.2.1", + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^1.0.0", + "convert-source-map": "^1.5.1", + "debug-log": "^1.0.1", + "default-require-extensions": "^1.0.0", + "find-cache-dir": "^0.1.1", + "find-up": "^2.1.0", + "foreground-child": "^1.5.3", + "glob": "^7.0.6", + "istanbul-lib-coverage": "^1.1.2", + "istanbul-lib-hook": "^1.1.0", + "istanbul-lib-instrument": "^1.10.0", + "istanbul-lib-report": "^1.1.3", + "istanbul-lib-source-maps": "^1.2.3", + "istanbul-reports": "^1.4.0", + "md5-hex": "^1.2.0", + "merge-source-map": "^1.1.0", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.0", + "resolve-from": "^2.0.0", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.1", + "spawn-wrap": "^1.4.2", + "test-exclude": "^4.2.0", "yargs": "11.1.0", - "yargs-parser": "8.1.0" + "yargs-parser": "^8.0.0" }, "dependencies": { "align-text": { @@ -747,9 +747,9 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" } }, "amdefine": { @@ -772,7 +772,7 @@ "bundled": true, "dev": true, "requires": { - "default-require-extensions": "1.0.0" + "default-require-extensions": "^1.0.0" } }, "archy": { @@ -825,9 +825,9 @@ "bundled": true, "dev": true, "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-generator": { @@ -835,14 +835,14 @@ "bundled": true, "dev": true, "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.10", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" } }, "babel-messages": { @@ -850,7 +850,7 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "6.26.0" + "babel-runtime": "^6.22.0" } }, "babel-runtime": { @@ -858,8 +858,8 @@ "bundled": true, "dev": true, "requires": { - "core-js": "2.5.6", - "regenerator-runtime": "0.11.1" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, "babel-template": { @@ -867,11 +867,11 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.10" + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, "babel-traverse": { @@ -879,15 +879,15 @@ "bundled": true, "dev": true, "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.4", - "lodash": "4.17.10" + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" } }, "babel-types": { @@ -895,10 +895,10 @@ "bundled": true, "dev": true, "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.10", - "to-fast-properties": "1.0.3" + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, "babylon": { @@ -916,13 +916,13 @@ "bundled": true, "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -930,7 +930,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -938,7 +938,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -946,7 +946,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -954,9 +954,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -976,7 +976,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -985,16 +985,16 @@ "bundled": true, "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -1002,7 +1002,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -1017,15 +1017,15 @@ "bundled": true, "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "dependencies": { "isobject": { @@ -1040,9 +1040,9 @@ "bundled": true, "dev": true, "requires": { - "md5-hex": "1.3.0", - "mkdirp": "0.5.1", - "write-file-atomic": "1.3.4" + "md5-hex": "^1.2.0", + "mkdirp": "^0.5.1", + "write-file-atomic": "^1.1.4" } }, "camelcase": { @@ -1057,8 +1057,8 @@ "dev": true, "optional": true, "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" } }, "chalk": { @@ -1066,11 +1066,11 @@ "bundled": true, "dev": true, "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "class-utils": { @@ -1078,10 +1078,10 @@ "bundled": true, "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -1089,7 +1089,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "isobject": { @@ -1105,8 +1105,8 @@ "dev": true, "optional": true, "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", + "center-align": "^0.1.1", + "right-align": "^0.1.1", "wordwrap": "0.0.2" }, "dependencies": { @@ -1128,8 +1128,8 @@ "bundled": true, "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "commondir": { @@ -1167,8 +1167,8 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "4.1.3", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "which": "^1.2.9" } }, "debug": { @@ -1199,7 +1199,7 @@ "bundled": true, "dev": true, "requires": { - "strip-bom": "2.0.0" + "strip-bom": "^2.0.0" } }, "define-property": { @@ -1207,8 +1207,8 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -1216,7 +1216,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -1224,7 +1224,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -1232,9 +1232,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -1254,7 +1254,7 @@ "bundled": true, "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, "error-ex": { @@ -1262,7 +1262,7 @@ "bundled": true, "dev": true, "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "escape-string-regexp": { @@ -1280,13 +1280,13 @@ "bundled": true, "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.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" }, "dependencies": { "cross-spawn": { @@ -1294,9 +1294,9 @@ "bundled": true, "dev": true, "requires": { - "lru-cache": "4.1.3", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } } } @@ -1306,13 +1306,13 @@ "bundled": true, "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -1320,7 +1320,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -1328,7 +1328,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -1338,8 +1338,8 @@ "bundled": true, "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -1347,7 +1347,7 @@ "bundled": true, "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -1357,14 +1357,14 @@ "bundled": true, "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -1372,7 +1372,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -1380,7 +1380,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -1388,7 +1388,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -1396,7 +1396,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -1404,9 +1404,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "kind-of": { @@ -1421,10 +1421,10 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -1432,7 +1432,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -1442,9 +1442,9 @@ "bundled": true, "dev": true, "requires": { - "commondir": "1.0.1", - "mkdirp": "0.5.1", - "pkg-dir": "1.0.0" + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" } }, "find-up": { @@ -1452,7 +1452,7 @@ "bundled": true, "dev": true, "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } }, "for-in": { @@ -1465,8 +1465,8 @@ "bundled": true, "dev": true, "requires": { - "cross-spawn": "4.0.2", - "signal-exit": "3.0.2" + "cross-spawn": "^4", + "signal-exit": "^3.0.0" } }, "fragment-cache": { @@ -1474,7 +1474,7 @@ "bundled": true, "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fs.realpath": { @@ -1502,12 +1502,12 @@ "bundled": true, "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "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" } }, "globals": { @@ -1525,10 +1525,10 @@ "bundled": true, "dev": true, "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" }, "dependencies": { "source-map": { @@ -1536,7 +1536,7 @@ "bundled": true, "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -1546,7 +1546,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -1559,9 +1559,9 @@ "bundled": true, "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -1576,8 +1576,8 @@ "bundled": true, "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { "is-number": { @@ -1585,7 +1585,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -1593,7 +1593,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1603,7 +1603,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -1623,8 +1623,8 @@ "bundled": true, "dev": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -1637,7 +1637,7 @@ "bundled": true, "dev": true, "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -1650,7 +1650,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-arrayish": { @@ -1668,7 +1668,7 @@ "bundled": true, "dev": true, "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-data-descriptor": { @@ -1676,7 +1676,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-descriptor": { @@ -1684,9 +1684,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -1706,7 +1706,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -1719,7 +1719,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-odd": { @@ -1727,7 +1727,7 @@ "bundled": true, "dev": true, "requires": { - "is-number": "4.0.0" + "is-number": "^4.0.0" }, "dependencies": { "is-number": { @@ -1742,7 +1742,7 @@ "bundled": true, "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -1792,7 +1792,7 @@ "bundled": true, "dev": true, "requires": { - "append-transform": "0.4.0" + "append-transform": "^0.4.0" } }, "istanbul-lib-instrument": { @@ -1800,13 +1800,13 @@ "bundled": true, "dev": true, "requires": { - "babel-generator": "6.26.1", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.2.0", - "semver": "5.5.0" + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.0", + "semver": "^5.3.0" } }, "istanbul-lib-report": { @@ -1814,10 +1814,10 @@ "bundled": true, "dev": true, "requires": { - "istanbul-lib-coverage": "1.2.0", - "mkdirp": "0.5.1", - "path-parse": "1.0.5", - "supports-color": "3.2.3" + "istanbul-lib-coverage": "^1.1.2", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" }, "dependencies": { "supports-color": { @@ -1825,7 +1825,7 @@ "bundled": true, "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } @@ -1835,11 +1835,11 @@ "bundled": true, "dev": true, "requires": { - "debug": "3.1.0", - "istanbul-lib-coverage": "1.2.0", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "source-map": "0.5.7" + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.1.2", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" }, "dependencies": { "debug": { @@ -1857,7 +1857,7 @@ "bundled": true, "dev": true, "requires": { - "handlebars": "4.0.11" + "handlebars": "^4.0.3" } }, "js-tokens": { @@ -1875,7 +1875,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } }, "lazy-cache": { @@ -1889,7 +1889,7 @@ "bundled": true, "dev": true, "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "load-json-file": { @@ -1897,11 +1897,11 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "locate-path": { @@ -1909,8 +1909,8 @@ "bundled": true, "dev": true, "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "dependencies": { "path-exists": { @@ -1935,7 +1935,7 @@ "bundled": true, "dev": true, "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "lru-cache": { @@ -1943,8 +1943,8 @@ "bundled": true, "dev": true, "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "map-cache": { @@ -1957,7 +1957,7 @@ "bundled": true, "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "md5-hex": { @@ -1965,7 +1965,7 @@ "bundled": true, "dev": true, "requires": { - "md5-o-matic": "0.1.1" + "md5-o-matic": "^0.1.1" } }, "md5-o-matic": { @@ -1978,7 +1978,7 @@ "bundled": true, "dev": true, "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "merge-source-map": { @@ -1986,7 +1986,7 @@ "bundled": true, "dev": true, "requires": { - "source-map": "0.6.1" + "source-map": "^0.6.1" }, "dependencies": { "source-map": { @@ -2001,19 +2001,19 @@ "bundled": true, "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2033,7 +2033,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -2046,8 +2046,8 @@ "bundled": true, "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -2055,7 +2055,7 @@ "bundled": true, "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -2078,18 +2078,18 @@ "bundled": true, "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-odd": "2.0.0", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-odd": "^2.0.0", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "arr-diff": { @@ -2114,10 +2114,10 @@ "bundled": true, "dev": true, "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "npm-run-path": { @@ -2125,7 +2125,7 @@ "bundled": true, "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "number-is-nan": { @@ -2143,9 +2143,9 @@ "bundled": true, "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -2153,7 +2153,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2163,7 +2163,7 @@ "bundled": true, "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" }, "dependencies": { "isobject": { @@ -2178,7 +2178,7 @@ "bundled": true, "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -2193,7 +2193,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "optimist": { @@ -2201,8 +2201,8 @@ "bundled": true, "dev": true, "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" } }, "os-homedir": { @@ -2215,9 +2215,9 @@ "bundled": true, "dev": true, "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" } }, "p-finally": { @@ -2230,7 +2230,7 @@ "bundled": true, "dev": true, "requires": { - "p-try": "1.0.0" + "p-try": "^1.0.0" } }, "p-locate": { @@ -2238,7 +2238,7 @@ "bundled": true, "dev": true, "requires": { - "p-limit": "1.2.0" + "p-limit": "^1.1.0" } }, "p-try": { @@ -2251,7 +2251,7 @@ "bundled": true, "dev": true, "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "pascalcase": { @@ -2264,7 +2264,7 @@ "bundled": true, "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { @@ -2287,9 +2287,9 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "pify": { @@ -2307,7 +2307,7 @@ "bundled": true, "dev": true, "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { @@ -2315,7 +2315,7 @@ "bundled": true, "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" }, "dependencies": { "find-up": { @@ -2323,8 +2323,8 @@ "bundled": true, "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } } } @@ -2344,9 +2344,9 @@ "bundled": true, "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -2354,8 +2354,8 @@ "bundled": true, "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" }, "dependencies": { "find-up": { @@ -2363,8 +2363,8 @@ "bundled": true, "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } } } @@ -2379,8 +2379,8 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "repeat-element": { @@ -2398,7 +2398,7 @@ "bundled": true, "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "require-directory": { @@ -2432,7 +2432,7 @@ "dev": true, "optional": true, "requires": { - "align-text": "0.1.4" + "align-text": "^0.1.1" } }, "rimraf": { @@ -2440,7 +2440,7 @@ "bundled": true, "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" } }, "safe-regex": { @@ -2448,7 +2448,7 @@ "bundled": true, "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "semver": { @@ -2466,10 +2466,10 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2477,7 +2477,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2487,7 +2487,7 @@ "bundled": true, "dev": true, "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -2510,14 +2510,14 @@ "bundled": true, "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.1", - "use": "3.1.0" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { "define-property": { @@ -2525,7 +2525,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2533,7 +2533,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2543,9 +2543,9 @@ "bundled": true, "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -2553,7 +2553,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2561,7 +2561,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2569,7 +2569,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2577,9 +2577,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "isobject": { @@ -2599,7 +2599,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" } }, "source-map": { @@ -2612,11 +2612,11 @@ "bundled": true, "dev": true, "requires": { - "atob": "2.1.1", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.0.0", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-url": { @@ -2629,12 +2629,12 @@ "bundled": true, "dev": true, "requires": { - "foreground-child": "1.5.6", - "mkdirp": "0.5.1", - "os-homedir": "1.0.2", - "rimraf": "2.6.2", - "signal-exit": "3.0.2", - "which": "1.3.0" + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" } }, "spdx-correct": { @@ -2642,8 +2642,8 @@ "bundled": true, "dev": true, "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -2656,8 +2656,8 @@ "bundled": true, "dev": true, "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -2670,7 +2670,7 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "static-extend": { @@ -2678,8 +2678,8 @@ "bundled": true, "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -2687,7 +2687,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2697,8 +2697,8 @@ "bundled": true, "dev": true, "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { "ansi-regex": { @@ -2711,7 +2711,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -2721,7 +2721,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -2729,7 +2729,7 @@ "bundled": true, "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } }, "strip-eof": { @@ -2747,11 +2747,11 @@ "bundled": true, "dev": true, "requires": { - "arrify": "1.0.1", - "micromatch": "3.1.10", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "require-main-filename": "1.0.1" + "arrify": "^1.0.1", + "micromatch": "^3.1.8", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" }, "dependencies": { "arr-diff": { @@ -2769,16 +2769,16 @@ "bundled": true, "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2786,7 +2786,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2796,13 +2796,13 @@ "bundled": true, "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -2810,7 +2810,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -2818,7 +2818,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -2826,7 +2826,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2834,7 +2834,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2844,7 +2844,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2852,7 +2852,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2862,9 +2862,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, "kind-of": { @@ -2879,14 +2879,14 @@ "bundled": true, "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -2894,7 +2894,7 @@ "bundled": true, "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -2902,7 +2902,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2912,10 +2912,10 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -2923,7 +2923,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2933,7 +2933,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2941,7 +2941,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2949,9 +2949,9 @@ "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-number": { @@ -2959,7 +2959,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -2967,7 +2967,7 @@ "bundled": true, "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -2987,19 +2987,19 @@ "bundled": true, "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } } } @@ -3014,7 +3014,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "to-regex": { @@ -3022,10 +3022,10 @@ "bundled": true, "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -3033,8 +3033,8 @@ "bundled": true, "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "dependencies": { "is-number": { @@ -3042,7 +3042,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } } } @@ -3058,9 +3058,9 @@ "dev": true, "optional": true, "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" }, "dependencies": { "yargs": { @@ -3069,9 +3069,9 @@ "dev": true, "optional": true, "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", "window-size": "0.1.0" } } @@ -3088,10 +3088,10 @@ "bundled": true, "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" }, "dependencies": { "extend-shallow": { @@ -3099,7 +3099,7 @@ "bundled": true, "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "set-value": { @@ -3107,10 +3107,10 @@ "bundled": true, "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" } } } @@ -3120,8 +3120,8 @@ "bundled": true, "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -3129,9 +3129,9 @@ "bundled": true, "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -3166,7 +3166,7 @@ "bundled": true, "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.2" }, "dependencies": { "kind-of": { @@ -3181,8 +3181,8 @@ "bundled": true, "dev": true, "requires": { - "spdx-correct": "3.0.0", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "which": { @@ -3190,7 +3190,7 @@ "bundled": true, "dev": true, "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { @@ -3214,8 +3214,8 @@ "bundled": true, "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -3223,7 +3223,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -3231,9 +3231,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -3248,9 +3248,9 @@ "bundled": true, "dev": true, "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" } }, "y18n": { @@ -3268,18 +3268,18 @@ "bundled": true, "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "1.2.0", - "find-up": "2.1.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "9.0.2" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.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", + "yargs-parser": "^9.0.2" }, "dependencies": { "ansi-regex": { @@ -3297,9 +3297,9 @@ "bundled": true, "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" } }, "strip-ansi": { @@ -3307,7 +3307,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "yargs-parser": { @@ -3315,7 +3315,7 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" } } } @@ -3325,7 +3325,7 @@ "bundled": true, "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^4.1.0" }, "dependencies": { "camelcase": { @@ -3349,7 +3349,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -3357,7 +3357,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "ora": { @@ -3365,10 +3365,10 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", "requires": { - "chalk": "2.4.1", - "cli-cursor": "2.1.0", - "cli-spinners": "1.3.1", - "log-symbols": "2.2.0" + "chalk": "^2.1.0", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.0.1", + "log-symbols": "^2.1.0" } }, "os-tmpdir": { @@ -3421,28 +3421,28 @@ "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.7.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" } }, "restore-cursor": { @@ -3450,8 +3450,8 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "safe-buffer": { @@ -3477,13 +3477,13 @@ "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "diff": "3.2.0", - "lodash.get": "4.4.2", - "lolex": "2.4.1", - "nise": "1.3.3", - "supports-color": "5.4.0", - "type-detect": "4.0.8" + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" } }, "sntp": { @@ -3492,7 +3492,7 @@ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", "dev": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "sprintf-js": { @@ -3506,20 +3506,20 @@ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", "dev": true }, "supports-color": { @@ -3527,7 +3527,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "text-encoding": { @@ -3542,7 +3542,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "tmp-promise": { @@ -3551,7 +3551,7 @@ "integrity": "sha512-hOabTz9Tp49wCozFwuJe5ISrOqkECm6kzw66XTP23DuzNU7QS/KiZq5LC9Y7QSy8f1rPSLy4bKaViP0OwGI1cA==", "dev": true, "requires": { - "bluebird": "3.5.1", + "bluebird": "^3.5.0", "tmp": "0.0.33" } }, @@ -3561,7 +3561,7 @@ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "tunnel-agent": { @@ -3570,7 +3570,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -3602,9 +3602,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "wrappy": { diff --git a/package.json b/package.json index 45c1f2e..947342a 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "unity-cache-server", - "version": "6.1.1", + "version": "6.1.2-beta.0", "description": "Unity Cache Server", "main": "lib/index.js", "engines": { - "node": "^8.11.3" + "node": "^8.12.0" }, "directories": { "test": "test" From a74aece688909100e1c0753ace86fd5b2debff3b Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Mon, 17 Sep 2018 15:20:03 -0500 Subject: [PATCH 08/14] Bumping beta version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 947342a..b9ac9ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unity-cache-server", - "version": "6.1.2-beta.0", + "version": "6.1.2-beta.1", "description": "Unity Cache Server", "main": "lib/index.js", "engines": { From 3823fd97c0cce985fc2a6776d223243ba38c5e56 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Mon, 17 Sep 2018 15:57:42 -0500 Subject: [PATCH 09/14] Fixed unhandled promise rejections and stalls in the test suite. The former was caused by lokiJS persistence adapter trying to write to temp locations that no longer exist (disabled autosave to fix), and the latter was caused by test servers stalling waiting for clients to end their connections. --- lib/server/transaction_mirror.js | 4 ++-- package-lock.json | 2 +- test/cache_api.js | 16 +++++++++------- test/cache_base.js | 6 +++--- test/cache_fs.js | 2 ++ test/cache_ram.js | 6 ++++-- test/command_processor.js | 2 ++ test/protocol.js | 28 +++++++++++++++++----------- test/reliability_manager.js | 2 ++ test/server.js | 12 ++++++------ test/test_init.js | 7 +++++++ test/transaction_mirror.js | 12 +++++++++++- 12 files changed, 66 insertions(+), 33 deletions(-) create mode 100644 test/test_init.js diff --git a/lib/server/transaction_mirror.js b/lib/server/transaction_mirror.js index 4f3ab58..33e2038 100644 --- a/lib/server/transaction_mirror.js +++ b/lib/server/transaction_mirror.js @@ -21,11 +21,11 @@ class TransactionMirror { this._cache = cache; this._queue = []; this._processing = false; - this._queueProcessDelay = TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS; + this._queueProcessDelay = connectOptions.queueProcessDelay || TransactionMirror.options.queueProcessDelay || PROCESS_DELAY_MS; const host = connectOptions.host; const port = connectOptions.port; - const idleTimeout = TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS; + const idleTimeout = connectOptions.idleTimeout || TransactionMirror.options.idleTimeout || CONNECT_IDLE_TIMEOUT_MS; this._client = new Client(host, port, {idleTimeout: idleTimeout}); helpers.log(consts.LOG_INFO, `[TransactionMirror] Mirroring transactions to ${host}:${port}`); } diff --git a/package-lock.json b/package-lock.json index 840a102..89ed39d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "unity-cache-server", - "version": "6.1.2-beta.0", + "version": "6.1.2-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/test/cache_api.js b/test/cache_api.js index 0df6904..c37f1c0 100644 --- a/test/cache_api.js +++ b/test/cache_api.js @@ -1,3 +1,5 @@ +require('./test_init'); + const assert = require('assert'); const tmp = require('tmp-promise'); const loki = require('lokijs'); @@ -18,6 +20,7 @@ const test_modules = [ pageSize: 1024 * 1024, minFreeBlockSize: 1024, persistenceOptions: { + autosave: false, adapter: new loki.LokiMemoryAdapter() }, highReliability: false @@ -28,7 +31,10 @@ const test_modules = [ path: "../lib/cache/cache_fs", options: { cachePath: tmp.tmpNameSync({}), - highReliability: false + highReliability: false, + persistenceOptions: { + autosave: false + } } } ]; @@ -44,9 +50,7 @@ describe("Cache API", () => { cache = new CacheModule(); }); - after(() => { - return fs.remove(module.options.cachePath); - }); + after(() => fs.remove(module.options.cachePath)); describe("static get properties", () => { it("should return an object with common property values", () => { @@ -340,9 +344,7 @@ describe("PutTransaction API", () => { fileData = generateCommandData(1024, 1024); }); - after(() => { - return fs.remove(module.options.cachePath); - }); + after(() => fs.remove(module.options.cachePath)); beforeEach( async () => { trx = await cache.createPutTransaction(fileData.guid, fileData.hash); diff --git a/test/cache_base.js b/test/cache_base.js index 7283525..d4944ec 100644 --- a/test/cache_base.js +++ b/test/cache_base.js @@ -1,3 +1,5 @@ +require('./test_init'); + const tmp = require('tmp'); const fs = require('fs-extra'); const { CacheBase, PutTransaction } = require('../lib/cache/cache_base'); @@ -86,9 +88,7 @@ describe("Cache: Base Class", () => { describe("init", () => { - after(() => { - return fs.remove(opts.cachePath); - }); + after(() => fs.remove(opts.cachePath)); it("should create the cache working directory if it doesn't exist", () => { return cache.init(opts) diff --git a/test/cache_fs.js b/test/cache_fs.js index f996c62..ba33119 100644 --- a/test/cache_fs.js +++ b/test/cache_fs.js @@ -1,3 +1,5 @@ +require('./test_init'); + const tmp = require('tmp'); const fs = require('fs-extra'); const Cache = require('../lib/cache/cache_fs'); diff --git a/test/cache_ram.js b/test/cache_ram.js index 85948c6..6f5dde4 100644 --- a/test/cache_ram.js +++ b/test/cache_ram.js @@ -1,3 +1,5 @@ +require('./test_init'); + const tmp = require('tmp'); const fs = require('fs-extra'); const Cache = require('../lib/cache/cache_ram'); @@ -140,9 +142,9 @@ describe("Cache: RAM", () => { }); - afterEach(async () => { + afterEach(() => { cache._clearCache(); - await fs.remove(opts.cachePath); + return fs.remove(opts.cachePath); }); describe("_serialize", () => { diff --git a/test/command_processor.js b/test/command_processor.js index e45aead..411bcc3 100644 --- a/test/command_processor.js +++ b/test/command_processor.js @@ -1,3 +1,5 @@ +require('./test_init'); + const assert = require('assert'); const sinon = require('sinon'); const { CommandProcessor, CacheBase , PutTransaction } = require('../lib'); diff --git a/test/protocol.js b/test/protocol.js index 1682c4f..439cda4 100644 --- a/test/protocol.js +++ b/test/protocol.js @@ -1,3 +1,5 @@ +require('./test_init'); + const assert = require('assert'); const crypto = require('crypto'); const helpers = require('../lib/helpers'); @@ -37,6 +39,7 @@ const test_modules = [ reliabilityThreshold: 0 }, persistenceOptions: { + autosave: false, adapter: new loki.LokiMemoryAdapter() } } @@ -49,6 +52,9 @@ const test_modules = [ highReliability: true, highReliabilityOptions: { reliabilityThreshold: 0 + }, + persistenceOptions: { + autosave: false } } } @@ -58,10 +64,6 @@ describe("Protocol", () => { test_modules.forEach(module => { describe(module.name, function() { - beforeEach(() => { - helpers.setLogger(() => {}); - }); - before(async () => { /** @type {CacheBase} **/ const CacheModule = require(module.path); @@ -74,8 +76,8 @@ describe("Protocol", () => { await server.start(err => assert(!err, `Cache Server reported error! ${err}`)); }); - after(() => { - server.stop(); + after(async () => { + await server.stop(); module.tmpDir.removeCallback(); }); @@ -142,6 +144,8 @@ describe("Protocol", () => { await clientWrite(client, helpers.encodeInt32(consts.PROTOCOL_VERSION)); }); + afterEach(() => client.end()); + it("should close the socket on an invalid PUT type", (done) => { expectLog(client, /Unrecognized command/i, done); const buf = Buffer.from( @@ -185,7 +189,7 @@ describe("Protocol", () => { }); }); - it("should not allow replacing files for a version that already exists", () => { + it("should not allow replacing files for a version that already exists", async () => { const newData = Buffer.from(crypto.randomBytes(self.data.bin.length).toString('ascii'), 'ascii'); const buf = Buffer.from( @@ -193,10 +197,10 @@ describe("Protocol", () => { encodeCommand(cmd.putAsset, null, null, newData) + encodeCommand(cmd.transactionEnd), 'ascii'); - return clientWrite(client, buf) - .then(() => cache.getFileStream(consts.FILE_TYPE.BIN, self.data.guid, self.data.hash)) - .then(stream => readStream(stream, self.data.bin.length)) - .then(buffer => assert.strictEqual(buffer.compare(self.data.bin), 0)); + await clientWrite(client, buf); + const stream = await cache.getFileStream(consts.FILE_TYPE.BIN, self.data.guid, self.data.hash); + const data = await readStream(stream, self.data.bin.length); + assert.strictEqual(data.compare(self.data.bin), 0); }); }); @@ -228,6 +232,8 @@ describe("Protocol", () => { await clientWrite(client, helpers.encodeInt32(consts.PROTOCOL_VERSION)); }); + afterEach(() => client.end()); + it("should close the socket on an invalid GET type", (done) => { expectLog(client, /Unrecognized command/i, done); clientWrite(client, encodeCommand('gx', self.data.guid, self.data.hash)).catch(err => done(err)); diff --git a/test/reliability_manager.js b/test/reliability_manager.js index 1d9b8be..230465d 100644 --- a/test/reliability_manager.js +++ b/test/reliability_manager.js @@ -1,3 +1,5 @@ +require('./test_init'); + const loki = require('lokijs'); const tmp = require('tmp-promise'); const randomBuffer = require('./test_utils').randomBuffer; diff --git a/test/server.js b/test/server.js index d792c4f..b8ee687 100644 --- a/test/server.js +++ b/test/server.js @@ -1,3 +1,5 @@ +require('./test_init'); + const assert = require('assert'); const net = require('net'); const os = require('os'); @@ -15,10 +17,6 @@ let client; describe("Server common", function() { - beforeEach(function() { - helpers.setLogger(() => {}); - }); - before(function () { return server.start(err => assert(!err, `Cache Server reported error! ${err}`)); }); @@ -33,6 +31,8 @@ describe("Server common", function() { client = net.connect({port: server.port}, done); }); + afterEach(() => client.end()); + it("should echo the version if supported", function (done) { client.on('data', function (data) { const ver = helpers.readUInt32(data); @@ -129,7 +129,7 @@ describe("Server common", function() { }); client.write(helpers.encodeInt32(consts.PROTOCOL_VERSION)); - client.write(cmd.quit); + client.end(cmd.quit); }); }); @@ -142,7 +142,7 @@ describe("Server common", function() { }); client.write(helpers.encodeInt32(consts.PROTOCOL_VERSION)); - client.write('xx'); + client.end('xx'); }); }); }) diff --git a/test/test_init.js b/test/test_init.js new file mode 100644 index 0000000..52b45c6 --- /dev/null +++ b/test/test_init.js @@ -0,0 +1,7 @@ +const helpers = require('../lib/helpers'); + +process.on('unhandledRejection', (reason) => { + console.error(reason); +}); + +helpers.setLogger(() => {}); \ No newline at end of file diff --git a/test/transaction_mirror.js b/test/transaction_mirror.js index ad3c0bf..fffee11 100644 --- a/test/transaction_mirror.js +++ b/test/transaction_mirror.js @@ -1,3 +1,5 @@ +require('./test_init'); + const { Server, CacheRAM } = require('../lib'); const TransactionMirror = require('../lib/server/transaction_mirror'); const tmp = require('tmp'); @@ -25,16 +27,24 @@ describe("TransactionMirror", () => { before(async () => { this.sourceCache = new CacheRAM(); this.targetCache = new CacheRAM(); + await this.sourceCache.init(cacheOpts); await this.targetCache.init(cacheOpts); this.targetServer = new Server(this.targetCache, {port: 0}); await this.targetServer.start(err => assert(!err, `Server reported error! ${err}`)); - const opts = { host: 'localhost', port: this.targetServer.port }; + const opts = { host: 'localhost', port: this.targetServer.port, idleTimeout: 100 }; this.mirror = new TransactionMirror(opts, this.sourceCache); this.mirror._queueProcessDelay = 1; }); + after(async () => { + await this.sourceCache.shutdown(); + await this.targetCache.shutdown(); + await this.targetServer.stop(); + + }); + it("should mirror all queued transactions to the target Cache Server", async () => { const fileData = [ generateCommandData(1024, 1024), From ddb802cb1692ba6e5da186e7539870295ee8cad5 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Wed, 19 Sep 2018 07:42:48 -0500 Subject: [PATCH 10/14] whitespace cleanup --- test/transaction_mirror.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/transaction_mirror.js b/test/transaction_mirror.js index fffee11..2f66669 100644 --- a/test/transaction_mirror.js +++ b/test/transaction_mirror.js @@ -42,7 +42,6 @@ describe("TransactionMirror", () => { await this.sourceCache.shutdown(); await this.targetCache.shutdown(); await this.targetServer.stop(); - }); it("should mirror all queued transactions to the target Cache Server", async () => { From bd023da4238c628b1bc7513bd7b0dfa0c1e87fa0 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Wed, 19 Sep 2018 14:41:17 -0500 Subject: [PATCH 11/14] Improve test coverage, and fix some minor syntax issues. Removed _writev implementation of HashedWriteStream because it was unused and untested. --- lib/cache/cache_fs.js | 5 --- lib/client/client.js | 2 + lib/helpers.js | 10 +++-- test/client.js | 101 ++++++++++++++++++++++++++++++++++++++++++ test/helpers.js | 14 ++++++ test/server.js | 1 - 6 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 test/client.js diff --git a/lib/cache/cache_fs.js b/lib/cache/cache_fs.js index e7c0a3f..5d36b0d 100644 --- a/lib/cache/cache_fs.js +++ b/lib/cache/cache_fs.js @@ -361,11 +361,6 @@ class HashedWriteStream extends fs.WriteStream { super._write(data, encoding, cb); } - _writev (chunks, cb) { - chunks.forEach(chunk => this._hash.update(chunk, 'ascii')); - super._writev(chunks, cb); - } - get byteHash() { return this._hash.digest(); } diff --git a/lib/client/client.js b/lib/client/client.js index 0dd0311..63a34ce 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -85,6 +85,8 @@ class CacheClient { * @returns {Promise<any>} */ quit() { + if(!this._client) return Promise.resolve(); + return new Promise(resolve => { this._client.once('close', () => resolve()); this._client.end(cmd.quit); diff --git a/lib/helpers.js b/lib/helpers.js index 5b7b762..915ee9a 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -93,6 +93,9 @@ exports.isBuffer = function(obj) { * @returns {Promise<any>} */ exports.parseAndValidateAddressString = function(address, defaultPort) { + if(ip.isV6Format(address) && !ip.isV4Format(address)) + return Promise.reject("IPV6 mirrors not supported"); + // eslint-disable-next-line prefer-const let [host, port] = address.split(':'); port = port || defaultPort; @@ -217,10 +220,9 @@ function locationOf(item, array, compare, start, end) { start = start || 0; end = end || array.length; - let pivot = (start + end) >> 1; - - let c = compare(item, array[pivot]); - if (end - start <= 1) return c == -1 ? pivot - 1 : pivot; + const pivot = (start + end) >> 1; + const c = compare(item, array[pivot]); + if (end - start <= 1) return c === -1 ? pivot - 1 : pivot; switch (c) { case -1: return locationOf(item, array, compare, start, pivot); diff --git a/test/client.js b/test/client.js new file mode 100644 index 0000000..9c8f9c4 --- /dev/null +++ b/test/client.js @@ -0,0 +1,101 @@ +require('./test_init'); + +const assert = require('assert'); +const net = require('net'); +const Client = require('../lib/client/client'); +const WritableStream = require('stream').Writable; +const consts = require('../lib/constants'); +const generateCommandData = require('./test_utils').generateCommandData; + +describe("Client", () => { + this.getClient = () => { + return new Client("127.0.0.1", 9999); + }; + + this.getConnectedClient = async (onConnect) => { + return new Promise((resolve) => { + const s = net.createServer(socket => onConnect(socket)); + s.listen(0, "0.0.0.0", () => { + const a = s.address(); + resolve({server: s, client: new Client(a.address, a.port)}); + }); + }); + }; + + describe("close", () => { + it("should resolve without error if called before connect()", async () => { + await this.getClient().quit(); + }); + }); + + describe("connect", () => { + it("should return the client object if called one or more times", async () => { + const data = await this.getConnectedClient(() => {}); + assert.strictEqual(await data.client.connect(), data.client); + assert.strictEqual(await data.client.connect(), data.client); + data.server.close(); + }); + }); + + describe("putFile", () => { + it("should throw an error if an unrecognized type is specified", async () => { + const b = Buffer.alloc(16); + await this.getClient().putFile('x', b, b, b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + }); + + it("should throw an error if an invalid guid is specified", async () => { + const b = Buffer.alloc(16); + + // wrong size buffer + await this.getClient().putFile('a', Buffer.alloc(12), b, b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + + // wrong type + await this.getClient().putFile('a', "not a buffer", b, b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + }); + + it("should throw an error if an invalid hash is specified", async () => { + const b = Buffer.alloc(16); + + // wrong size buffer + await this.getClient().putFile(Client.fileTypes.BIN, b, Buffer.alloc(12), b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + + // wrong type + await this.getClient().putFile(Client.fileTypes.BIN, b, "not a buffer", b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + }); + + it("should throw an error if client is not connected", async () => { + const b = Buffer.alloc(16); + await this.getClient().putFile(Client.fileTypes.BIN, b, b, b, 16) + .then(() => { throw new Error("Expected error"); }, err => assert(err)); + }); + + it("should send the given buffer to the server", (done) => { + const data = generateCommandData(256, 256); + let client, server; + + this.getConnectedClient(socket => { + socket.pipe(new WritableStream({ + write(chunk, encoding, callback) { + const len = consts.VERSION_SIZE + consts.CMD_SIZE + consts.SIZE_SIZE; + const slice = chunk.slice(len, len + data.bin.length); + assert.strictEqual(data.bin.compare(slice), 0); + callback(); + }, + final(cb) { + cb(); + done(); + } + })); + }) + .then(data => { client = data.client; server = data.server; return client.connect(); }) + .then(() => client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length)) + .then(() => client.quit()) + .then(() => server.close()); + }); + }); +}); \ No newline at end of file diff --git a/test/helpers.js b/test/helpers.js index e431c42..2ea0d70 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -50,6 +50,20 @@ describe("Helper functions", () => { assert.strictEqual(result.port, 0); }); + it("should return the same IP address passed in if already in ip v4 format", async () => { + const result = await helpers.parseAndValidateAddressString("1.2.3.4", 1234); + assert.equal(result.host, "1.2.3.4"); + assert.strictEqual(result.port, 1234); + }); + + it("should throw an error if address in ip v6 format", async () => { + await helpers.parseAndValidateAddressString("2001::4860::4860::8888", 0) + .then(() => { throw new Error("Expected error"); }).catch(err => assert(err)); + + await helpers.parseAndValidateAddressString("2001:db8:0:0:0:0:2:1", 0) + .then(() => { throw new Error("Expected error"); }).catch(err => assert(err)); + }); + it("should parse an address:port string", async () => { const result = await helpers.parseAndValidateAddressString("localhost:1234", 0); assert.equal(result.host, "127.0.0.1"); diff --git a/test/server.js b/test/server.js index b8ee687..f10507f 100644 --- a/test/server.js +++ b/test/server.js @@ -10,7 +10,6 @@ const Cache = require('../lib/cache/cache_base').CacheBase; const sleep = require('./test_utils').sleep; const cmd = require('./test_utils').cmd; -helpers.setLogger(()=>{}); const cache = new Cache(); const server = new CacheServer(cache, {port: 0}); let client; From d7f338df21657d0bda5f2b804dd0907ac2587942 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Wed, 19 Sep 2018 15:00:43 -0500 Subject: [PATCH 12/14] Refactored test to better cleanup client/server connections --- test/client.js | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/test/client.js b/test/client.js index 9c8f9c4..87a283d 100644 --- a/test/client.js +++ b/test/client.js @@ -8,20 +8,33 @@ const consts = require('../lib/constants'); const generateCommandData = require('./test_utils').generateCommandData; describe("Client", () => { - this.getClient = () => { - return new Client("127.0.0.1", 9999); - }; + + beforeEach(() => { + this._client = null; + this._server = null; + }); + + afterEach(async () => { + if(this._client) { await this._client.quit(); } + if(this._server) { await this._server.close(); } + }); - this.getConnectedClient = async (onConnect) => { + this.initClientServer = async (onConnect) => { + const self = this; return new Promise((resolve) => { - const s = net.createServer(socket => onConnect(socket)); - s.listen(0, "0.0.0.0", () => { - const a = s.address(); - resolve({server: s, client: new Client(a.address, a.port)}); + self._server = net.createServer(socket => onConnect(socket)); + self._server.listen(0, "0.0.0.0", () => { + const a = self._server.address(); + self._client = new Client(a.address, a.port); + resolve(); }); }); }; + this.getClient = () => { + return new Client("127.0.0.1", 9999); + }; + describe("close", () => { it("should resolve without error if called before connect()", async () => { await this.getClient().quit(); @@ -30,10 +43,9 @@ describe("Client", () => { describe("connect", () => { it("should return the client object if called one or more times", async () => { - const data = await this.getConnectedClient(() => {}); - assert.strictEqual(await data.client.connect(), data.client); - assert.strictEqual(await data.client.connect(), data.client); - data.server.close(); + await this.initClientServer(() => {}); + assert.strictEqual(await this._client.connect(), this._client); + assert.strictEqual(await this._client.connect(), this._client); }); }); @@ -76,9 +88,8 @@ describe("Client", () => { it("should send the given buffer to the server", (done) => { const data = generateCommandData(256, 256); - let client, server; - this.getConnectedClient(socket => { + this.initClientServer(socket => { socket.pipe(new WritableStream({ write(chunk, encoding, callback) { const len = consts.VERSION_SIZE + consts.CMD_SIZE + consts.SIZE_SIZE; @@ -92,10 +103,9 @@ describe("Client", () => { } })); }) - .then(data => { client = data.client; server = data.server; return client.connect(); }) - .then(() => client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length)) - .then(() => client.quit()) - .then(() => server.close()); + .then(() => this._client.connect()) + .then(() => this._client.putFile(Client.fileTypes.BIN, data.guid, data.hash, data.bin, data.bin.length)) + .then(() => this._client.quit()); }); }); }); \ No newline at end of file From 61ab79ac0578d64ff729107fb1ad3381ab755057 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Thu, 20 Sep 2018 06:24:21 -0500 Subject: [PATCH 13/14] Package version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b9ac9ef..60cd7ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unity-cache-server", - "version": "6.1.2-beta.1", + "version": "6.1.2-beta.3", "description": "Unity Cache Server", "main": "lib/index.js", "engines": { From 96b312fe2b58771e3ae4c1a18a272b5699999029 Mon Sep 17 00:00:00 2001 From: Stephen Palmer <stephenp@unity3d.com> Date: Wed, 26 Sep 2018 07:31:29 -0500 Subject: [PATCH 14/14] - minor syntax fixes - bump version for release --- lib/cache/cache_fs.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/cache/cache_fs.js b/lib/cache/cache_fs.js index 5d36b0d..f9aa82a 100644 --- a/lib/cache/cache_fs.js +++ b/lib/cache/cache_fs.js @@ -123,7 +123,7 @@ class CacheFS extends CacheBase { let deleteSize = 0; let deletedItemCount = 0; let deleteItems = []; - let verb = dryRun ? 'Gathering' : 'Removing'; + const verb = dryRun ? 'Gathering' : 'Removing'; let spinnerMessage = verb + ' expired files'; const progressData = () => { @@ -184,7 +184,7 @@ class CacheFS extends CacheBase { needsSorted = false; } - let i = deleteItems[deleteItems.length - 1]; // i is the MRU out of the current delete list + const i = deleteItems[deleteItems.length - 1]; // i is the MRU out of the current delete list if (item.stats.atime < i.stats.atime) { deleteItems = helpers.insertSorted(item, deleteItems, (a, b) => { diff --git a/package.json b/package.json index 60cd7ee..d1b0021 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unity-cache-server", - "version": "6.1.2-beta.3", + "version": "6.1.2", "description": "Unity Cache Server", "main": "lib/index.js", "engines": {