From 15d4e06a0fe3e7e40806fe8330b8fad5984a4f54 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 09:04:11 +0100 Subject: [PATCH 01/18] Email and Profile Config files now inside AACloud Folder Structure --- .gitignore | 3 +++ Run.js | 6 +++--- this.config.json | 10 +++++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 402b59b95..54bc08006 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ bin/* *.cache node_modules/* exchange/Auth0.js +Email-Config/Email.Config.json +Execution.Config.json +User-Profile/User.Profile.json diff --git a/Run.js b/Run.js index 937991c36..c0c86ad7c 100644 --- a/Run.js +++ b/Run.js @@ -49,7 +49,7 @@ function readStoragePermissions() { console.log( "[INFO] Run -> readStoragePermissions -> Entering function. "); let fs = require('fs'); - filePath = '../' + 'User-Profile' + '/' + 'User.Profile.json'; + filePath = './' + 'User-Profile' + '/' + 'User.Profile.json'; global.USER_PROFILE = JSON.parse(fs.readFileSync(filePath, 'utf8')); @@ -83,7 +83,7 @@ function readEmailConfiguration() { console.log( "Run : [INFO] readEmailConfiguration -> Entering function. "); let fs = require('fs'); - filePath = '../' + 'Email-Config' + '/' + 'Email.Config.json'; + filePath = './' + 'Email-Config' + '/' + 'Email.Config.json'; global.EMAIL_CONFIG = JSON.parse(fs.readFileSync(filePath, 'utf8')); readExecutionConfiguration(); @@ -98,7 +98,7 @@ function readExecutionConfiguration() { let filePath; try { let fs = require('fs'); - filePath = '../Execution-Config/Execution.Config.json'; + filePath = 'Execution.Config.json'; let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); global.DEV_TEAM = executionProperties.devTeam; global.EXCHANGE_NAME = executionProperties.exchangeName; diff --git a/this.config.json b/this.config.json index 3a23977c8..d4a37b864 100644 --- a/this.config.json +++ b/this.config.json @@ -14,35 +14,35 @@ "repo": "AAMariam-Trading-Bot" }, { - "enabled": "true", + "enabled": "false", "devTeam": "AAMasters", "bot": "AACharly", "process": "Poloniex-Live-Trades", "repo": "AACharly-Extraction-Bot" }, { - "enabled": "true", + "enabled": "false", "devTeam": "AAMasters", "bot": "AACharly", "process": "Poloniex-Hole-Fixing", "repo": "AACharly-Extraction-Bot" }, { - "enabled": "true", + "enabled": "false", "devTeam": "AAMasters", "bot": "AABruce", "process": "One-Min-Daily-Candles-Volumes", "repo": "AABruce-Indicator-Bot" }, { - "enabled": "true", + "enabled": "false", "devTeam": "AAMasters", "bot": "AAOlivia", "process": "Multi-Period-Daily", "repo": "AAOlivia-Indicator-Bot" }, { - "enabled": "true", + "enabled": "false", "devTeam": "AAMasters", "bot": "AAOlivia", "process": "Multi-Period-Market", From 7dc099cbdf218a0baf4654b82ddfe9371fe0ad2e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 09:09:51 +0100 Subject: [PATCH 02/18] One folder for all configs --- .gitignore | 7 ++++--- Run.js | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 54bc08006..52053745f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ bin/* *.cache node_modules/* exchange/Auth0.js -Email-Config/Email.Config.json -Execution.Config.json -User-Profile/User.Profile.json +configs/Email.Config.json + +configs/User.Profile.json +configs/Execution.Config.json diff --git a/Run.js b/Run.js index c0c86ad7c..03e0ffdfc 100644 --- a/Run.js +++ b/Run.js @@ -49,7 +49,7 @@ function readStoragePermissions() { console.log( "[INFO] Run -> readStoragePermissions -> Entering function. "); let fs = require('fs'); - filePath = './' + 'User-Profile' + '/' + 'User.Profile.json'; + filePath = './' + 'configs' + '/' + 'User.Profile.json'; global.USER_PROFILE = JSON.parse(fs.readFileSync(filePath, 'utf8')); @@ -83,7 +83,7 @@ function readEmailConfiguration() { console.log( "Run : [INFO] readEmailConfiguration -> Entering function. "); let fs = require('fs'); - filePath = './' + 'Email-Config' + '/' + 'Email.Config.json'; + filePath = './' + 'configs' + '/' + 'Email.Config.json'; global.EMAIL_CONFIG = JSON.parse(fs.readFileSync(filePath, 'utf8')); readExecutionConfiguration(); @@ -98,7 +98,7 @@ function readExecutionConfiguration() { let filePath; try { let fs = require('fs'); - filePath = 'Execution.Config.json'; + filePath = './configs/Execution.Config.json'; let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); global.DEV_TEAM = executionProperties.devTeam; global.EXCHANGE_NAME = executionProperties.exchangeName; From 0a406e7ad32f0f743417618e640ab47f866c479b Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 09:23:55 +0100 Subject: [PATCH 03/18] Keys also read from the same config folder --- .gitignore | 1 + Run.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 52053745f..d9043d22a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ configs/Email.Config.json configs/User.Profile.json configs/Execution.Config.json +configs/Secret.Keys.json diff --git a/Run.js b/Run.js index 03e0ffdfc..56f3bfd7f 100644 --- a/Run.js +++ b/Run.js @@ -123,7 +123,7 @@ function readExchangeAPIKey() { console.log( "[INFO] Run -> readExchangeAPIKey -> Entering function. "); let fs = require('fs'); - let filePath = '../' + 'Exchange-Keys' + '/' + 'Secret.Keys' + '.json'; + let filePath = './configs/Secret.Keys' + '.json'; global.EXCHANGE_KEYS = JSON.parse(fs.readFileSync(filePath, 'utf8')); startRoot(); From 68e4a0011469a0c0908412deb3b29e6bc73590c6 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 11:08:06 +0100 Subject: [PATCH 04/18] LOGGED IN USER taken from Execution Config File --- Run.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Run.js b/Run.js index 56f3bfd7f..3a49cb7fc 100644 --- a/Run.js +++ b/Run.js @@ -2,8 +2,6 @@ global.CURRENT_ENVIRONMENT = "Develop"; global.CURRENT_EXECUTION_AT = "Browser"; global.SHALL_BOT_STOP = false; -global.USER_LOGGED_IN = "Ciencias"; -global.DEV_TEAM = "AAMasters"; global.AT_BREAKPOINT = false; // This is used only when running at the browser. /* Default parameters can be changed by the execution configuration */ @@ -101,6 +99,7 @@ function readExecutionConfiguration() { filePath = './configs/Execution.Config.json'; let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); global.DEV_TEAM = executionProperties.devTeam; + global.USER_LOGGED_IN = executionProperties.userName; global.EXCHANGE_NAME = executionProperties.exchangeName; global.MARKET = executionProperties.market; global.EXECUTION_CONFIG = { From f2e042e7a3d2c34888fcd643d754a04249d8299a Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 11:35:57 +0100 Subject: [PATCH 05/18] By default it should run at the CLOUD --- Run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Run.js b/Run.js index 3a49cb7fc..6b2399998 100644 --- a/Run.js +++ b/Run.js @@ -1,6 +1,6 @@  global.CURRENT_ENVIRONMENT = "Develop"; -global.CURRENT_EXECUTION_AT = "Browser"; +global.CURRENT_EXECUTION_AT = "Cloud"; global.SHALL_BOT_STOP = false; global.AT_BREAKPOINT = false; // This is used only when running at the browser. From 9725ec52db0469da81c6924a804b1f91610c3cc8 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Sat, 17 Nov 2018 16:14:42 +0100 Subject: [PATCH 06/18] Generate Dinamically Storage Permissions --- Project.njsproj | 1 + Run.js | 46 ++++++++++++++++++++++++------ StorageAccessManager.js | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 StorageAccessManager.js diff --git a/Project.njsproj b/Project.njsproj index 516525a6d..c6a345349 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -68,6 +68,7 @@ Code + Code diff --git a/Run.js b/Run.js index 6b2399998..f930cb063 100644 --- a/Run.js +++ b/Run.js @@ -50,22 +50,50 @@ function readStoragePermissions() { filePath = './' + 'configs' + '/' + 'User.Profile.json'; global.USER_PROFILE = JSON.parse(fs.readFileSync(filePath, 'utf8')); + /* Dinamically generating the azure storage permissions for the bot to run */ - /* Here we will rearrange the storage permissions array into a map, so that it can be easily consumed when needed. */ + const MAX_STORAGE_PERMISSION_DAYS = 10; + const STORAGE_ACCESS_MANAGER = require('./StorageAccessManager'); + storageAccessManager = STORAGE_ACCESS_MANAGER.newStorageAccessManager(); - let permissionsMap = new Map; + storageAccessManager.initialize(global.USER_PROFILE.connectionString, onInitialized); - for (i = 0; i < global.USER_PROFILE.storagePermissions.length; i++) { + function onInitialized() { - let permission = global.USER_PROFILE.storagePermissions[i]; + /* Here we will rearrange the storage permissions array into a map, so that it can be easily consumed when needed. */ - permissionsMap.set(permission[0], permission[1]); + let permissionsMap = new Map; + + let containers = ["AAPlatform", "AAVikings", global.USER_PROFILE.teamName] + let container; + let key; + let value; + + for (let i = 0; i < containers.length; i++) { + + container = containers[i]; + let readPermission = storageAccessManager.getPermission(container.toLowerCase(), "READ", MAX_STORAGE_PERMISSION_DAYS); + + key = container + ".READ"; + value = readPermission; + + permissionsMap.set(key, value); + + } + + let writePermission = storageAccessManager.getPermission(container.toLowerCase(), "WRITE", MAX_STORAGE_PERMISSION_DAYS); + + key = container + ".WRITE"; + value = writePermission; + + permissionsMap.set(key, value); + + global.USER_PROFILE.storagePermissions = permissionsMap; + global.USER_PROFILE.connectionString = ""; + + readEmailConfiguration(); } - - global.USER_PROFILE.storagePermissions = permissionsMap; - - readEmailConfiguration(); } catch (err) { console.log("[ERROR] Run -> readStoragePermissions -> err = " + err.message); diff --git a/StorageAccessManager.js b/StorageAccessManager.js new file mode 100644 index 000000000..ae4ad9a67 --- /dev/null +++ b/StorageAccessManager.js @@ -0,0 +1,63 @@ +exports.newStorageAccessManager = function newStorageAccessManager() { + + let thisObject = { + getPermission: getPermission, + initialize: initialize + } + + let connectionString; + + return thisObject; + + function initialize(pConnectionString, callBackFunction) { + + connectionString = pConnectionString; + + callBackFunction(); + } + + function getPermission(pContainer, pType, pDays) { + + let azure = require('azure-storage'); + let blobService = azure.createBlobService(connectionString); + + let startDate = new Date(); + startDate.setDate(startDate.getDate() - 1); + + let expiryDate = new Date(startDate); + expiryDate.setDate(startDate.getDate() + pDays); + + let azurePermissions; + + switch (pType) { + case "READ": { + azurePermissions = azure.BlobUtilities.SharedAccessPermissions.READ; + break; + } + case "WRITE": { + azurePermissions = azure.BlobUtilities.SharedAccessPermissions.WRITE; + break; + } + case "DELETE": { + azurePermissions = azure.BlobUtilities.SharedAccessPermissions.DELETE; + break; + } + } + + let blobName = undefined; + + let sharedAccessPolicy = { + AccessPolicy: { + Permissions: azurePermissions, + Start: startDate, + Expiry: expiryDate + } + }; + + let sasToken = blobService.generateSharedAccessSignature(pContainer, blobName, sharedAccessPolicy); + + return "BlobEndpoint=https://aadevelop.blob.core.windows.net;SharedAccessSignature=" + sasToken + ""; + + } +} + From 616f17f99040b959f764ec63e9d2820d7b64193b Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 12:37:07 -0300 Subject: [PATCH 07/18] Removing secrets file and adding paramater for the execution config --- Run.js | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/Run.js b/Run.js index f930cb063..c2324344f 100644 --- a/Run.js +++ b/Run.js @@ -124,7 +124,13 @@ function readExecutionConfiguration() { let filePath; try { let fs = require('fs'); - filePath = './configs/Execution.Config.json'; + + let configDirectory = process.argv[2]; + if(configDirectory === undefined){ + console.log("[ERROR] Configuration file not passed as a command line argument."); + return; + } + filePath = configDirectory +'/Execution.Config.json'; let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); global.DEV_TEAM = executionProperties.devTeam; global.USER_LOGGED_IN = executionProperties.userName; @@ -135,7 +141,7 @@ function readExecutionConfiguration() { startMode: executionProperties.startMode }; - readExchangeAPIKey(); + startRoot(); } catch (err) { console.log("[ERROR] readExecutionConfiguration -> err = " + err.message); @@ -143,33 +149,6 @@ function readExecutionConfiguration() { } } -//TODO Move this method inside ExchangeAPI -function readExchangeAPIKey() { - - try { - console.log( "[INFO] Run -> readExchangeAPIKey -> Entering function. "); - - let fs = require('fs'); - let filePath = './configs/Secret.Keys' + '.json'; - - global.EXCHANGE_KEYS = JSON.parse(fs.readFileSync(filePath, 'utf8')); - startRoot(); - } - catch (err) { - console.log("[ERROR] Run -> readExchangeAPIKey -> err = " + err.message); - console.log("[HINT] Run -> You need to have a file at this path -> " + filePath); - - global.EXCHANGE_KEYS = { - Poloniex: [{ - Key: "", - Secret: "" - }] - } - - startRoot(); - } -} - function startRoot() { console.log( "[INFO] Run -> startRoot -> Entering function. "); From 8310b6b6afdb120106ee2acbe30d7080eb276b40 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 12:58:34 -0300 Subject: [PATCH 08/18] Removing USER_LOGGED_IN since it's only used on Browser execution --- Run.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Run.js b/Run.js index c2324344f..fc86c4bcd 100644 --- a/Run.js +++ b/Run.js @@ -133,7 +133,6 @@ function readExecutionConfiguration() { filePath = configDirectory +'/Execution.Config.json'; let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); global.DEV_TEAM = executionProperties.devTeam; - global.USER_LOGGED_IN = executionProperties.userName; global.EXCHANGE_NAME = executionProperties.exchangeName; global.MARKET = executionProperties.market; global.EXECUTION_CONFIG = { From 4fa295fc87c2c21fe920b860151c812423680309 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 13:14:39 -0300 Subject: [PATCH 09/18] Adding azure dependency --- package-lock.json | 117 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index e49ce5eda..8197cfa4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -170,6 +170,31 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "azure-storage": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.2.tgz", + "integrity": "sha512-pOyGPya9+NDpAfm5YcFfklo57HfjDbYLXxs4lomPwvRxmb0Di/A+a+RkUmEFzaQ8S13CqxK40bRRB0sjj2ZQxA==", + "requires": { + "browserify-mime": "1.2.9", + "extend": "3.0.2", + "json-edm-parser": "0.1.2", + "md5.js": "1.3.4", + "readable-stream": "2.0.6", + "request": "2.88.0", + "underscore": "1.8.3", + "uuid": "3.3.2", + "validator": "9.4.1", + "xml2js": "0.2.8", + "xmlbuilder": "9.0.7" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + } + } + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -179,6 +204,11 @@ "tweetnacl": "0.14.5" } }, + "browserify-mime": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", + "integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=" + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -334,6 +364,15 @@ "har-schema": "2.0.0" } }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "2.0.1", + "safe-buffer": "5.1.2" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -367,6 +406,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isomorphic-fetch": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", @@ -392,6 +436,14 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "optional": true }, + "json-edm-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", + "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", + "requires": { + "jsonparse": "1.2.0" + } + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -407,6 +459,11 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "jsonparse": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", + "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -423,6 +480,15 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "md5.js": { + "version": "1.3.4", + "resolved": "http://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.1" + } + }, "mime-db": { "version": "1.36.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", @@ -465,6 +531,11 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, "psl": { "version": "1.1.29", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", @@ -485,6 +556,19 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, + "readable-stream": { + "version": "2.0.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.1", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", @@ -527,6 +611,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "0.5.8", + "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", @@ -543,6 +632,11 @@ "tweetnacl": "0.14.5" } }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -584,11 +678,21 @@ "inherits": "2.0.1" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, + "validator": { + "version": "9.4.1", + "resolved": "http://registry.npmjs.org/validator/-/validator-9.4.1.tgz", + "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -604,6 +708,19 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" }, + "xml2js": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", + "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", + "requires": { + "sax": "0.5.8" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, "zen-observable": { "version": "0.8.9", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.9.tgz", diff --git a/package.json b/package.json index 16aaf5699..564db3a39 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "querystring": "^0.2.0", "request": "^2.88.0", "retry": "^0.12.0", - "underscore": "^1.9.1" + "underscore": "^1.9.1", + "azure-storage": "^2.8.2" } } From 4027f54f6257b743b2b3b8f47506121fe05e31f2 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 13:50:29 -0300 Subject: [PATCH 10/18] Changing execution order --- Run.js | 62 +++++++++++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/Run.js b/Run.js index fc86c4bcd..980a4d657 100644 --- a/Run.js +++ b/Run.js @@ -34,13 +34,37 @@ process.on('exit', function (code) { } }); -global.USER_PROFILE = {}; -global.EMAIL_CONFIG = {}; +readExecutionConfiguration(); -readStoragePermissions(); +function readExecutionConfiguration() { + let filePath; + try { + let fs = require('fs'); + + let configDirectory = process.argv[2]; + if (configDirectory === undefined) { + console.log("[ERROR] Configuration file not passed as a command line argument."); + return; + } + filePath = configDirectory + '/Execution.Config.json'; + let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); + global.DEV_TEAM = executionProperties.devTeam; + global.EXCHANGE_NAME = executionProperties.exchangeName; + global.MARKET = executionProperties.market; + global.EXECUTION_CONFIG = { + executionList: executionProperties.executionList, + startMode: executionProperties.startMode + }; + + readStoragePermissions(); + } + catch (err) { + console.log("[ERROR] readExecutionConfiguration -> err = " + err.message); + console.log("[HINT] You need to have a file at this path -> " + filePath); + } +} function readStoragePermissions() { - let filePath; try { @@ -112,7 +136,7 @@ function readEmailConfiguration() { filePath = './' + 'configs' + '/' + 'Email.Config.json'; global.EMAIL_CONFIG = JSON.parse(fs.readFileSync(filePath, 'utf8')); - readExecutionConfiguration(); + startRoot(); } catch (err) { console.log("[ERROR] Run -> readEmailConfiguration -> err = " + err.message); @@ -120,34 +144,6 @@ function readEmailConfiguration() { } } -function readExecutionConfiguration() { - let filePath; - try { - let fs = require('fs'); - - let configDirectory = process.argv[2]; - if(configDirectory === undefined){ - console.log("[ERROR] Configuration file not passed as a command line argument."); - return; - } - filePath = configDirectory +'/Execution.Config.json'; - let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); - global.DEV_TEAM = executionProperties.devTeam; - global.EXCHANGE_NAME = executionProperties.exchangeName; - global.MARKET = executionProperties.market; - global.EXECUTION_CONFIG = { - executionList: executionProperties.executionList, - startMode: executionProperties.startMode - }; - - startRoot(); - } - catch (err) { - console.log("[ERROR] readExecutionConfiguration -> err = " + err.message); - console.log("[HINT] You need to have a file at this path -> " + filePath); - } -} - function startRoot() { console.log( "[INFO] Run -> startRoot -> Entering function. "); From ad567daba47221a720c65a6482f3a9dc256a71f0 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 13:52:09 -0300 Subject: [PATCH 11/18] Adding dev team name to default containers --- Run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Run.js b/Run.js index 980a4d657..ba93a3e1f 100644 --- a/Run.js +++ b/Run.js @@ -88,7 +88,7 @@ function readStoragePermissions() { let permissionsMap = new Map; - let containers = ["AAPlatform", "AAVikings", global.USER_PROFILE.teamName] + let containers = ["AAPlatform", "AAVikings", global.DEV_TEAM] let container; let key; let value; From b8f655d1ba23125805c0cd986fa1a4ac6c22fe72 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sat, 17 Nov 2018 14:16:22 -0300 Subject: [PATCH 12/18] Adding AAMasters by default --- Run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Run.js b/Run.js index ba93a3e1f..f21106276 100644 --- a/Run.js +++ b/Run.js @@ -88,7 +88,7 @@ function readStoragePermissions() { let permissionsMap = new Map; - let containers = ["AAPlatform", "AAVikings", global.DEV_TEAM] + let containers = ["AAPlatform", "AAMasters", "AAVikings", global.DEV_TEAM] let container; let key; let value; From f58a9f76a5b8d6286ba8532a444a968ea65044fe Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Thu, 13 Dec 2018 09:12:25 -0300 Subject: [PATCH 13/18] Adding env variables and fixing issues --- Assistant.js | 45 ++++-------------------------------- Root.js | 7 +++++- Run.js | 38 +++++++++++++++++------------- StorageAccessManager.js | 2 +- TradingBotProcessMainLoop.js | 2 +- exchange/ExchangeAPI.js | 5 ++-- package-lock.json | 5 ++++ package.json | 3 ++- 8 files changed, 45 insertions(+), 62 deletions(-) diff --git a/Assistant.js b/Assistant.js index 6f8b9b7f4..301130f36 100644 --- a/Assistant.js +++ b/Assistant.js @@ -918,10 +918,6 @@ try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> Entering function."); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pType = " + pType); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pRate = " + pRate); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountA = " + pAmountA); } - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountB = " + pAmountB); } /* Removing extra decimals. */ @@ -929,6 +925,11 @@ pAmountA = thisObject.truncDecimals(pAmountA); pAmountB = thisObject.truncDecimals(pAmountB); + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pType = " + pType); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pRate = " + pRate); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountA = " + pAmountA); } + if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] putPosition -> pAmountB = " + pAmountB); } + /* Validations that the limits are not surpassed. */ if (pType === 'buy') { @@ -947,24 +948,6 @@ callBackFunction(err); return; } - - let aRate = thisObject.truncDecimals(pAmountA / pRate); - - if (aRate !== pAmountB) { - - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA / pRate !== pAmountB."); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA = " + pAmountA); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB = " + pAmountB); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pRate = " + pRate); - - let err = { - result: global.DEFAULT_FAIL_RESPONSE.result, - message: 'pAmountB * pRate !== pAmountA' - }; - - callBackFunction(err); - return; - } } if (pType === 'sell') { @@ -983,24 +966,6 @@ callBackFunction(err); return; } - - let bRate = thisObject.truncDecimals(pAmountB * pRate); - - if (bRate !== pAmountA) { - - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB * pRate !== pAmountA."); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountA = " + pAmountA); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pAmountB = " + pAmountB); - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> pRate = " + pRate); - - let err = { - result: global.DEFAULT_FAIL_RESPONSE.result, - message: 'pAmountB * pRate !== pAmountA' - }; - - callBackFunction(err); - return; - } } /* All validations passed, we proceed. */ diff --git a/Root.js b/Root.js index 4c0f321dd..5fcf14cf8 100644 --- a/Root.js +++ b/Root.js @@ -529,8 +529,9 @@ exports.newRoot = function newRoot() { if (processConfig.startMode.live !== undefined) { if (processConfig.startMode.live.run === "true" && global.EXECUTION_CONFIG.startMode.live.run === "true") { - + botConfig.startMode = "Live"; + console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode); let month = pad((new Date()).getUTCMonth() + 1, 2); let year = (new Date()).getUTCFullYear(); @@ -558,6 +559,8 @@ exports.newRoot = function newRoot() { if (processConfig.startMode.backtest.run === "true" && global.EXECUTION_CONFIG.startMode.backtest.run === "true") { botConfig.startMode = "Backtest"; + console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode); + botConfig.backtest = processConfig.startMode.backtest; /* We override these waitTimes to the one specified at the backtest configuration. */ @@ -586,6 +589,8 @@ exports.newRoot = function newRoot() { if (processConfig.startMode.competition.run === "true" && global.EXECUTION_CONFIG.startMode.competition.run === "true") { botConfig.startMode = "Competition"; + console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> Start Mode = " + botConfig.startMode); + botConfig.competition = processConfig.startMode.competition; if (processConfig.startMode.competition.resumeExecution === "false" && global.EXECUTION_CONFIG.startMode.competition.resumeExecution === "false") { diff --git a/Run.js b/Run.js index f21106276..18b7b7cca 100644 --- a/Run.js +++ b/Run.js @@ -1,4 +1,4 @@ - +require('dotenv').config() global.CURRENT_ENVIRONMENT = "Develop"; global.CURRENT_EXECUTION_AT = "Cloud"; global.SHALL_BOT_STOP = false; @@ -37,30 +37,36 @@ process.on('exit', function (code) { readExecutionConfiguration(); function readExecutionConfiguration() { - let filePath; try { - let fs = require('fs'); + console.log("[INFO] Run -> readExecutionConfiguration -> Entering function. "); + + global.DEV_TEAM = process.env.DEV_TEAM; + + let executionList = [{ + enabled: "true", + devTeam: process.env.DEV_TEAM, + bot: process.env.BOT, + process: process.env.PROCESS + }] + + // TODO Improve this by changing Root.js + let mode = + '{ "run":"false",' + + '"resumeExecution":' + process.env.RESUME_EXECUTION + + '}' + let startMode = JSON.parse('{ "live": ' + mode +', "backtest": '+mode+', "competition": '+mode+'}') + startMode[process.env.START_MODE].run="true" - let configDirectory = process.argv[2]; - if (configDirectory === undefined) { - console.log("[ERROR] Configuration file not passed as a command line argument."); - return; - } - filePath = configDirectory + '/Execution.Config.json'; - let executionProperties = JSON.parse(fs.readFileSync(filePath, 'utf8')); - global.DEV_TEAM = executionProperties.devTeam; - global.EXCHANGE_NAME = executionProperties.exchangeName; - global.MARKET = executionProperties.market; global.EXECUTION_CONFIG = { - executionList: executionProperties.executionList, - startMode: executionProperties.startMode + executionList: executionList, + startMode: startMode }; readStoragePermissions(); } catch (err) { console.log("[ERROR] readExecutionConfiguration -> err = " + err.message); - console.log("[HINT] You need to have a file at this path -> " + filePath); + console.log("[ERROR] readExecutionConfiguration -> err = " + err.stack); } } diff --git a/StorageAccessManager.js b/StorageAccessManager.js index ae4ad9a67..ed6794ced 100644 --- a/StorageAccessManager.js +++ b/StorageAccessManager.js @@ -57,7 +57,7 @@ let sasToken = blobService.generateSharedAccessSignature(pContainer, blobName, sharedAccessPolicy); return "BlobEndpoint=https://aadevelop.blob.core.windows.net;SharedAccessSignature=" + sasToken + ""; - + //return "BlobEndpoint=https://aaproduction.blob.core.windows.net;SharedAccessSignature=" + sasToken + ""; } } diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js index 21b9845bf..877150c6b 100644 --- a/TradingBotProcessMainLoop.js +++ b/TradingBotProcessMainLoop.js @@ -176,7 +176,7 @@ /* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */ const UTILITIES = require(ROOT_DIR + 'CloudUtilities'); - const EXCHANGE_API = require(ROOT_DIR + 'Exchange/ExchangeAPI'); + const EXCHANGE_API = require(ROOT_DIR + 'exchange/ExchangeAPI'); const CONTEXT = require(ROOT_DIR + 'Context'); const ASSISTANT = require(ROOT_DIR + 'Assistant'); const STATUS_REPORT = require(ROOT_DIR + 'StatusReport'); diff --git a/exchange/ExchangeAPI.js b/exchange/ExchangeAPI.js index 0d56607fe..0c1559768 100644 --- a/exchange/ExchangeAPI.js +++ b/exchange/ExchangeAPI.js @@ -37,7 +37,7 @@ // TODO integrate with financial beings module to get the exchange let botExchange = 'Poloniex'; let exchange = botExchange.toLowerCase() + 'Client.js'; - let api = require('./Wrappers/' + exchange); + let api = require('./wrappers/' + exchange); request(authOptions, onTokenResponse); @@ -67,7 +67,8 @@ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createKeyVaultAPIClient -> Entering function."); } const keyVaultAPI = graphqlClient({ - url: 'https://app-api.advancedalgos.net/graphql', + //url: 'https://platform-api.advancedalgos.net/graphql', + url: 'https://platform-dev-api.advancedalgos.net/graphql', headers: { Authorization: 'Bearer ' + authToken } diff --git a/package-lock.json b/package-lock.json index 8197cfa4b..ef0cf5a63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -245,6 +245,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==" + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", diff --git a/package.json b/package.json index 564db3a39..a91b814fd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "request": "^2.88.0", "retry": "^0.12.0", "underscore": "^1.9.1", - "azure-storage": "^2.8.2" + "azure-storage": "^2.8.2", + "dotenv": "^6.0.0" } } From 6135d516db363f6c84053d59ae805d4687fdcbc5 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Mon, 28 Jan 2019 11:36:48 -0300 Subject: [PATCH 14/18] Container support Changes required to accepts parameters and run the bots on the virtual machine. --- .gitignore | 1 + Assistant.js | 4 +- Context.js | 1 - ExtractionBotProcessMainLoop.js | 12 +- IndicatorBotProcessMainLoop.js | 12 +- Integrations/OperationsModuleIntegration.js | 59 +++ Project.njsproj | 13 + Root.js | 28 +- Run.js | 42 +- StorageAccessManager.js | 3 +- TradingBotProcessMainLoop.js | 25 +- exchange/ExchangeAPI.js | 38 +- package-lock.json | 508 +++++++++++++++----- package.json | 8 +- utils/auth.js | 25 + utils/logger.js | 40 ++ 16 files changed, 637 insertions(+), 182 deletions(-) create mode 100644 Integrations/OperationsModuleIntegration.js create mode 100644 utils/auth.js create mode 100644 utils/logger.js diff --git a/.gitignore b/.gitignore index d9043d22a..7ab8c3a90 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ configs/Email.Config.json configs/User.Profile.json configs/Execution.Config.json configs/Secret.Keys.json +.env diff --git a/Assistant.js b/Assistant.js index 301130f36..232e61610 100644 --- a/Assistant.js +++ b/Assistant.js @@ -982,8 +982,8 @@ if (pRate !== marketRate) { - logger.write(MODULE_NAME, "[ERROR] putPosition -> Input Validations -> putPosition Rate can not be different to marketRate while in Backtesting Mode. "); - onResponse(global.DEFAULT_FAIL_RESPONSE, positionId); + logger.write(MODULE_NAME, "[WARNING] putPosition -> Input Validations -> putPosition Rate can is different to marketRate while in Backtesting Mode. "); + //onResponse(global.DEFAULT_FAIL_RESPONSE, positionId); } let positionId = Math.trunc(Math.random(1) * 1000000); diff --git a/Context.js b/Context.js index c834d8d1a..df5cd196f 100644 --- a/Context.js +++ b/Context.js @@ -169,7 +169,6 @@ } catch (err) { logger.write(MODULE_NAME, "[ERROR] initialize -> getStatusReport -> err = " + err.message); - logger.write(MODULE_NAME, "[ERROR] initialize -> getStatusReport -> key = " + key); callBack(global.DEFAULT_FAIL_RESPONSE); } } diff --git a/ExtractionBotProcessMainLoop.js b/ExtractionBotProcessMainLoop.js index 235f07587..9802d27c4 100644 --- a/ExtractionBotProcessMainLoop.js +++ b/ExtractionBotProcessMainLoop.js @@ -50,7 +50,11 @@ switch (global.CURRENT_EXECUTION_AT) { // This is what determines if the bot is loaded from the devTeam or an endUser copy. case "Cloud": { - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + if (global.RUN_AS_TEAM) { + filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + } else { + filePath = global.DEV_TEAM + "/" + "members" + "/" + global.USER_LOGGED_IN + "/" + global.CURRENT_BOT_REPO + "/" + pProcessConfig.name; // DevTeam Members bots only are run at the browser. + } break; } case "Browser": { @@ -154,8 +158,6 @@ return str.length < max ? pad(" " + str, max) : str; } - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter) + 1, 8)); - /* For each loop we want to create a new log file. */ logger = DEBUG_MODULE.newDebugLog(); @@ -178,6 +180,10 @@ bot.processDatetime = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution. + /* High level log entry */ + + console.log(processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ let userBot; diff --git a/IndicatorBotProcessMainLoop.js b/IndicatorBotProcessMainLoop.js index 9cd328bf9..8248487dd 100644 --- a/IndicatorBotProcessMainLoop.js +++ b/IndicatorBotProcessMainLoop.js @@ -50,7 +50,11 @@ switch (global.CURRENT_EXECUTION_AT) { // This is what determines if the bot is loaded from the devTeam or an endUser copy. case "Cloud": { - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + if (global.RUN_AS_TEAM) { + filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + } else { + filePath = global.DEV_TEAM + "/" + "members" + "/" + global.USER_LOGGED_IN + "/" + global.CURRENT_BOT_REPO + "/" + pProcessConfig.name; // DevTeam Members bots only are run at the browser. + } break; } case "Browser": { @@ -155,8 +159,6 @@ return str.length < max ? pad(" " + str, max) : str; } - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter) + 1, 8 )); - /* For each loop we want to create a new log file. */ logger = DEBUG_MODULE.newDebugLog(); @@ -178,6 +180,10 @@ bot.processDatetime = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution. + /* High level log entry */ + + console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ let userBot; diff --git a/Integrations/OperationsModuleIntegration.js b/Integrations/OperationsModuleIntegration.js new file mode 100644 index 000000000..41c4642c7 --- /dev/null +++ b/Integrations/OperationsModuleIntegration.js @@ -0,0 +1,59 @@ +const axios = require('axios') +const appRoot = require('app-root-path') +const { logger } = require(`${appRoot}/utils/logger`) +const auth = require(`${appRoot}/utils/auth`) + +exports.updateExecutionResults = async function (summaryDate, buyAverage, sellAverage, + marketRate, combinedProfitsA, combinedProfitsB) { + + logger.debug('updateExecutionResults -> Entering Function.') + + try { + + const authResponse = await auth.authenticate() + + const operationsResponse = await axios({ + url: process.env.GATEWAY_ENDPOINT, + method: 'post', + data: { + query: ` + mutation($id: ID!, $summaryDate: Int!, $buyAverage: Float!, $sellAverage: Float!, + $marketRate: Float!, $combinedProfitsA: Float!, $combinedProfitsB: Float!, + $assetA: String!, $assetB: String!){ + operations_UpdateExecutionSummary( + id: $id, + summaryDate: $summaryDate, + buyAverage: $buyAverage, + sellAverage: $sellAverage, + marketRate: $marketRate, + combinedProfitsA: $combinedProfitsA, + combinedProfitsB: $combinedProfitsB, + assetA: $assetA, + assetB: $assetB + ) + } + `, + variables: { + id: process.env.CLONE_ID, + summaryDate: summaryDate, + buyAverage: buyAverage, + sellAverage: sellAverage, + marketRate: marketRate, + combinedProfitsA: combinedProfitsA, + combinedProfitsB: combinedProfitsB, + assetA: global.MARKET.assetA, + assetB: global.MARKET.assetB + }, + }, + headers: { + authorization: 'Bearer ' + authResponse.data.access_token + } + }) + + logger.debug('updateExecutionResults -> Operations Module Response: %s', operationsResponse.data.data.operations_UpdateExecutionSummary) + + } catch (error) { + logger.error('updateExecutionResults -> Error: ' + error.stack) + throw new Error('There has been an error updating the execution report: ' + error) + } +} \ No newline at end of file diff --git a/Project.njsproj b/Project.njsproj index c6a345349..c8f20791c 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -33,6 +33,12 @@ Code + + Code + + + Code + Code @@ -45,6 +51,9 @@ + + Code + Code @@ -76,13 +85,17 @@ + + + + diff --git a/Root.js b/Root.js index 5fcf14cf8..92ac034fc 100644 --- a/Root.js +++ b/Root.js @@ -1,4 +1,5 @@ - +const appRoot = require('app-root-path') +const operationsIntegration = require(`${appRoot}/Integrations/OperationsModuleIntegration`) exports.newRoot = function newRoot() { @@ -218,14 +219,13 @@ exports.newRoot = function newRoot() { Here we check that the local configuration for the execution exist, if it doesn't exist we will take the one on the server. */ - let executionListItem; if (global.EXECUTION_CONFIG === undefined) { - executionListItem = listItem; + listItem = PLATFORM_CONFIG.executionList[p]; } else { - executionListItem = global.EXECUTION_CONFIG.executionList[p]; + listItem = global.EXECUTION_CONFIG.executionList[p]; } - if (listItem.enabled !== "true" || executionListItem.enabled !== "true") { + if (listItem.enabled !== "true") { console.log(logDisplace + "Root : [INFO] start -> Skipping process for being disabled."); console.log(logDisplace + "Root : [INFO] start -> listItem.process = " + listItem.process); @@ -344,7 +344,7 @@ exports.newRoot = function newRoot() { if (FULL_LOG === true) { console.log(logDisplace + "Root : [INFO] start -> findProcess -> Process found at the bot configuration file. -> listItem.process = " + listItem.process); } let processConfig = botConfig.processes[i]; - + processConfig.startMode = global.EXECUTION_CONFIG.startMode // Override file storage configuration try { /* @@ -888,7 +888,7 @@ exports.newRoot = function newRoot() { tradingBotMainLoop.run(pGenes, pTotalInstances, whenRunFinishes); - function whenRunFinishes(err) { + function whenRunFinishes(err, context) { pBotConfig.loopCounter = 0; @@ -914,6 +914,20 @@ exports.newRoot = function newRoot() { console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingBot -> createBotInstance -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs."); logger.persist(); } + + // Update operations module with latest context + if (context !== undefined) { + let lastExecution = context.executionHistory[context.executionHistory.length - 1] + let date = lastExecution[0] / 1000 | 0 + let buyAvgRate = lastExecution[1] + let sellAvgRate = lastExecution[2] + let marketRate = lastExecution[7] + let combinedProfitsA = lastExecution[13] + let combinedProfitsB = lastExecution[14] + + operationsIntegration.updateExecutionResults(date, buyAvgRate, sellAvgRate, + marketRate, combinedProfitsA, combinedProfitsB) + } } } else { diff --git a/Run.js b/Run.js index 18b7b7cca..747440525 100644 --- a/Run.js +++ b/Run.js @@ -1,8 +1,10 @@ require('dotenv').config() -global.CURRENT_ENVIRONMENT = "Develop"; -global.CURRENT_EXECUTION_AT = "Cloud"; + +global.CURRENT_ENVIRONMENT = "Develop"; +global.CURRENT_EXECUTION_AT = "Cloud"; global.SHALL_BOT_STOP = false; global.AT_BREAKPOINT = false; // This is used only when running at the browser. +global.RUN_AS_TEAM = false; /* Default parameters can be changed by the execution configuration */ global.EXCHANGE_NAME = "Poloniex"; @@ -13,6 +15,7 @@ global.MARKET = { process.on('uncaughtException', function (err) { console.log('[INFO] Run -> uncaughtException -> err.message = ' + err.message); + console.log('[INFO] Run -> uncaughtException -> err.stack = ', err.stack); return; }); @@ -40,22 +43,31 @@ function readExecutionConfiguration() { try { console.log("[INFO] Run -> readExecutionConfiguration -> Entering function. "); + global.CURRENT_ENVIRONMENT = process.env.PLATFORM_ENVIRONMENT global.DEV_TEAM = process.env.DEV_TEAM; + global.RUN_AS_TEAM = (process.env.RUN_AS_TEAM === "true"); + global.GATEWAY_ENDPOINT = process.env.GATEWAY_ENDPOINT; + global.STORAGE_URL = process.env.STORAGE_URL; + global.USER_LOGGED_IN = process.env.USER_LOGGED_IN; + global.CURRENT_BOT_REPO = process.env.BOT + "-" + process.env.TYPE + "-Bot"; let executionList = [{ - enabled: "true", - devTeam: process.env.DEV_TEAM, - bot: process.env.BOT, - process: process.env.PROCESS + enabled: "true", + devTeam: process.env.DEV_TEAM, + bot: process.env.BOT, + process: process.env.PROCESS, + repo: global.CURRENT_BOT_REPO }] - // TODO Improve this by changing Root.js let mode = - '{ "run":"false",' + - '"resumeExecution":' + process.env.RESUME_EXECUTION + + '{ "run": "false",' + + '"resumeExecution": "' + process.env.RESUME_EXECUTION + '",' + + '"beginDatetime": "' + process.env.BEGIN_DATE_TIME + '",' + + '"endDatetime": "' + process.env.END_DATE_TIME + '",' + + '"waitTime": "' + process.env.WAIT_TIME + '"' + '}' let startMode = JSON.parse('{ "live": ' + mode +', "backtest": '+mode+', "competition": '+mode+'}') - startMode[process.env.START_MODE].run="true" + startMode[process.env.START_MODE].run = "true" global.EXECUTION_CONFIG = { executionList: executionList, @@ -64,6 +76,7 @@ function readExecutionConfiguration() { readStoragePermissions(); } + catch (err) { console.log("[ERROR] readExecutionConfiguration -> err = " + err.message); console.log("[ERROR] readExecutionConfiguration -> err = " + err.stack); @@ -76,17 +89,14 @@ function readStoragePermissions() { try { console.log( "[INFO] Run -> readStoragePermissions -> Entering function. "); - let fs = require('fs'); - filePath = './' + 'configs' + '/' + 'User.Profile.json'; - global.USER_PROFILE = JSON.parse(fs.readFileSync(filePath, 'utf8')); - /* Dinamically generating the azure storage permissions for the bot to run */ - + global.STORAGE_BASE_URL = process.env.STORAGE_BASE_URL + global.USER_PROFILE = {} const MAX_STORAGE_PERMISSION_DAYS = 10; const STORAGE_ACCESS_MANAGER = require('./StorageAccessManager'); storageAccessManager = STORAGE_ACCESS_MANAGER.newStorageAccessManager(); - storageAccessManager.initialize(global.USER_PROFILE.connectionString, onInitialized); + storageAccessManager.initialize(process.env.STORAGE_CONNECTION_STRING, onInitialized); function onInitialized() { diff --git a/StorageAccessManager.js b/StorageAccessManager.js index ed6794ced..9a36d9d25 100644 --- a/StorageAccessManager.js +++ b/StorageAccessManager.js @@ -56,8 +56,7 @@ let sasToken = blobService.generateSharedAccessSignature(pContainer, blobName, sharedAccessPolicy); - return "BlobEndpoint=https://aadevelop.blob.core.windows.net;SharedAccessSignature=" + sasToken + ""; - //return "BlobEndpoint=https://aaproduction.blob.core.windows.net;SharedAccessSignature=" + sasToken + ""; + return "BlobEndpoint=" + global.STORAGE_BASE_URL + ";SharedAccessSignature=" + sasToken + ""; } } diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js index 877150c6b..3c39c5660 100644 --- a/TradingBotProcessMainLoop.js +++ b/TradingBotProcessMainLoop.js @@ -52,7 +52,12 @@ switch (global.CURRENT_EXECUTION_AT) { // This is what determines if the bot is loaded from the devTeam or an endUser copy. case "Cloud": { - filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + if (global.RUN_AS_TEAM) { + filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name; // DevTeams bots only are run at the cloud. + } else { + filePath = global.DEV_TEAM + "/" + "members" + "/" + global.USER_LOGGED_IN + "/" + global.CURRENT_BOT_REPO + "/" + pProcessConfig.name; // DevTeam Members bots only are run at the browser. + } + break; } case "Browser": { @@ -134,6 +139,8 @@ function run(pGenes, pTotalAlgobots, callBackFunction) { + let context; + try { if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] run -> Entering function."); } @@ -160,8 +167,6 @@ return str.length < max ? pad(" " + str, max) : str; } - console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.instance, 20) + " " + pad(bot.process, 30) + " Entered into Main Loop # " + pad(Number(bot.loopCounter) + 1, 8)); - /* For each loop we want to create a new log file. */ logger = DEBUG_MODULE.newDebugLog(); @@ -289,7 +294,7 @@ clearTimeout(nextLoopTimeoutHandle); clearTimeout(checkLoopHealthHandle); bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); + callBackFunction(global.DEFAULT_OK_RESPONSE, context); return; } } @@ -341,7 +346,7 @@ clearTimeout(nextLoopTimeoutHandle); clearTimeout(checkLoopHealthHandle); bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); + callBackFunction(global.DEFAULT_OK_RESPONSE, context); return; } } @@ -369,9 +374,12 @@ } - /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ + /* High level log entry */ - let context; + console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.devTeam, 20) + " " + pad(bot.process, 30) + " " + bot.startMode + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + + /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ + let exchangeAPI; let assistant; let userBot; @@ -994,7 +1002,7 @@ clearTimeout(nextLoopTimeoutHandle); clearTimeout(checkLoopHealthHandle); bot.enableCheckLoopHealth = false; - callBackFunction(global.DEFAULT_OK_RESPONSE); + callBackFunction(global.DEFAULT_OK_RESPONSE, context); return; } @@ -1184,6 +1192,7 @@ callBackFunction(err); } } + } catch (err) { diff --git a/exchange/ExchangeAPI.js b/exchange/ExchangeAPI.js index 0c1559768..a2d728c97 100644 --- a/exchange/ExchangeAPI.js +++ b/exchange/ExchangeAPI.js @@ -5,12 +5,12 @@ This module allows trading bots to connect to the exchange and do trading operations on it. So far it can only work with Poloniex. */ - const _ = require('lodash'); - const isValidOrder = require('./exchangeUtils').isValidOrder; + const _ = require('lodash') + const isValidOrder = require('./exchangeUtils').isValidOrder const graphqlClient = require('graphql-client') - const request = require('request') - const authOptions = require('./Auth0') - + const appRoot = require('app-root-path') + const auth = require(`${appRoot}/utils/auth`) + let MODULE_NAME = "Exchange API"; let thisObject = { @@ -29,7 +29,7 @@ return thisObject; - function initialize(callBackFunction) { + async function initialize(callBackFunction) { try { if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); } @@ -38,27 +38,16 @@ let botExchange = 'Poloniex'; let exchange = botExchange.toLowerCase() + 'Client.js'; let api = require('./wrappers/' + exchange); - - request(authOptions, onTokenResponse); - function onTokenResponse(error, response, body) { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] onTokenResponse -> Entering function."); } + const authResponse = await auth.authenticate() - if (error) { - logger.write(MODULE_NAME, "[ERROR] onTokenResponse -> err = " + error.message); - callBackFunction(global.DEFAULT_FAIL_RESPONSE); - } else { - if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] onTokenResponse -> Token Received."); } - let response = JSON.parse(body) - let authToken = response.access_token - let keyVaultAPI = createKeyVaultAPIClient(authToken) - apiClient = api.newAPIClient(keyVaultAPI, logger); + let keyVaultAPI = createKeyVaultAPIClient(authResponse.data.access_token) + apiClient = api.newAPIClient(keyVaultAPI, logger); + + callBackFunction(global.DEFAULT_OK_RESPONSE); - callBackFunction(global.DEFAULT_OK_RESPONSE); - } - } } catch (err) { - logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.message); + logger.write(MODULE_NAME, "[ERROR] initialize -> err = " + err.stack); callBackFunction(global.DEFAULT_FAIL_RESPONSE); } } @@ -67,8 +56,7 @@ if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] createKeyVaultAPIClient -> Entering function."); } const keyVaultAPI = graphqlClient({ - //url: 'https://platform-api.advancedalgos.net/graphql', - url: 'https://platform-dev-api.advancedalgos.net/graphql', + url: global.GATEWAY_ENDPOINT, headers: { Authorization: 'Bearer ' + authToken } diff --git a/package-lock.json b/package-lock.json index ef0cf5a63..d98bbf8d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,10 +20,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "apollo-boost": { @@ -31,14 +31,14 @@ "resolved": "https://registry.npmjs.org/apollo-boost/-/apollo-boost-0.1.16.tgz", "integrity": "sha512-ppnQr90n2cn0ZMveEbqxW6NxmskIpThiLziLlRpRLy4keoAICg1NZecxJQmeaBLMtyhf5UholAjpS2SLmEJeHg==", "requires": { - "apollo-cache": "1.1.17", - "apollo-cache-inmemory": "1.2.10", - "apollo-client": "2.4.2", - "apollo-link": "1.2.3", - "apollo-link-error": "1.1.1", - "apollo-link-http": "1.5.5", - "apollo-link-state": "0.4.2", - "graphql-tag": "2.10.0" + "apollo-cache": "^1.1.17", + "apollo-cache-inmemory": "^1.2.10", + "apollo-client": "^2.4.2", + "apollo-link": "^1.0.6", + "apollo-link-error": "^1.0.3", + "apollo-link-http": "^1.3.1", + "apollo-link-state": "^0.4.0", + "graphql-tag": "^2.4.2" } }, "apollo-cache": { @@ -46,7 +46,7 @@ "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.1.17.tgz", "integrity": "sha512-7sp24n2HZO4vXgTaKNomLyIfGxG4gDdDkBB0jkRzRi7HhnKmfwhiF/RCiKNbgLdrPX151INdls0KwIVliD0dHQ==", "requires": { - "apollo-utilities": "1.0.21" + "apollo-utilities": "^1.0.21" } }, "apollo-cache-inmemory": { @@ -54,9 +54,9 @@ "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz", "integrity": "sha512-eBusPFVtYIuo+PIfJdAwUCQ4cs7AJ4mB7sTdXxNQCXToYw8mzE6EfHnV37kdVfBXSaa82BzE2rb/YUq/duuamw==", "requires": { - "apollo-cache": "1.1.17", - "apollo-utilities": "1.0.21", - "graphql-anywhere": "4.1.19" + "apollo-cache": "^1.1.17", + "apollo-utilities": "^1.0.21", + "graphql-anywhere": "^4.1.19" } }, "apollo-client": { @@ -65,13 +65,13 @@ "integrity": "sha512-g1z23umaVSoKLj9xNl0aAnk2KBF4JeBi7MeKFc9CGTixH7TkqeQUQtxcjrC7j2h4KmDbuhOAHOFUGf8YshN+ag==", "requires": { "@types/async": "2.0.49", - "@types/zen-observable": "0.8.0", + "@types/zen-observable": "^0.8.0", "apollo-cache": "1.1.17", - "apollo-link": "1.2.3", - "apollo-link-dedup": "1.0.10", + "apollo-link": "^1.0.0", + "apollo-link-dedup": "^1.0.0", "apollo-utilities": "1.0.21", - "symbol-observable": "1.2.0", - "zen-observable": "0.8.9" + "symbol-observable": "^1.0.2", + "zen-observable": "^0.8.0" } }, "apollo-link": { @@ -79,8 +79,8 @@ "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.3.tgz", "integrity": "sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==", "requires": { - "apollo-utilities": "1.0.21", - "zen-observable-ts": "0.8.10" + "apollo-utilities": "^1.0.0", + "zen-observable-ts": "^0.8.10" } }, "apollo-link-dedup": { @@ -88,7 +88,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz", "integrity": "sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w==", "requires": { - "apollo-link": "1.2.3" + "apollo-link": "^1.2.3" } }, "apollo-link-error": { @@ -96,7 +96,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.1.1.tgz", "integrity": "sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA==", "requires": { - "apollo-link": "1.2.3" + "apollo-link": "^1.2.3" } }, "apollo-link-http": { @@ -104,8 +104,8 @@ "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.5.tgz", "integrity": "sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ==", "requires": { - "apollo-link": "1.2.3", - "apollo-link-http-common": "0.2.5" + "apollo-link": "^1.2.3", + "apollo-link-http-common": "^0.2.5" } }, "apollo-link-http-common": { @@ -113,7 +113,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz", "integrity": "sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w==", "requires": { - "apollo-link": "1.2.3" + "apollo-link": "^1.2.3" } }, "apollo-link-state": { @@ -121,8 +121,8 @@ "resolved": "https://registry.npmjs.org/apollo-link-state/-/apollo-link-state-0.4.2.tgz", "integrity": "sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw==", "requires": { - "apollo-utilities": "1.0.21", - "graphql-anywhere": "4.1.19" + "apollo-utilities": "^1.0.8", + "graphql-anywhere": "^4.1.0-alpha.0" } }, "apollo-utilities": { @@ -130,16 +130,21 @@ "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.21.tgz", "integrity": "sha512-ZcxELlEl+sDCYBgEMdNXJAsZtRVm8wk4HIA58bMsqYfd1DSAJQEtZ93F0GZgYNAGy3QyaoBeZtbb0/01++G8JQ==", "requires": { - "fast-json-stable-stringify": "2.0.0", - "fclone": "1.0.11" + "fast-json-stable-stringify": "^2.0.0", + "fclone": "^1.0.11" } }, + "app-root-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz", + "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": "~2.1.0" } }, "assert": { @@ -155,6 +160,14 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -170,22 +183,31 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "axios": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, "azure-storage": { "version": "2.10.2", "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.2.tgz", "integrity": "sha512-pOyGPya9+NDpAfm5YcFfklo57HfjDbYLXxs4lomPwvRxmb0Di/A+a+RkUmEFzaQ8S13CqxK40bRRB0sjj2ZQxA==", "requires": { - "browserify-mime": "1.2.9", - "extend": "3.0.2", + "browserify-mime": "~1.2.9", + "extend": "^3.0.2", "json-edm-parser": "0.1.2", "md5.js": "1.3.4", - "readable-stream": "2.0.6", - "request": "2.88.0", - "underscore": "1.8.3", - "uuid": "3.3.2", - "validator": "9.4.1", + "readable-stream": "~2.0.0", + "request": "^2.86.0", + "underscore": "~1.8.3", + "uuid": "^3.0.0", + "validator": "~9.4.1", "xml2js": "0.2.8", - "xmlbuilder": "9.0.7" + "xmlbuilder": "^9.0.7" }, "dependencies": { "underscore": { @@ -201,7 +223,7 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "browserify-mime": { @@ -219,12 +241,62 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "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==", + "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=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" + }, + "colorspace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz", + "integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, "combined-stream": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "core-util-is": { @@ -237,7 +309,15 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" } }, "delayed-stream": { @@ -245,6 +325,16 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "requires": { + "colorspace": "1.1.x", + "enabled": "1.0.x", + "kuler": "1.0.x" + } + }, "dotenv": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", @@ -256,8 +346,16 @@ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "optional": true, "requires": { - "jsbn": "0.1.1", - "safer-buffer": "2.1.2" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "requires": { + "env-variable": "0.0.x" } }, "encoding": { @@ -265,9 +363,14 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.24" + "iconv-lite": "~0.4.13" } }, + "env-variable": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", + "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -288,11 +391,29 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-safe-stringify": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz", + "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==" + }, "fclone": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + }, + "follow-redirects": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", + "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", + "requires": { + "debug": "=3.1.0" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -303,9 +424,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.20" + "mime-types": "^2.1.12" }, "dependencies": { "combined-stream": { @@ -313,7 +434,7 @@ "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } } } @@ -323,7 +444,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "graphql": { @@ -331,7 +452,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.0.2.tgz", "integrity": "sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw==", "requires": { - "iterall": "1.2.2" + "iterall": "^1.2.2" } }, "graphql-anywhere": { @@ -339,7 +460,7 @@ "resolved": "https://registry.npmjs.org/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz", "integrity": "sha512-mQlvbECzYPBcgBC9JsdM4v+DSvNmcIP+8Vwr+ij3gktbaLSE0Iza30mztuz40Jlf7ooMs+0emBZucNjLzqz7tA==", "requires": { - "apollo-utilities": "1.0.21" + "apollo-utilities": "^1.0.21" } }, "graphql-client": { @@ -347,7 +468,7 @@ "resolved": "https://registry.npmjs.org/graphql-client/-/graphql-client-2.0.1.tgz", "integrity": "sha512-XXdjUD3mwsBDcUB7g+iXQeRt+3gmIbvA/Yx1nE5aq2RQmaJwiH4hEoYw27AW8cDR90pCrPlHJAb1jJq3zUMbZA==", "requires": { - "isomorphic-fetch": "2.2.1" + "isomorphic-fetch": "^2.2.1" } }, "graphql-tag": { @@ -365,8 +486,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.3.0", + "har-schema": "^2.0.0" } }, "hash-base": { @@ -374,8 +495,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.2" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "http-signature": { @@ -383,9 +504,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.2" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "iconv-lite": { @@ -393,7 +514,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "inherits": { @@ -401,6 +522,16 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -421,8 +552,8 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "3.0.0" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "isstream": { @@ -446,7 +577,7 @@ "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", "requires": { - "jsonparse": "1.2.0" + "jsonparse": "~1.2.0" } }, "json-schema": { @@ -480,18 +611,45 @@ "verror": "1.10.0" } }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "requires": { + "colornames": "^1.1.1" + } + }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "logform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", + "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, "md5.js": { "version": "1.3.4", "resolved": "http://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.1" + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "mime-db": { @@ -504,16 +662,21 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", "requires": { - "mime-db": "1.36.0" + "mime-db": "~1.36.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "nodemailer": { @@ -531,6 +694,11 @@ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -566,12 +734,12 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.1", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } }, "request": { @@ -579,26 +747,26 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.7", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.1.0", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.20", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" } }, "retry": { @@ -621,22 +789,35 @@ "resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz", "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", "requires": { - "asn1": "0.2.4", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.2", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.2", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "safer-buffer": "2.1.2", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -647,21 +828,31 @@ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "requires": { - "psl": "1.1.29", - "punycode": "1.4.1" + "psl": "^1.1.24", + "punycode": "^1.4.1" } }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -703,9 +894,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "whatwg-fetch": { @@ -713,12 +904,105 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" }, + "winston": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz", + "integrity": "sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg==", + "requires": { + "async": "^2.6.0", + "diagnostics": "^1.1.1", + "is-stream": "^1.1.0", + "logform": "^1.9.1", + "one-time": "0.0.4", + "readable-stream": "^2.3.6", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "requires": { + "readable-stream": "^2.3.6", + "triple-beam": "^1.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "xml2js": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", "requires": { - "sax": "0.5.8" + "sax": "0.5.x" } }, "xmlbuilder": { @@ -736,7 +1020,7 @@ "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz", "integrity": "sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ==", "requires": { - "zen-observable": "0.8.9" + "zen-observable": "^0.8.0" } } } diff --git a/package.json b/package.json index a91b814fd..8b4027f28 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,19 @@ "license": "ISC", "dependencies": { "apollo-boost": "^0.1.16", + "app-root-path": "^2.1.0", "assert": "^1.4.1", + "axios": "^0.18.0", + "azure-storage": "^2.8.2", + "dotenv": "^6.0.0", "graphql": "^14.0.2", "graphql-client": "^2.0.1", "lodash": "^4.17.11", "nodemailer": "^4.6.8", "nonce": "^1.0.4", "querystring": "^0.2.0", - "request": "^2.88.0", "retry": "^0.12.0", "underscore": "^1.9.1", - "azure-storage": "^2.8.2", - "dotenv": "^6.0.0" + "winston": "^3.1.0" } } diff --git a/utils/auth.js b/utils/auth.js new file mode 100644 index 000000000..114a25e9e --- /dev/null +++ b/utils/auth.js @@ -0,0 +1,25 @@ +const axios = require('axios') +const appRoot = require('app-root-path') +const { logger } = require(`${appRoot}/utils/logger`) + +exports.authenticate = function () { + try { + logger.debug('authenticate -> Entering Function.') + + const authBody = '{"client_id":"' + process.env.AUTH_CLIENT_ID + + '","client_secret": "' + process.env.AUTH_CLIENT_SECRET + + '","audience":"' + process.env.AUTH_AUDIENCE + + '","grant_type":"client_credentials"}' + + return axios({ + url: process.env.AUTH_URL, + method: 'post', + data: authBody, + headers: { 'content-type': 'application/json' } + }) + + } catch (error) { + logger.error('authenticate -> Error: ' + error.stack) + throw new Error('There has been an error on the authentication: ' + error) + } +} \ No newline at end of file diff --git a/utils/logger.js b/utils/logger.js new file mode 100644 index 000000000..1cc942d0c --- /dev/null +++ b/utils/logger.js @@ -0,0 +1,40 @@ +const winston = require('winston') +const appRoot = require('app-root-path') +const util = require('util') + +const options = { + file: { + level: 'info', + filename: `${appRoot}/logs/app.log`, + handleExceptions: true, + json: true, + maxsize: 5242880, // 5MB + maxFiles: 5, + colorize: false, + timestamp: true + }, + console: { + level: 'debug', + handleExceptions: true, + json: false, + colorize: true, + timestamp: true + } +} + +exports.logger = winston.createLogger({ + level: 'info', + format: winston.format.combine( + winston.format.colorize(), + winston.format.splat(), + winston.format.timestamp({ format: 'YY/MM/DD HH:mm' }), + winston.format.printf( + info => `${info.timestamp} - ${info.level}: ${JSON.parse(JSON.stringify(util.inspect(info.message)))}` + ) + ), + transports: [ + new winston.transports.File(options.file), + new winston.transports.Console(options.console) + ], + exitOnError: false // do not exit on handled exceptions +}) \ No newline at end of file From 46309d6cc577d60b0a625f52e45a7d07e1261684 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Mon, 28 Jan 2019 17:27:45 -0300 Subject: [PATCH 15/18] Adding support for extractors and indicators --- Root.js | 6 +- Run.js | 84 ++++++++-- package-lock.json | 408 ++++++++++++++++++++++++++++------------------ package.json | 1 + 4 files changed, 321 insertions(+), 178 deletions(-) diff --git a/Root.js b/Root.js index 92ac034fc..d07ebb858 100644 --- a/Root.js +++ b/Root.js @@ -211,7 +211,7 @@ exports.newRoot = function newRoot() { for (let p = 0; p < global.PLATFORM_CONFIG.executionList.length; p++) { - let listItem = PLATFORM_CONFIG.executionList[p]; + let listItem; /* The local configuration allows to select the configuration to run @@ -225,10 +225,10 @@ exports.newRoot = function newRoot() { listItem = global.EXECUTION_CONFIG.executionList[p]; } - if (listItem.enabled !== "true") { + if (listItem === undefined || listItem.enabled !== "true") { console.log(logDisplace + "Root : [INFO] start -> Skipping process for being disabled."); - console.log(logDisplace + "Root : [INFO] start -> listItem.process = " + listItem.process); + console.log(logDisplace + "Root : [INFO] start -> listItem.process = " + PLATFORM_CONFIG.executionList[p].process); continue; } diff --git a/Run.js b/Run.js index 747440525..bd58bb8ec 100644 --- a/Run.js +++ b/Run.js @@ -42,14 +42,76 @@ readExecutionConfiguration(); function readExecutionConfiguration() { try { console.log("[INFO] Run -> readExecutionConfiguration -> Entering function. "); + let startMode + // Environment Configuration global.CURRENT_ENVIRONMENT = process.env.PLATFORM_ENVIRONMENT - global.DEV_TEAM = process.env.DEV_TEAM; - global.RUN_AS_TEAM = (process.env.RUN_AS_TEAM === "true"); - global.GATEWAY_ENDPOINT = process.env.GATEWAY_ENDPOINT; - global.STORAGE_URL = process.env.STORAGE_URL; - global.USER_LOGGED_IN = process.env.USER_LOGGED_IN; - global.CURRENT_BOT_REPO = process.env.BOT + "-" + process.env.TYPE + "-Bot"; + global.GATEWAY_ENDPOINT = process.env.GATEWAY_ENDPOINT + global.STORAGE_URL = process.env.STORAGE_URL + + // General Financial Being Configuration + global.DEV_TEAM = process.env.DEV_TEAM + global.CURRENT_BOT_REPO = process.env.BOT + "-" + process.env.TYPE + "-Bot" + global.RUN_AS_TEAM = (process.env.RUN_AS_TEAM === "true") + global.USER_LOGGED_IN = process.env.USER_LOGGED_IN + + if (process.env.TYPE === 'Trading') { + let live = { + run: "false", + resumeExecution: process.env.RESUME_EXECUTION + } + + let backtest = { + run: "false", + resumeExecution: process.env.RESUME_EXECUTION, + beginDatetime: process.env.BEGIN_DATE_TIME, + endDatetime: process.env.END_DATE_TIME, + waitTime: process.env.WAIT_TIME + } + + let competition = { + run: "false", + resumeExecution: process.env.RESUME_EXECUTION, + beginDatetime: process.env.BEGIN_DATE_TIME, + endDatetime: process.env.END_DATE_TIME + } + + startMode = { + live: live, + backtest: backtest, + competition: competition + } + } else if (process.env.TYPE === 'Indicator' || process.env.TYPE === 'Extractor') { + let allMonths = { + run: "false", + minYear: process.env.MIN_YEAR, + maxYear: process.env.MAX_YEAR + } + let oneMonth = { + run: "false", + year: process.env.YEAR, + month: process.env.MONTH + } + let noTime = { + run: "false" + } + let fixedInterval = { + run: "false", + interval: process.env.INTERVAL + } + + startMode = { + allMonths: allMonths, + oneMonth: oneMonth, + noTime: noTime, + fixedInterval: fixedInterval + } + } else { + console.log("[ERROR] readExecutionConfiguration -> Bot Type is invalid." ); + throw new Error("readExecutionConfiguration -> Bot Type is invalid.") + } + + startMode[process.env.START_MODE].run = "true" let executionList = [{ enabled: "true", @@ -59,16 +121,6 @@ function readExecutionConfiguration() { repo: global.CURRENT_BOT_REPO }] - let mode = - '{ "run": "false",' + - '"resumeExecution": "' + process.env.RESUME_EXECUTION + '",' + - '"beginDatetime": "' + process.env.BEGIN_DATE_TIME + '",' + - '"endDatetime": "' + process.env.END_DATE_TIME + '",' + - '"waitTime": "' + process.env.WAIT_TIME + '"' + - '}' - let startMode = JSON.parse('{ "live": ' + mode +', "backtest": '+mode+', "competition": '+mode+'}') - startMode[process.env.START_MODE].run = "true" - global.EXECUTION_CONFIG = { executionList: executionList, startMode: startMode diff --git a/package-lock.json b/package-lock.json index d98bbf8d0..fb0afbaa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,10 +20,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "apollo-boost": { @@ -31,14 +31,14 @@ "resolved": "https://registry.npmjs.org/apollo-boost/-/apollo-boost-0.1.16.tgz", "integrity": "sha512-ppnQr90n2cn0ZMveEbqxW6NxmskIpThiLziLlRpRLy4keoAICg1NZecxJQmeaBLMtyhf5UholAjpS2SLmEJeHg==", "requires": { - "apollo-cache": "^1.1.17", - "apollo-cache-inmemory": "^1.2.10", - "apollo-client": "^2.4.2", - "apollo-link": "^1.0.6", - "apollo-link-error": "^1.0.3", - "apollo-link-http": "^1.3.1", - "apollo-link-state": "^0.4.0", - "graphql-tag": "^2.4.2" + "apollo-cache": "1.1.17", + "apollo-cache-inmemory": "1.2.10", + "apollo-client": "2.4.2", + "apollo-link": "1.2.3", + "apollo-link-error": "1.1.1", + "apollo-link-http": "1.5.5", + "apollo-link-state": "0.4.2", + "graphql-tag": "2.10.0" } }, "apollo-cache": { @@ -46,7 +46,7 @@ "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.1.17.tgz", "integrity": "sha512-7sp24n2HZO4vXgTaKNomLyIfGxG4gDdDkBB0jkRzRi7HhnKmfwhiF/RCiKNbgLdrPX151INdls0KwIVliD0dHQ==", "requires": { - "apollo-utilities": "^1.0.21" + "apollo-utilities": "1.0.21" } }, "apollo-cache-inmemory": { @@ -54,9 +54,9 @@ "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.2.10.tgz", "integrity": "sha512-eBusPFVtYIuo+PIfJdAwUCQ4cs7AJ4mB7sTdXxNQCXToYw8mzE6EfHnV37kdVfBXSaa82BzE2rb/YUq/duuamw==", "requires": { - "apollo-cache": "^1.1.17", - "apollo-utilities": "^1.0.21", - "graphql-anywhere": "^4.1.19" + "apollo-cache": "1.1.17", + "apollo-utilities": "1.0.21", + "graphql-anywhere": "4.1.19" } }, "apollo-client": { @@ -65,13 +65,13 @@ "integrity": "sha512-g1z23umaVSoKLj9xNl0aAnk2KBF4JeBi7MeKFc9CGTixH7TkqeQUQtxcjrC7j2h4KmDbuhOAHOFUGf8YshN+ag==", "requires": { "@types/async": "2.0.49", - "@types/zen-observable": "^0.8.0", + "@types/zen-observable": "0.8.0", "apollo-cache": "1.1.17", - "apollo-link": "^1.0.0", - "apollo-link-dedup": "^1.0.0", + "apollo-link": "1.2.3", + "apollo-link-dedup": "1.0.10", "apollo-utilities": "1.0.21", - "symbol-observable": "^1.0.2", - "zen-observable": "^0.8.0" + "symbol-observable": "1.2.0", + "zen-observable": "0.8.9" } }, "apollo-link": { @@ -79,8 +79,8 @@ "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.3.tgz", "integrity": "sha512-iL9yS2OfxYhigme5bpTbmRyC+Htt6tyo2fRMHT3K1XRL/C5IQDDz37OjpPy4ndx7WInSvfSZaaOTKFja9VWqSw==", "requires": { - "apollo-utilities": "^1.0.0", - "zen-observable-ts": "^0.8.10" + "apollo-utilities": "1.0.21", + "zen-observable-ts": "0.8.10" } }, "apollo-link-dedup": { @@ -88,7 +88,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.10.tgz", "integrity": "sha512-tpUI9lMZsidxdNygSY1FxflXEkUZnvKRkMUsXXuQUNoSLeNtEvUX7QtKRAl4k9ubLl8JKKc9X3L3onAFeGTK8w==", "requires": { - "apollo-link": "^1.2.3" + "apollo-link": "1.2.3" } }, "apollo-link-error": { @@ -96,7 +96,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-error/-/apollo-link-error-1.1.1.tgz", "integrity": "sha512-/yPcaQWcBdB94vpJ4FsiCJt1dAGGRm+6Tsj3wKwP+72taBH+UsGRQQZk7U/1cpZwl1yqhHZn+ZNhVOebpPcIlA==", "requires": { - "apollo-link": "^1.2.3" + "apollo-link": "1.2.3" } }, "apollo-link-http": { @@ -104,8 +104,8 @@ "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.5.tgz", "integrity": "sha512-C5N6N/mRwmepvtzO27dgMEU3MMtRKSqcljBkYNZmWwH11BxkUQ5imBLPM3V4QJXNE7NFuAQAB5PeUd4ligivTQ==", "requires": { - "apollo-link": "^1.2.3", - "apollo-link-http-common": "^0.2.5" + "apollo-link": "1.2.3", + "apollo-link-http-common": "0.2.5" } }, "apollo-link-http-common": { @@ -113,7 +113,7 @@ "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.5.tgz", "integrity": "sha512-6FV1wr5AqAyJ64Em1dq5hhGgiyxZE383VJQmhIoDVc3MyNcFL92TkhxREOs4rnH2a9X2iJMko7nodHSGLC6d8w==", "requires": { - "apollo-link": "^1.2.3" + "apollo-link": "1.2.3" } }, "apollo-link-state": { @@ -121,8 +121,8 @@ "resolved": "https://registry.npmjs.org/apollo-link-state/-/apollo-link-state-0.4.2.tgz", "integrity": "sha512-xMPcAfuiPVYXaLwC6oJFIZrKgV3GmdO31Ag2eufRoXpvT0AfJZjdaPB4450Nu9TslHRePN9A3quxNueILlQxlw==", "requires": { - "apollo-utilities": "^1.0.8", - "graphql-anywhere": "^4.1.0-alpha.0" + "apollo-utilities": "1.0.21", + "graphql-anywhere": "4.1.19" } }, "apollo-utilities": { @@ -130,8 +130,8 @@ "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.0.21.tgz", "integrity": "sha512-ZcxELlEl+sDCYBgEMdNXJAsZtRVm8wk4HIA58bMsqYfd1DSAJQEtZ93F0GZgYNAGy3QyaoBeZtbb0/01++G8JQ==", "requires": { - "fast-json-stable-stringify": "^2.0.0", - "fclone": "^1.0.11" + "fast-json-stable-stringify": "2.0.0", + "fclone": "1.0.11" } }, "app-root-path": { @@ -144,7 +144,7 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "requires": { - "safer-buffer": "~2.1.0" + "safer-buffer": "2.1.2" } }, "assert": { @@ -165,7 +165,7 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.11" } }, "asynckit": { @@ -188,8 +188,8 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", "requires": { - "follow-redirects": "^1.3.0", - "is-buffer": "^1.1.5" + "follow-redirects": "1.6.1", + "is-buffer": "1.1.6" } }, "azure-storage": { @@ -197,17 +197,17 @@ "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.2.tgz", "integrity": "sha512-pOyGPya9+NDpAfm5YcFfklo57HfjDbYLXxs4lomPwvRxmb0Di/A+a+RkUmEFzaQ8S13CqxK40bRRB0sjj2ZQxA==", "requires": { - "browserify-mime": "~1.2.9", - "extend": "^3.0.2", + "browserify-mime": "1.2.9", + "extend": "3.0.2", "json-edm-parser": "0.1.2", "md5.js": "1.3.4", - "readable-stream": "~2.0.0", - "request": "^2.86.0", - "underscore": "~1.8.3", - "uuid": "^3.0.0", - "validator": "~9.4.1", + "readable-stream": "2.0.6", + "request": "2.88.0", + "underscore": "1.8.3", + "uuid": "3.3.2", + "validator": "9.4.1", "xml2js": "0.2.8", - "xmlbuilder": "^9.0.7" + "xmlbuilder": "9.0.7" }, "dependencies": { "underscore": { @@ -223,7 +223,7 @@ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "browserify-mime": { @@ -231,6 +231,11 @@ "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", "integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8=" }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -246,8 +251,8 @@ "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-convert": "1.9.3", + "color-string": "1.5.3" } }, "color-convert": { @@ -268,8 +273,8 @@ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "color-name": "1.1.3", + "simple-swizzle": "0.2.2" } }, "colornames": { @@ -287,8 +292,8 @@ "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz", "integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==", "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" + "color": "3.0.0", + "text-hex": "1.0.0" } }, "combined-stream": { @@ -296,7 +301,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "core-util-is": { @@ -309,7 +314,7 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "debug": { @@ -330,9 +335,9 @@ "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", "requires": { - "colorspace": "1.1.x", - "enabled": "1.0.x", - "kuler": "1.0.x" + "colorspace": "1.1.1", + "enabled": "1.0.2", + "kuler": "1.0.1" } }, "dotenv": { @@ -346,8 +351,16 @@ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "optional": true, "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "jsbn": "0.1.1", + "safer-buffer": "2.1.2" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", + "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "requires": { + "safe-buffer": "5.1.2" } }, "enabled": { @@ -355,7 +368,7 @@ "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", "requires": { - "env-variable": "0.0.x" + "env-variable": "0.0.5" } }, "encoding": { @@ -363,7 +376,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "~0.4.13" + "iconv-lite": "0.4.24" } }, "env-variable": { @@ -411,7 +424,7 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", "requires": { - "debug": "=3.1.0" + "debug": "3.1.0" } }, "forever-agent": { @@ -424,9 +437,9 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.20" }, "dependencies": { "combined-stream": { @@ -434,7 +447,7 @@ "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } } } @@ -444,7 +457,7 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "graphql": { @@ -452,7 +465,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.0.2.tgz", "integrity": "sha512-gUC4YYsaiSJT1h40krG3J+USGlwhzNTXSb4IOZljn9ag5Tj+RkoXrWp+Kh7WyE3t1NCfab5kzCuxBIvOMERMXw==", "requires": { - "iterall": "^1.2.2" + "iterall": "1.2.2" } }, "graphql-anywhere": { @@ -460,7 +473,7 @@ "resolved": "https://registry.npmjs.org/graphql-anywhere/-/graphql-anywhere-4.1.19.tgz", "integrity": "sha512-mQlvbECzYPBcgBC9JsdM4v+DSvNmcIP+8Vwr+ij3gktbaLSE0Iza30mztuz40Jlf7ooMs+0emBZucNjLzqz7tA==", "requires": { - "apollo-utilities": "^1.0.21" + "apollo-utilities": "1.0.21" } }, "graphql-client": { @@ -468,7 +481,7 @@ "resolved": "https://registry.npmjs.org/graphql-client/-/graphql-client-2.0.1.tgz", "integrity": "sha512-XXdjUD3mwsBDcUB7g+iXQeRt+3gmIbvA/Yx1nE5aq2RQmaJwiH4hEoYw27AW8cDR90pCrPlHJAb1jJq3zUMbZA==", "requires": { - "isomorphic-fetch": "^2.2.1" + "isomorphic-fetch": "2.2.1" } }, "graphql-tag": { @@ -486,8 +499,8 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "hash-base": { @@ -495,8 +508,8 @@ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.1", + "safe-buffer": "5.1.2" } }, "http-signature": { @@ -504,9 +517,9 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.2" } }, "iconv-lite": { @@ -514,7 +527,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "inherits": { @@ -552,8 +565,8 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" + "node-fetch": "1.7.3", + "whatwg-fetch": "3.0.0" } }, "isstream": { @@ -577,7 +590,7 @@ "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", "integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=", "requires": { - "jsonparse": "~1.2.0" + "jsonparse": "1.2.0" } }, "json-schema": { @@ -600,6 +613,29 @@ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=" }, + "jsonwebtoken": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz", + "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==", + "requires": { + "jws": "3.2.1", + "lodash.includes": "4.3.0", + "lodash.isboolean": "3.0.3", + "lodash.isinteger": "4.0.4", + "lodash.isnumber": "3.0.3", + "lodash.isplainobject": "4.0.6", + "lodash.isstring": "4.0.1", + "lodash.once": "4.1.1", + "ms": "2.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -611,12 +647,31 @@ "verror": "1.10.0" } }, + "jwa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz", + "integrity": "sha512-Grku9ZST5NNQ3hqNUodSkDfEBqAmGA1R8yiyPHOnLzEKI0GaCQC/XhFmsheXYuXzFQJdILbh+lYBiliqG5R/Vg==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.10", + "safe-buffer": "5.1.2" + } + }, + "jws": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz", + "integrity": "sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g==", + "requires": { + "jwa": "1.2.0", + "safe-buffer": "5.1.2" + } + }, "kuler": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", "requires": { - "colornames": "^1.1.1" + "colornames": "1.1.1" } }, "lodash": { @@ -624,16 +679,51 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, "logform": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz", "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==", "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^2.3.3", - "ms": "^2.1.1", - "triple-beam": "^1.2.0" + "colors": "1.3.3", + "fast-safe-stringify": "2.0.6", + "fecha": "2.3.3", + "ms": "2.1.1", + "triple-beam": "1.3.0" }, "dependencies": { "ms": { @@ -648,8 +738,8 @@ "resolved": "http://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.1" } }, "mime-db": { @@ -662,7 +752,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", "requires": { - "mime-db": "~1.36.0" + "mime-db": "1.36.0" } }, "ms": { @@ -675,8 +765,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" + "encoding": "0.1.12", + "is-stream": "1.1.0" } }, "nodemailer": { @@ -734,12 +824,12 @@ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.1", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } }, "request": { @@ -747,26 +837,26 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.7", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.1.0", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.20", + "oauth-sign": "0.9.0", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.4.3", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" } }, "retry": { @@ -794,7 +884,7 @@ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", "requires": { - "is-arrayish": "^0.3.1" + "is-arrayish": "0.3.2" } }, "sshpk": { @@ -802,15 +892,15 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" + "asn1": "0.2.4", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.2", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.2", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "safer-buffer": "2.1.2", + "tweetnacl": "0.14.5" } }, "stack-trace": { @@ -838,8 +928,8 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" + "psl": "1.1.29", + "punycode": "1.4.1" } }, "triple-beam": { @@ -852,7 +942,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "tweetnacl": { @@ -894,9 +984,9 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "^1.0.0", + "assert-plus": "1.0.0", "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "extsprintf": "1.3.0" } }, "whatwg-fetch": { @@ -909,15 +999,15 @@ "resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz", "integrity": "sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg==", "requires": { - "async": "^2.6.0", - "diagnostics": "^1.1.1", - "is-stream": "^1.1.0", - "logform": "^1.9.1", + "async": "2.6.1", + "diagnostics": "1.1.1", + "is-stream": "1.1.0", + "logform": "1.10.0", "one-time": "0.0.4", - "readable-stream": "^2.3.6", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.2.0" + "readable-stream": "2.3.6", + "stack-trace": "0.0.10", + "triple-beam": "1.3.0", + "winston-transport": "4.3.0" }, "dependencies": { "inherits": { @@ -935,13 +1025,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -949,7 +1039,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } } } @@ -959,8 +1049,8 @@ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", "requires": { - "readable-stream": "^2.3.6", - "triple-beam": "^1.2.0" + "readable-stream": "2.3.6", + "triple-beam": "1.3.0" }, "dependencies": { "inherits": { @@ -978,13 +1068,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -992,7 +1082,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } } } @@ -1002,7 +1092,7 @@ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", "integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=", "requires": { - "sax": "0.5.x" + "sax": "0.5.8" } }, "xmlbuilder": { @@ -1020,7 +1110,7 @@ "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.10.tgz", "integrity": "sha512-5vqMtRggU/2GhePC9OU4sYEWOdvmayp2k3gjPf4F0mXwB3CSbbNznfDUvDJx9O2ZTa1EIXdJhPchQveFKwNXPQ==", "requires": { - "zen-observable": "^0.8.0" + "zen-observable": "0.8.9" } } } diff --git a/package.json b/package.json index 8b4027f28..fa8757b2c 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dotenv": "^6.0.0", "graphql": "^14.0.2", "graphql-client": "^2.0.1", + "jsonwebtoken": "^8.4.0", "lodash": "^4.17.11", "nodemailer": "^4.6.8", "nonce": "^1.0.4", From 23ad5e8a9411cf27c3ae66716ae8f370815f852b Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Tue, 29 Jan 2019 16:17:41 -0300 Subject: [PATCH 16/18] Updating indicator oneMonth start mode --- Run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Run.js b/Run.js index bd58bb8ec..1dd32de50 100644 --- a/Run.js +++ b/Run.js @@ -89,7 +89,7 @@ function readExecutionConfiguration() { } let oneMonth = { run: "false", - year: process.env.YEAR, + year: process.env.MIN_YEAR, month: process.env.MONTH } let noTime = { From 76a0ce15f21a92137a6a7a22546b295b8c7a1221 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Thu, 7 Feb 2019 09:51:21 -0300 Subject: [PATCH 17/18] Updating logs format --- ExtractionBotProcessMainLoop.js | 3 ++- IndicatorBotProcessMainLoop.js | 3 ++- TradingBotProcessMainLoop.js | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ExtractionBotProcessMainLoop.js b/ExtractionBotProcessMainLoop.js index 9802d27c4..e3caf7318 100644 --- a/ExtractionBotProcessMainLoop.js +++ b/ExtractionBotProcessMainLoop.js @@ -182,7 +182,8 @@ /* High level log entry */ - console.log(processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ diff --git a/IndicatorBotProcessMainLoop.js b/IndicatorBotProcessMainLoop.js index 8248487dd..5ed0969df 100644 --- a/IndicatorBotProcessMainLoop.js +++ b/IndicatorBotProcessMainLoop.js @@ -182,7 +182,8 @@ /* High level log entry */ - console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " " + pad(pMonth, 2) + "/" + pad(pYear, 4) + + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ diff --git a/TradingBotProcessMainLoop.js b/TradingBotProcessMainLoop.js index 3c39c5660..b31cc9492 100644 --- a/TradingBotProcessMainLoop.js +++ b/TradingBotProcessMainLoop.js @@ -366,7 +366,7 @@ } } - if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> bot.processDatetime = " + bot.processDatetime); } + if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> bot.processDatetime = " + bot.processDatetime.toISOString()); } if (global.AT_BREAKPOINT === true) { @@ -376,7 +376,8 @@ /* High level log entry */ - console.log(bot.processDatetime.toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.devTeam, 20) + " " + pad(bot.process, 30) + " " + bot.startMode + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8)); + console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.devTeam, 20) + " " + pad(bot.process, 30) + + " " + bot.startMode + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8) + " bot.processDatetime = " + bot.processDatetime.toISOString()); /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */ From 3c0c7f43dec89f0a5b93e81461e484267dd4af99 Mon Sep 17 00:00:00 2001 From: "mati108@gmail.com" <34651529+matbenitez@users.noreply.github.com> Date: Sun, 10 Feb 2019 17:31:09 -0300 Subject: [PATCH 18/18] Adding clone support --- Assistant.js | 41 +-------------------- Integrations/OperationsModuleIntegration.js | 8 ++-- Project.njsproj | 2 - Root.js | 12 ++++-- Run.js | 23 +----------- exchange/ExchangeAPI.js | 4 +- utils/auth.js | 38 +++++++++++++------ 7 files changed, 45 insertions(+), 83 deletions(-) diff --git a/Assistant.js b/Assistant.js index 232e61610..f5e86c857 100644 --- a/Assistant.js +++ b/Assistant.js @@ -1358,45 +1358,8 @@ } function sendEmail(pTitle, pBody, pTo) { - try { - - /** - Email configuration is not available when running the bot on the browser. - */ - if (global.CURRENT_EXECUTION_AT === "Browser") { - logger.write(MODULE_NAME, "[WARN] sendEmail -> Send emails is disabled from the browser."); - return; - } - - let emailList = pTo; //TODO Pending to add spam controller - let runIndex = context.statusReport.runs.length - 1; - - let transporter = nodemailer.createTransport({ - service: global.EMAIL_CONFIG.service, - auth: { - user: global.EMAIL_CONFIG.user, - pass: global.EMAIL_CONFIG.pass - } - }); - - let mailOptions = { - from: global.EMAIL_CONFIG.from, - bcc: emailList, - subject: bot.startMode + "." + runIndex + ' - ' + pTitle, - text: pBody - }; - - transporter.sendMail(mailOptions, function (error, info) { - if (error) { - logger.write(MODULE_NAME, "[ERROR] sendEmail -> err = " + error); - } else { - logger.write(MODULE_NAME, "[INFO] sendEmail -> Email sent = " + info.response); - } - }); - - } catch (err) { - logger.write(MODULE_NAME, "[ERROR] sendEmail -> err = " + err.message); - } + logger.write(MODULE_NAME, "[WARN] sendEmail -> Send emails is currently disabled."); + return; } function truncDecimals(pFloatValue, pDecimals) { diff --git a/Integrations/OperationsModuleIntegration.js b/Integrations/OperationsModuleIntegration.js index 41c4642c7..b8de71616 100644 --- a/Integrations/OperationsModuleIntegration.js +++ b/Integrations/OperationsModuleIntegration.js @@ -10,7 +10,7 @@ exports.updateExecutionResults = async function (summaryDate, buyAverage, sellAv try { - const authResponse = await auth.authenticate() + const accessToken = await auth.authenticate() const operationsResponse = await axios({ url: process.env.GATEWAY_ENDPOINT, @@ -46,11 +46,13 @@ exports.updateExecutionResults = async function (summaryDate, buyAverage, sellAv }, }, headers: { - authorization: 'Bearer ' + authResponse.data.access_token + authorization: 'Bearer ' + accessToken } }) - logger.debug('updateExecutionResults -> Operations Module Response: %s', operationsResponse.data.data.operations_UpdateExecutionSummary) + if (!operationsResponse.data.errors) + logger.debug('updateExecutionResults -> Operations Module Response: %s', operationsResponse.data.data.operations_UpdateExecutionSummary) + else throw new Error(operationsResponse.data.errors[0].message) } catch (error) { logger.error('updateExecutionResults -> Error: ' + error.stack) diff --git a/Project.njsproj b/Project.njsproj index c8f20791c..fe4d8f923 100644 --- a/Project.njsproj +++ b/Project.njsproj @@ -85,13 +85,11 @@ - - diff --git a/Root.js b/Root.js index d07ebb858..86486ae54 100644 --- a/Root.js +++ b/Root.js @@ -841,11 +841,11 @@ exports.newRoot = function newRoot() { } - let clonName = "Clon" + clonKey; + let clonName = botConfig.codeName + "-" + "Clon" + clonKey + "-" + process.env.CLONE_ID; - botConfig.filePathRoot = botConfig.devTeam + "/" + botConfig.codeName + "-" + clonName + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion; + botConfig.filePathRoot = botConfig.devTeam + "/" + clonName + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion; - botConfig.instance = "Clon" + clonKey; + botConfig.instance = clonName; botConfig.instanceIndex = i; setTimeout(execute, i * Math.random() * 10 * 1000); @@ -861,7 +861,11 @@ exports.newRoot = function newRoot() { /* If the bot does not have any genes at all */ let genes = {}; - pBotConfig.instance = "Master"; + let clonName = botConfig.codeName + "-" + process.env.CLONE_ID; + + botConfig.filePathRoot = botConfig.devTeam + "/" + clonName + "/" + global.PLATFORM_CONFIG.codeName + "." + global.PLATFORM_CONFIG.version.major + "." + global.PLATFORM_CONFIG.version.minor + "/" + global.EXCHANGE_NAME + "/" + botConfig.dataSetVersion; + + pBotConfig.instance = clonName; pBotConfig.instanceIndex = 0; createBotInstance(genes, 1, pBotConfig); diff --git a/Run.js b/Run.js index 1dd32de50..2abe7cb4c 100644 --- a/Run.js +++ b/Run.js @@ -47,7 +47,6 @@ function readExecutionConfiguration() { // Environment Configuration global.CURRENT_ENVIRONMENT = process.env.PLATFORM_ENVIRONMENT global.GATEWAY_ENDPOINT = process.env.GATEWAY_ENDPOINT - global.STORAGE_URL = process.env.STORAGE_URL // General Financial Being Configuration global.DEV_TEAM = process.env.DEV_TEAM @@ -182,8 +181,9 @@ function readStoragePermissions() { global.USER_PROFILE.storagePermissions = permissionsMap; global.USER_PROFILE.connectionString = ""; + process.env.STORAGE_CONNECTION_STRING = ""; - readEmailConfiguration(); + startRoot(); } } @@ -193,25 +193,6 @@ function readStoragePermissions() { } } -function readEmailConfiguration() { - - let filePath; - - try { - console.log( "Run : [INFO] readEmailConfiguration -> Entering function. "); - - let fs = require('fs'); - filePath = './' + 'configs' + '/' + 'Email.Config.json'; - global.EMAIL_CONFIG = JSON.parse(fs.readFileSync(filePath, 'utf8')); - - startRoot(); - } - catch (err) { - console.log("[ERROR] Run -> readEmailConfiguration -> err = " + err.message); - console.log("[HINT] Run -> You need to have a file at this path -> " + filePath); - } -} - function startRoot() { console.log( "[INFO] Run -> startRoot -> Entering function. "); diff --git a/exchange/ExchangeAPI.js b/exchange/ExchangeAPI.js index a2d728c97..2ad5eddfd 100644 --- a/exchange/ExchangeAPI.js +++ b/exchange/ExchangeAPI.js @@ -39,9 +39,9 @@ let exchange = botExchange.toLowerCase() + 'Client.js'; let api = require('./wrappers/' + exchange); - const authResponse = await auth.authenticate() + const accessToken = await auth.authenticate() - let keyVaultAPI = createKeyVaultAPIClient(authResponse.data.access_token) + let keyVaultAPI = createKeyVaultAPIClient(accessToken) apiClient = api.newAPIClient(keyVaultAPI, logger); callBackFunction(global.DEFAULT_OK_RESPONSE); diff --git a/utils/auth.js b/utils/auth.js index 114a25e9e..c7f0b8d87 100644 --- a/utils/auth.js +++ b/utils/auth.js @@ -2,22 +2,36 @@ const appRoot = require('app-root-path') const { logger } = require(`${appRoot}/utils/logger`) -exports.authenticate = function () { +exports.authenticate = async function () { try { - logger.debug('authenticate -> Entering Function.') - const authBody = '{"client_id":"' + process.env.AUTH_CLIENT_ID - + '","client_secret": "' + process.env.AUTH_CLIENT_SECRET - + '","audience":"' + process.env.AUTH_AUDIENCE - + '","grant_type":"client_credentials"}' + if (!global.ACCESS_TOKEN) { + logger.debug('authenticate -> Entering Function.') - return axios({ - url: process.env.AUTH_URL, - method: 'post', - data: authBody, - headers: { 'content-type': 'application/json' } - }) + const authBody = '{"client_id":"' + process.env.AUTH_CLIENT_ID + + '","client_secret": "' + process.env.AUTH_CLIENT_SECRET + + '","audience":"' + process.env.AUTH_AUDIENCE + + '","grant_type":"client_credentials"}' + let authResponse = await axios({ + url: process.env.AUTH_URL, + method: 'post', + data: authBody, + headers: { 'content-type': 'application/json' } + }) + + if (!authResponse.data.errors) + global.ACCESS_TOKEN = authResponse.data.access_token + else throw new Error(operationsResponse.data.errors[0].message) + + process.env.AUTH_CLIENT_ID = "" + process.env.AUTH_CLIENT_SECRET = "" + process.env.AUTH_AUDIENCE = "" + process.env.AUTH_URL = "" + } + + return global.ACCESS_TOKEN + } catch (error) { logger.error('authenticate -> Error: ' + error.stack) throw new Error('There has been an error on the authentication: ' + error)