From 909c9706c0bb316dd3ae0199924a086f627568d6 Mon Sep 17 00:00:00 2001 From: JP Lomas Date: Sat, 28 Nov 2020 10:04:33 +0000 Subject: [PATCH 1/5] Logging --- server/main.js | 209 +++++++++++++++++++++++-------------------------- 1 file changed, 98 insertions(+), 111 deletions(-) diff --git a/server/main.js b/server/main.js index 59f9f98..ae3e1eb 100644 --- a/server/main.js +++ b/server/main.js @@ -1,145 +1,132 @@ -import { Meteor } from 'meteor/meteor' -import QrlNode from './qrlNode' +import { Meteor } from "meteor/meteor"; +import QrlNode from "./qrlNode"; -const ip = 'testnet-1.automated.theqrl.org' -const ip_mainnet = 'mainnet-1.automated.theqrl.org' -const port = '19009' -const testnet = new QrlNode(ip, port) -const mainnet = new QrlNode(ip_mainnet, port) +const ip = "testnet-1.automated.theqrl.org"; +const ip_mainnet = "95.179.131.134"; +const port = "19009"; +const testnet = new QrlNode(ip, port); +const mainnet = new QrlNode(ip_mainnet, port); Meteor.startup(() => { - // Enable cross origin requests for all endpoints // Preflight - WebApp.rawConnectHandlers.use(function(req, res, next) { + WebApp.rawConnectHandlers.use(function (req, res, next) { res.setHeader("Access-Control-Allow-Origin", "*"); res.setHeader("Access-Control-Allow-Headers", "Authorization,Content-Type"); return next(); }); const headers = { - 'Cache-Control': 'no-store', - Pragma: 'no-cache', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With', - } + "Cache-Control": "no-store", + Pragma: "no-cache", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, OPTIONS", + "Access-Control-Allow-Headers": + "Content-Type, Authorization, X-Requested-With", + }; // TESTNET testnet.connect().then(() => { - console.log('Connected to Testnet') - + console.log("Connection attempt to Testnet"); + console.log("Mainnet connection status: " + testnet.connection); // Routes - get JsonRoutes.add("get", "/grpc/testnet/:request", function (req, res, next) { - const id = req.params.request - testnet.api(id).then((result) => { + const id = req.params.request; + mainnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, - headers - }) - }) - }) - + headers, + }); + }); + }); // Routes - post JsonRoutes.add("post", "/grpc/testnet/:request", function (req, res, next) { - const id = req.params.request - const options = req.body - - try { - options.address = Buffer.from(options.address.substring(1), 'hex') - } catch (e) { - // no need to throw anything + const id = req.params.request; + const options = req.body; + if (options.address) { + options.address = Buffer.from(options.address.substring(1), "hex"); } - try { - if (parseInt(options.query, 10).toString() === options.query) { - // block query - options.query = Buffer.from(options.query) - } else { - // hex query - // drop initial Q if QRL address - if (options.query[0].toLowerCase() === 'q') { - options.query = Buffer.from(options.query.substring(1), 'hex') + if (parseInt(options.query, 10).toString() === options.query) { + // block query + options.query = Buffer.from(options.query); + } else { + if (options.query) { + if (options.query[0].toLowerCase() === "q") { + options.query = Buffer.from(options.query.substring(1), "hex"); } else { - options.query = Buffer.from(options.query, 'hex') + options.query = Buffer.from(options.query, "hex"); } } - } catch (e) { - // no need to throw anything } + console.log(req.connection.remoteAddress + " -> [GRPC/Testnet] " + id); + testnet + .api(id, options) + .then((result) => { + JsonRoutes.sendResult(res, { + data: result, + headers, + }); + }) + .catch((error) => { + JsonRoutes.sendResult(res, { + data: error, + headers, + }); + }); + }); + }); + // end TESTNET - testnet.api(id, options).then((result) => { + // MAINNET + mainnet.connect().then(() => { + console.log("Connection attempt to Mainnet"); + console.log("Mainnet connection status: " + mainnet.connection); + // Routes - get + JsonRoutes.add("get", "/grpc/mainnet/:request", function (req, res, next) { + const id = req.params.request; + mainnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, - headers - }) - }).catch(error => { - JsonRoutes.sendResult(res, { - data: error, - headers - }) - }) - - }) - }) - -// MAINNET -mainnet.connect().then(() => { - console.log('Connected to Mainnet') - - // Routes - get - JsonRoutes.add("get", "/grpc/mainnet/:request", function (req, res, next) { - const id = req.params.request - mainnet.api(id).then((result) => { - JsonRoutes.sendResult(res, { - data: result, - headers - }) - }) - }) - - // Routes - post - JsonRoutes.add("post", "/grpc/mainnet/:request", function (req, res, next) { - const id = req.params.request - const options = req.body - - try { - console.log('options.address', options.address) - options.address = Buffer.from(options.address.substring(1), 'hex') - } catch (e) { - // no need to throw anything - } - try { + headers, + }); + }); + }); + // Routes - post + JsonRoutes.add("post", "/grpc/mainnet/:request", function (req, res, next) { + const id = req.params.request; + const options = req.body; + if (options.address) { + options.address = Buffer.from(options.address.substring(1), "hex"); + } if (parseInt(options.query, 10).toString() === options.query) { // block query - options.query = Buffer.from(options.query) + options.query = Buffer.from(options.query); } else { - // hex query - // drop initial Q if QRL address - if (options.query[0].toLowerCase() === 'q') { - options.query = Buffer.from(options.query.substring(1), 'hex') - } else { - options.query = Buffer.from(options.query, 'hex') + if (options.query) { + if (options.query[0].toLowerCase() === "q") { + options.query = Buffer.from(options.query.substring(1), "hex"); + } else { + options.query = Buffer.from(options.query, "hex"); + } } } - } catch (e) { - // no need to throw anything - } - - mainnet.api(id, options).then((result) => { - JsonRoutes.sendResult(res, { - data: result, - headers - }) - }).catch(error => { - JsonRoutes.sendResult(res, { - data: error, - headers - }) - }) - - }) -}) - - -}) + console.log(req.connection.remoteAddress + " -> [GRPC/Mainnet] " + id); + mainnet + .api(id, options) + .then((result) => { + JsonRoutes.sendResult(res, { + data: result, + headers, + }); + }) + .catch((error) => { + JsonRoutes.sendResult(res, { + data: error, + headers, + }); + }); + }); + }); + // end MAINNET +}); From eec4f245399679c88c29095d9d9fd9231b0cb7f6 Mon Sep 17 00:00:00 2001 From: JP Lomas Date: Sat, 28 Nov 2020 12:00:24 +0000 Subject: [PATCH 2/5] Setup Linters --- .eslintrc.json | 16 + .prettierrc | 7 + package-lock.json | 1028 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 + 4 files changed, 1059 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .prettierrc diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..9b128da --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "root": true, + "env": { + "browser": true, + "es6": true, + "commonjs": true, + "jquery": true + }, + "plugins": ["prettier"], + "extends": ["prettier"], + "rules": { + "prettier/prettier": "error" + }, + "parser": "babel-eslint", + "ignorePatterns": [".prettierrc"] +} \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ce3864b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 2, + "useTabs": false, + "trailingComma": "es5", + "semi": false, + "singleQuote": true +} diff --git a/package-lock.json b/package-lock.json index 4522660..51f3d4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3,6 +3,78 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.7.tgz", + "integrity": "sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg==", + "dev": true + }, "@babel/polyfill": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", @@ -20,6 +92,74 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.9.tgz", + "integrity": "sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.7.tgz", + "integrity": "sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", + "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, "@grpc/grpc-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.1.tgz", @@ -137,6 +277,18 @@ "event-target-shim": "^5.0.0" } }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -145,11 +297,73 @@ "debug": "4" } }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -179,6 +393,38 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -189,6 +435,17 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "crypto-js": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", @@ -202,6 +459,21 @@ "ms": "2.1.2" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -210,6 +482,260 @@ "safe-buffer": "^5.0.1" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.14.0.tgz", + "integrity": "sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-import-resolver-meteor": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-meteor/-/eslint-import-resolver-meteor-0.4.0.tgz", + "integrity": "sha1-yGhjhAghIIz4EzxczlGQnCamFWk=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "resolve": "^1.1.6" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", + "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.3.0" + } + }, + "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 + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -220,16 +746,89 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fast-text-encoding": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==" }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gaxios": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", @@ -251,6 +850,12 @@ "json-bigint": "^1.0.0" } }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -264,6 +869,21 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "google-auth-library": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", @@ -313,6 +933,21 @@ "mime": "^2.2.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -322,6 +957,28 @@ "debug": "4" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -336,16 +993,74 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "jquery": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-bigint": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -359,6 +1074,18 @@ "resolved": "https://registry.npmjs.org/json-formatter-js/-/json-formatter-js-2.3.4.tgz", "integrity": "sha512-gmAzYRtPRmYzeAT4T7+t3NhTF89JOAIioCVDddl9YDb3ls3kWcskirafw/MZGJaRhEU6fRimGJHl7CC7gaAI2Q==" }, + "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-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", @@ -378,6 +1105,22 @@ "safe-buffer": "^5.0.1" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -970,11 +1713,32 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", @@ -985,6 +1749,12 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, + "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 + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -993,11 +1763,73 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "protobufjs": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", @@ -1025,6 +1857,12 @@ } } }, + "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 + }, "qrlbase.proto": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/qrlbase.proto/-/qrlbase.proto-1.0.0.tgz", @@ -1035,6 +1873,28 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1053,6 +1913,114 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -1061,16 +2029,76 @@ "rimraf": "^3.0.0" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "dev": true + }, "walkdir": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 48ea7d2..d601905 100644 --- a/package.json +++ b/package.json @@ -24,5 +24,13 @@ "server": "server/main.js" }, "testModule": "tests/main.js" + }, + "devDependencies": { + "babel-eslint": "^10.1.0", + "eslint": "^7.14.0", + "eslint-config-prettier": "^6.15.0", + "eslint-import-resolver-meteor": "^0.4.0", + "eslint-plugin-prettier": "^3.1.4", + "prettier": "2.2.1" } } From f0c7b89b01c21ca3a4b5af0f4cc12d60ed7203e3 Mon Sep 17 00:00:00 2001 From: JP Lomas Date: Sat, 28 Nov 2020 12:53:51 +0000 Subject: [PATCH 3/5] Depreciate GetAddressState --- client/main.html | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/client/main.html b/client/main.html index 74a4041..899f4cc 100644 --- a/client/main.html +++ b/client/main.html @@ -102,6 +102,9 @@

POST

/grpc/${network}/GetAddressState
+
+ Depreciated - not recommended for use +
@@ -165,6 +168,29 @@

POST

Sends: String Query (block id, txhash or QRL address)

Returns: Located data

+

 

 

+
+

GetTokensByAddress

+
+ /grpc/${network}/GetTokensByAddress +
+
+
+ +
+
+
+ + +
+
+
+

Sends: String QRL address, Integer items per page to return, Integer page number

+

Returns: Token holdings information

 

 

From 6cae1062450c0450c690a7e347c3530bb1d96ded Mon Sep 17 00:00:00 2001 From: JP Lomas Date: Sat, 28 Nov 2020 12:54:16 +0000 Subject: [PATCH 4/5] Check health of connection every 60s --- client/main.js | 66 +++++++++++------- server/main.js | 166 +++++++++++++++++++++++++++++----------------- server/qrlNode.js | 93 +++++++++++++++----------- 3 files changed, 199 insertions(+), 126 deletions(-) diff --git a/client/main.js b/client/main.js index a7ce5eb..33791f8 100644 --- a/client/main.js +++ b/client/main.js @@ -1,4 +1,4 @@ -global.Buffer = global.Buffer || require("buffer").Buffer +global.Buffer = global.Buffer || require('buffer').Buffer import JSONFormatter from 'json-formatter-js' import './main.html' @@ -9,7 +9,7 @@ async function getData(url = '') { cache: 'no-cache', credentials: 'same-origin', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', @@ -24,11 +24,11 @@ async function postData(url = '', data = {}) { cache: 'no-cache', credentials: 'same-origin', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', - body: JSON.stringify(data) + body: JSON.stringify(data), }) return response.json() } @@ -43,45 +43,61 @@ function displayData(data) { Template.get.events({ 'click #GetStats-get-Testnet': () => { - getData('/grpc/testnet/GetStats') - .then(data => displayData(data)) + getData('/grpc/testnet/GetStats').then((data) => displayData(data)) }, 'click #GetStats-get-Mainnet': () => { - getData('/grpc/mainnet/GetStats') - .then(data => displayData(data)) + getData('/grpc/mainnet/GetStats').then((data) => displayData(data)) }, }) Template.post.events({ 'click #GetStats-Testnet': () => { - postData('/grpc/testnet/GetStats', + postData( + '/grpc/testnet/GetStats', JSON.parse($('#GetStats').val()) - ) - .then(data => displayData(data)) + ).then((data) => displayData(data)) }, 'click #GetStats-Mainnet': () => { - postData('/grpc/mainnet/GetStats', + postData( + '/grpc/mainnet/GetStats', JSON.parse($('#GetStats').val()) - ) - .then(data => displayData(data)) + ).then((data) => displayData(data)) }, 'click #GetAddressState-Testnet': () => { - postData('/grpc/testnet/GetAddressState', + postData( + '/grpc/testnet/GetAddressState', JSON.parse($('#GetAddressState').val()) - ) - .then(data => displayData(data)) + ).then((data) => displayData(data)) }, 'click #GetOptimizedAddressState-Testnet': () => { - postData('/grpc/testnet/GetOptimizedAddressState', + postData( + '/grpc/testnet/GetOptimizedAddressState', JSON.parse($('#GetOptimizedAddressState').val()) - ) - .then(data => displayData(data)) + ).then((data) => displayData(data)) }, 'click #GetObject-Testnet': () => { - postData('/grpc/testnet/GetObject', + postData( + '/grpc/testnet/GetObject', JSON.parse($('#GetObject').val()) - ) - .then(data => displayData(data)) + ).then((data) => displayData(data)) + }, + 'click #GetObject-Mainnet': () => { + postData( + '/grpc/mainnet/GetObject', + JSON.parse($('#GetObject').val()) + ).then((data) => displayData(data)) + }, + 'click #GetTokensByAddress-Testnet': () => { + postData( + '/grpc/testnet/GetTokensByAddress', + JSON.parse($('#GetTokensByAddress').val()) + ).then((data) => displayData(data)) + }, + 'click #GetTokensByAddress-Mainnet': () => { + postData( + '/grpc/mainnets/GetTokensByAddress', + JSON.parse($('#GetTokensByAddress').val()) + ).then((data) => displayData(data)) }, }) @@ -89,5 +105,5 @@ Template.modal.events({ 'click .mc': () => { $('.modal').removeClass('is-active') $('html').removeClass('is-clipped') - } -}) \ No newline at end of file + }, +}) diff --git a/server/main.js b/server/main.js index ae3e1eb..582c0e0 100644 --- a/server/main.js +++ b/server/main.js @@ -1,132 +1,176 @@ -import { Meteor } from "meteor/meteor"; -import QrlNode from "./qrlNode"; +import { Meteor } from 'meteor/meteor' +import QrlNode from './qrlNode' -const ip = "testnet-1.automated.theqrl.org"; -const ip_mainnet = "95.179.131.134"; -const port = "19009"; -const testnet = new QrlNode(ip, port); -const mainnet = new QrlNode(ip_mainnet, port); +const ipTestnet = 'testnet-1.automated.theqrl.org' +const ipMainnet = '95.179.131.134' +const port = '19009' +const testnet = new QrlNode(ipTestnet, port) +const mainnet = new QrlNode(ipMainnet, port) + +const checkConnectionStatus = () => { + if (mainnet.connection === true) { + console.log('Mainnet is connected OKAY') + } else { + console.log('ERROR: Mainnet is not connected') + } + if (testnet.connection === true) { + console.log('Testnet is connected OKAY') + } else { + console.log('ERROR: Testnet is not connected') + } +} Meteor.startup(() => { // Enable cross origin requests for all endpoints // Preflight WebApp.rawConnectHandlers.use(function (req, res, next) { - res.setHeader("Access-Control-Allow-Origin", "*"); - res.setHeader("Access-Control-Allow-Headers", "Authorization,Content-Type"); - return next(); - }); + res.setHeader('Access-Control-Allow-Origin', '*') + res.setHeader('Access-Control-Allow-Headers', 'Authorization,Content-Type') + return next() + }) const headers = { - "Cache-Control": "no-store", - Pragma: "no-cache", - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Methods": "GET, PUT, POST, DELETE, OPTIONS", - "Access-Control-Allow-Headers": - "Content-Type, Authorization, X-Requested-With", - }; + 'Cache-Control': 'no-store', + Pragma: 'no-cache', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS', + 'Access-Control-Allow-Headers': + 'Content-Type, Authorization, X-Requested-With', + } + + JsonRoutes.Middleware.use(function (req, res, next) { + const originalUrl = req.originalUrl + const apiCall = req.originalUrl.split('/') + if ( + apiCall[2] !== 'mainnet' && + apiCall[2] !== 'testnet' && + originalUrl !== '/' + ) { + console.log( + 'ERROR: [invalid route] ' + + req.connection.remoteAddress + + ' -> ' + + originalUrl + ) + JsonRoutes.sendResult(res, { + code: 401, + data: { + result: 'ERROR: Invalid API call', + invalid_route: originalUrl, + }, + headers, + }) + } else { + next() + } + }) // TESTNET testnet.connect().then(() => { - console.log("Connection attempt to Testnet"); - console.log("Mainnet connection status: " + testnet.connection); + console.log('Connection attempt to Testnet') + console.log('Mainnet connection status: ' + testnet.connection) // Routes - get - JsonRoutes.add("get", "/grpc/testnet/:request", function (req, res, next) { - const id = req.params.request; + JsonRoutes.add('get', '/grpc/testnet/:request', function (req, res, next) { + const id = req.params.request mainnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, headers, - }); - }); - }); + }) + }) + }) // Routes - post - JsonRoutes.add("post", "/grpc/testnet/:request", function (req, res, next) { - const id = req.params.request; - const options = req.body; + JsonRoutes.add('post', '/grpc/testnet/:request', function (req, res, next) { + const id = req.params.request + const options = req.body if (options.address) { - options.address = Buffer.from(options.address.substring(1), "hex"); + options.address = Buffer.from(options.address.substring(1), 'hex') } if (parseInt(options.query, 10).toString() === options.query) { // block query - options.query = Buffer.from(options.query); + options.query = Buffer.from(options.query) } else { if (options.query) { - if (options.query[0].toLowerCase() === "q") { - options.query = Buffer.from(options.query.substring(1), "hex"); + if (options.query[0].toLowerCase() === 'q') { + options.query = Buffer.from(options.query.substring(1), 'hex') } else { - options.query = Buffer.from(options.query, "hex"); + options.query = Buffer.from(options.query, 'hex') } } } - console.log(req.connection.remoteAddress + " -> [GRPC/Testnet] " + id); + console.log(req.connection.remoteAddress + ' -> [GRPC/Testnet] ' + id) testnet .api(id, options) .then((result) => { JsonRoutes.sendResult(res, { data: result, headers, - }); + }) }) .catch((error) => { JsonRoutes.sendResult(res, { data: error, headers, - }); - }); - }); - }); + }) + }) + }) + }) // end TESTNET // MAINNET mainnet.connect().then(() => { - console.log("Connection attempt to Mainnet"); - console.log("Mainnet connection status: " + mainnet.connection); + console.log('Connection attempt to Mainnet') + console.log('Mainnet connection status: ' + mainnet.connection) // Routes - get - JsonRoutes.add("get", "/grpc/mainnet/:request", function (req, res, next) { - const id = req.params.request; + JsonRoutes.add('get', '/grpc/mainnet/:request', function (req, res, next) { + const id = req.params.request mainnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, headers, - }); - }); - }); + }) + }) + }) // Routes - post - JsonRoutes.add("post", "/grpc/mainnet/:request", function (req, res, next) { - const id = req.params.request; - const options = req.body; + JsonRoutes.add('post', '/grpc/mainnet/:request', function (req, res, next) { + const id = req.params.request + const options = req.body if (options.address) { - options.address = Buffer.from(options.address.substring(1), "hex"); + options.address = Buffer.from(options.address.substring(1), 'hex') } if (parseInt(options.query, 10).toString() === options.query) { // block query - options.query = Buffer.from(options.query); + options.query = Buffer.from(options.query) } else { if (options.query) { - if (options.query[0].toLowerCase() === "q") { - options.query = Buffer.from(options.query.substring(1), "hex"); + if (options.query[0].toLowerCase() === 'q') { + options.query = Buffer.from(options.query.substring(1), 'hex') } else { - options.query = Buffer.from(options.query, "hex"); + options.query = Buffer.from(options.query, 'hex') } } } - console.log(req.connection.remoteAddress + " -> [GRPC/Mainnet] " + id); + console.log(req.connection.remoteAddress + ' -> [GRPC/Mainnet] ' + id) mainnet .api(id, options) .then((result) => { JsonRoutes.sendResult(res, { data: result, headers, - }); + }) }) .catch((error) => { JsonRoutes.sendResult(res, { data: error, headers, - }); - }); - }); - }); + }) + }) + }) + }) // end MAINNET -}); + + Meteor.setInterval(() => { + checkConnectionStatus() + }, 60000) +}) diff --git a/server/qrlNode.js b/server/qrlNode.js index a5a9622..03d4a68 100644 --- a/server/qrlNode.js +++ b/server/qrlNode.js @@ -10,13 +10,13 @@ const util = require('util') const readFile = util.promisify(fs.readFile) const writeFile = util.promisify(fs.writeFile) -const PROTO_PATH = Assets.absoluteFilePath("qrlbase.proto").split( - "qrlbase.proto" +const PROTO_PATH = Assets.absoluteFilePath('qrlbase.proto').split( + 'qrlbase.proto' )[0] let qrlClient = null -function clientGetNodeInfo (client) { +function clientGetNodeInfo(client) { try { return new Promise((resolve, reject) => { client.getNodeInfo({}, (error, response) => { @@ -32,12 +32,16 @@ function clientGetNodeInfo (client) { } function checkProtoHash(file) { - return readFile(file).then(contents => { + return readFile(file).then((contents) => { // console.log(contents) - const protoFileWordArray = CryptoJS.lib.WordArray.create(contents.toString()) - const calculatedProtoHash = CryptoJS.SHA256(protoFileWordArray).toString(CryptoJS.enc.Hex) + const protoFileWordArray = CryptoJS.lib.WordArray.create( + contents.toString() + ) + const calculatedProtoHash = CryptoJS.SHA256(protoFileWordArray).toString( + CryptoJS.enc.Hex + ) let verified = false - QRLPROTO_SHA256.forEach(value => { + QRLPROTO_SHA256.forEach((value) => { if (value.protoHash) { if (value.protoHash === calculatedProtoHash) { verified = true @@ -49,23 +53,30 @@ function checkProtoHash(file) { } function loadGrpcBaseProto(grpcEndpoint) { - return protoLoader.load(`${PROTO_PATH}qrlbase.proto`, {}).then(async packageDefinition => { + return protoLoader + .load(`${PROTO_PATH}qrlbase.proto`, {}) + .then(async (packageDefinition) => { try { - const packageObject = await grpc.loadPackageDefinition(packageDefinition) - const client = await new packageObject.qrl.Base(grpcEndpoint, grpc.credentials.createInsecure()) + const packageObject = await grpc.loadPackageDefinition( + packageDefinition + ) + const client = await new packageObject.qrl.Base( + grpcEndpoint, + grpc.credentials.createInsecure() + ) // console.log(client) const res = await clientGetNodeInfo(client) const qrlProtoFilePath = tmp.fileSync({ mode: '0644', prefix: 'qrl-', - postfix: '.proto' + postfix: '.proto', }).name - writeFile(qrlProtoFilePath, res.grpcProto).then(fsErr => { + writeFile(qrlProtoFilePath, res.grpcProto).then((fsErr) => { if (fsErr) { console.log('tmp filesystem error') } }) - return(qrlProtoFilePath) + return qrlProtoFilePath } catch (error) { console.log('Unable to load grpc base proto (' + error + ')') } @@ -73,34 +84,36 @@ function loadGrpcBaseProto(grpcEndpoint) { } async function loadGrpcProto(protofile, endpoint) { - const options = { - keepCase: true, - longs: String, - enums: String, - defaults: true, - oneofs: true, - includeDirs: [PROTO_PATH], - } - const packageDefinition = await protoLoader.load(protofile, options) - const grpcObject = grpc.loadPackageDefinition(packageDefinition) - const grpcObjectString = JSON.stringify(grpcObject.qrl) - const protoObjectWordArray = CryptoJS.lib.WordArray.create(grpcObjectString) - const calculatedObjectHash = CryptoJS.SHA256(protoObjectWordArray).toString(CryptoJS.enc.Hex) - let verified = false - QRLPROTO_SHA256.forEach(value => { - if (value.objectHash) { - if (value.objectHash === calculatedObjectHash) { - verified = true - } + const options = { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [PROTO_PATH], + } + const packageDefinition = await protoLoader.load(protofile, options) + const grpcObject = grpc.loadPackageDefinition(packageDefinition) + const grpcObjectString = JSON.stringify(grpcObject.qrl) + const protoObjectWordArray = CryptoJS.lib.WordArray.create(grpcObjectString) + const calculatedObjectHash = CryptoJS.SHA256(protoObjectWordArray).toString( + CryptoJS.enc.Hex + ) + let verified = false + QRLPROTO_SHA256.forEach((value) => { + if (value.objectHash) { + if (value.objectHash === calculatedObjectHash) { + verified = true } - }) - // If the grpc object shasum matches, establish the grpc connection. - if (verified) { - return new grpcObject.qrl.PublicAPI( - endpoint, - grpc.credentials.createInsecure() - ) } + }) + // If the grpc object shasum matches, establish the grpc connection. + if (verified) { + return new grpcObject.qrl.PublicAPI( + endpoint, + grpc.credentials.createInsecure() + ) + } } async function makeClient(grpcEndpoint) { @@ -184,4 +197,4 @@ class QrlNode { } } -module.exports = QrlNode \ No newline at end of file +module.exports = QrlNode From 7dad54fd3201983ff6b4c6bf5490cd59020bcf16 Mon Sep 17 00:00:00 2001 From: JP Lomas Date: Mon, 28 Dec 2020 15:55:03 +0000 Subject: [PATCH 5/5] Add /util/mainnet/unconfirmedTxCount GET route --- server/main.js | 60 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/server/main.js b/server/main.js index 582c0e0..e153309 100644 --- a/server/main.js +++ b/server/main.js @@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor' import QrlNode from './qrlNode' const ipTestnet = 'testnet-1.automated.theqrl.org' -const ipMainnet = '95.179.131.134' +const ipMainnet = 'mainnet-1.automated.theqrl.org' const port = '19009' const testnet = new QrlNode(ipTestnet, port) const mainnet = new QrlNode(ipMainnet, port) @@ -35,24 +35,14 @@ Meteor.startup(() => { Pragma: 'no-cache', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS', - 'Access-Control-Allow-Headers': - 'Content-Type, Authorization, X-Requested-With', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With', } JsonRoutes.Middleware.use(function (req, res, next) { const originalUrl = req.originalUrl const apiCall = req.originalUrl.split('/') - if ( - apiCall[2] !== 'mainnet' && - apiCall[2] !== 'testnet' && - originalUrl !== '/' - ) { - console.log( - 'ERROR: [invalid route] ' + - req.connection.remoteAddress + - ' -> ' + - originalUrl - ) + if (apiCall[2] !== 'mainnet' && apiCall[2] !== 'testnet' && originalUrl !== '/') { + console.log('ERROR: [invalid route] ' + req.connection.remoteAddress + ' -> ' + originalUrl) JsonRoutes.sendResult(res, { code: 401, data: { @@ -73,13 +63,31 @@ Meteor.startup(() => { // Routes - get JsonRoutes.add('get', '/grpc/testnet/:request', function (req, res, next) { const id = req.params.request - mainnet.api(id).then((result) => { + console.log(req.connection.remoteAddress + ' -> GET [Grpc/Testnet] ' + id) + testnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, headers, }) }) }) + JsonRoutes.add('get', '/util/testnet/unconfirmedTxCount', function (req, res, next) { + console.log(req.connection.remoteAddress + ' -> [Util/Testnet] unconfirmedTxCount') + testnet + .api('getLatestData', { + filter: 'TRANSACTIONS_UNCONFIRMED', + offset: 0, + quantity: 50, + }) + .then((result) => { + console.table(result) + const unconfirmedTxCount = { unconfirmedTransactionCount: result.transactions_unconfirmed.length } + JsonRoutes.sendResult(res, { + data: unconfirmedTxCount, + headers, + }) + }) + }) // Routes - post JsonRoutes.add('post', '/grpc/testnet/:request', function (req, res, next) { const id = req.params.request @@ -99,7 +107,7 @@ Meteor.startup(() => { } } } - console.log(req.connection.remoteAddress + ' -> [GRPC/Testnet] ' + id) + console.log(req.connection.remoteAddress + ' -> POST [Grpc/Testnet] ' + id) testnet .api(id, options) .then((result) => { @@ -125,6 +133,7 @@ Meteor.startup(() => { // Routes - get JsonRoutes.add('get', '/grpc/mainnet/:request', function (req, res, next) { const id = req.params.request + console.log(req.connection.remoteAddress + ' -> GET [Grpc/Mainnet] ' + id) mainnet.api(id).then((result) => { JsonRoutes.sendResult(res, { data: result, @@ -132,6 +141,23 @@ Meteor.startup(() => { }) }) }) + JsonRoutes.add('get', '/util/mainnet/unconfirmedTxCount', function (req, res, next) { + console.log(req.connection.remoteAddress + ' -> [Util/Mainnet] unconfirmedTxCount') + mainnet + .api('getLatestData', { + filter: 'TRANSACTIONS_UNCONFIRMED', + offset: 0, + quantity: 50, + }) + .then((result) => { + console.table(result) + const unconfirmedTxCount = { unconfirmedTransactionCount: result.transactions_unconfirmed.length } + JsonRoutes.sendResult(res, { + data: unconfirmedTxCount, + headers, + }) + }) + }) // Routes - post JsonRoutes.add('post', '/grpc/mainnet/:request', function (req, res, next) { const id = req.params.request @@ -151,7 +177,7 @@ Meteor.startup(() => { } } } - console.log(req.connection.remoteAddress + ' -> [GRPC/Mainnet] ' + id) + console.log(req.connection.remoteAddress + ' -> POST [Grpc/Mainnet] ' + id) mainnet .api(id, options) .then((result) => {