Merge pull request #31 from AAVikings/operations_adding_clone_id
Operations adding clone
This commit is contained in:
17 files changed
+967
-233
No files matched your search
@@ -9,3 +9,9 @@ bin/*
|
||||
*.cache
|
||||
node_modules/*
|
||||
exchange/Auth0.js
|
||||
configs/Email.Config.json
|
||||
|
||||
configs/User.Profile.json
|
||||
configs/Execution.Config.json
|
||||
configs/Secret.Keys.json
|
||||
.env
|
||||
+9
-81
@@ -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. */
|
||||
@@ -1017,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);
|
||||
@@ -1393,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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,11 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -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,11 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
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 accessToken = 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 ' + accessToken
|
||||
}
|
||||
})
|
||||
|
||||
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)
|
||||
throw new Error('There has been an error updating the execution report: ' + error)
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,12 @@
|
||||
<Compile Include="CloudRequire.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="utils\auth.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="utils\logger.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DataDependencies.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -45,6 +51,9 @@
|
||||
<Compile Include="exchange\wrappers\binanceClient.js" />
|
||||
<Compile Include="exchange\wrappers\poloniex.js" />
|
||||
<Compile Include="exchange\wrappers\poloniexClient.js" />
|
||||
<Compile Include="Integrations\OperationsModuleIntegration.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Root.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -68,6 +77,7 @@
|
||||
<Compile Include="StatusReport.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="StorageAccessManager.js" />
|
||||
<Compile Include="TradingBotProcessMainLoop.js">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -82,6 +92,8 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Exchange\" />
|
||||
<Folder Include="Exchange\Wrappers\" />
|
||||
<Folder Include="Integrations\" />
|
||||
<Folder Include="utils\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<!--Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them.-->
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
const appRoot = require('app-root-path')
|
||||
const operationsIntegration = require(`${appRoot}/Integrations/OperationsModuleIntegration`)
|
||||
|
||||
exports.newRoot = function newRoot() {
|
||||
|
||||
@@ -210,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
|
||||
@@ -218,17 +219,16 @@ 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 === 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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
/*
|
||||
@@ -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") {
|
||||
@@ -836,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);
|
||||
@@ -856,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);
|
||||
@@ -883,7 +892,7 @@ exports.newRoot = function newRoot() {
|
||||
|
||||
tradingBotMainLoop.run(pGenes, pTotalInstances, whenRunFinishes);
|
||||
|
||||
function whenRunFinishes(err) {
|
||||
function whenRunFinishes(err, context) {
|
||||
|
||||
pBotConfig.loopCounter = 0;
|
||||
|
||||
@@ -909,6 +918,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 {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
global.CURRENT_ENVIRONMENT = "Develop";
|
||||
global.CURRENT_EXECUTION_AT = "Browser";
|
||||
require('dotenv').config()
|
||||
|
||||
global.CURRENT_ENVIRONMENT = "Develop";
|
||||
global.CURRENT_EXECUTION_AT = "Cloud";
|
||||
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.
|
||||
global.RUN_AS_TEAM = false;
|
||||
|
||||
/* Default parameters can be changed by the execution configuration */
|
||||
global.EXCHANGE_NAME = "Poloniex";
|
||||
@@ -15,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;
|
||||
});
|
||||
|
||||
@@ -36,38 +37,155 @@ process.on('exit', function (code) {
|
||||
}
|
||||
});
|
||||
|
||||
global.USER_PROFILE = {};
|
||||
global.EMAIL_CONFIG = {};
|
||||
readExecutionConfiguration();
|
||||
|
||||
readStoragePermissions();
|
||||
function readExecutionConfiguration() {
|
||||
try {
|
||||
console.log("[INFO] Run -> readExecutionConfiguration -> Entering function. ");
|
||||
let startMode
|
||||
|
||||
// Environment Configuration
|
||||
global.CURRENT_ENVIRONMENT = process.env.PLATFORM_ENVIRONMENT
|
||||
global.GATEWAY_ENDPOINT = process.env.GATEWAY_ENDPOINT
|
||||
|
||||
// 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.MIN_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",
|
||||
devTeam: process.env.DEV_TEAM,
|
||||
bot: process.env.BOT,
|
||||
process: process.env.PROCESS,
|
||||
repo: global.CURRENT_BOT_REPO
|
||||
}]
|
||||
|
||||
global.EXECUTION_CONFIG = {
|
||||
executionList: executionList,
|
||||
startMode: startMode
|
||||
};
|
||||
|
||||
readStoragePermissions();
|
||||
}
|
||||
|
||||
catch (err) {
|
||||
console.log("[ERROR] readExecutionConfiguration -> err = " + err.message);
|
||||
console.log("[ERROR] readExecutionConfiguration -> err = " + err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
function readStoragePermissions() {
|
||||
|
||||
let filePath;
|
||||
|
||||
try {
|
||||
console.log( "[INFO] Run -> readStoragePermissions -> Entering function. ");
|
||||
|
||||
let fs = require('fs');
|
||||
filePath = '../' + 'User-Profile' + '/' + '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(process.env.STORAGE_CONNECTION_STRING, onInitialized);
|
||||
|
||||
/* Here we will rearrange the storage permissions array into a map, so that it can be easily consumed when needed. */
|
||||
function onInitialized() {
|
||||
|
||||
let permissionsMap = new Map;
|
||||
/* Here we will rearrange the storage permissions array into a map, so that it can be easily consumed when needed. */
|
||||
|
||||
for (i = 0; i < global.USER_PROFILE.storagePermissions.length; i++) {
|
||||
let permissionsMap = new Map;
|
||||
|
||||
let permission = global.USER_PROFILE.storagePermissions[i];
|
||||
let containers = ["AAPlatform", "AAMasters", "AAVikings", global.DEV_TEAM]
|
||||
let container;
|
||||
let key;
|
||||
let value;
|
||||
|
||||
permissionsMap.set(permission[0], permission[1]);
|
||||
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 = "";
|
||||
process.env.STORAGE_CONNECTION_STRING = "";
|
||||
|
||||
startRoot();
|
||||
|
||||
}
|
||||
|
||||
global.USER_PROFILE.storagePermissions = permissionsMap;
|
||||
|
||||
readEmailConfiguration();
|
||||
}
|
||||
catch (err) {
|
||||
console.log("[ERROR] Run -> readStoragePermissions -> err = " + err.message);
|
||||
@@ -75,74 +193,6 @@ function readStoragePermissions() {
|
||||
}
|
||||
}
|
||||
|
||||
function readEmailConfiguration() {
|
||||
|
||||
let filePath;
|
||||
|
||||
try {
|
||||
console.log( "Run : [INFO] readEmailConfiguration -> Entering function. ");
|
||||
|
||||
let fs = require('fs');
|
||||
filePath = '../' + 'Email-Config' + '/' + 'Email.Config.json';
|
||||
global.EMAIL_CONFIG = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
|
||||
readExecutionConfiguration();
|
||||
}
|
||||
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 readExecutionConfiguration() {
|
||||
let filePath;
|
||||
try {
|
||||
let fs = require('fs');
|
||||
filePath = '../Execution-Config/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
|
||||
};
|
||||
|
||||
readExchangeAPIKey();
|
||||
}
|
||||
catch (err) {
|
||||
console.log("[ERROR] readExecutionConfiguration -> err = " + err.message);
|
||||
console.log("[HINT] You need to have a file at this path -> " + filePath);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Move this method inside ExchangeAPI
|
||||
function readExchangeAPIKey() {
|
||||
|
||||
try {
|
||||
console.log( "[INFO] Run -> readExchangeAPIKey -> Entering function. ");
|
||||
|
||||
let fs = require('fs');
|
||||
let filePath = '../' + 'Exchange-Keys' + '/' + '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. ");
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
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=" + global.STORAGE_BASE_URL + ";SharedAccessSignature=" + sasToken + "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -176,7 +181,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');
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -361,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) {
|
||||
|
||||
@@ -369,9 +374,13 @@
|
||||
|
||||
}
|
||||
|
||||
/* 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(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. */
|
||||
|
||||
let exchangeAPI;
|
||||
let assistant;
|
||||
let userBot;
|
||||
@@ -994,7 +1003,7 @@
|
||||
clearTimeout(nextLoopTimeoutHandle);
|
||||
clearTimeout(checkLoopHealthHandle);
|
||||
bot.enableCheckLoopHealth = false;
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE);
|
||||
callBackFunction(global.DEFAULT_OK_RESPONSE, context);
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -1184,6 +1193,7 @@
|
||||
callBackFunction(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch (err) {
|
||||
|
||||
+14
-25
@@ -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."); }
|
||||
@@ -37,28 +37,17 @@
|
||||
// TODO integrate with financial beings module to get the exchange
|
||||
let botExchange = 'Poloniex';
|
||||
let exchange = botExchange.toLowerCase() + 'Client.js';
|
||||
let api = require('./Wrappers/' + exchange);
|
||||
|
||||
request(authOptions, onTokenResponse);
|
||||
let api = require('./wrappers/' + exchange);
|
||||
|
||||
function onTokenResponse(error, response, body) {
|
||||
if (global.LOG_CONTROL[MODULE_NAME].logInfo === true) { logger.write(MODULE_NAME, "[INFO] onTokenResponse -> Entering function."); }
|
||||
const accessToken = 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(accessToken)
|
||||
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,7 +56,7 @@
|
||||
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: global.GATEWAY_ENDPOINT,
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + authToken
|
||||
}
|
||||
|
||||
Generated
+496
@@ -134,6 +134,11 @@
|
||||
"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",
|
||||
@@ -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.11"
|
||||
}
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@@ -170,6 +183,40 @@
|
||||
"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.6.1",
|
||||
"is-buffer": "1.1.6"
|
||||
}
|
||||
},
|
||||
"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 +226,16 @@
|
||||
"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="
|
||||
},
|
||||
"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",
|
||||
@@ -189,6 +246,56 @@
|
||||
"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.3",
|
||||
"color-string": "1.5.3"
|
||||
}
|
||||
},
|
||||
"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.1.3",
|
||||
"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.0",
|
||||
"text-hex": "1.0.0"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
|
||||
@@ -210,11 +317,34 @@
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"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.1",
|
||||
"enabled": "1.0.2",
|
||||
"kuler": "1.0.1"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@@ -225,6 +355,22 @@
|
||||
"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": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||
"requires": {
|
||||
"env-variable": "0.0.5"
|
||||
}
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
@@ -233,6 +379,11 @@
|
||||
"iconv-lite": "0.4.24"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
@@ -253,11 +404,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",
|
||||
@@ -334,6 +503,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",
|
||||
@@ -357,6 +535,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",
|
||||
@@ -367,6 +555,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 +585,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 +608,34 @@
|
||||
"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="
|
||||
},
|
||||
"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",
|
||||
@@ -418,11 +647,101 @@
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"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.3.3",
|
||||
"fast-safe-stringify": "2.0.6",
|
||||
"fecha": "2.3.3",
|
||||
"ms": "2.1.1",
|
||||
"triple-beam": "1.3.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"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.36.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
|
||||
@@ -436,6 +755,11 @@
|
||||
"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",
|
||||
@@ -460,11 +784,21 @@
|
||||
"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",
|
||||
"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 +819,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 +874,19 @@
|
||||
"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="
|
||||
},
|
||||
"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.2"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
|
||||
@@ -543,11 +903,26 @@
|
||||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"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",
|
||||
@@ -557,6 +932,11 @@
|
||||
"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",
|
||||
@@ -584,11 +964,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 +994,112 @@
|
||||
"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.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.10",
|
||||
"triple-beam": "1.3.0",
|
||||
"winston-transport": "4.3.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.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": {
|
||||
"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.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"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.3.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.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": {
|
||||
"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.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
||||
+7
-2
@@ -10,15 +10,20 @@
|
||||
"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",
|
||||
"jsonwebtoken": "^8.4.0",
|
||||
"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"
|
||||
"underscore": "^1.9.1",
|
||||
"winston": "^3.1.0"
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -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",
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
const axios = require('axios')
|
||||
const appRoot = require('app-root-path')
|
||||
const { logger } = require(`${appRoot}/utils/logger`)
|
||||
|
||||
exports.authenticate = async function () {
|
||||
try {
|
||||
|
||||
if (!global.ACCESS_TOKEN) {
|
||||
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"}'
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
})
|
||||
Reference in new issue
Block a user