From 24eff2e01236a3e9a0db0cf49835ca3aa5a7399a Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Fri, 16 Nov 2018 14:36:49 +0100 Subject: [PATCH 1/8] Make load() return a promise --- index.js | 18 +- package-lock.json | 2854 ++++++++++++++++++++++++++++++++++++++++++--- package.json | 3 +- test/_spec.js | 47 +- 4 files changed, 2768 insertions(+), 154 deletions(-) diff --git a/index.js b/index.js index 05fe146..202f38a 100644 --- a/index.js +++ b/index.js @@ -118,7 +118,7 @@ class NodeTestHelper extends EventEmitter { } } - load(testNode, testFlow, testCredentials, cb) { + async load(testNode, testFlow, testCredentials, cb) { const log = this._log; const logSpy = this._logSpy = this._sandbox.spy(log, 'log'); logSpy.FATAL = log.FATAL; @@ -147,6 +147,10 @@ class NodeTestHelper extends EventEmitter { if (typeof testCredentials === 'function') { cb = testCredentials; + testCredentials = null; + } + + if (testCredentials == null) { testCredentials = {}; } @@ -189,12 +193,12 @@ class NodeTestHelper extends EventEmitter { testNode(red); } - redNodes.loadFlows() - .then(() => { - redNodes.startFlows(); - should.deepEqual(testFlow, redNodes.getFlows().flows); - cb(); - }); + await redNodes.loadFlows(); + redNodes.startFlows(); + should.deepEqual(testFlow, redNodes.getFlows().flows); + if (typeof cb === 'function') { + cb(); + } } unload() { diff --git a/package-lock.json b/package-lock.json index f5896dc..37d72de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,55 +12,223 @@ "samsam": "1.3.0" } }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", + "dev": true + }, + "ajv": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", + "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "append-field": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", + "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=", + "dev": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.5" + } + }, + "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.3" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "array-indexofobject": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-indexofobject/-/array-indexofobject-0.0.1.tgz", + "integrity": "sha1-qqEo5iybPDWAlFaMIZ/2T+SJ1Co=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async": { + "version": "0.1.22", + "resolved": "http://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "basic-auth": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz", + "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "bcrypt": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz", + "integrity": "sha512-pRyDdo73C8Nim3jwFJ7DWe3TZCgwDfWZ6nHS5LSdU77kWbj1frruvdndP02AOavtD4y8v6Fp2dolbHgp4SDrfg==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.6.2", + "node-pre-gyp": "0.6.36" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=", + "dev": true + }, + "bl": { + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "2.3.5", + "safe-buffer": "5.1.1" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, "body-parser": { "version": "1.18.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", + "depd": "1.1.2", + "http-errors": "1.6.2", "iconv-lite": "0.4.19", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.1", "raw-body": "2.3.2", - "type-is": "~1.6.15" + "type-is": "1.6.16" } }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "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", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -70,22 +238,147 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buildmail": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-2.0.0.tgz", + "integrity": "sha1-8LewpZ6aShtQZrv6BR0kjzgy7s4=", + "dev": true, + "requires": { + "addressparser": "0.3.2", + "libbase64": "0.1.0", + "libmime": "1.2.0", + "libqp": "1.1.0", + "needle": "0.10.0" + }, + "dependencies": { + "addressparser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-0.3.2.tgz", + "integrity": "sha1-WYc/Nej89sc2HBAjkmHXbhU0i7I=", + "dev": true + }, + "needle": { + "version": "0.10.0", + "resolved": "http://registry.npmjs.org/needle/-/needle-0.10.0.tgz", + "integrity": "sha1-FqJNY/KmEVLrdMzh0Sr4XFB1d9Q=", + "dev": true, + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.19" + } + } + } + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "dev": true, + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.14" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "callback-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz", + "integrity": "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.5" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "cheerio": { + "version": "0.22.0", + "resolved": "http://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "dev": true, + "requires": { + "css-select": "1.2.0", + "dom-serializer": "0.1.0", + "entities": "1.1.2", + "htmlparser2": "3.10.0", + "lodash.assignin": "4.2.0", + "lodash.bind": "4.2.1", + "lodash.defaults": "4.2.0", + "lodash.filter": "4.6.0", + "lodash.flatten": "4.4.0", + "lodash.foreach": "4.5.0", + "lodash.map": "4.6.0", + "lodash.merge": "4.6.1", + "lodash.pick": "4.4.0", + "lodash.reduce": "4.6.0", + "lodash.reject": "4.6.0", + "lodash.some": "4.6.0" + } + }, + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "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 + }, "combined-stream": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -94,6 +387,24 @@ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, + "commist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.0.0.tgz", + "integrity": "sha1-wMNSUBz29S6RJOPvicmAbiAi6+8=", + "dev": true, + "requires": { + "leven": "1.0.2", + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -105,6 +416,24 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "typedarray": "0.0.6" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -120,6 +449,16 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, + "cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "dev": true, + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -130,11 +469,73 @@ "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", "integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=" }, + "cookies": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.3.tgz", + "integrity": "sha512-+gixgxYSgQLTaTIilDHAdlNPZDENDQernEMiIcZpYYP14zgHsCt4Ce1FEjFtcp6GefhozebB6orvhAAWx/IS0A==", + "dev": true, + "requires": { + "depd": "1.1.2", + "keygrip": "1.0.3" + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "vary": "1.1.2" + } + }, + "crc": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=", + "dev": true + }, + "cron": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.3.0.tgz", + "integrity": "sha512-K/SF7JlgMmNjcThWxkKvsHhey2EDB4CeOEWJ9aXWj3fbQJppsvTPIeyLdHfNq5IbbsMUUjRW1nr5dSO95f2E4w==", + "dev": true, + "requires": { + "moment-timezone": "0.5.23" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "1.0.0", + "css-what": "2.1.2", + "domutils": "1.5.1", + "nth-check": "1.0.2" + } + }, + "css-what": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", + "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -143,11 +544,25 @@ "ms": "2.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "optional": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true, + "optional": true + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -158,11 +573,112 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "dev": true, + "requires": { + "readable-stream": "1.1.14", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "1.1.3", + "entities": "1.1.2" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.2.1.tgz", + "integrity": "sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1.2.1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0.1.0", + "domelementtype": "1.2.1" + } + }, + "duplexify": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", + "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "stream-shift": "1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "0.1.1", + "safer-buffer": "2.1.2" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -173,12 +689,36 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, + "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" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "escape-html": { @@ -192,6 +732,12 @@ "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 + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -202,36 +748,53 @@ "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", "requires": { - "accepts": "~1.3.4", + "accepts": "1.3.5", "array-flatten": "1.1.1", "body-parser": "1.18.2", "content-disposition": "0.5.2", - "content-type": "~1.0.4", + "content-type": "1.0.4", "cookie": "0.3.1", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.1", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "finalhandler": "1.1.0", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.2", + "proxy-addr": "2.0.3", "qs": "6.5.1", - "range-parser": "~1.2.0", + "range-parser": "1.2.0", "safe-buffer": "5.1.1", "send": "0.16.1", "serve-static": "1.13.1", "setprototypeof": "1.1.0", - "statuses": "~1.3.1", - "type-is": "~1.6.15", + "statuses": "1.3.1", + "type-is": "1.6.16", "utils-merge": "1.0.1", - "vary": "~1.1.2" + "vary": "1.1.2" + } + }, + "express-session": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", + "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "dev": true, + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "crc": "3.4.4", + "debug": "2.6.9", + "depd": "1.1.2", + "on-headers": "1.0.1", + "parseurl": "1.3.2", + "uid-safe": "2.1.5", + "utils-merge": "1.0.1" } }, "extend": { @@ -239,18 +802,53 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "feedparser": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/feedparser/-/feedparser-2.2.9.tgz", + "integrity": "sha1-kTgZfa/a4F/K3eADa+6vYGbCxek=", + "dev": true, + "requires": { + "addressparser": "1.0.1", + "array-indexofobject": "0.0.1", + "lodash.assign": "4.2.0", + "lodash.get": "4.4.2", + "lodash.has": "4.5.2", + "lodash.uniq": "4.5.0", + "mri": "1.1.1", + "readable-stream": "2.3.5", + "sax": "1.2.4" + } + }, "finalhandler": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" } }, "find-up": { @@ -258,17 +856,49 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "^2.0.0" + "locate-path": "2.0.0" } }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "follow-redirects": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", + "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", + "dev": true, + "requires": { + "debug": "3.2.6" + }, + "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 + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.18" } }, "formidable": { @@ -286,24 +916,123 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.2" + } + }, + "fs.notify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fs.notify/-/fs.notify-0.0.4.tgz", + "integrity": "sha1-YyhNRaNLUs5gCIpt2+xbd208AT0=", + "dev": true, + "requires": { + "async": "0.1.22", + "retry": "0.6.1" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "dev": true, + "optional": true, + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "optional": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.3" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + } + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "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" + "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" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "3.0.1", + "glob": "7.1.2", + "glob-parent": "3.1.0", + "is-negated-glob": "1.0.0", + "ordered-read-streams": "1.0.1", + "pumpify": "1.5.1", + "readable-stream": "2.3.5", + "remove-trailing-separator": "1.1.0", + "to-absolute-glob": "2.0.2", + "unique-stream": "2.2.1" } }, "graceful-fs": { @@ -317,23 +1046,106 @@ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "6.5.5", + "har-schema": "2.0.0" + } + }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true, + "optional": true + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, + "help-me": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz", + "integrity": "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y=", + "dev": true, + "requires": { + "callback-stream": "1.1.0", + "glob-stream": "6.1.0", + "through2": "2.0.5", + "xtend": "4.0.1" + } + }, "hosted-git-info": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==" }, + "htmlparser2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz", + "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", + "dev": true, + "requires": { + "domelementtype": "1.3.0", + "domhandler": "2.4.2", + "domutils": "1.5.1", + "entities": "1.1.2", + "inherits": "2.0.3", + "readable-stream": "3.0.6" + }, + "dependencies": { + "domelementtype": { + "version": "1.3.0", + "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "readable-stream": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz", + "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", @@ -342,7 +1154,7 @@ "depd": "1.1.1", "inherits": "2.0.3", "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" + "statuses": "1.3.1" }, "dependencies": { "depd": { @@ -357,19 +1169,83 @@ } } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.15.2" + } + }, + "i18next": { + "version": "1.10.6", + "resolved": "http://registry.npmjs.org/i18next/-/i18next-1.10.6.tgz", + "integrity": "sha1-/d2LSRUCxIlnpiljvHIv+JfN3qA=", + "dev": true, + "requires": { + "cookies": "0.7.3", + "i18next-client": "1.10.3", + "json5": "0.2.0" + } + }, + "i18next-client": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/i18next-client/-/i18next-client-1.10.3.tgz", + "integrity": "sha1-dtA1NVftkNHnqHdU1QBNP3gB/ek=", + "dev": true + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" }, + "imap": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/imap/-/imap-0.8.19.tgz", + "integrity": "sha1-NniHOTSrCc6mukh0HyhNoq9Z2NU=", + "dev": true, + "requires": { + "readable-stream": "1.1.14", + "utf7": "1.0.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "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" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -377,11 +1253,28 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true, + "optional": true + }, "ipaddr.js": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=" }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "1.0.0", + "is-windows": "1.0.2" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -392,33 +1285,222 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "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.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.1" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.2.0", + "resolved": "http://registry.npmjs.org/json5/-/json5-0.2.0.tgz", + "integrity": "sha1-ttcDXHDEVw+IPH7cdZ3jrgPbM0M=", + "dev": true + }, + "jsonata": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-1.5.4.tgz", + "integrity": "sha512-F/p92UWYUn+kD3SE898jjlz1mkBzjtok9ZTtWT6+axS4Z2Wtc8p/md6xHkyCGWPdIEJBTSw0mlvKE+s+fAVSjg==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, "just-extend": { "version": "1.1.27", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==" }, + "keygrip": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", + "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==", + "dev": true + }, + "leven": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz", + "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=", + "dev": true + }, + "libbase64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", + "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", + "dev": true + }, + "libmime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-1.2.0.tgz", + "integrity": "sha1-jYS087Ils3BEECNu9JSQZDa6dCs=", + "dev": true, + "requires": { + "iconv-lite": "0.4.19", + "libbase64": "0.1.0", + "libqp": "1.1.0" + } + }, + "libqp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", + "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" } }, "locate-path": { @@ -426,25 +1508,168 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "2.0.0", + "path-exists": "3.0.0" } }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=", + "dev": true + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=", + "dev": true + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, + "lodash.has": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=", + "dev": true + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "dev": true + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=", + "dev": true + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=", + "dev": true + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, "lolex": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==" }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "mailcomposer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-2.1.0.tgz", + "integrity": "sha1-plMYIomWFP7omckiJtgeK5y7GD0=", + "dev": true, + "requires": { + "buildmail": "2.0.0", + "libmime": "1.2.0" + } + }, + "mailparser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", + "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", + "dev": true, + "requires": { + "encoding": "0.1.12", + "mime": "1.4.1", + "mimelib": "0.3.1", + "uue": "3.1.2" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memorystore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/memorystore/-/memorystore-1.6.0.tgz", + "integrity": "sha1-H7X7Xwsu3xrdGEkX6RjwlKn/NGU=", + "dev": true, + "requires": { + "debug": "3.1.0", + "lru-cache": "4.1.3" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -470,7 +1695,17 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" + } + }, + "mimelib": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", + "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", + "dev": true, + "requires": { + "addressparser": "1.0.1", + "encoding": "0.1.12" } }, "minimatch": { @@ -479,7 +1714,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -526,11 +1761,144 @@ } } }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "moment-timezone": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz", + "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==", + "dev": true, + "requires": { + "moment": "2.22.2" + } + }, + "mqtt": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-2.18.0.tgz", + "integrity": "sha512-d4hXWziT6tLMjaQs5TVh8uHWS072GBfmBIABezbWZ8W0nNzgMUm6iEmXDLvxkj5YVgl8qDdM0pWQ2NwRwhU7nA==", + "dev": true, + "requires": { + "commist": "1.0.0", + "concat-stream": "1.6.2", + "end-of-stream": "1.4.1", + "help-me": "1.1.0", + "inherits": "2.0.3", + "minimist": "1.2.0", + "mqtt-packet": "5.6.0", + "pump": "3.0.0", + "readable-stream": "2.3.6", + "reinterval": "1.1.0", + "split2": "2.2.0", + "websocket-stream": "5.1.2", + "xtend": "4.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "mqtt-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-5.6.0.tgz", + "integrity": "sha512-QECe2ivqcR1LRsPobRsjenEKAC3i1a5gmm+jNKJLrsiq9PaSQ18LlKFuxvhGxWkvGEPadWv6rKd31O4ICqS1Xw==", + "dev": true, + "requires": { + "bl": "1.2.2", + "inherits": "2.0.3", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1" + } + }, + "mri": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.1.tgz", + "integrity": "sha1-haom09ru7t+A3FmEr5XMXKXK2fE=", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", + "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", + "dev": true, + "requires": { + "append-field": "0.1.0", + "busboy": "0.2.14", + "concat-stream": "1.6.2", + "mkdirp": "0.5.1", + "object-assign": "3.0.0", + "on-finished": "2.3.0", + "type-is": "1.6.16", + "xtend": "4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + } + } + }, + "mustache": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/mustache/-/mustache-2.3.0.tgz", + "integrity": "sha1-QCj3d4sXcIpImTCm5SrDvKDaQdA=", + "dev": true + }, + "nan": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", + "dev": true, + "optional": true + }, + "needle": { + "version": "0.11.0", + "resolved": "http://registry.npmjs.org/needle/-/needle-0.11.0.tgz", + "integrity": "sha1-AqcbAI6vfVWuifuf12hbe4jXvCk=", + "dev": true, + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.19" + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -541,11 +1909,11 @@ "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==", "requires": { - "@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" + "@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" }, "dependencies": { "isarray": { @@ -563,17 +1931,487 @@ } } }, + "node-pre-gyp": { + "version": "0.6.36", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", + "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", + "dev": true, + "optional": true, + "requires": { + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.2", + "rc": "1.2.8", + "request": "2.88.0", + "rimraf": "2.6.2", + "semver": "5.5.1", + "tar": "2.2.1", + "tar-pack": "3.4.1" + } + }, + "node-red": { + "version": "0.18.7", + "resolved": "https://registry.npmjs.org/node-red/-/node-red-0.18.7.tgz", + "integrity": "sha512-c88H51qK2chQNITdN3tDzk4TgPWHzBxEGE2jQwHihjeneGnJEihDnoncsGB7CA2s9aU1tlh2lbifdObFhQr8gA==", + "dev": true, + "requires": { + "basic-auth": "2.0.0", + "bcrypt": "1.0.3", + "bcryptjs": "2.4.3", + "body-parser": "1.18.3", + "cheerio": "0.22.0", + "clone": "2.1.1", + "cookie": "0.3.1", + "cookie-parser": "1.4.3", + "cors": "2.8.4", + "cron": "1.3.0", + "express": "4.16.3", + "express-session": "1.15.6", + "follow-redirects": "1.4.1", + "fs-extra": "5.0.0", + "fs.notify": "0.0.4", + "hash-sum": "1.0.2", + "i18next": "1.10.6", + "is-utf8": "0.2.1", + "js-yaml": "3.11.0", + "json-stringify-safe": "5.0.1", + "jsonata": "1.5.4", + "media-typer": "0.3.0", + "memorystore": "1.6.0", + "mqtt": "2.18.0", + "multer": "1.3.0", + "mustache": "2.3.0", + "node-red-node-email": "0.1.29", + "node-red-node-feedparser": "0.1.14", + "node-red-node-rbe": "0.2.4", + "node-red-node-twitter": "1.1.4", + "nopt": "4.0.1", + "oauth2orize": "1.11.0", + "on-headers": "1.0.1", + "passport": "0.4.0", + "passport-http-bearer": "1.0.1", + "passport-oauth2-client-password": "0.1.2", + "raw-body": "2.3.3", + "semver": "5.5.0", + "sentiment": "2.1.0", + "uglify-js": "3.3.25", + "when": "3.7.8", + "ws": "1.1.5", + "xml2js": "0.4.19" + }, + "dependencies": { + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "1.6.16" + } + }, + "express": { + "version": "4.16.3", + "resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz", + "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "dev": true, + "requires": { + "accepts": "1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.3", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "1.4.0", + "type-is": "1.6.16", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.4.0", + "unpipe": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.5.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": "2.1.2" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.3", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.2" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "node-red-node-email": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/node-red-node-email/-/node-red-node-email-0.1.29.tgz", + "integrity": "sha512-+tqda0bNT8A0PM9G47XqFiUP9gEe1zvB/9f+JJhbLWTEk9TeRB4UeyycubmCbR1/TzJnk2v9yCDogFhDJQWbOw==", + "dev": true, + "requires": { + "imap": "0.8.19", + "mailparser": "0.6.2", + "nodemailer": "1.11.0", + "poplib": "0.1.7" + } + }, + "node-red-node-feedparser": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/node-red-node-feedparser/-/node-red-node-feedparser-0.1.14.tgz", + "integrity": "sha512-Bb9M5bFrOqoFxBVxfstBM/g+VPaV4EPQptXQBMrlsCd3P40CXcGL0mDylXU+3cekWNd5hLHfqTHvXJdkowHGDw==", + "dev": true, + "requires": { + "feedparser": "2.2.9", + "request": "2.88.0" + } + }, + "node-red-node-rbe": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/node-red-node-rbe/-/node-red-node-rbe-0.2.4.tgz", + "integrity": "sha512-ft/8/dTRGzGQ9vCnAzuBxzR+aDv4Yun/vuSKi/eI5Qj2/ZBal28L9HpWziSTWlLrMhZns8CRz7s2p84P2ee/vA==", + "dev": true + }, + "node-red-node-twitter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-red-node-twitter/-/node-red-node-twitter-1.1.4.tgz", + "integrity": "sha512-mkw8HOosXHMBRdyJkio77vPx4Ls5IY26P5ZyoMWmKMkimXKTnX00DdpmNlkW+dHwMDYq1H66WzFtQhNOdEAbgA==", + "dev": true, + "requires": { + "request": "2.88.0", + "twitter-ng": "0.6.2" + } + }, + "nodemailer": { + "version": "1.11.0", + "resolved": "http://registry.npmjs.org/nodemailer/-/nodemailer-1.11.0.tgz", + "integrity": "sha1-TmnLObAwFbHR7wx4qBVBK56Xb3k=", + "dev": true, + "requires": { + "libmime": "1.2.0", + "mailcomposer": "2.1.0", + "needle": "0.11.0", + "nodemailer-direct-transport": "1.1.0", + "nodemailer-smtp-transport": "1.1.0" + } + }, + "nodemailer-direct-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-1.1.0.tgz", + "integrity": "sha1-oveHCO5vFuoFc/yClJ0Tj/Fy9iQ=", + "dev": true, + "requires": { + "smtp-connection": "1.3.8" + } + }, + "nodemailer-smtp-transport": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-1.1.0.tgz", + "integrity": "sha1-5sN/MYhaswgOfe089SjErX5pE5g=", + "dev": true, + "requires": { + "clone": "1.0.4", + "nodemailer-wellknown": "0.1.10", + "smtp-connection": "1.3.8" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + } + } + }, + "nodemailer-wellknown": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", + "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", + "dev": true + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "dev": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.1", + "validate-npm-package-license": "3.0.3" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.5", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "1.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 + }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "oauth2orize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/oauth2orize/-/oauth2orize-1.11.0.tgz", + "integrity": "sha1-eTzvJR1F696sMq5AqLaBT6qx1IM=", + "dev": true, + "requires": { + "debug": "2.6.9", + "uid2": "0.0.3", + "utils-merge": "1.0.1" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -582,13 +2420,66 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", + "dev": true + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "2.3.5" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "p-limit": { @@ -596,7 +2487,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "requires": { - "p-try": "^1.0.0" + "p-try": "1.0.0" } }, "p-locate": { @@ -604,7 +2495,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "^1.1.0" + "p-limit": "1.2.0" } }, "p-try": { @@ -617,8 +2508,8 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.2" } }, "parseurl": { @@ -626,6 +2517,46 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "dev": true, + "requires": { + "passport-strategy": "1.0.0", + "pause": "0.0.1" + } + }, + "passport-http-bearer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz", + "integrity": "sha1-FHRp6jZp4qhMYWfvmdu3fh8AmKg=", + "dev": true, + "requires": { + "passport-strategy": "1.0.0" + } + }, + "passport-oauth2-client-password": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/passport-oauth2-client-password/-/passport-oauth2-client-password-0.1.2.tgz", + "integrity": "sha1-TzeLZ4uS0W270jOmxwZSAJPlYbo=", + "dev": true, + "requires": { + "passport-strategy": "1.0.0" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -647,33 +2578,111 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "requires": { - "pify": "^3.0.0" + "pify": "3.0.0" } }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, + "poplib": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/poplib/-/poplib-0.1.7.tgz", + "integrity": "sha1-L0tYtVkpcjUM2X9IKrpo+OBVdLw=", + "dev": true, + "requires": { + "optimist": "0.6.1" + } + }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, - "proxy-addr": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", - "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "proxy-addr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", + "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.6.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "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": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.6.0" + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "3.6.1", + "inherits": "2.0.3", + "pump": "2.0.1" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "once": "1.4.0" + } + } } }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=", + "dev": true + }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -690,14 +2699,36 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.6.0", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true, + "optional": true + } + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" } }, "read-pkg-up": { @@ -705,8 +2736,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "2.1.0", + "read-pkg": "3.0.0" } }, "readable-stream": { @@ -714,13 +2745,103 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.0.3", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.1.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.21", + "oauth-sign": "0.9.0", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.4.3", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" + }, + "dependencies": { + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "1.37.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "retry": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz", + "integrity": "sha1-/ckO7ZQ/3hG4k1VLjMY9DombqRg=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" } }, "safe-buffer": { @@ -728,11 +2849,23 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, "samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "semver": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", @@ -744,31 +2877,44 @@ "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", "requires": { "debug": "2.6.9", - "depd": "~1.1.1", - "destroy": "~1.0.4", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.2", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.3.1" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" } }, + "sentiment": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sentiment/-/sentiment-2.1.0.tgz", + "integrity": "sha1-MyeRAMNcOFGcpeQ1JFGGxRL+D9w=", + "dev": true + }, "serve-static": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", "requires": { - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.1" } }, + "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, + "optional": true + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -779,11 +2925,11 @@ "resolved": "https://registry.npmjs.org/should/-/should-13.2.1.tgz", "integrity": "sha512-l+/NwEMO+DcstsHEwPHRHzC9j4UOE3VQwJGcMWSsD/vqpqHbnQ+1iSHy64Ihmmjx1uiRPD9pFadTSc3MJtXAgw==", "requires": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" + "should-equal": "2.0.0", + "should-format": "3.0.3", + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0", + "should-util": "1.0.0" } }, "should-equal": { @@ -791,7 +2937,7 @@ "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", "requires": { - "should-type": "^1.4.0" + "should-type": "1.4.0" } }, "should-format": { @@ -799,8 +2945,8 @@ "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" + "should-type": "1.4.0", + "should-type-adaptors": "1.1.0" } }, "should-sinon": { @@ -818,8 +2964,8 @@ "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" + "should-type": "1.4.0", + "should-util": "1.0.0" } }, "should-util": { @@ -827,18 +2973,25 @@ "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz", "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=" }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true, + "optional": true + }, "sinon": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.0.3.tgz", "integrity": "sha1-mVDxYWGH/wzX11pg1mvCf+1WmUU=", "requires": { - "@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" + "@sinonjs/formatio": "2.0.0", + "diff": "3.5.0", + "lodash.get": "4.4.2", + "lolex": "2.3.2", + "nise": "1.3.3", + "supports-color": "5.4.0", + "type-detect": "4.0.8" }, "dependencies": { "has-flag": { @@ -851,18 +3004,30 @@ "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" } } } }, + "smtp-connection": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-1.3.8.tgz", + "integrity": "sha1-VYMsIWDPswhuHc2H/RwZ+mG39TY=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "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": { @@ -875,8 +3040,8 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "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": { @@ -884,6 +3049,38 @@ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "2.0.5" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "dev": true, + "requires": { + "asn1": "0.2.4", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.2", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.2", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "safer-buffer": "2.1.2", + "tweetnacl": "0.14.5" + } + }, "statuses": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", @@ -894,12 +3091,44 @@ "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.0.6.tgz", "integrity": "sha1-Iff5M/iE9klHxa0+tt10E8tFMco=" }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "dev": true + }, + "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.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -907,21 +3136,28 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, + "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, + "optional": true + }, "superagent": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.2.tgz", "integrity": "sha512-gVH4QfYHcY3P0f/BZzavLreHW3T1v7hG9B+hpMQotGQqurOvhv87GcMCd6LWySmBuf+BDR44TQd0aISjVHLeNQ==", "requires": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.0", - "debug": "^3.1.0", - "extend": "^3.0.0", - "form-data": "^2.3.1", - "formidable": "^1.1.1", - "methods": "^1.1.1", - "mime": "^1.4.1", - "qs": "^6.5.1", - "readable-stream": "^2.0.5" + "component-emitter": "1.2.1", + "cookiejar": "2.1.1", + "debug": "3.1.0", + "extend": "3.0.1", + "form-data": "2.3.2", + "formidable": "1.2.0", + "methods": "1.1.2", + "mime": "1.4.1", + "qs": "6.5.1", + "readable-stream": "2.3.5" }, "dependencies": { "debug": { @@ -939,8 +3175,8 @@ "resolved": "https://registry.npmjs.org/supertest/-/supertest-3.0.0.tgz", "integrity": "sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY=", "requires": { - "methods": "~1.1.2", - "superagent": "^3.0.0" + "methods": "1.1.2", + "superagent": "3.8.2" } }, "supports-color": { @@ -949,7 +3185,35 @@ "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "2.0.0" + } + }, + "tar": { + "version": "2.2.1", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", + "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.5", + "rimraf": "2.6.2", + "tar": "2.2.1", + "uid-number": "0.0.6" } }, "text-encoding": { @@ -957,6 +3221,104 @@ "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "2.3.6", + "xtend": "4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, + "requires": { + "through2": "2.0.5", + "xtend": "4.0.1" + } + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "1.0.0", + "is-negated-glob": "1.0.0" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "1.1.29", + "punycode": "1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "twitter-ng": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/twitter-ng/-/twitter-ng-0.6.2.tgz", + "integrity": "sha1-E3BxFd0Eyb0fLGRtqXZYm+TWS8Q=", + "dev": true, + "requires": { + "oauth": "0.9.15" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -968,14 +3330,114 @@ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.3.25", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.25.tgz", + "integrity": "sha512-hobogryjDV36VrLK3Y69ou4REyrTApzUblVFmdQOYRe8cYaSmFJXMb4dR9McdvYDSbeNdzUgYr2YVukJaErJcA==", + "dev": true, + "requires": { + "commander": "2.15.1", + "source-map": "0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + } + } + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "dev": true, + "optional": true + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dev": true, + "requires": { + "random-bytes": "1.0.0" + } + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "1.0.1", + "through2-filter": "2.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" + } + }, + "utf7": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utf7/-/utf7-1.0.2.tgz", + "integrity": "sha1-lV9JCq5lO6IguUVqCod2wZk2CZE=", + "dev": true, + "requires": { + "semver": "5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -986,13 +3448,29 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uue": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", + "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "extend": "3.0.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "vary": { @@ -1000,16 +3478,116 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "websocket-stream": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.1.2.tgz", + "integrity": "sha512-lchLOk435iDWs0jNuL+hiU14i3ERSrMA0IKSiJh7z6X/i4XNsutBZrtqu2CPOZuA4G/zabiqVAos0vW+S7GEVw==", + "dev": true, + "requires": { + "duplexify": "3.6.1", + "inherits": "2.0.3", + "readable-stream": "2.3.5", + "safe-buffer": "5.1.1", + "ws": "3.3.3", + "xtend": "4.0.1" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1", + "ultron": "1.1.1" + } + } + } + }, "when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=" }, + "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, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "requires": { + "options": "0.0.6", + "ultron": "1.0.2" + }, + "dependencies": { + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", + "dev": true + } + } + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.7" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } } diff --git a/package.json b/package.json index 4e0abac..0c722c9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "node-red": "~0.18.4" }, "devDependencies": { - "mocha": "~5.0.4" + "mocha": "~5.0.4", + "node-red": "~0.18.4" }, "contributors": [ { diff --git a/test/_spec.js b/test/_spec.js index c2b6d89..0a2bc6f 100644 --- a/test/_spec.js +++ b/test/_spec.js @@ -1,11 +1,42 @@ -var should = require("should"); -var helper = require('../index.js'); +const should = require("should"); +const helper = require('../index.js'); describe('_spec.js', function() { - console.log('todo'); + console.log('todo'); - it('should have credentials', function(done) { - helper.should.have.property('credentials'); - done(); - }); -}); \ No newline at end of file + it('should have credentials', function(done) { + helper.should.have.property('credentials'); + done(); + }); +}); + + +describe('load', function() { + + afterEach(async () => { + await helper.unload(); + }); + + const flow = [{id: "n1", type: "helper", name: "helper"}]; + + it('should not throw exception', function() { + helper.load([], flow); + }); + + it('should call callback', function(done) { + should.not.exist(helper.getNode("n1")); + helper.load([], flow, () => { + should.exist(helper.getNode("n1")); + done(); + }); + should.not.exist(helper.getNode("n1")); + }); + + it('should resolve promise', function() { + should.not.exist(helper.getNode("n1")); + helper.load([], flow).then(() => { + should.exist(helper.getNode("n1")); + }); + should.not.exist(helper.getNode("n1")); + }); +}); From dcc296d97a1831b96373550c2595752e1f3092e5 Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 14:47:33 +0100 Subject: [PATCH 2/8] Add a next-function to get single events async. --- index.js | 52 +++++++++++++- test/_spec.js | 194 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 237 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 202f38a..c395953 100644 --- a/index.js +++ b/index.js @@ -218,9 +218,59 @@ class NodeTestHelper extends EventEmitter { * @returns {Node} */ getNode(id) { - return this._redNodes.getNode(id); + const node = this._redNodes.getNode(id); + this.decorateNode(node); + return node; } + decorateNode(node) { + if (node == null || node.testhelper) {return;} + + node.testhelper = {}; + + this.decorateNodeEvent(node, 'input'); + + PROXY_METHODS.forEach(methodName => { + this.decorateNodeEvent(node, `call:${methodName}`); + }); + + const cloneMessage = this._RED.util.cloneMessage; + + node.next = async function(event) { + if (node.testhelper[event].args.length > 0) { + return node.testhelper[event].args.shift(); + } + return new Promise((resolve, reject) => { + node.testhelper[event].resolvers.push(resolve); + }); + } + } + + decorateNodeEvent(node, eventName) { + node.testhelper[eventName] = { + args: [], + resolvers: [] + }; + + node.on(eventName, arg => { + if (eventName === "input") { + arg = this._RED.util.cloneMessage(arg); + } + try { + if (node.testhelper[eventName].resolvers.length > 0) { + const resolver = node.testhelper[eventName].resolvers.shift(); + resolver(arg); + } else { + node.testhelper[eventName].args.push(arg); + } + } catch (e) { + console.log(e); + } + }); + + } + + clearFlows() { return this._redNodes.stopFlows(); } diff --git a/test/_spec.js b/test/_spec.js index 0a2bc6f..1ca3d44 100644 --- a/test/_spec.js +++ b/test/_spec.js @@ -1,24 +1,58 @@ const should = require("should"); const helper = require('../index.js'); +afterEach(async () => { + await helper.unload(); +}); + +const flow = [{id: "n1", type: "helper", name: "helper"}]; + +const flow2 = [ + {id: 'n3', type: 'to', name: 'test name', wires: [['n1'], ['n2']]}, + {id: 'n1', type: 'helper'}, + {id: 'n2', type: 'helper'}, +]; + +const twoOutputOneMessageNode = function(RED) { + function to(config) { + RED.nodes.createNode(this, config); + const node = this; + node.on('input', function(msg) { + node.warn("this is a warning"); + msg.payload = "output1"; + node.send([msg, null]); + msg.payload = "output2"; + node.send([null, msg]); + }); + } + + RED.nodes.registerType("to", to); +}; + +const twoOutputTwoMessagesNode = function(RED) { + function to(config) { + RED.nodes.createNode(this, config); + const node = this; + node.on('input', function(msg) { + node.send([{payload: "output1"}, {payload: "output2"}]); + }); + } + + RED.nodes.registerType("to", to); +}; + describe('_spec.js', function() { console.log('todo'); - it('should have credentials', function(done) { + it('should have credentials', async function() { + await helper.load([], []); helper.should.have.property('credentials'); - done(); }); }); describe('load', function() { - afterEach(async () => { - await helper.unload(); - }); - - const flow = [{id: "n1", type: "helper", name: "helper"}]; - it('should not throw exception', function() { helper.load([], flow); }); @@ -40,3 +74,147 @@ describe('load', function() { should.not.exist(helper.getNode("n1")); }); }); + +describe('on-input', function() { + it('should work with one message', function(done) { + helper.load([], flow, function() { + const n1 = helper.getNode("n1"); + n1.on('input', msg => { + msg.payload.should.equal("works"); + done(); + }); + n1.receive({payload: "works"}); + }); + }); + + it('should work with two outputs, two messages', function(done) { + helper.load([twoOutputTwoMessagesNode], flow2, function() { + try { + const n1 = helper.getNode("n1"); + const n2 = helper.getNode("n2"); + const to = helper.getNode("n3"); + let output1 = false; + let output2 = false; + n1.on('input', msg => { + msg.payload.should.equal("output1"); + output1 = true; + if (output1 && output2) { + done(); + } + }); + n2.on('input', msg => { + msg.payload.should.equal("output2"); + output2 = true; + if (output1 && output2) { + done(); + } + }); + to.receive({payload: "testing"}); + } catch (e) { + done(e); + } + }); + }); + + it('should work with two outputs, modified message', function(done) { + helper.load([twoOutputOneMessageNode], flow2, function() { + try { + const n1 = helper.getNode("n1"); + const n2 = helper.getNode("n2"); + const to = helper.getNode("n3"); + let output1 = false; + let output2 = false; + n1.on('input', msg => { + msg.payload.should.equal("output1"); + output1 = true; + if (output1 && output2) { + done(); + } + }); + n2.on('input', msg => { + msg.payload.should.equal("output2"); + output2 = true; + if (output1 && output2) { + done(); + } + }); + to.receive({payload: "testing"}); + } catch (e) { + done(e); + } + }); + }); +}); + +describe('next input', function() { + + it('should work with one output', async function() { + await helper.load([], flow); + const n1 = helper.getNode("n1"); + n1.receive({payload: "works"}); + const msg = await n1.next('input'); + msg.payload.should.equal("works"); + }); + + it('should work with two outputs, two messages', async function() { + await helper.load([twoOutputTwoMessagesNode], flow2); + const n1 = helper.getNode("n1"); + const n2 = helper.getNode("n2"); + const to = helper.getNode("n3"); + + to.receive({payload: "testing"}); + + let msg = await n1.next('input'); + msg.payload.should.equal("output1"); + msg = await n2.next('input'); + msg.payload.should.equal("output2"); + }); + + it('should work with two outputs, modified message', async function() { + await helper.load([twoOutputOneMessageNode], flow2); + const n1 = helper.getNode("n1"); + const n2 = helper.getNode("n2"); + const to = helper.getNode("n3"); + + to.receive({payload: "testing"}); + + let msg = await n1.next('input'); + msg.payload.should.equal("output1"); + msg = await n2.next('input'); + msg.payload.should.equal("output2"); + }); +}); + +describe('get log events', function() { + + it('should work with event subscription', function(done) { + helper.load(twoOutputOneMessageNode, flow2, function() { + try { + const n3 = helper.getNode("n3"); + n3.on('call:warn', call => { + call.should.be.calledWithExactly('this is a warning'); + done(); + }); + n3.receive({payload: "testing"}); + } catch (e) { + done(e); + } + }); + }); + + it('should work with next', async function() { + await helper.load(twoOutputOneMessageNode, flow2); + const n3 = helper.getNode("n3"); + n3.receive({payload: "testing"}); + let call = await n3.next('call:warn'); + call.should.be.calledWithExactly('this is a warning'); + }); + + it('should work when in opposite order', async function() { + await helper.load(twoOutputOneMessageNode, flow2); + const n3 = helper.getNode("n3"); + process.nextTick(()=>{n3.receive({payload: "testing"})}); + let call = await n3.next('call:warn'); + call.should.be.calledWithExactly('this is a warning'); + }); +}); From bf889388caf3135be93e8cc3ee78b72a70d6d502 Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 20:24:25 +0100 Subject: [PATCH 3/8] Fix problem when stopping server that isn't started, such as during a failed test --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index c395953..61b736f 100644 --- a/index.js +++ b/index.js @@ -204,7 +204,7 @@ class NodeTestHelper extends EventEmitter { unload() { // TODO: any other state to remove between tests? this._redNodes.clearRegistry(); - this._logSpy.restore(); + this._logSpy && this._logSpy.restore(); this._sandbox.restore(); // internal API From 94b8b4caa4ed4a1e7a85ebeda43ba8096e1e5f3f Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 20:25:25 +0100 Subject: [PATCH 4/8] Make startServer and stopServer return promises --- index.js | 40 +++++++++++++++++++++++++--------------- test/_spec.js | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index 61b736f..09306e3 100644 --- a/index.js +++ b/index.js @@ -290,28 +290,38 @@ class NodeTestHelper extends EventEmitter { logging:{console:{level:'off'}} }); server.listen(this._listenPort, this._address); - server.on('listening', () => { - this._port = server.address().port; - // internal API - this._comms.start(); - done(); - }); this._server = server; + return new Promise(resolve => { + server.on('listening', () => { + this._port = server.address().port; + // internal API + this._comms.start(); + done && done(); + resolve(); + }); + }); } //TODO consider saving TCP handshake/server reinit on start/stop/start sequences stopServer(done) { - if (this._server) { - try { - // internal API - this._comms.stop(); - this._server.stop(done); - } catch (e) { + return new Promise(resolve => { + if (typeof done === 'function') { + done = () => {done(); resolve();} + } else { + done = resolve; + } + if (this._server) { + try { + // internal API + this._comms.stop(); + this._server.stop(done); + } catch (e) { + done(); + } + } else { done(); } - } else { - done(); - } + }); } url() { diff --git a/test/_spec.js b/test/_spec.js index 1ca3d44..c126ecc 100644 --- a/test/_spec.js +++ b/test/_spec.js @@ -3,6 +3,7 @@ const helper = require('../index.js'); afterEach(async () => { await helper.unload(); + await helper.stopServer(); }); const flow = [{id: "n1", type: "helper", name: "helper"}]; @@ -51,6 +52,24 @@ describe('_spec.js', function() { }); +describe('start', function() { + + it('should start and call callback', function(done) { + delete helper._server; + helper.startServer(function() { + should.exist(helper._server); + done(); + }); + }); + + it('should start and resolve promise', async function() { + delete helper._server; + await helper.startServer(); + should.exist(helper._server); + }); +}); + + describe('load', function() { it('should not throw exception', function() { From c6136e5226b65787c8a29f3612ffc01da25a11de Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 19:28:39 +0100 Subject: [PATCH 5/8] Copy examples/*_spec.js --- examples/comment_async_spec.js | 38 ++ examples/function_async_spec.js | 582 ++++++++++++++++++++++++++++++ examples/lower-case_async_spec.js | 45 +++ 3 files changed, 665 insertions(+) create mode 100644 examples/comment_async_spec.js create mode 100644 examples/function_async_spec.js create mode 100644 examples/lower-case_async_spec.js diff --git a/examples/comment_async_spec.js b/examples/comment_async_spec.js new file mode 100644 index 0000000..78f9b0c --- /dev/null +++ b/examples/comment_async_spec.js @@ -0,0 +1,38 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var helper = require("../index.js"); +helper.init(require.resolve('node-red')); + +var commentNode = require("./nodes/90-comment.js"); + +describe('comment Node', function() { + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"comment", name: "comment" }]; + helper.load(commentNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'comment'); + done(); + }); + }); + +}); diff --git a/examples/function_async_spec.js b/examples/function_async_spec.js new file mode 100644 index 0000000..1791b18 --- /dev/null +++ b/examples/function_async_spec.js @@ -0,0 +1,582 @@ +/** + * Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var helper = require("../index.js"); +helper.init(require.resolve('node-red')); + +var functionNode = require("./nodes/80-function.js"); + +describe('function node', function() { + + before(function(done) { + helper.startServer(done); + }); + + after(function(done) { + helper.stopServer(done); + }); + + afterEach(function() { + helper.unload(); + }); + + it('should be loaded', function(done) { + var flow = [{id:"n1", type:"function", name: "function" }]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'function'); + done(); + }); + }); + + it('should send returned message', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should send returned message using send()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should pass through _topic', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg.should.have.property('_topic', 'baz'); + done(); + }); + n1.receive({payload:"foo",topic: "bar", _topic: "baz"}); + }); + }); + + it('should send to multiple outputs', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]], + func:"return [{payload: '1'},{payload: '2'}];"}, + {id:"n2", type:"helper"}, {id:"n3", type:"helper"} ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var count = 0; + n2.on("input", function(msg) { + should(msg).have.property('payload', '1'); + count++; + if (count == 2) { + done(); + } + }); + n3.on("input", function(msg) { + should(msg).have.property('payload', '2'); + count++; + if (count == 2) { + done(); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should send to multiple messages', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]], + func:"return [[{payload: 1},{payload: 2}]];"}, + {id:"n2", type:"helper"} ]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + count++; + try { + should(msg).have.property('payload', count); + should(msg).have.property('_msgid', 1234); + if (count == 2) { + done(); + } + } catch(err) { + done(err); + } + }); + n1.receive({payload:"foo", topic: "bar",_msgid:1234}); + }); + }); + + it('should allow input to be discarded by returning null', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return null"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + setTimeout(function() { + done(); + }, 20); + n2.on("input", function(msg) { + should.fail(null,null,"unexpected message"); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle null amongst valid messages', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]],func:"return [[msg,null,msg],null]"}, + {id:"n2", type:"helper"}, + {id:"n3", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n2MsgCount = 0; + var n3MsgCount = 0; + n2.on("input", function(msg) { + n2MsgCount++; + }); + n3.on("input", function(msg) { + n3MsgCount++; + }); + n1.receive({payload:"foo",topic: "bar"}); + setTimeout(function() { + n2MsgCount.should.equal(2); + n3MsgCount.should.equal(0); + done(); + },20); + }); + }); + + it('should get keys in global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.keys();return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + function testNonObjectMessage(functionText,done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n2MsgCount = 0; + n2.on("input", function(msg) { + n2MsgCount++; + }); + n1.receive({}); + setTimeout(function() { + try { + n2MsgCount.should.equal(0); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'function.error.non-message-returned'); + done(); + } catch(err) { + done(err); + } + },20); + }); + } + it('should drop and log non-object message types - string', function(done) { + testNonObjectMessage('return "foo"', done) + }); + it('should drop and log non-object message types - buffer', function(done) { + testNonObjectMessage('return new Buffer("hello")', done) + }); + it('should drop and log non-object message types - array', function(done) { + testNonObjectMessage('return [[[1,2,3]]]', done) + }); + it('should drop and log non-object message types - boolean', function(done) { + testNonObjectMessage('return true', done) + }); + it('should drop and log non-object message types - number', function(done) { + testNonObjectMessage('return 123', done) + }); + + it('should handle and log script error', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"retunr"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.receive({payload:"foo",topic: "bar"}); + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 1, col 1)'); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('should handle node.on()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){node.log('closed')});"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.receive({payload:"foo",topic: "bar"}); + helper.getNode("n1").close(); + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'closed'); + done(); + } catch(err) { + done(err); + } + }); + }); + + it('should set node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get keys in node context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should set flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.flow.get('count');return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get keys in flow context', function(done) { + var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys();return msg;"}, + {id:"n2", type:"helper",z:"flowA"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should set global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().global.get("count").should.equal("0"); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should get global context', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count');return msg;"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle setTimeout()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setTimeout(function(){node.send(msg);},1000);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + var endTime = process.hrtime(startTime); + var nanoTime = endTime[0] * 1000000000 + endTime[1]; + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + if (900000000 < nanoTime && nanoTime < 1100000000) { + done(); + } else { + try { + should.fail(null, null, "Delayed time was not between 900 and 1100 ms"); + } catch (err) { + done(err); + } + } + }); + var startTime = process.hrtime(); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle setInterval()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setInterval(function(){node.send(msg);},100);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var count = 0; + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + count++; + if (count > 2) { + done(); + } + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + it('should handle clearInterval()', function(done) { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"var id=setInterval(null,100);setTimeout(function(){clearInterval(id);node.send(msg);},1000);"}, + {id:"n2", type:"helper"}]; + helper.load(functionNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + done(); + }); + n1.receive({payload:"foo",topic: "bar"}); + }); + }); + + describe('Logger', function () { + it('should log an Info Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.log('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + }); + }); + it('should log a Warning Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.warn('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().WARN); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + }); + }); + it('should log an Error Message', function (done) { + var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.error('test');"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({payload: "foo", topic: "bar"}); + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); + done(); + } catch (err) { + done(err); + } + }); + }); + }); + +}); diff --git a/examples/lower-case_async_spec.js b/examples/lower-case_async_spec.js new file mode 100644 index 0000000..39dc55e --- /dev/null +++ b/examples/lower-case_async_spec.js @@ -0,0 +1,45 @@ +var helper = require("../index.js"); +var lowerNode = require("./nodes/lower-case.js"); + +helper.init(require.resolve('node-red')); + +describe('lower-case Node', function () { + + afterEach(function () { + helper.unload(); + }); + + it('should be loaded', function (done) { + var flow = [{ id: "n1", type: "lower-case", name: "lower-case" }]; + helper.load(lowerNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'lower-case'); + done(); + }); + }); + + it('should be loaded in exported flow', function (done) { + var flow = [{"id":"3912a37a.c3818c","type":"lower-case","z":"e316ac4b.c85a2","name":"lower-case","x":240,"y":320,"wires":[[]]}]; + helper.load(lowerNode, flow, function () { + var n1 = helper.getNode("3912a37a.c3818c"); + n1.should.have.property('name', 'lower-case'); + done(); + }); + }); + + it('should make payload lower case', function (done) { + var flow = [ + { id: "n1", type: "lower-case", name: "test name",wires:[["n2"]] }, + { id: "n2", type: "helper" } + ]; + helper.load(lowerNode, flow, function () { + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n2.on("input", function (msg) { + msg.should.have.property('payload', 'uppercase'); + done(); + }); + n1.receive({ payload: "UpperCase" }); + }); + }); +}); From 22b64df0379029e00d418e1adc43a17f8d27f8ba Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 20:12:32 +0100 Subject: [PATCH 6/8] Change callbacks to promises (and a few callbacks to arrow-style) --- examples/comment_async_spec.js | 14 +- examples/function_async_spec.js | 790 +++++++++++++----------------- examples/lower-case_async_spec.js | 43 +- 3 files changed, 369 insertions(+), 478 deletions(-) diff --git a/examples/comment_async_spec.js b/examples/comment_async_spec.js index 78f9b0c..1a37236 100644 --- a/examples/comment_async_spec.js +++ b/examples/comment_async_spec.js @@ -22,17 +22,15 @@ var commentNode = require("./nodes/90-comment.js"); describe('comment Node', function() { - afterEach(function() { - helper.unload(); + afterEach(async function() { + await helper.unload(); }); - it('should be loaded', function(done) { + it('should be loaded', async function() { var flow = [{id:"n1", type:"comment", name: "comment" }]; - helper.load(commentNode, flow, function() { - var n1 = helper.getNode("n1"); - n1.should.have.property('name', 'comment'); - done(); - }); + await helper.load(commentNode, flow); + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'comment'); }); }); diff --git a/examples/function_async_spec.js b/examples/function_async_spec.js index 1791b18..866ed3a 100644 --- a/examples/function_async_spec.js +++ b/examples/function_async_spec.js @@ -20,562 +20,462 @@ helper.init(require.resolve('node-red')); var functionNode = require("./nodes/80-function.js"); +const sleep = ms => new Promise(resolve => setTimeout(resolve,ms)); + describe('function node', function() { - before(function(done) { - helper.startServer(done); + before(async function() { + await helper.startServer(); }); - after(function(done) { - helper.stopServer(done); + after(async function() { + await helper.stopServer(); }); - afterEach(function() { - helper.unload(); + afterEach(async function() { + await helper.unload(); }); - it('should be loaded', function(done) { + it('should be loaded', async function() { var flow = [{id:"n1", type:"function", name: "function" }]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - n1.should.have.property('name', 'function'); - done(); - }); + await helper.load(functionNode,flow); + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'function'); }); - it('should send returned message', function(done) { + it('should send returned message', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, - {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + {id:"n2",type:"helper"}]; + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic:"bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); }); - it('should send returned message using send()', function(done) { + it('should send returned message using send()', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.send(msg);"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic:"bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); }); - it('should pass through _topic', function(done) { + it('should pass through _topic', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - msg.should.have.property('_topic', 'baz'); - done(); - }); - n1.receive({payload:"foo",topic: "bar", _topic: "baz"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic:"bar", _topic:"baz"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg.should.have.property('_topic', 'baz'); }); - it('should send to multiple outputs', function(done) { + it('should send to multiple outputs', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]], func:"return [{payload: '1'},{payload: '2'}];"}, {id:"n2", type:"helper"}, {id:"n3", type:"helper"} ]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var n3 = helper.getNode("n3"); - var count = 0; - n2.on("input", function(msg) { - should(msg).have.property('payload', '1'); - count++; - if (count == 2) { - done(); - } - }); - n3.on("input", function(msg) { - should(msg).have.property('payload', '2'); - count++; - if (count == 2) { - done(); - } - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + + n1.receive({payload:"foo",topic:"bar"}); + let msg = await n2.next("input"); + should(msg).have.property('payload', '1'); + msg = await n3.next("input"); + should(msg).have.property('payload', '2'); }); - it('should send to multiple messages', function(done) { + it('should send to multiple messages', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]], func:"return [[{payload: 1},{payload: 2}]];"}, {id:"n2", type:"helper"} ]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var count = 0; - n2.on("input", function(msg) { - count++; - try { - should(msg).have.property('payload', count); - should(msg).have.property('_msgid', 1234); - if (count == 2) { - done(); - } - } catch(err) { - done(err); - } - }); - n1.receive({payload:"foo", topic: "bar",_msgid:1234}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo", topic: "bar",_msgid:1234}); + let msg = await n2.next("input"); + should(msg).have.property('payload', 1); + should(msg).have.property('_msgid', 1234); + msg = await n2.next("input"); + should(msg).have.property('payload', 2); + should(msg).have.property('_msgid', 1234); }); - it('should allow input to be discarded by returning null', function(done) { + it('should allow input to be discarded by returning null', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"return null"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - setTimeout(function() { - done(); - }, 20); - n2.on("input", function(msg) { - should.fail(null,null,"unexpected message"); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + await Promise.race([ + n2.next("input").then(() => should.fail(null,null,"unexpected message")), + sleep(20) + ]); }); - it('should handle null amongst valid messages', function(done) { + it('should handle null amongst valid messages', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"],["n3"]],func:"return [[msg,null,msg],null]"}, {id:"n2", type:"helper"}, {id:"n3", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var n3 = helper.getNode("n3"); - var n2MsgCount = 0; - var n3MsgCount = 0; - n2.on("input", function(msg) { - n2MsgCount++; - }); - n3.on("input", function(msg) { - n3MsgCount++; - }); - n1.receive({payload:"foo",topic: "bar"}); - setTimeout(function() { - n2MsgCount.should.equal(2); - n3MsgCount.should.equal(0); - done(); - },20); - }); - }); - - it('should get keys in global context', function(done) { + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var n3 = helper.getNode("n3"); + var n2MsgCount = 0; + var n3MsgCount = 0; + + n1.receive({payload:"foo",topic:"bar"}); + await n2.next("input"); + await n2.next("input"); + await Promise.race([ + n2.next("input").then(() => {should.fail(null,null,"unexpected message")}), + n3.next("input").then(() => {should.fail(null,null,"unexpected message")}), + sleep(20) + ]); + }); + + it('should get keys in global context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.keys();return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().global.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', ['count']); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); }); - function testNonObjectMessage(functionText,done) { + async function testNonObjectMessage(functionText) { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:functionText}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var n2MsgCount = 0; - n2.on("input", function(msg) { - n2MsgCount++; - }); - n1.receive({}); - setTimeout(function() { - try { - n2MsgCount.should.equal(0); - var logEvents = helper.log().args.filter(function(evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().ERROR); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'function.error.non-message-returned'); - done(); - } catch(err) { - done(err); - } - },20); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({}); + await sleep(20); + + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + let msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'function.error.non-message-returned'); + + await Promise.race([ + n2.next("input").then(() => {should.fail(null,null,"unexpected message")}), + sleep(20) + ]); } - it('should drop and log non-object message types - string', function(done) { - testNonObjectMessage('return "foo"', done) + + it('should drop and log non-object message types - string', async function() { + await testNonObjectMessage('return "foo"') }); - it('should drop and log non-object message types - buffer', function(done) { - testNonObjectMessage('return new Buffer("hello")', done) + it('should drop and log non-object message types - buffer', async function() { + await testNonObjectMessage('return new Buffer("hello")') }); - it('should drop and log non-object message types - array', function(done) { - testNonObjectMessage('return [[[1,2,3]]]', done) + it('should drop and log non-object message types - array', async function() { + await testNonObjectMessage('return [[[1,2,3]]]') }); - it('should drop and log non-object message types - boolean', function(done) { - testNonObjectMessage('return true', done) + it('should drop and log non-object message types - boolean', async function() { + await testNonObjectMessage('return true') }); - it('should drop and log non-object message types - number', function(done) { - testNonObjectMessage('return 123', done) + it('should drop and log non-object message types - number', async function() { + await testNonObjectMessage('return 123') }); - it('should handle and log script error', function(done) { + it('should handle and log script error', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"retunr"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - n1.receive({payload:"foo",topic: "bar"}); - try { - helper.log().called.should.be.true(); - var logEvents = helper.log().args.filter(function(evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().ERROR); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 1, col 1)'); - done(); - } catch(err) { - done(err); - } - }); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); - it('should handle node.on()', function(done) { - var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){node.log('closed')});"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - n1.receive({payload:"foo",topic: "bar"}); - helper.getNode("n1").close(); - try { - helper.log().called.should.be.true(); - var logEvents = helper.log().args.filter(function(evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().INFO); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'closed'); - done(); - } catch(err) { - done(err); - } - }); + n1.receive({payload:"foo",topic: "bar"}); + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 1, col 1)'); }); - it('should set node context', function(done) { + it('should handle node.on()', async function() { + var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"node.on('close',function(){node.log('closed')});"}]; + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + + n1.receive({payload:"foo",topic: "bar"}); + helper.getNode("n1").close(); + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'closed'); + }); + + it('should set node context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"context.set('count','0');return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - n1.context().get("count").should.equal("0"); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n1.context().get("count").should.equal("0"); }); - it('should get node context', function(done) { + it('should get node context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.get('count');return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', '0'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); }); - it('should get keys in node context', function(done) { + it('should get keys in node context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.keys();return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', ['count']); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); }); - it('should set flow context', function(done) { + it('should set flow context', async function() { var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"flow.set('count','0');return msg;"}, {id:"n2", type:"helper",z:"flowA"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - n2.context().flow.get("count").should.equal("0"); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().flow.get("count").should.equal("0"); }); - it('should get flow context', function(done) { + it('should get flow context', async function() { var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.get('count');return msg;"}, {id:"n2", type:"helper",z:"flowA"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().flow.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', '0'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.context().flow.set("count","0"); + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); }); - it('should get flow context', function(done) { + it('should get flow context', async function() { var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=context.flow.get('count');return msg;"}, {id:"n2", type:"helper",z:"flowA"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().flow.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', '0'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); }); - it('should get keys in flow context', function(done) { + it('should get keys in flow context', async function() { var flow = [{id:"n1",type:"function",z:"flowA",wires:[["n2"]],func:"msg.payload=flow.keys();return msg;"}, {id:"n2", type:"helper",z:"flowA"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().flow.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', ['count']); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().flow.set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', ['count']); }); - it('should set global context', function(done) { + it('should set global context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"global.set('count','0');return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - n2.context().global.get("count").should.equal("0"); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + n2.context().global.get("count").should.equal("0"); }); - it('should get global context', function(done) { + it('should get global context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=global.get('count');return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().global.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', '0'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); }); - it('should get global context', function(done) { + it('should get global context', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"msg.payload=context.global.get('count');return msg;"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n1.context().global.set("count","0"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', '0'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n1.context().global.set("count","0"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', '0'); }); - it('should handle setTimeout()', function(done) { + it('should handle setTimeout()', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setTimeout(function(){node.send(msg);},1000);"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - var endTime = process.hrtime(startTime); - var nanoTime = endTime[0] * 1000000000 + endTime[1]; - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - if (900000000 < nanoTime && nanoTime < 1100000000) { - done(); - } else { - try { - should.fail(null, null, "Delayed time was not between 900 and 1100 ms"); - } catch (err) { - done(err); - } - } - }); - var startTime = process.hrtime(); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + var startTime = process.hrtime(); + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + var endTime = process.hrtime(startTime); + var nanoTime = endTime[0] * 1000000000 + endTime[1]; + + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + if (900000000 > nanoTime || nanoTime > 1100000000) { + should.fail(null, null, "Delayed time was not between 900 and 1100 ms"); + } }); - it('should handle setInterval()', function(done) { + it('should handle setInterval()', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"setInterval(function(){node.send(msg);},100);"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - var count = 0; - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - count++; - if (count > 2) { - done(); - } - }); - n1.receive({payload:"foo",topic: "bar"}); - }); - }); - - it('should handle clearInterval()', function(done) { + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); + }); + + it('should handle clearInterval()', async function() { var flow = [{id:"n1",type:"function",wires:[["n2"]],func:"var id=setInterval(null,100);setTimeout(function(){clearInterval(id);node.send(msg);},1000);"}, {id:"n2", type:"helper"}]; - helper.load(functionNode, flow, function() { - var n1 = helper.getNode("n1"); - var n2 = helper.getNode("n2"); - n2.on("input", function(msg) { - msg.should.have.property('topic', 'bar'); - msg.should.have.property('payload', 'foo'); - done(); - }); - n1.receive({payload:"foo",topic: "bar"}); - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + + n1.receive({payload:"foo",topic: "bar"}); + let msg = await n2.next("input"); + msg.should.have.property('topic', 'bar'); + msg.should.have.property('payload', 'foo'); }); - describe('Logger', function () { - it('should log an Info Message', function (done) { + describe('Logger',function() { + it('should log an Info Message', async function() { var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.log('test');"}]; - helper.load(functionNode, flow, function () { - var n1 = helper.getNode("n1"); - n1.receive({payload: "foo", topic: "bar"}); - try { - helper.log().called.should.be.true(); - var logEvents = helper.log().args.filter(function (evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().INFO); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'test'); - done(); - } catch (err) { - done(err); - } - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + + n1.receive({payload: "foo", topic: "bar"}); + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().INFO); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); }); - it('should log a Warning Message', function (done) { + + it('should log a Warning Message', async function() { var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.warn('test');"}]; - helper.load(functionNode, flow, function () { - var n1 = helper.getNode("n1"); - n1.receive({payload: "foo", topic: "bar"}); - try { - helper.log().called.should.be.true(); - var logEvents = helper.log().args.filter(function (evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().WARN); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'test'); - done(); - } catch (err) { - done(err); - } - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + + n1.receive({payload: "foo", topic: "bar"}); + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().WARN); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); }); - it('should log an Error Message', function (done) { + + it('should log an Error Message', async function() { var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "node.error('test');"}]; - helper.load(functionNode, flow, function () { - var n1 = helper.getNode("n1"); - n1.receive({payload: "foo", topic: "bar"}); - try { - helper.log().called.should.be.true(); - var logEvents = helper.log().args.filter(function (evt) { - return evt[0].type == "function"; - }); - logEvents.should.have.length(1); - var msg = logEvents[0][0]; - msg.should.have.property('level', helper.log().ERROR); - msg.should.have.property('id', 'n1'); - msg.should.have.property('type', 'function'); - msg.should.have.property('msg', 'test'); - done(); - } catch (err) { - done(err); - } - }); + await helper.load(functionNode, flow); + var n1 = helper.getNode("n1"); + + n1.receive({payload: "foo", topic: "bar"}); + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(evt => evt[0].type == "function"); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + msg.should.have.property('msg', 'test'); }); }); diff --git a/examples/lower-case_async_spec.js b/examples/lower-case_async_spec.js index 39dc55e..7181aee 100644 --- a/examples/lower-case_async_spec.js +++ b/examples/lower-case_async_spec.js @@ -5,41 +5,34 @@ helper.init(require.resolve('node-red')); describe('lower-case Node', function () { - afterEach(function () { - helper.unload(); + afterEach(async function () { + await helper.unload(); }); - it('should be loaded', function (done) { - var flow = [{ id: "n1", type: "lower-case", name: "lower-case" }]; - helper.load(lowerNode, flow, function () { - var n1 = helper.getNode("n1"); - n1.should.have.property('name', 'lower-case'); - done(); - }); + it('should be loaded', async function () { + var flow = [{id: "n1", type: "lower-case", name: "lower-case"}]; + await helper.load(lowerNode, flow); + var n1 = helper.getNode("n1"); + n1.should.have.property('name', 'lower-case'); }); - it('should be loaded in exported flow', function (done) { + it('should be loaded in exported flow', async function () { var flow = [{"id":"3912a37a.c3818c","type":"lower-case","z":"e316ac4b.c85a2","name":"lower-case","x":240,"y":320,"wires":[[]]}]; - helper.load(lowerNode, flow, function () { - var n1 = helper.getNode("3912a37a.c3818c"); - n1.should.have.property('name', 'lower-case'); - done(); - }); + await helper.load(lowerNode, flow); + var n1 = helper.getNode("3912a37a.c3818c"); + n1.should.have.property('name', 'lower-case'); }); - it('should make payload lower case', function (done) { + it('should make payload lower case', async function () { var flow = [ { id: "n1", type: "lower-case", name: "test name",wires:[["n2"]] }, { id: "n2", type: "helper" } ]; - helper.load(lowerNode, flow, function () { - var n2 = helper.getNode("n2"); - var n1 = helper.getNode("n1"); - n2.on("input", function (msg) { - msg.should.have.property('payload', 'uppercase'); - done(); - }); - n1.receive({ payload: "UpperCase" }); - }); + await helper.load(lowerNode, flow); + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + n1.receive({ payload: "UpperCase" }); + let msg = await n2.next("input"); + msg.should.have.property('payload', 'uppercase'); }); }); From 6ec9e91229d463acb54ba41ea2a86e14aa69f39d Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Sun, 18 Nov 2018 21:38:43 +0100 Subject: [PATCH 7/8] Don't use "async" so we don't require ES2017. --- index.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 09306e3..fa73b33 100644 --- a/index.js +++ b/index.js @@ -118,7 +118,7 @@ class NodeTestHelper extends EventEmitter { } } - async load(testNode, testFlow, testCredentials, cb) { + load(testNode, testFlow, testCredentials, cb) { const log = this._log; const logSpy = this._logSpy = this._sandbox.spy(log, 'log'); logSpy.FATAL = log.FATAL; @@ -193,12 +193,14 @@ class NodeTestHelper extends EventEmitter { testNode(red); } - await redNodes.loadFlows(); - redNodes.startFlows(); - should.deepEqual(testFlow, redNodes.getFlows().flows); - if (typeof cb === 'function') { - cb(); - } + return redNodes.loadFlows() + .then(() => { + redNodes.startFlows(); + should.deepEqual(testFlow, redNodes.getFlows().flows); + if (typeof cb === 'function') { + cb(); + } + }); } unload() { @@ -236,7 +238,7 @@ class NodeTestHelper extends EventEmitter { const cloneMessage = this._RED.util.cloneMessage; - node.next = async function(event) { + node.next = function(event) { if (node.testhelper[event].args.length > 0) { return node.testhelper[event].args.shift(); } From bb6305fc9550d6feb838bc2fcba17299a88932f8 Mon Sep 17 00:00:00 2001 From: Niels Ulrik Andersen Date: Mon, 19 Nov 2018 12:06:11 +0100 Subject: [PATCH 8/8] Document API --- README.md | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5f5e287..ad9f26a 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ it('should warn if the `somethingGood` prop is falsy', function (done) { /* ..etc.. */ }; helper.load(FooNode, flow, function () { + var n1 = helper.getNode("n1"); n1.warn.should.be.calledWithExactly('badness'); done(); }); @@ -289,14 +290,14 @@ For additional test examples taken from the Node-RED core, see the `.js` files s > *Work in progress.* -### load(testNode, testFlows, testCredentials, cb) +### load(testNode, testFlows[, testCredentials][, cb]) -Loads a flow then starts the flow. This function has the following arguments: +Return a promise to load a flow then start the flow. This function has the following arguments: * testNode: (object|array of objects) Module object of a node to be tested returned by require function. This node will be registered, and can be used in testFlows. * testFlow: (array of objects) Flow data to test a node. If you want to use flow data exported from Node-RED editor, export the flow to the clipboard and paste the content into your test scripts. * testCredentials: (object) Optional node credentials. -* cb: (function) Function to call back when testFlows has been started. +* cb: (function) Optional function to call back when testFlows has been started. ### unload() @@ -306,9 +307,34 @@ Return promise to stop all flows, clean up test runtime. Returns a node instance by id in the testFlow. Any node that is defined in testFlows can be retrieved, including any helper node added to the flow. +An extra method is added to the node: + +* next(event) + Alternative to on(event, callback) for async/await style programming. Returns promise to find the next event in queue. If there is no events in queue, the promise itself will be queued. + + If the event is input, a clone of the message will be returned. + + Example: + + ````javascript + it('should make payload lower case', async function() { + var flow = [ + {id:"n1",type:"lower-case",name:"test name",wires:[["n2"]]}, + {id:"n2",type:"helper"} + ]; + await helper.load(lowerNode, flow); + var n2 = helper.getNode("n2"); + var n1 = helper.getNode("n1"); + + n1.receive({payload:"UpperCase"}); + let msg = await n2.next("input"); + msg.should.have.property('payload', 'uppercase'); + }); + ```` + ### clearFlows() -Stop all flows. +Return promise to stop all flows. ### request() @@ -320,9 +346,9 @@ Example: helper.request().post('/inject/invalid').expect(404).end(done); ``` -### startServer(done) +### startServer([done]) -Starts a Node-RED server for testing nodes that depend on http or web sockets endpoints like the debug node. +Return promise to start a Node-RED server for testing nodes that depend on http or web sockets endpoints like the debug node. To start a Node-RED server before all test cases: ```javascript @@ -331,9 +357,9 @@ before(function(done) { }); ``` -### stopServer(done) +### stopServer([done]) -Stop server. Generally called after unload() complete. For example, to unload a flow then stop a server after each test: +Return promise to stop server. Generally called after unload() complete. For example, to unload a flow then stop a server after each test: ```javascript afterEach(function(done) {