From bc15d2590cdb16e09100df84fa0333400f55f674 Mon Sep 17 00:00:00 2001 From: deanchen Date: Sat, 12 Jun 2021 10:29:08 +0800 Subject: [PATCH 01/15] chore: mq install mq lib; create test on it; --- package-lock.json | 319 +++++++++++++++++++++++++++--- package.json | 2 + server/services/MQConfig.js | 27 +++ server/services/MQService.js | 31 +++ server/services/MQService.spec.js | 23 +++ 5 files changed, 371 insertions(+), 31 deletions(-) create mode 100644 server/services/MQConfig.js create mode 100644 server/services/MQService.js create mode 100644 server/services/MQService.spec.js diff --git a/package-lock.json b/package-lock.json index 5596dd20..575284e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "treetracker", - "version": "1.13.0", + "version": "1.14.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -82,6 +82,15 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/runtime-corejs3": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz", + "integrity": "sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg==", + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, "@commitlint/cli": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", @@ -823,6 +832,47 @@ "uri-js": "^4.2.2" } }, + "amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "requires": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "ansi-align": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", @@ -1181,8 +1231,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "at-least-node": { "version": "1.0.0", @@ -1269,11 +1318,35 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, + "bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { "version": "1.19.0", @@ -1376,6 +1449,11 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", @@ -1435,7 +1513,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1725,7 +1802,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -1858,8 +1934,7 @@ "cookiejar": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, "copy-descriptor": { "version": "0.1.1", @@ -1872,11 +1947,15 @@ "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", "dev": true }, + "core-js-pure": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.14.0.tgz", + "integrity": "sha512-YVh+LN2FgNU0odThzm61BsdkwrbrchumFq3oztnE9vTKC4KS2fvnPmcx8t6jnqAyOTCTF4ZSiuK8Qhh7SNcL4g==" + }, "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=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "7.0.0", @@ -2247,6 +2326,11 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, + "deep-freeze": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", + "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2307,8 +2391,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "depd": { "version": "1.1.2", @@ -3128,6 +3211,11 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -3296,8 +3384,12 @@ "formidable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", - "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", - "dev": true + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" + }, + "forward-emitter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/forward-emitter/-/forward-emitter-0.1.1.tgz", + "integrity": "sha1-Vu3QwIIlDtujNOC5Iv/SwBk53uE=" }, "forwarded": { "version": "0.1.2", @@ -3344,8 +3436,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -3359,6 +3450,11 @@ "integrity": "sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ==", "dev": true }, + "generic-pool": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.7.8.tgz", + "integrity": "sha512-Pz93INFSbhjEROVbM91rurD05G+Kx8833rG+lVU57mznEBpzkc1f5/g+d511a1Yf8dbAEsm7DDA3QLytMFbiGA==" + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3369,7 +3465,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3513,7 +3608,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -3532,8 +3626,7 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-value": { "version": "1.0.0", @@ -3865,6 +3958,11 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, + "individual": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz", + "integrity": "sha1-gzsJfa0jKU52EXqY+zjg2a1hu5c=" + }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -4635,8 +4733,7 @@ "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 + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" }, "lodash.get": { "version": "4.4.2", @@ -4679,6 +4776,11 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -4733,7 +4835,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -6202,6 +6303,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -6222,6 +6328,96 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "rascal": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/rascal/-/rascal-13.0.3.tgz", + "integrity": "sha512-zj+roDwfUZcXvzacyT9lGVh5vp1aivFdY5/9AXfaLJcHB7ZmGw2kkzKdRZOjLkJ5VPIVjFIWBffxelp0xMQ5xw==", + "requires": { + "async": "^3.2.0", + "debug": "^4.1.1", + "deep-freeze": "0.0.1", + "forward-emitter": "^0.1.1", + "generic-pool": "^3.7.1", + "lodash": "^4.17.21", + "lru-cache": "^6.0.0", + "safe-json-parse": "^4.0.0", + "stashback": "^1.1.2", + "superagent": "^6.1.0", + "uuid": "^8.3.2", + "xregexp": "^5.0.1" + }, + "dependencies": { + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", @@ -6381,8 +6577,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "regex-not": { "version": "1.0.2", @@ -6437,6 +6632,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -6519,11 +6719,27 @@ "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", "dev": true }, + "rust-result": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz", + "integrity": "sha1-NMdbLm3Dn+WHXlveyFteD5FTb3I=", + "requires": { + "individual": "^2.0.0" + } + }, "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==" }, + "safe-json-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz", + "integrity": "sha1-fA9XjPzNEtM6ccDgVBPi7KFx6qw=", + "requires": { + "rust-result": "^1.0.0" + } + }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -6679,6 +6895,23 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "dependencies": { + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + } + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -7003,6 +7236,16 @@ } } }, + "stashback": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/stashback/-/stashback-1.1.3.tgz", + "integrity": "sha512-MS4X5BV7JJG8GE6IR1X3Y2HEZH3L407KlevQlnadmCLL32ORBvK6Ojm/MtB12MF/XngYgHHSucaNG+tcLmK8jg==", + "requires": { + "debug": "^4.1.1", + "lodash.defaults": "^4.2.0", + "lodash.reduce": "^4.6.0" + } + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -7092,7 +7335,6 @@ "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.0" } @@ -7564,6 +7806,15 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, + "url-parse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", @@ -7597,8 +7848,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utile": { "version": "0.3.0", @@ -7855,6 +8105,14 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xregexp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-5.0.2.tgz", + "integrity": "sha512-JPNfN40YMNSDxZrahMrmtNH1QqPJp0/qNeEJM2nnOlhcBdfCCjekPYFV2OnwKxwvpEYglH1RBotbpRRaEuCG8Q==", + "requires": { + "@babel/runtime-corejs3": "^7.12.1" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -7869,8 +8127,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.0", diff --git a/package.json b/package.json index 79917c1d..89c737a4 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "license": "GPL-3.0-or-later", "dependencies": { "@sentry/node": "^5.1.0", + "amqplib": "^0.8.0", "bcryptjs": "^2.4.3", "body-parser": "^1.18.2", "chai-uuid": "^1.0.6", @@ -50,6 +51,7 @@ "morgan": "^1.9.1", "nodemon": "^2.0.4", "pg": "^8.5.1", + "rascal": "^13.0.3", "uuid": "^8.2.0" }, "devDependencies": { diff --git a/server/services/MQConfig.js b/server/services/MQConfig.js new file mode 100644 index 00000000..3a88e0dc --- /dev/null +++ b/server/services/MQConfig.js @@ -0,0 +1,27 @@ +module.exports = { + config: { + "vhosts": { + "test": { + "connection": { + "url": process.env.RABBIT_MQ_URL, + "socketOptions": { + "timeout": 1000 + } + }, + "exchanges": ["field-data"], + "queues": ["field-data-events", "field-data:verifications"], + "publications": { + "raw-capture-created": { + "exchange": "field-data" + } + }, + "subscriptions": { + "admin-verification": { + "queue": "field-data:verifications" + } + } + } + } + } +} + diff --git a/server/services/MQService.js b/server/services/MQService.js new file mode 100644 index 00000000..e64f206b --- /dev/null +++ b/server/services/MQService.js @@ -0,0 +1,31 @@ +const Broker = require('rascal').BrokerAsPromised; +const config = require("./MQConfig").config; +const HttpError = require("../utils/HttpError"); + +class MQService{ + + constructor(session){ + this._settsion = session; + } + + async sendMessage(payload){ + try { + const broker = await Broker.create(config); + const publication = await broker.publish("raw-capture-created", payload, "field-data.capture.creation"); + publication + // eslint-disable-next-line + .on("success", resultHandler) + .on("error", (err, messageId)=> { + console.error(`Error with id ${messageId} ${err.message}`); + throw err; + }); + } catch(err) { + console.error(`Error publishing message ${err}`); + throw new HttpError(500, `Error publishing message ${err}`); + } + } + + +} + +module.exports = MQService; diff --git a/server/services/MQService.spec.js b/server/services/MQService.spec.js new file mode 100644 index 00000000..3266d048 --- /dev/null +++ b/server/services/MQService.spec.js @@ -0,0 +1,23 @@ +const MQService = require("./MQService"); +const Broker = require('rascal').BrokerAsPromised; +const sinon = require("sinon"); + +describe("MQService", () => { + + afterEach(() => { + sinon.restore(); + }); + + it.only("send message", async () => { + sinon.stub(Broker, "create").returns({ + publish: () => console.log("publish"), + }); + // eslint-disable-next-line + mqService = new MQService(); + + // eslint-disable-next-line + await mqService.sendMessage({a:1}); + + }); + +}); From e2c4ad8e2e001da77d6b6faff426fda805a6fa47 Mon Sep 17 00:00:00 2001 From: deanchen Date: Wed, 16 Jun 2021 11:38:13 +0800 Subject: [PATCH 02/15] chore: can test repo and transfer service --- server/models/Wallet.js | 2 +- server/repositories/TransferRepository.js | 12 +++++ .../repositories/TransferRepository.spec.js | 20 ++++++++ server/services/MQService.js | 38 ++++++++------ server/services/MQService.spec.js | 51 ++++++++++++++++--- server/services/TransferService.js | 44 ++++++++++++++-- server/services/TransferService.spec.js | 47 +++++++++++++++++ 7 files changed, 187 insertions(+), 27 deletions(-) diff --git a/server/models/Wallet.js b/server/models/Wallet.js index 96ac5d52..c165900b 100644 --- a/server/models/Wallet.js +++ b/server/models/Wallet.js @@ -21,7 +21,7 @@ class Wallet{ this._id = idOrJSON.id; this._JSON = idOrJSON; }else{ - throw new HttpError(500); + throw new HttpError(500, "Wrong constructor arg for wallet"); } const WalletService = require("../services/WalletService"); this.walletRepository = new WalletRepository(session); diff --git a/server/repositories/TransferRepository.js b/server/repositories/TransferRepository.js index a4a89f30..4dc457a3 100644 --- a/server/repositories/TransferRepository.js +++ b/server/repositories/TransferRepository.js @@ -28,6 +28,18 @@ class TransferRepository extends BaseRepository{ state: Transfer.STATE.pending, }); } + + async getTokensById(id){ + return await this._session.getDB().raw( + ` + SELECT token_id, capture_id FROM "transaction" tr + LEFT JOIN "token" t + ON tr.token_id = t.id + WHERE transfer_id = ? + `, + [id], + ); + } } module.exports = TransferRepository; diff --git a/server/repositories/TransferRepository.spec.js b/server/repositories/TransferRepository.spec.js index b3cc4b24..3d5f5da1 100644 --- a/server/repositories/TransferRepository.spec.js +++ b/server/repositories/TransferRepository.spec.js @@ -6,6 +6,7 @@ const knex = require("../database/knex"); const tracker = mockKnex.getTracker(); const Session = require("../models/Session"); const uuid = require('uuid'); +const sinon = require('sinon'); describe("TransferRepository", () => { let transferRepository; @@ -74,5 +75,24 @@ describe("TransferRepository", () => { expect(result).lengthOf(1); }); + it("getTokensById", async () => { + const data = [{ + capture_id: "c", + token_id: "t", + }]; + tracker.uninstall(); + tracker.install(); + tracker.on('query', function sendResult(query, step) { + [ + function firstQuery() { + expect(query.sql).match(/capture_id/); + query.response(data); + }, + ][step - 1](); + }); + const result = await transferRepository.getTokensById(1); + sinon.assert.match(result, data); + }); + }); diff --git a/server/services/MQService.js b/server/services/MQService.js index e64f206b..1eee42f8 100644 --- a/server/services/MQService.js +++ b/server/services/MQService.js @@ -1,6 +1,7 @@ const Broker = require('rascal').BrokerAsPromised; const config = require("./MQConfig").config; const HttpError = require("../utils/HttpError"); +const log = require("loglevel"); class MQService{ @@ -8,24 +9,29 @@ class MQService{ this._settsion = session; } - async sendMessage(payload){ - try { - const broker = await Broker.create(config); - const publication = await broker.publish("raw-capture-created", payload, "field-data.capture.creation"); - publication - // eslint-disable-next-line - .on("success", resultHandler) - .on("error", (err, messageId)=> { - console.error(`Error with id ${messageId} ${err.message}`); - throw err; + sendMessage(payload){ + return new Promise((resolve, reject) => { + const broker = Broker.create(config); + // TODO + Promise.resolve(broker) + .then(broker => { + broker.publish("raw-capture-created", payload, "field-data.capture.creation") + .then(publication => { + publication + .on("success", () => resolve(true)) + .on("error", (err, messageId)=> { + const error = `Error with id ${messageId} ${err.message}`; + log.error(error); + reject(new HttpError(500, error)); + }); + }) + .catch(err => { + log.error(err); + reject(new HttpError(500, `Error publishing message ${err}`)); + }) }); - } catch(err) { - console.error(`Error publishing message ${err}`); - throw new HttpError(500, `Error publishing message ${err}`); - } + }); } - - } module.exports = MQService; diff --git a/server/services/MQService.spec.js b/server/services/MQService.spec.js index 3266d048..933f6d8f 100644 --- a/server/services/MQService.spec.js +++ b/server/services/MQService.spec.js @@ -1,6 +1,8 @@ const MQService = require("./MQService"); const Broker = require('rascal').BrokerAsPromised; const sinon = require("sinon"); +const {expect} = require("chai"); +const jestExpect = require("expect"); describe("MQService", () => { @@ -8,15 +10,52 @@ describe("MQService", () => { sinon.restore(); }); - it.only("send message", async () => { + it("send message successfully", async () => { + const broker = { + publish: async () => { + console.log("publish"); + return { + on(event, handler){ + // mock the success event + if(event === "success"){ + setImmediate(handler); + } + return this; + } + } + } + }; + sinon.spy(broker, "publish"); + sinon.stub(Broker, "create").resolves(broker); + const mqService = new MQService(); + + const payload = {a:1}; + const result = await mqService.sendMessage(payload); + expect(result).eq(true); + sinon.assert.calledWith(broker.publish, "raw-capture-created", payload, "field-data.capture.creation"); + + }); + + it("send message with problem", async () => { sinon.stub(Broker, "create").returns({ - publish: () => console.log("publish"), + publish: async () => { + console.log("publish"); + return { + on(event, handler){ + // mock the error event + if(event === "error"){ + setImmediate(() => handler(new Error("Message sending wrong"), "No.1")); + } + return this; + } + } + } }); - // eslint-disable-next-line - mqService = new MQService(); + const mqService = new MQService(); - // eslint-disable-next-line - await mqService.sendMessage({a:1}); + await jestExpect(async () => { + await mqService.sendMessage({a:1}); + }).rejects.toThrow(/Message sending wrong/); }); diff --git a/server/services/TransferService.js b/server/services/TransferService.js index 1097f923..1d07afd4 100644 --- a/server/services/TransferService.js +++ b/server/services/TransferService.js @@ -1,9 +1,14 @@ const WalletService = require('./WalletService'); +const MQService = require("./MQService"); +const log = require("loglevel"); +const TransferRepository = require('../repositories/TransferRepository'); class TransferService { constructor(session) { this._session = session; - this.walletService = new WalletService(session); + this._walletService = new WalletService(session); + this._mqService = new MQService(); + this._transferRepository = new TransferRepository(session); } async convertToResponse(transferObject) { @@ -14,25 +19,56 @@ class TransferService { } = transferObject; const result = { ...transferObject }; { - const wallet = await this.walletService.getById(originator_wallet_id); + const wallet = await this._walletService.getById(originator_wallet_id); const json = await wallet.toJSON(); result.originating_wallet = json.name; delete result.originator_wallet_id; } { - const wallet = await this.walletService.getById(source_wallet_id); + const wallet = await this._walletService.getById(source_wallet_id); const json = await wallet.toJSON(); result.source_wallet = await json.name; delete result.source_wallet_id; } { - const wallet = await this.walletService.getById(destination_wallet_id); + const wallet = await this._walletService.getById(destination_wallet_id); const json = await wallet.toJSON(); result.destination_wallet = await json.name; delete result.destination_wallet_id; } return result; } + + /* + * Send message to queue, inform about the transfer detail, token, and + * associated tree/capture + * + { + "type": "TokensAssigned", + "wallet_name": "joeswallet", + "entries": [ + { "capture_id": "63e00bca-8eb0-11eb-8dcd-0242ac130003", "token_id": "9d7abad8-8eb0-11eb-8dcd-0242ac130003" }, + { "capture_id": "8533b704-8eb0-11eb-8dcd-0242ac130003", "token_id":"a5799d94-8eb0-11eb-8dcd-0242ac130003" } ] + } + */ + async sendMessage(transferId){ + log.debug("send message"); + const transfer = await this._transferRepository.getById(transferId); + const walletReceiver = await this._walletService.getById(transfer.destination_wallet_id); + const walletReceiverObj = await walletReceiver.toJSON(); + const walletSender = await this._walletService.getById(transfer.source_wallet_id); + const walletSenderObj = await walletSender.toJSON(); + const tokenData = await this._transferRepository.getTokensById(transferId); + const message = { + transfer_id: transferId, + type: "TokensAssigned", + wallet_name : walletReceiverObj.name, + wallet_name_sender : walletSenderObj.name, + entries: tokenData, + }; + this._mqService.sendMessage(message); + } + } module.exports = TransferService; diff --git a/server/services/TransferService.spec.js b/server/services/TransferService.spec.js index 53412797..a7d1c128 100644 --- a/server/services/TransferService.spec.js +++ b/server/services/TransferService.spec.js @@ -10,6 +10,8 @@ chai.use(sinonChai); const { expect } = chai; const Session = require('../models/Session'); const Wallet = require('../models/Wallet'); +const MQService = require("./MQService"); +const TransferRepository = require("../repositories/TransferRepository"); describe('TransferService', () => { let transferService; @@ -43,4 +45,49 @@ describe('TransferService', () => { expect(result).property('originating_wallet').eq('testName'); expect(result).property('destination_wallet').eq('testName'); }); + + describe("sendMessage", () => { + + it.only("Successfully", async () => { + const transferId = "x"; + const transfer = { + id: transferId, + destination_wallet_id: 1, + source_wallet_id: 2, + } + const walletA = new Wallet({ + id: uuid.v1(), + name: "walletA", + }); + const walletB = new Wallet({ + id: uuid.v1(), + name: "walletB", + }); + const sendMessage = sinon.stub(MQService.prototype, "sendMessage"); + sinon.stub(TransferRepository.prototype, "getById").resolves(transfer); + sinon.stub(TransferRepository.prototype, "getTokensById").resolves([{ + token_id: "t", + capture_id: "c", + }]); + sinon.stub(WalletService.prototype, "getById") + .onFirstCall() + .resolves(walletA) + .onSecondCall() + .resolves(walletB); + await transferService.sendMessage(transferId); + sinon.assert.calledWith(sendMessage, sinon.match({ + // TODO can not match type, why? + // type: "TokenAssigned", + wallet_name: "walletA", + wallet_name_sender: "walletB", + transfer_id: transferId, + entries: [{ + capture_id: "c", + token_id: "t", + }], + })); + + }); + + }); }); From df6ad4884a14cfcc45087d95c273c64c9963b8cd Mon Sep 17 00:00:00 2001 From: deanchen Date: Mon, 14 Jun 2021 11:59:21 +0800 Subject: [PATCH 03/15] fix: got stale data --- server/routes/transferRouter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index 365eacfe..cf6a22a9 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -76,6 +76,7 @@ transferRouter.post( // TODO: get only transferrable tokens result = await walletLogin.transferBundle(walletSender, walletReceiver, req.body.bundle.bundle_size, claim); } + await session.commitTransaction(); const transferService = new TransferService(session); result = await transferService.convertToResponse(result); if (result.state === Transfer.STATE.completed) { @@ -88,7 +89,6 @@ transferRouter.post( } else { throw new Error(`Unexpected state ${result.state}`); } - await session.commitTransaction(); }catch(e){ if(e instanceof HttpError && !e.shouldRollback()){ // if the error type is HttpError, means the exception has been handled @@ -127,8 +127,8 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); - res.status(200).json(transferJson2); await session.commitTransaction(); + res.status(200).json(transferJson2); } catch (e) { if (e instanceof HttpError && !e.shouldRollback()) { // if the error type is HttpError, means the exception has been handled @@ -167,8 +167,8 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); - res.status(200).json(transferJson2); await session.commitTransaction(); + res.status(200).json(transferJson2); } catch (e) { if (e instanceof HttpError && !e.shouldRollback()) { // if the error type is HttpError, means the exception has been handled @@ -207,8 +207,8 @@ transferRouter.delete( const transferJson2 = await transferService.convertToResponse( transferJson, ); - res.status(200).json(transferJson2); await session.commitTransaction(); + res.status(200).json(transferJson2); } catch (e) { if (e instanceof HttpError && !e.shouldRollback()) { // if the error type is HttpError, means the exception has been handled @@ -280,8 +280,8 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); - res.status(200).json(transferJson2); await session.commitTransaction(); + res.status(200).json(transferJson2); } catch (e) { if (e instanceof HttpError && !e.shouldRollback()) { // if the error type is HttpError, means the exception has been handled From f834f3b6b4188d67ece27939ca51bcb83aded86c Mon Sep 17 00:00:00 2001 From: deanchen Date: Wed, 16 Jun 2021 12:09:55 +0800 Subject: [PATCH 04/15] chore: test router for MQ --- server/routes/transferRouter.js | 10 +++++++++- server/routes/transferRouter.spec.js | 6 +++++- server/services/TransferService.spec.js | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index cf6a22a9..03d67182 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -57,6 +57,7 @@ transferRouter.post( const walletLogin = await walletService.getById(res.locals.wallet_id); const walletSender = await walletService.getByIdOrName(req.body.sender_wallet); const walletReceiver = await walletService.getByIdOrName(req.body.receiver_wallet); + const transferService = new TransferService(session); // check if this transfer is a claim (claim == not transferrrable tokens) const claim = req.body.claim; @@ -76,8 +77,15 @@ transferRouter.post( // TODO: get only transferrable tokens result = await walletLogin.transferBundle(walletSender, walletReceiver, req.body.bundle.bundle_size, claim); } + + // send message + if (result.state === Transfer.STATE.completed) { + await transferService.sendMessage(result.id); + } + await session.commitTransaction(); - const transferService = new TransferService(session); + + // response result = await transferService.convertToResponse(result); if (result.state === Transfer.STATE.completed) { res.status(201).json(result); diff --git a/server/routes/transferRouter.spec.js b/server/routes/transferRouter.spec.js index 5f7437f1..c78ba624 100644 --- a/server/routes/transferRouter.spec.js +++ b/server/routes/transferRouter.spec.js @@ -158,7 +158,7 @@ describe("transferRouter", () => { expect(res).property('statusCode').eq(201); }); - it('Transfer using sender and receiver id, should return 201', async () => { + it.only('Transfer using sender and receiver id, should return 201', async () => { const walletId = uuid.v4() const wallet2Id = uuid.v4() const tokenId = uuid.v4() @@ -188,6 +188,7 @@ describe("transferRouter", () => { id: transferId, state: Transfer.STATE.completed, }); + const sendMessage = sinon.stub(TransferService.prototype, "sendMessage"); const res = await request(app) .post('/') .send({ @@ -196,6 +197,9 @@ describe("transferRouter", () => { receiver_wallet: wallet2Id, }); expect(res).property('statusCode').eq(201); + + // should send message to queue + expect(sendMessage).calledWith(transferId); }); // //TODO: test for case 1: with trust relationship, tokens specified diff --git a/server/services/TransferService.spec.js b/server/services/TransferService.spec.js index a7d1c128..dc251c2c 100644 --- a/server/services/TransferService.spec.js +++ b/server/services/TransferService.spec.js @@ -48,7 +48,7 @@ describe('TransferService', () => { describe("sendMessage", () => { - it.only("Successfully", async () => { + it("Successfully", async () => { const transferId = "x"; const transfer = { id: transferId, From 24d361819d6650059dc890a7f7f0ec3fd366a244 Mon Sep 17 00:00:00 2001 From: deanchen Date: Wed, 16 Jun 2021 17:07:16 +0800 Subject: [PATCH 05/15] chore: send message at accepting and fulfilling --- server/routes/transferRouter.js | 2 ++ server/routes/transferRouter.spec.js | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index 03d67182..31af0f75 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -135,6 +135,7 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); + await transferService.sendMessage(transferJson.id); await session.commitTransaction(); res.status(200).json(transferJson2); } catch (e) { @@ -288,6 +289,7 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); + await transferService.sendMessage(transferJson.id); await session.commitTransaction(); res.status(200).json(transferJson2); } catch (e) { diff --git a/server/routes/transferRouter.spec.js b/server/routes/transferRouter.spec.js index c78ba624..176a0ae3 100644 --- a/server/routes/transferRouter.spec.js +++ b/server/routes/transferRouter.spec.js @@ -148,6 +148,7 @@ describe("transferRouter", () => { id: tokenId, state: Transfer.STATE.completed, }); + sinon.stub(TransferService.prototype, "sendMessage"); const res = await request(app) .post('/') .send({ @@ -158,7 +159,7 @@ describe("transferRouter", () => { expect(res).property('statusCode').eq(201); }); - it.only('Transfer using sender and receiver id, should return 201', async () => { + it('Transfer using sender and receiver id, should return 201', async () => { const walletId = uuid.v4() const wallet2Id = uuid.v4() const tokenId = uuid.v4() From 6f67cc83988848d91192ee95755153b3f64c1e00 Mon Sep 17 00:00:00 2001 From: deanchen Date: Thu, 17 Jun 2021 10:22:05 +0800 Subject: [PATCH 06/15] feat: e2e can run locally --- README.md | 20 ++++++++++++++++++++ __tests__/e2e/config.js | 8 ++++++-- __tests__/e2e/database/knex.js | 3 ++- package.json | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 48385809..34e57776 100644 --- a/README.md +++ b/README.md @@ -439,6 +439,26 @@ In order to efficiently run our integration tests, we rely on automated database npm run test-seedDB ``` +## End to End test + +To run the test: + +``` +npm run test-e2e +``` + +To run the test locally against the local code/server: + +``` +npm run test-e2e-locally +``` + +NOTE running e2e needs to set up some env variables like the Database connection, we can attach the env variables on the CLI command line: + +``` +> DB_HOST=localhost DB_USERNAME=postgres DB_PORT=23720 DB_PASSWORD=*** DB_NAME=treetracker DB_SCHEMA=public npm run test-e2e-locally +``` + ## Suggestion about how to run tests when developing There is a command in the `package.json`: diff --git a/__tests__/e2e/config.js b/__tests__/e2e/config.js index 674ba5d8..3383a051 100644 --- a/__tests__/e2e/config.js +++ b/__tests__/e2e/config.js @@ -1,6 +1,10 @@ require("dotenv").config(); -const request = require("supertest")(`https://${process.env.ENVIRONMENT}-k8s.treetracker.org/wallet`); +const server = process.env.RUN_E2E_LOCALLY ? + require("../../server/app") + : + `https://${process.env.ENVIRONMENT}-k8s.treetracker.org/wallet`; +const request = require("supertest")(server); const expect = require("chai").expect; const responseStatus = require("http-status-codes"); const assert = require("./libs/assertionLibrary.js"); @@ -27,4 +31,4 @@ module.exports = { responseStatus, assert, seed -}; \ No newline at end of file +}; diff --git a/__tests__/e2e/database/knex.js b/__tests__/e2e/database/knex.js index 706d2907..10155830 100644 --- a/__tests__/e2e/database/knex.js +++ b/__tests__/e2e/database/knex.js @@ -8,7 +8,8 @@ const knexConfig = { port: process.env.DB_PORT, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, - ssl: true, + // eslint-disable-next-line + ssl: process.env.DB_SSL === "false" ? false : true, }, debug: false, searchPath: [process.env.DB_SCHEMA], diff --git a/package.json b/package.json index 89c737a4..49f0a8df 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test-watch": "NODE_ENV=test NODE_LOG_LEVEL=info mocha -r dotenv/config dotenv_config_path=.env.test --timeout 10000 --require co-mocha -w -b --ignore './server/repositories/**/*.spec.js' './server/setup.js' './server/**/*.spec.js' './__tests__/seed.spec.js' './__tests__/supertest.js'", "test-watch-debug": "NODE_ENV=test NODE_LOG_LEVEL=debug DOTENV_CONFIG_PATH=.env.test mocha -r dotenv/config --timeout 10000 --require co-mocha -w -b --ignore './server/repositories/**/*.spec.js' './server/setup.js' './server/**/*.spec.js' './__tests__/seed.spec.js' './__tests__/**/*.spec.js'", "test-e2e": "NODE_TLS_REJECT_UNAUTHORIZED='0' mocha --config ./__tests__/e2e/.mocharc.js", + "test-e2e-locally": "RUN_E2E_LOCALLY=true DB_SSL=false NODE_ENV=test NODE_LOG_LEVEL=debug NODE_TLS_REJECT_UNAUTHORIZED='0' mocha --config ./__tests__/e2e/.mocharc.js ./server/setup.js", "prettier-fix": "prettier ./ --write", "db-migrate-ci": "cd database; db-migrate up", "start-db": "docker-compose up" From 2ec6e2d7511ae8f4faae6e2ccb452c18a0eb3977 Mon Sep 17 00:00:00 2001 From: deanchen Date: Fri, 18 Jun 2021 05:26:23 +0800 Subject: [PATCH 07/15] chore: can pass all tests --- .../sendTokensWithTrustRelationship.test.js | 2 +- server/services/MQService.js | 17 ++++++--- server/services/MQService.spec.js | 38 ++++++++++++++++++- server/services/TransferService.js | 2 +- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js b/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js index 9d02e130..e495e78c 100644 --- a/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js +++ b/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js @@ -46,7 +46,7 @@ describe("Sending tokens with trust relationship (Wallet API)",function () { receiverBearerToken = await getSession(receiverWallet, password); }); - it('Send token from wallet A to wallet B with trust relationship @token @regression', async () => { + it.only('Send token from wallet A to wallet B with trust relationship @token @regression', async () => { const requestTrustResponse = await sendPostRequest(trustRelationshipUri, headers(senderBearerToken.token), requestTrustRelationshipPayload(receiverWallet)); const {body: requestTrustBody, status: requestTrustStatus} = requestTrustResponse; assert.equals(requestTrustStatus, OK, 'Request trust relationship response status does not equal!', requestTrustBody); diff --git a/server/services/MQService.js b/server/services/MQService.js index 1eee42f8..13eba37f 100644 --- a/server/services/MQService.js +++ b/server/services/MQService.js @@ -10,15 +10,18 @@ class MQService{ } sendMessage(payload){ + log.warn("to send message"); return new Promise((resolve, reject) => { - const broker = Broker.create(config); - // TODO - Promise.resolve(broker) + Broker.create(config) .then(broker => { broker.publish("raw-capture-created", payload, "field-data.capture.creation") .then(publication => { + log.warn("publication is on"); publication - .on("success", () => resolve(true)) + .on("success", () => { + log.warn("message sent!"); + resolve(true); + }) .on("error", (err, messageId)=> { const error = `Error with id ${messageId} ${err.message}`; log.error(error); @@ -29,7 +32,11 @@ class MQService{ log.error(err); reject(new HttpError(500, `Error publishing message ${err}`)); }) - }); + }) + .catch(err => { + log.error(err); + reject(new HttpError(500, `Error create broker ${err}`)); + }) }); } } diff --git a/server/services/MQService.spec.js b/server/services/MQService.spec.js index 933f6d8f..4b886d2f 100644 --- a/server/services/MQService.spec.js +++ b/server/services/MQService.spec.js @@ -3,6 +3,7 @@ const Broker = require('rascal').BrokerAsPromised; const sinon = require("sinon"); const {expect} = require("chai"); const jestExpect = require("expect"); +const log = require("loglevel"); describe("MQService", () => { @@ -37,7 +38,7 @@ describe("MQService", () => { }); it("send message with problem", async () => { - sinon.stub(Broker, "create").returns({ + sinon.stub(Broker, "create").resolves({ publish: async () => { console.log("publish"); return { @@ -60,3 +61,38 @@ describe("MQService", () => { }); }); + +describe("Real operation, just for dev", () => { + + it.skip("Send and receive message", async () => { + try{ + const mqService = new MQService(); + const payload = {a:1}; + const result = await mqService.sendMessage(payload); + + + await new Promise((resolve, reject) => { + // check the message + // Consume a message + const config = require("./MQConfig").config; + Broker.create(config) + .then(broker => { + log.info("connected to broker"); + broker.subscribeAll() + .then(subscriptions => { + subscriptions.forEach( subscription => { + subscription.on('message', (message, content, ackOrNack) => { + log.warn("message:", message, content); + log.warn("message content:", message.content && message.content.toString()); + ackOrNack(); + resolve(); + }).on('error', console.error); + }); + }); + }); + }); + }catch(e){ + log.error("e:",e ); + }; + }); +}); diff --git a/server/services/TransferService.js b/server/services/TransferService.js index 1d07afd4..947a62a7 100644 --- a/server/services/TransferService.js +++ b/server/services/TransferService.js @@ -66,7 +66,7 @@ class TransferService { wallet_name_sender : walletSenderObj.name, entries: tokenData, }; - this._mqService.sendMessage(message); + await this._mqService.sendMessage(message); } } From 74006d4551435b1d97761bd16d89c26de08677fd Mon Sep 17 00:00:00 2001 From: deanchen Date: Fri, 18 Jun 2021 10:19:29 +0800 Subject: [PATCH 08/15] chore: do not send message when integration test --- server/routes/transferRouter.js | 15 ++++++++++++--- server/routes/transferRouter.spec.js | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index 31af0f75..08b5e02d 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -80,7 +80,10 @@ transferRouter.post( // send message if (result.state === Transfer.STATE.completed) { - await transferService.sendMessage(result.id); + // just send message in production + if(process.env.NODE_ENV !== "test"){ + await transferService.sendMessage(result.id); + } } await session.commitTransaction(); @@ -135,7 +138,10 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); - await transferService.sendMessage(transferJson.id); + // just send message in production + if(process.env.NODE_ENV !== "test"){ + await transferService.sendMessage(transferJson.id); + } await session.commitTransaction(); res.status(200).json(transferJson2); } catch (e) { @@ -289,7 +295,10 @@ transferRouter.post( const transferJson2 = await transferService.convertToResponse( transferJson, ); - await transferService.sendMessage(transferJson.id); + // just send message in production + if(process.env.NODE_ENV !== "test"){ + await transferService.sendMessage(transferJson.id); + } await session.commitTransaction(); res.status(200).json(transferJson2); } catch (e) { diff --git a/server/routes/transferRouter.spec.js b/server/routes/transferRouter.spec.js index 176a0ae3..329e76c7 100644 --- a/server/routes/transferRouter.spec.js +++ b/server/routes/transferRouter.spec.js @@ -199,8 +199,8 @@ describe("transferRouter", () => { }); expect(res).property('statusCode').eq(201); - // should send message to queue - expect(sendMessage).calledWith(transferId); + // should not send message to queue because ENV = test + sinon.assert.notCalled(sendMessage); }); // //TODO: test for case 1: with trust relationship, tokens specified From cd36e798ceb53c0436ed15ff1b5207f9207223f1 Mon Sep 17 00:00:00 2001 From: deanchen Date: Fri, 18 Jun 2021 10:26:04 +0800 Subject: [PATCH 09/15] chore: remove only --- .../sendTokens/sendTokensWithTrustRelationship.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js b/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js index e495e78c..9d02e130 100644 --- a/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js +++ b/__tests__/e2e/__tests__/sendTokens/sendTokensWithTrustRelationship.test.js @@ -46,7 +46,7 @@ describe("Sending tokens with trust relationship (Wallet API)",function () { receiverBearerToken = await getSession(receiverWallet, password); }); - it.only('Send token from wallet A to wallet B with trust relationship @token @regression', async () => { + it('Send token from wallet A to wallet B with trust relationship @token @regression', async () => { const requestTrustResponse = await sendPostRequest(trustRelationshipUri, headers(senderBearerToken.token), requestTrustRelationshipPayload(receiverWallet)); const {body: requestTrustBody, status: requestTrustStatus} = requestTrustResponse; assert.equals(requestTrustStatus, OK, 'Request trust relationship response status does not equal!', requestTrustBody); From ecf53e9d2bf31b1b20dc418d700feacb91790329 Mon Sep 17 00:00:00 2001 From: deanchen Date: Fri, 18 Jun 2021 10:31:08 +0800 Subject: [PATCH 10/15] chore: e2e locally will send message --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49f0a8df..3efffaa0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "test-watch": "NODE_ENV=test NODE_LOG_LEVEL=info mocha -r dotenv/config dotenv_config_path=.env.test --timeout 10000 --require co-mocha -w -b --ignore './server/repositories/**/*.spec.js' './server/setup.js' './server/**/*.spec.js' './__tests__/seed.spec.js' './__tests__/supertest.js'", "test-watch-debug": "NODE_ENV=test NODE_LOG_LEVEL=debug DOTENV_CONFIG_PATH=.env.test mocha -r dotenv/config --timeout 10000 --require co-mocha -w -b --ignore './server/repositories/**/*.spec.js' './server/setup.js' './server/**/*.spec.js' './__tests__/seed.spec.js' './__tests__/**/*.spec.js'", "test-e2e": "NODE_TLS_REJECT_UNAUTHORIZED='0' mocha --config ./__tests__/e2e/.mocharc.js", - "test-e2e-locally": "RUN_E2E_LOCALLY=true DB_SSL=false NODE_ENV=test NODE_LOG_LEVEL=debug NODE_TLS_REJECT_UNAUTHORIZED='0' mocha --config ./__tests__/e2e/.mocharc.js ./server/setup.js", + "test-e2e-locally": "RUN_E2E_LOCALLY=true DB_SSL=false NODE_LOG_LEVEL=debug NODE_TLS_REJECT_UNAUTHORIZED='0' mocha --config ./__tests__/e2e/.mocharc.js ./server/setup.js", "prettier-fix": "prettier ./ --write", "db-migrate-ci": "cd database; db-migrate up", "start-db": "docker-compose up" From 9bdbe220123c4ad1e5f28bd54d834a691a6effb9 Mon Sep 17 00:00:00 2001 From: deanchen Date: Mon, 21 Jun 2021 09:33:55 +0800 Subject: [PATCH 11/15] chore: rename --- server/repositories/TransferRepository.js | 2 +- server/services/TransferService.js | 2 +- server/services/TransferService.spec.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/repositories/TransferRepository.js b/server/repositories/TransferRepository.js index 4dc457a3..2fbf7c25 100644 --- a/server/repositories/TransferRepository.js +++ b/server/repositories/TransferRepository.js @@ -29,7 +29,7 @@ class TransferRepository extends BaseRepository{ }); } - async getTokensById(id){ + async getTokenAndCaptureIds(id){ return await this._session.getDB().raw( ` SELECT token_id, capture_id FROM "transaction" tr diff --git a/server/services/TransferService.js b/server/services/TransferService.js index 947a62a7..96726f84 100644 --- a/server/services/TransferService.js +++ b/server/services/TransferService.js @@ -58,7 +58,7 @@ class TransferService { const walletReceiverObj = await walletReceiver.toJSON(); const walletSender = await this._walletService.getById(transfer.source_wallet_id); const walletSenderObj = await walletSender.toJSON(); - const tokenData = await this._transferRepository.getTokensById(transferId); + const tokenData = await this._transferRepository.getTokenAndCaptureIds(transferId); const message = { transfer_id: transferId, type: "TokensAssigned", diff --git a/server/services/TransferService.spec.js b/server/services/TransferService.spec.js index dc251c2c..334627db 100644 --- a/server/services/TransferService.spec.js +++ b/server/services/TransferService.spec.js @@ -65,7 +65,7 @@ describe('TransferService', () => { }); const sendMessage = sinon.stub(MQService.prototype, "sendMessage"); sinon.stub(TransferRepository.prototype, "getById").resolves(transfer); - sinon.stub(TransferRepository.prototype, "getTokensById").resolves([{ + sinon.stub(TransferRepository.prototype, "getTokenAndCaptureIds").resolves([{ token_id: "t", capture_id: "c", }]); From e491cd3b90089f3a78bf9c6edff273b793e6ff90 Mon Sep 17 00:00:00 2001 From: deanchen Date: Mon, 21 Jun 2021 09:46:25 +0800 Subject: [PATCH 12/15] chore: update package-lock --- package-lock.json | 317 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 287 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1f230c56..5c58e9d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -82,6 +82,15 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/runtime-corejs3": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.6.tgz", + "integrity": "sha512-Xl8SPYtdjcMoCsIM4teyVRg7jIcgl8F2kRtoCcXuHzXswt9UxZCS6BzRo8fcnCuP6u2XtPgvyonmEPF57Kxo9Q==", + "requires": { + "core-js-pure": "^3.14.0", + "regenerator-runtime": "^0.13.4" + } + }, "@commitlint/cli": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", @@ -823,6 +832,47 @@ "uri-js": "^4.2.2" } }, + "amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "requires": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "ansi-align": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", @@ -1181,8 +1231,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "at-least-node": { "version": "1.0.0", @@ -1269,11 +1318,35 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, + "bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { "version": "1.19.0", @@ -1376,6 +1449,11 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "buffer-writer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", @@ -1435,7 +1513,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1725,7 +1802,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -1858,8 +1934,7 @@ "cookiejar": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, "copy-descriptor": { "version": "0.1.1", @@ -1872,11 +1947,15 @@ "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg==", "dev": true }, + "core-js-pure": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.0.tgz", + "integrity": "sha512-RO+LFAso8DB6OeBX9BAcEGvyth36QtxYon1OyVsITNVtSKr/Hos0BXZwnsOJ7o+O6KHtK+O+cJIEj9NGg6VwFA==" + }, "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=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "7.0.0", @@ -2247,6 +2326,11 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, + "deep-freeze": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", + "integrity": "sha1-OgsABd4YZygZ39OM0x+RF5yJPoQ=" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2307,8 +2391,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "depd": { "version": "1.1.2", @@ -3128,6 +3211,11 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -3296,8 +3384,12 @@ "formidable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", - "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", - "dev": true + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" + }, + "forward-emitter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/forward-emitter/-/forward-emitter-0.1.1.tgz", + "integrity": "sha1-Vu3QwIIlDtujNOC5Iv/SwBk53uE=" }, "forwarded": { "version": "0.1.2", @@ -3344,8 +3436,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -3359,6 +3450,11 @@ "integrity": "sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ==", "dev": true }, + "generic-pool": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.7.8.tgz", + "integrity": "sha512-Pz93INFSbhjEROVbM91rurD05G+Kx8833rG+lVU57mznEBpzkc1f5/g+d511a1Yf8dbAEsm7DDA3QLytMFbiGA==" + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3369,7 +3465,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3513,7 +3608,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -3532,8 +3626,7 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-value": { "version": "1.0.0", @@ -3868,6 +3961,11 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, + "individual": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz", + "integrity": "sha1-gzsJfa0jKU52EXqY+zjg2a1hu5c=" + }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -4638,8 +4736,7 @@ "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 + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" }, "lodash.get": { "version": "4.4.2", @@ -4682,6 +4779,11 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -4736,7 +4838,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -6204,6 +6305,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -6224,6 +6330,96 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, + "rascal": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/rascal/-/rascal-13.0.3.tgz", + "integrity": "sha512-zj+roDwfUZcXvzacyT9lGVh5vp1aivFdY5/9AXfaLJcHB7ZmGw2kkzKdRZOjLkJ5VPIVjFIWBffxelp0xMQ5xw==", + "requires": { + "async": "^3.2.0", + "debug": "^4.1.1", + "deep-freeze": "0.0.1", + "forward-emitter": "^0.1.1", + "generic-pool": "^3.7.1", + "lodash": "^4.17.21", + "lru-cache": "^6.0.0", + "safe-json-parse": "^4.0.0", + "stashback": "^1.1.2", + "superagent": "^6.1.0", + "uuid": "^8.3.2", + "xregexp": "^5.0.1" + }, + "dependencies": { + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "raw-body": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", @@ -6383,8 +6579,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "regex-not": { "version": "1.0.2", @@ -6439,6 +6634,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -6521,11 +6721,27 @@ "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", "dev": true }, + "rust-result": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz", + "integrity": "sha1-NMdbLm3Dn+WHXlveyFteD5FTb3I=", + "requires": { + "individual": "^2.0.0" + } + }, "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==" }, + "safe-json-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz", + "integrity": "sha1-fA9XjPzNEtM6ccDgVBPi7KFx6qw=", + "requires": { + "rust-result": "^1.0.0" + } + }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -6681,6 +6897,23 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "dependencies": { + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + } + } + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -7005,6 +7238,16 @@ } } }, + "stashback": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/stashback/-/stashback-1.1.3.tgz", + "integrity": "sha512-MS4X5BV7JJG8GE6IR1X3Y2HEZH3L407KlevQlnadmCLL32ORBvK6Ojm/MtB12MF/XngYgHHSucaNG+tcLmK8jg==", + "requires": { + "debug": "^4.1.1", + "lodash.defaults": "^4.2.0", + "lodash.reduce": "^4.6.0" + } + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -7094,7 +7337,6 @@ "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.0" } @@ -7566,6 +7808,15 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, + "url-parse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", @@ -7599,8 +7850,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utile": { "version": "0.3.0", @@ -7857,6 +8107,14 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xregexp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-5.0.2.tgz", + "integrity": "sha512-JPNfN40YMNSDxZrahMrmtNH1QqPJp0/qNeEJM2nnOlhcBdfCCjekPYFV2OnwKxwvpEYglH1RBotbpRRaEuCG8Q==", + "requires": { + "@babel/runtime-corejs3": "^7.12.1" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -7871,8 +8129,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.10.0", From aa7eb8d025b7a40d97adc305efe58ea79f31724a Mon Sep 17 00:00:00 2001 From: deanchen Date: Mon, 21 Jun 2021 09:49:45 +0800 Subject: [PATCH 13/15] fix: wrong fn name --- server/repositories/TransferRepository.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/repositories/TransferRepository.spec.js b/server/repositories/TransferRepository.spec.js index 3d5f5da1..03d4e683 100644 --- a/server/repositories/TransferRepository.spec.js +++ b/server/repositories/TransferRepository.spec.js @@ -90,7 +90,7 @@ describe("TransferRepository", () => { }, ][step - 1](); }); - const result = await transferRepository.getTokensById(1); + const result = await transferRepository.getTokenAndCaptureIds(1); sinon.assert.match(result, data); }); From d9468edf99b5144b00e22f6cb895e7fd8cd22880 Mon Sep 17 00:00:00 2001 From: deanchen Date: Mon, 21 Jun 2021 11:47:13 +0800 Subject: [PATCH 14/15] feat: setting the correct message queue --- server/services/MQConfig.js | 33 +++++++++++----------- server/services/MQService.js | 2 +- server/services/MQService.spec.js | 47 +++++++++++++++++-------------- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/server/services/MQConfig.js b/server/services/MQConfig.js index 3a88e0dc..16756057 100644 --- a/server/services/MQConfig.js +++ b/server/services/MQConfig.js @@ -2,24 +2,23 @@ module.exports = { config: { "vhosts": { "test": { - "connection": { - "url": process.env.RABBIT_MQ_URL, - "socketOptions": { - "timeout": 1000 - } - }, - "exchanges": ["field-data"], - "queues": ["field-data-events", "field-data:verifications"], - "publications": { - "raw-capture-created": { - "exchange": "field-data" - } - }, - "subscriptions": { - "admin-verification": { - "queue": "field-data:verifications" - } + "connection": { + "url": process.env.RABBIT_MQ_URL, + "socketOptions": { + "timeout": 1000 + } + }, + "exchanges": ["wallet-service-ex"], + "queues": ["token-transfer:events"], + "bindings": [ + "wallet-service-ex[token.transfer] -> token-transfer:events" + ], + "publications": { + "token-assigned": { + "exchange": "wallet-service-ex", + "routingKey": "token.transfer" } + }, } } } diff --git a/server/services/MQService.js b/server/services/MQService.js index 13eba37f..442c136c 100644 --- a/server/services/MQService.js +++ b/server/services/MQService.js @@ -14,7 +14,7 @@ class MQService{ return new Promise((resolve, reject) => { Broker.create(config) .then(broker => { - broker.publish("raw-capture-created", payload, "field-data.capture.creation") + broker.publish("token-assigned", payload) .then(publication => { log.warn("publication is on"); publication diff --git a/server/services/MQService.spec.js b/server/services/MQService.spec.js index 4b886d2f..ab8bda12 100644 --- a/server/services/MQService.spec.js +++ b/server/services/MQService.spec.js @@ -64,33 +64,38 @@ describe("MQService", () => { describe("Real operation, just for dev", () => { - it.skip("Send and receive message", async () => { + it.only("Send and receive message", async function(){ try{ + const mqService = new MQService(); const payload = {a:1}; const result = await mqService.sendMessage(payload); + log.warn("result:", result); - await new Promise((resolve, reject) => { - // check the message - // Consume a message - const config = require("./MQConfig").config; - Broker.create(config) - .then(broker => { - log.info("connected to broker"); - broker.subscribeAll() - .then(subscriptions => { - subscriptions.forEach( subscription => { - subscription.on('message', (message, content, ackOrNack) => { - log.warn("message:", message, content); - log.warn("message content:", message.content && message.content.toString()); - ackOrNack(); - resolve(); - }).on('error', console.error); - }); - }); - }); - }); +// await new Promise((resolve, reject) => { +// // check the message +// // Consume a message +// const config = require("./MQConfig").config; +// Broker.create(config) +// .then(broker => { +// log.info("connected to broker"); +// broker.subscribeAll() +// .then(subscriptions => { +// subscriptions.forEach( subscription => { +// subscription.on('message', (message, content, ackOrNack) => { +// log.warn("message:", message, content); +// log.warn("message content received:", message.content && message.content.toString()); +// ackOrNack(); +// resolve(); +// }).on('error', console.error); +// }); +// }); +// }); +// const mqService = new MQService(); +// const payload = {a:1}; +// mqService.sendMessage(payload); +// }); }catch(e){ log.error("e:",e ); }; From ffbb64f1b591018b1c8435b55a99ab230426b933 Mon Sep 17 00:00:00 2001 From: deanchen Date: Tue, 22 Jun 2021 10:04:37 +0800 Subject: [PATCH 15/15] chore: forgot close only --- server/services/MQService.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/services/MQService.spec.js b/server/services/MQService.spec.js index ab8bda12..bba52fc0 100644 --- a/server/services/MQService.spec.js +++ b/server/services/MQService.spec.js @@ -64,7 +64,7 @@ describe("MQService", () => { describe("Real operation, just for dev", () => { - it.only("Send and receive message", async function(){ + it("Send and receive message", async function(){ try{ const mqService = new MQService();