diff --git a/Environment.js b/Environment.js index a599d095e..78846c598 100644 --- a/Environment.js +++ b/Environment.js @@ -17,6 +17,7 @@ exports.newEnvironment = function () { DESKTOP_WEB_SOCKETS_INTERFACE_HOST: 'localhost', PLATFORM_HTTP_INTERFACE_PORT: 34248, DESKTOP_HTTP_INTERFACE_PORT: 33248, + NETWORK_HTTP_INTERFACE_PORT: 31248, PATH_TO_DATA_STORAGE: path.join(basePath, './Platform/My-Data-Storage'), PATH_TO_PROJECTS: path.join(basePath, './Projects'), PATH_TO_LOG_FILES: path.join(basePath, './Platform/My-Log-Files'), diff --git a/Network/NetwokNode.js b/Network/NetwokNode.js index 4bd5f705c..64dcaaa88 100644 --- a/Network/NetwokNode.js +++ b/Network/NetwokNode.js @@ -6,6 +6,7 @@ exports.newNetworkNode = function newNetworkNode() { p2pNetworkPeers: undefined, p2pNetworkNode: undefined, webSocketsInterface: undefined, + httpInterface: undefined, socialGraphService: undefined, storage: undefined, run: run @@ -65,6 +66,12 @@ exports.newNetworkNode = function newNetworkNode() { thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface() thisObject.webSocketsInterface.initialize() console.log('Network Node Web Sockets Interface ........................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort) + /* + Other Network Nodes and Client Apps will communicate with this Network Node via it's HTTP Interface. + */ + thisObject.httpInterface = NT.projects.network.modules.httpInterface.newNetworkModulesHttpInterface() + thisObject.httpInterface.initialize() + console.log('Network Node Http Interface .................................................. Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webPort) } } } diff --git a/NetworkRoot.js b/NetworkRoot.js index a09e3cd62..eab6a7d4e 100644 --- a/NetworkRoot.js +++ b/NetworkRoot.js @@ -47,6 +47,7 @@ exports.newNetworkRoot = function newNetworkRoot() { fs: require('fs'), path: require('path'), util: require('util'), + http: require('http'), nodeFetch: require('node-fetch'), web3: require('web3'), ws: require('ws'), diff --git a/Platform/Client/githubServer.js b/Platform/Client/githubServer.js index 79fce8b98..80464ce8a 100644 --- a/Platform/Client/githubServer.js +++ b/Platform/Client/githubServer.js @@ -79,7 +79,7 @@ exports.newGithubServer = function newGithubServer() { const octokit = new Octokit({ auth: token, - userAgent: 'Superalgos Beta 12' + userAgent: 'Superalgos v.1.0' }) await getList() @@ -207,7 +207,7 @@ exports.newGithubServer = function newGithubServer() { const { Octokit } = SA.nodeModules.octokit const octokit = new Octokit({ auth: token, - userAgent: 'Superalgos Beta 12' + userAgent: 'Superalgos v.1.0' }) await getPrList() await mergePrs() diff --git a/Platform/Client/httpInterface.js b/Platform/Client/httpInterface.js index 197ffb051..b571cf4af 100644 --- a/Platform/Client/httpInterface.js +++ b/Platform/Client/httpInterface.js @@ -44,202 +44,262 @@ exports.newHttpInterface = function newHttpInterface() { let endpointOrFile = requestPath[1] switch (endpointOrFile) { - case 'Environment': - { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.env), httpResponse) - } + case 'Environment': { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.env), httpResponse) + } break - case 'WEB3': - { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + case 'WEB3': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - async function processRequest(body) { - try { - if (body === undefined) { return } - let params = JSON.parse(body) - - switch (params.method) { - case 'getNetworkClientStatus': { - - let serverResponse = await PL.servers.WEB3_SERVER.getNetworkClientStatus( - params.host, - params.port, - params.interface - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'createWalletAccount': { - - let serverResponse = await PL.servers.WEB3_SERVER.createWalletAccount( - params.entropy - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'getWalletBalances': { - - let serverResponse = await PL.servers.WEB3_SERVER.getWalletBalances( - params.host, - params.port, - params.interface, - params.walletDefinition - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'signData': { - - let serverResponse = await PL.servers.WEB3_SERVER.signData( - params.privateKey, - params.data - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'hashData': { - - let serverResponse = await PL.servers.WEB3_SERVER.hashData( - params.data - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'recoverAddress': { - - let serverResponse = await PL.servers.WEB3_SERVER.recoverAddress( - params.signature - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'mnemonicToPrivateKey': { - - let serverResponse = await PL.servers.WEB3_SERVER.mnemonicToPrivateKey( - params.mnemonic - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - default: { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify({ error: 'Method ' + params.method + ' is invalid.' }), httpResponse) - } - } - } catch (err) { - console.log('[ERROR] httpInterface -> WEB3s -> Method call produced an error.') - console.log('[ERROR] httpInterface -> WEB3s -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> WEB3s -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + async function processRequest(body) { + try { + if (body === undefined) { + return } + let params = JSON.parse(body) + + switch (params.method) { + case 'getNetworkClientStatus': { + + let serverResponse = await PL.servers.WEB3_SERVER.getNetworkClientStatus( + params.host, + params.port, + params.interface + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'createWalletAccount': { + + let serverResponse = await PL.servers.WEB3_SERVER.createWalletAccount( + params.entropy + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'getUserWalletBalance': { + + let serverResponse = await PL.servers.WEB3_SERVER.getUserWalletBalance( + params.walletAddress, + params.contractAddress + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'getWalletBalances': { + + let serverResponse = await PL.servers.WEB3_SERVER.getWalletBalances( + params.host, + params.port, + params.interface, + params.walletDefinition + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'signData': { + + let serverResponse = await PL.servers.WEB3_SERVER.signData( + params.privateKey, + params.data + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'hashData': { + + let serverResponse = await PL.servers.WEB3_SERVER.hashData( + params.data + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'recoverAddress': { + + let serverResponse = await PL.servers.WEB3_SERVER.recoverAddress( + params.signature + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'mnemonicToPrivateKey': { + + let serverResponse = await PL.servers.WEB3_SERVER.mnemonicToPrivateKey( + params.mnemonic + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + default: { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify({error: 'Method ' + params.method + ' is invalid.'}), httpResponse) + } + } + } catch (err) { + console.log('[ERROR] httpInterface -> WEB3s -> Method call produced an error.') + console.log('[ERROR] httpInterface -> WEB3s -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> WEB3s -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } } + } break - case 'CCXT': - { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + case 'CCXT': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - async function processRequest(body) { - try { - if (body === undefined) { return } - let params = JSON.parse(body) + async function processRequest(body) { + try { + if (body === undefined) { + return + } + let params = JSON.parse(body) - switch (params.method) { - case 'fetchMarkets': { + switch (params.method) { + case 'fetchMarkets': { - const exchangeClass = SA.nodeModules.ccxt[params.exchangeId] + const exchangeClass = SA.nodeModules.ccxt[params.exchangeId] + const exchangeConstructorParams = { + 'timeout': 30000, + 'enableRateLimit': true, + verbose: false + } + + let ccxtExchange = new exchangeClass(exchangeConstructorParams) + let ccxtMarkets = [] + + if (ccxtExchange.has.fetchMarkets === true) { + ccxtMarkets = await ccxtExchange.fetchMarkets() + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(ccxtMarkets), httpResponse) + return + } + case 'listExchanges': { + let exchanges = [] + for (let i = 0; i < SA.nodeModules.ccxt.exchanges.length; i++) { + let exchangeId = SA.nodeModules.ccxt.exchanges[i] + + const exchangeClass = SA.nodeModules.ccxt[exchangeId] const exchangeConstructorParams = { 'timeout': 30000, 'enableRateLimit': true, verbose: false } - - let ccxtExchange = new exchangeClass(exchangeConstructorParams) - let ccxtMarkets = [] - - if (ccxtExchange.has.fetchMarkets === true) { - ccxtMarkets = await ccxtExchange.fetchMarkets() + let ccxtExchange + try { + ccxtExchange = new exchangeClass(exchangeConstructorParams) + } catch (err) { + } + if (ccxtExchange === undefined) { + continue } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(ccxtMarkets), httpResponse) - return - } - case 'listExchanges': { - let exchanges = [] - for (let i = 0; i < SA.nodeModules.ccxt.exchanges.length; i++) { - let exchangeId = SA.nodeModules.ccxt.exchanges[i] - - const exchangeClass = SA.nodeModules.ccxt[exchangeId] - const exchangeConstructorParams = { - 'timeout': 30000, - 'enableRateLimit': true, - verbose: false - } - let ccxtExchange - try { ccxtExchange = new exchangeClass(exchangeConstructorParams) } - catch (err) { } - if (ccxtExchange === undefined) { continue } - if (ccxtExchange.has.fetchOHLCV === params.has.fetchOHLCV) { - if (ccxtExchange.has.fetchMarkets === params.has.fetchMarkets) { - if (ccxtExchange.timeframes['1m'] !== undefined) { - let exchange = { - name: ccxtExchange.name, - id: ccxtExchange.id - } - exchanges.push(exchange) + if (ccxtExchange.has.fetchOHLCV === params.has.fetchOHLCV) { + if (ccxtExchange.has.fetchMarkets === params.has.fetchMarkets) { + if (ccxtExchange.timeframes['1m'] !== undefined) { + let exchange = { + name: ccxtExchange.name, + id: ccxtExchange.id } + exchanges.push(exchange) } } } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(exchanges), httpResponse) - return } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(exchanges), httpResponse) + return } - - let content = { - err: global.DEFAULT_FAIL_RESPONSE // method not supported - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(content), httpResponse) - - } catch (err) { - console.log('[INFO] httpInterface -> CCXT FetchMarkets -> Could not fetch markets.') - let error = { - result: 'Fail Because', - message: err.message - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } + + let content = { + err: global.DEFAULT_FAIL_RESPONSE // method not supported + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(content), httpResponse) + + } catch (err) { + console.log('[INFO] httpInterface -> CCXT FetchMarkets -> Could not fetch markets.') + let error = { + result: 'Fail Because', + message: err.message + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } } + } break - case 'Webhook': - { - switch (requestPath[2]) { // switch by command - case 'Fetch-Messages': { - let exchange = requestPath[3] - let market = requestPath[4] + case 'Webhook': { + switch (requestPath[2]) { // switch by command + case 'Fetch-Messages': { + let exchange = requestPath[3] + let market = requestPath[4] + + /* Some validations */ + if (exchange === undefined) { + console.log('[WARN] httpInterface -> Webhook -> Fetch-Messages -> Message with no Exchange received -> messageReceived = ' + messageReceived) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + return + } + if (market === undefined) { + console.log('[WARN] httpInterface -> Webhook -> Fetch-Messages -> Message with no market received -> messageReceived = ' + messageReceived) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + return + } + + let key = exchange + '-' + market + + let webhookMessages = webhook.get(key) + if (webhookMessages === undefined) { + webhookMessages = [] + } + + console.log('[INFO] httpInterface -> Webhook -> Fetch-Messages -> Exchange-Market = ' + exchange + '-' + market) + console.log('[INFO] httpInterface -> Webhook -> Fetch-Messages -> Messages Fetched by Webhooks Sensor Bot = ' + webhookMessages.length) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(webhookMessages), httpResponse) + webhookMessages = [] + + webhook.set(key, webhookMessages) + break + } + case 'New-Message': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + function processRequest(messageReceived) { + if (messageReceived === undefined) { + return + } + + let timestamp = (new Date()).valueOf() + let source = requestPath[3] + let exchange = requestPath[4] + let market = requestPath[5] /* Some validations */ + if (source === undefined) { + console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no Source received -> messageReceived = ' + messageReceived) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + return + } if (exchange === undefined) { - console.log('[WARN] httpInterface -> Webhook -> Fetch-Messages -> Message with no Exchange received -> messageReceived = ' + messageReceived) + console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no Exchange received -> messageReceived = ' + messageReceived) SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) return } if (market === undefined) { - console.log('[WARN] httpInterface -> Webhook -> Fetch-Messages -> Message with no market received -> messageReceived = ' + messageReceived) + console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no market received -> messageReceived = ' + messageReceived) SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) return } @@ -251,446 +311,1024 @@ exports.newHttpInterface = function newHttpInterface() { webhookMessages = [] } - console.log('[INFO] httpInterface -> Webhook -> Fetch-Messages -> Exchange-Market = ' + exchange + '-' + market) - console.log('[INFO] httpInterface -> Webhook -> Fetch-Messages -> Messages Fetched by Webhooks Sensor Bot = ' + webhookMessages.length) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(webhookMessages), httpResponse) - webhookMessages = [] - + webhookMessages.push([timestamp, source, messageReceived]) webhook.set(key, webhookMessages) - break - } - case 'New-Message': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - function processRequest(messageReceived) { - if (messageReceived === undefined) { return } - - let timestamp = (new Date()).valueOf() - let source = requestPath[3] - let exchange = requestPath[4] - let market = requestPath[5] - - /* Some validations */ - if (source === undefined) { - console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no Source received -> messageReceived = ' + messageReceived) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - return - } - if (exchange === undefined) { - console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no Exchange received -> messageReceived = ' + messageReceived) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - return - } - if (market === undefined) { - console.log('[WARN] httpInterface -> Webhook -> New-Message -> Message with no market received -> messageReceived = ' + messageReceived) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - return - } - - let key = exchange + '-' + market - - let webhookMessages = webhook.get(key) - if (webhookMessages === undefined) { - webhookMessages = [] - } - - webhookMessages.push([timestamp, source, messageReceived]) - webhook.set(key, webhookMessages) - - console.log('[INFO] httpInterface -> Webhook -> New-Message -> Exchange-Market = ' + exchange + '-' + market) - console.log('[INFO] httpInterface -> Webhook -> New-Message -> messageReceived = ' + messageReceived) - console.log('[INFO] httpInterface -> Webhook -> New-Message -> Messages waiting to be Fetched by Webhooks Sensor Bot = ' + webhookMessages.length) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } - break - } - } - } - break - case 'Docs': - { - switch (requestPath[2]) { // switch by command - case 'Save-Node-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Nodes' - - if (checkAllSchmemaDocuments('Node', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break + console.log('[INFO] httpInterface -> Webhook -> New-Message -> Exchange-Market = ' + exchange + '-' + market) + console.log('[INFO] httpInterface -> Webhook -> New-Message -> messageReceived = ' + messageReceived) + console.log('[INFO] httpInterface -> Webhook -> New-Message -> Messages waiting to be Fetched by Webhooks Sensor Bot = ' + webhookMessages.length) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) } - case 'Save-Concept-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Concepts' - - if (checkAllSchmemaDocuments('Concept', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break - } - - case 'Save-Topic-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Topics' - - if (checkAllSchmemaDocuments('Topic', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break - } - - case 'Save-Tutorial-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Tutorials' - - if (checkAllSchmemaDocuments('Tutorial', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break - } - - case 'Save-Review-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Reviews' - - if (checkAllSchmemaDocuments('Review', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break - } - - case 'Save-Book-Schema': { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let docsSchema = JSON.parse(body) - let project = requestPath[3] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Books' - - if (checkAllSchmemaDocuments('Book', docsSchema, filePath) === true) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - break - } - } - - function checkAllSchmemaDocuments(category, docsSchema, filePath) { - const fs = SA.nodeModules.fs - let noErrorsDuringSaving = true - - for (let i = 0; i < docsSchema.length; i++) { - let schemaDocument = docsSchema[i] - /* - For some type of schemas we will save the file at an extra - folder derived from the document's type. - */ - let fileName = schemaDocument.type.toLowerCase() - for (let j = 0; j < 10; j++) { - fileName = cleanFileName(fileName) - } - let pageNumber = '00' + schemaDocument.pageNumber - let newFilepath = filePath - switch (category) { - case 'Topic': { - fileName = schemaDocument.topic.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - newFilepath = createPrefixDirectories(filePath, schemaDocument.topic) - break - } - case 'Tutorial': { - fileName = schemaDocument.tutorial.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - newFilepath = createPrefixDirectories(filePath, schemaDocument.tutorial) - break - } - case 'Review': { - fileName = schemaDocument.review.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() - fileName = cleanFileName(fileName) - newFilepath = createPrefixDirectories(filePath, schemaDocument.review) - break - } - case 'Node': { - newFilepath = createPrefixDirectories(filePath, schemaDocument.type) - break - } - case 'Concept': { - newFilepath = createPrefixDirectories(filePath, schemaDocument.type) - break - } - } - - function createPrefixDirectories(filePath, schemaTextToUse) { - let firstLetter = schemaTextToUse.substring(0, 1) - createNewDir(filePath + '/' + firstLetter) - let extraWord = schemaTextToUse.split(' ')[0] - createNewDir(filePath + '/' + firstLetter + '/' + extraWord) - return filePath + '/' + firstLetter + '/' + extraWord + '/' + cleanFileName(schemaTextToUse) - } - - fileName = fileName + '.json' - - if (schemaDocument.deleted === true) { - try { - fs.unlinkSync(newFilepath + '/' + fileName) - console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' deleted.') - } catch (err) { - noErrorsDuringSaving = false - console.log('[ERROR] httpInterface -> Docs -> Delete -> ' + newFilepath + '/' + fileName + ' could not be deleted.') - console.log('[ERROR] httpInterface -> Docs -> Delete -> Resolve the issue that is preventing the Client to delete this file. Look at the error message below as a guide. At the UI you will need to delete this page again in order for the Client to retry next time you execute the docs.save command.') - console.log('[ERROR] httpInterface -> Docs -> Delete -> err.stack = ' + err.stack) - } - } else { - if (schemaDocument.updated === true || schemaDocument.created === true) { - try { - let created = schemaDocument.created - let updated = schemaDocument.updated - schemaDocument.updated = undefined - schemaDocument.created = undefined - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - createNewDir(newFilepath) - fs.writeFileSync(newFilepath + '/' + fileName, fileContent) - if (created === true) { - console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' created.') - } else { - if (updated === true) { - console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' updated.') - } - } - } catch (err) { - noErrorsDuringSaving = false - console.log('[ERROR] httpInterface -> Docs -> Save -> ' + newFilepath + '/' + fileName + ' could not be created / updated.') - console.log('[ERROR] httpInterface -> Docs -> Save -> err.stack = ' + err.stack) - } - } - } - - function createNewDir(path) { - try { - fs.mkdirSync(path, {recursive: true}) - } catch (err) { - if (err.message.indexOf('file already exists') < 0) { - throw (err) - } - } - } - } - - return noErrorsDuringSaving - } - - function cleanFileName(fileName) { - for (let i = 0; i < 100; i++) { - fileName = fileName - .replace(' ', '-') - .replace('--', '-') - .replace('?', '') - .replace('#', '') - .replace('$', '') - .replace('%', '') - .replace('^', '') - .replace('&', '') - .replace('*', '') - .replace('(', '') - .replace(')', '') - .replace('!', '') - .replace('..', '.') - .replace(',', '') - .replace('\'', '') - } - return fileName - } - } - break - case 'App': - { - // If running the electron app do not try to get git tool. I don't allow it. - if (process.env.SA_MODE === 'gitDisable') { - console.log('[WARN] No contributions on binary distributions. Do manual installation') break } - switch (requestPath[2]) { // switch by command + } + } + break + case 'Docs': { + switch (requestPath[2]) { // switch by command + case 'Save-Node-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - case 'Contribute': { + async function processRequest(body) { try { - let commitMessage = unescape(requestPath[3]) - const username = unescape(requestPath[4]) - const token = unescape(requestPath[5]) - const currentBranch = unescape(requestPath[6]) - const contributionsBranch = unescape(requestPath[7]) - let error - - /* Unsaving # */ - for (let i = 0; i < 10; i++) { - commitMessage = commitMessage.replace('_SLASH_', '/') - commitMessage = commitMessage.replace('_HASHTAG_', '#') + if (body === undefined) { + return } - contribute() + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Nodes' - async function contribute() { - const { lookpath } = SA.nodeModules.lookpath - const gitpath = await lookpath('git') - if (gitpath === undefined) { - console.log('[ERROR] `git` not installed.') + if (checkAllSchmemaDocuments('Node', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Node-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + + case 'Save-Concept-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Concepts' + + if (checkAllSchmemaDocuments('Concept', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Concept-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + + case 'Save-Topic-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Topics' + + if (checkAllSchmemaDocuments('Topic', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Topic-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + + case 'Save-Tutorial-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Tutorials' + + if (checkAllSchmemaDocuments('Tutorial', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Tutorial-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + + case 'Save-Review-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Reviews' + + if (checkAllSchmemaDocuments('Review', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Review-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + + case 'Save-Book-Schema': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let docsSchema = JSON.parse(body) + let project = requestPath[3] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/Docs-Books' + + if (checkAllSchmemaDocuments('Book', docsSchema, filePath) === true) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Docs -> Save-Book-Schema -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + + break + } + } + + function checkAllSchmemaDocuments(category, docsSchema, filePath) { + const fs = SA.nodeModules.fs + let noErrorsDuringSaving = true + + for (let i = 0; i < docsSchema.length; i++) { + let schemaDocument = docsSchema[i] + /* + For some type of schemas we will save the file at an extra + folder derived from the document's type. + */ + let fileName = schemaDocument.type.toLowerCase() + for (let j = 0; j < 10; j++) { + fileName = cleanFileName(fileName) + } + let pageNumber = '00' + schemaDocument.pageNumber + let newFilepath = filePath + switch (category) { + case 'Topic': { + fileName = schemaDocument.topic.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() + fileName = cleanFileName(fileName) + newFilepath = createPrefixDirectories(filePath, schemaDocument.topic) + break + } + case 'Tutorial': { + fileName = schemaDocument.tutorial.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() + fileName = cleanFileName(fileName) + newFilepath = createPrefixDirectories(filePath, schemaDocument.tutorial) + break + } + case 'Review': { + fileName = schemaDocument.review.toLowerCase() + '-' + pageNumber.substring(pageNumber.length - 3, pageNumber.length) + '-' + schemaDocument.type.toLowerCase() + fileName = cleanFileName(fileName) + newFilepath = createPrefixDirectories(filePath, schemaDocument.review) + break + } + case 'Node': { + newFilepath = createPrefixDirectories(filePath, schemaDocument.type) + break + } + case 'Concept': { + newFilepath = createPrefixDirectories(filePath, schemaDocument.type) + break + } + } + + function createPrefixDirectories(filePath, schemaTextToUse) { + let firstLetter = schemaTextToUse.substring(0, 1) + createNewDir(filePath + '/' + firstLetter) + let extraWord = schemaTextToUse.split(' ')[0] + createNewDir(filePath + '/' + firstLetter + '/' + extraWord) + return filePath + '/' + firstLetter + '/' + extraWord + '/' + cleanFileName(schemaTextToUse) + } + + fileName = fileName + '.json' + + if (schemaDocument.deleted === true) { + try { + fs.unlinkSync(newFilepath + '/' + fileName) + console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' deleted.') + } catch (err) { + noErrorsDuringSaving = false + console.log('[ERROR] httpInterface -> Docs -> Delete -> ' + newFilepath + '/' + fileName + ' could not be deleted.') + console.log('[ERROR] httpInterface -> Docs -> Delete -> Resolve the issue that is preventing the Client to delete this file. Look at the error message below as a guide. At the UI you will need to delete this page again in order for the Client to retry next time you execute the docs.save command.') + console.log('[ERROR] httpInterface -> Docs -> Delete -> err.stack = ' + err.stack) + } + } else { + if (schemaDocument.updated === true || schemaDocument.created === true) { + try { + let created = schemaDocument.created + let updated = schemaDocument.updated + schemaDocument.updated = undefined + schemaDocument.created = undefined + let fileContent = JSON.stringify(schemaDocument, undefined, 4) + createNewDir(newFilepath) + fs.writeFileSync(newFilepath + '/' + fileName, fileContent) + if (created === true) { + console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' created.') } else { - await doGit() - if (error !== undefined) { + if (updated === true) { + console.log('[SUCCESS] ' + newFilepath + '/' + fileName + ' updated.') + } + } + } catch (err) { + noErrorsDuringSaving = false + console.log('[ERROR] httpInterface -> Docs -> Save -> ' + newFilepath + '/' + fileName + ' could not be created / updated.') + console.log('[ERROR] httpInterface -> Docs -> Save -> err.stack = ' + err.stack) + } + } + } - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'App Error - Contribution Not Sent', - anchor: undefined, - placeholder: {} - } + function createNewDir(path) { + try { + fs.mkdirSync(path, {recursive: true}) + } catch (err) { + if (err.message.indexOf('file already exists') < 0) { + throw (err) + } + } + } + } - respondWithDocsObject(docs, error) - return + return noErrorsDuringSaving + } + + function cleanFileName(fileName) { + for (let i = 0; i < 100; i++) { + fileName = fileName + .replace(' ', '-') + .replace('--', '-') + .replace('?', '') + .replace('#', '') + .replace('$', '') + .replace('%', '') + .replace('^', '') + .replace('&', '') + .replace('*', '') + .replace('(', '') + .replace(')', '') + .replace('!', '') + .replace('..', '.') + .replace(',', '') + .replace('\'', '') + } + return fileName + } + } + break + case 'App': { + // If running the electron app do not try to get git tool. I don't allow it. + if (process.env.SA_MODE === 'gitDisable') { + console.log('[WARN] No contributions on binary distributions. Do manual installation') + break + } + switch (requestPath[2]) { // switch by command + + case 'Contribute': { + try { + let commitMessage = unescape(requestPath[3]) + const username = unescape(requestPath[4]) + const token = unescape(requestPath[5]) + const currentBranch = unescape(requestPath[6]) + const contributionsBranch = unescape(requestPath[7]) + let error + + /* Unsaving # */ + for (let i = 0; i < 10; i++) { + commitMessage = commitMessage.replace('_SLASH_', '/') + commitMessage = commitMessage.replace('_HASHTAG_', '#') + } + + contribute() + + async function contribute() { + const {lookpath} = SA.nodeModules.lookpath + const gitpath = await lookpath('git') + if (gitpath === undefined) { + console.log('[ERROR] `git` not installed.') + } else { + await doGit() + if (error !== undefined) { + + let docs = { + project: 'Foundations', + category: 'Topic', + type: 'App Error - Contribution Not Sent', + anchor: undefined, + placeholder: {} } - await doGithub() + respondWithDocsObject(docs, error) + return + } + + await doGithub() + if (error !== undefined) { + + let docs = { + project: 'Foundations', + category: 'Topic', + type: 'App Error - Contribution Not Sent', + anchor: undefined, + placeholder: {} + } + console.log('respond with docs ') + + respondWithDocsObject(docs, error) + return + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } + } + + async function doGit() { + const simpleGit = SA.nodeModules.simpleGit + const options = { + baseDir: process.cwd(), + binary: 'git', + maxConcurrentProcesses: 6, + } + const git = simpleGit(options) + + try { + await git.add('./*') + await git.commit(commitMessage) + await git.push('origin', currentBranch) + } catch (err) { + console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> commitMessage = ' + commitMessage) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> contributionsBranch = ' + contributionsBranch) + console.log('') + console.log('Troubleshooting Tips:') + console.log('') + console.log('1. Make sure that you have set up your Github Username and Token at the APIs -> Github API node at the workspace.') + console.log('2. Make sure you are running the latest version of Git available for your OS.') + console.log('3. Make sure that you have cloned your Superalgos repository fork, and not the main Superalgos repository.') + console.log('4. If your fork is old, you might need to do an app.update and also a node setup at every branch. If you just reforked all is good.') + error = err + } + } + + async function doGithub() { + + const {Octokit} = SA.nodeModules.octokit + + const octokit = new Octokit({ + auth: token, + userAgent: 'Superalgos v.1.0' + }) + + const repo = 'Superalgos' + const owner = 'Superalgos' + const head = username + ':' + contributionsBranch + const base = currentBranch + const title = 'Contribution: ' + commitMessage + + try { + await octokit.pulls.create({ + owner, + repo, + title, + head, + base, + }); + } catch (err) { + if (err.stack.indexOf('A pull request already exists') >= 0) { + return + } else { + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> commitMessage = ' + commitMessage) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> username = ' + username) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> contributionsBranch = ' + contributionsBranch) + error = err + } + } + } + + } catch (err) { + console.log('[ERROR] httpInterface -> App -> Contribute -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Contribute -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> App -> Contribute -> commitMessage = ' + commitMessage) + console.log('[ERROR] httpInterface -> App -> Contribute -> username = ' + username) + console.log('[ERROR] httpInterface -> App -> Contribute -> token starts with = ' + token.substring(0, 10) + '...') + console.log('[ERROR] httpInterface -> App -> Contribute -> token ends with = ' + '...' + token.substring(token.length - 10)) + console.log('[ERROR] httpInterface -> App -> Contribute -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> App -> Contribute -> contributionsBranch = ' + contributionsBranch) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + break + } + + case 'Update': { + try { + const currentBranch = unescape(requestPath[3]) + update() + + async function update() { + const {lookpath} = SA.nodeModules.lookpath + const gitpath = await lookpath('git'); + if (gitpath === undefined) { + console.log('[ERROR] `git` not installed.') + } else { + let result = await doGit() + + if (result.error === undefined) { + let customResponse = { + result: global.CUSTOM_OK_RESPONSE.result, + message: result.message + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) + } else { + + let docs = { + project: 'Foundations', + category: 'Topic', + type: 'App Error - Update Failed', + anchor: undefined, + placeholder: {} + } + + respondWithDocsObject(docs, result.error) + + } + } + } + + async function doGit() { + const simpleGit = SA.nodeModules.simpleGit + const options = { + baseDir: process.cwd(), + binary: 'git', + maxConcurrentProcesses: 6, + } + const git = simpleGit(options) + + let message + try { + message = await git.pull('https://github.com/Superalgos/Superalgos', currentBranch) + return {message: message} + } catch (err) { + console.log('[ERROR] Error updating ' + currentBranch) + console.log(err.stack) + return {error: err} + } + } + + } catch (err) { + console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + break + } + + case 'Checkout': { + try { + const currentBranch = unescape(requestPath[3]) + let error + + checkout() + + async function checkout() { + const {lookpath} = SA.nodeModules.lookpath + const gitpath = await lookpath('git'); + if (gitpath === undefined) { + console.log('[ERROR] `git` not installed.') + } else { + await doGit() + + if (error === undefined) { + // Run node setup to prepare instance for branch change + await runNodeSetup() + // Return to UI that Branch is successfully changed + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } else { + let docs = { + project: 'Foundations', + category: 'Topic', + type: 'Switching Branches - Current Branch Not Changed', + anchor: undefined, + placeholder: {} + } + + respondWithDocsObject(docs, error) + } + } + } + + async function doGit() { + const simpleGit = SA.nodeModules.simpleGit + const options = { + baseDir: process.cwd(), + binary: 'git', + maxConcurrentProcesses: 6, + } + const git = simpleGit(options) + try { + await git.checkout(currentBranch) + + // Check to see it main repo has been set as upstream + let remotes = await git.getRemotes(); + let isUpstreamSet + for (let remote in remotes) { + if (remotes[remote].name === 'upstream') { + isUpstreamSet = true + } else { + isUpstreamSet = false + } + } + // If upstream has not been set. Set it now + if (isUpstreamSet === false) { + await git.addRemote('upstream', 'https://github.com/Superalgos/Superalgos'); + } + // Pull branch from main repo + await git.pull('upstream', currentBranch); + // Reset branch to match main repo + let upstreamLocation = `upstream/${currentBranch}` + await git.reset('hard', [upstreamLocation]) + + } catch (err) { + console.log('[ERROR] Error changing current branch to ' + currentBranch) + console.log(err.stack) + error = err + } + } + + async function runNodeSetup() { + console.log("Running Node setup to adjust for new Branch") + const process = SA.nodeModules.process + const childProcess = SA.nodeModules.childProcess + + let dir = process.cwd() + let command = "node setup noShortcuts"; + let stdout = childProcess.execSync(command, + { + cwd: dir + }).toString(); + + console.log("Node Setup has completed with the following result:", stdout) + } + + } catch (err) { + console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + break + } + + case 'Branch': { + try { + branch() + + async function branch() { + const {lookpath} = SA.nodeModules.lookpath + const gitpath = await lookpath('git'); + if (gitpath === undefined) { + console.log('[ERROR] `git` not installed.') + } else { + let result = await doGit() + + if (result.error === undefined) { + let customResponse = { + result: global.CUSTOM_OK_RESPONSE.result, + message: result + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) + } else { + let docs = { + project: 'Foundations', + category: 'Topic', + type: 'App Error - Could Not Get Current Branch', + anchor: undefined, + placeholder: {} + } + + respondWithDocsObject(docs, error) + } + } + } + + async function doGit() { + const simpleGit = SA.nodeModules.simpleGit + const options = { + baseDir: process.cwd(), + binary: 'git', + maxConcurrentProcesses: 6, + } + const git = simpleGit(options) + try { + return await git.branch() + } catch (err) { + console.log('[ERROR] Error reading current branch.') + console.log(err.stack) + } + } + + } catch (err) { + console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') + console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + break + } + + case 'FixAppSchema': { + /* + We will use this process when we have moved APP SCHEMA files from one project to another, and we need to fix the + actions where this node was referenced, so that it points to the new project where the node has moved to. + */ + let customResponse = { + result: global.CUSTOM_OK_RESPONSE.result, + message: '' + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) + + console.log('Fixing App Schemas...') + + let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) + let PROJECTS_MAP = new Map() + let directoryCount = 0 + let allAppSchemas = [] + let allAppSchemasFilePaths = [] + let allAppSchemasFileProjects = [] + + for (let i = 0; i < projects.length; i++) { + let project = projects[i] + + + const fs = SA.nodeModules.fs + let folder = 'App-Schema' + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/' + SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(filePath + folder, onFilesReady) + + function onFilesReady(files) { + try { + let SCHEMA_MAP = new Map() + + console.log('files.length... ' + files.length) + + for (let k = 0; k < files.length; k++) { + let name = files[k] + let nameSplitted = name.split(folder) + let fileName = nameSplitted[1] + for (let i = 0; i < 10; i++) { + fileName = fileName.replace('\\', '/') + } + let fileToRead = filePath + folder + fileName + + console.log('Reading file... ' + fileToRead) + + let fileContent = fs.readFileSync(fileToRead) + let schemaDocument + try { + schemaDocument = JSON.parse(fileContent) + SCHEMA_MAP.set(schemaDocument.type, schemaDocument) + allAppSchemas.push(schemaDocument) + allAppSchemasFilePaths.push(fileToRead) + allAppSchemasFileProjects.push(project) + } catch (err) { + console.log('[ERROR] sendSchema -> Error Parsing JSON File: ' + fileToRead + ' .Error = ' + err.stack) + return + } + } + PROJECTS_MAP.set(project, SCHEMA_MAP) + directoryCount++ + + console.log('directoryCount = ' + directoryCount, 'projects.length = ' + projects.length) + //console.log(Array.from(PROJECTS_MAP.get(project).keys())) + if (directoryCount === projects.length) { + fixSchemas() + } + } catch (err) { + console.log(err.stack) + } + } + } + + function fixSchemas() { + try { + console.log('fixSchemas...' + allAppSchemas.length) + let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) + const fs = SA.nodeModules.fs + let needFixing = 0 + for (let i = 0; i < allAppSchemas.length; i++) { + let schemaDocument = allAppSchemas[i] + let wasUpdated = false + for (let j = 0; j < schemaDocument.menuItems.length; j++) { + let menuItem = schemaDocument.menuItems[j] + if (menuItem.relatedUiObject !== undefined && menuItem.relatedUiObjectProject === undefined) { + needFixing++ + + let hits = 0 + let foundProject + let multiProject = '' + for (let k = 0; k < projects.length; k++) { + let project = projects[k] + + let testDocument = PROJECTS_MAP.get(project).get(menuItem.relatedUiObject) + if (testDocument !== undefined) { + hits++ + foundProject = project + multiProject = multiProject + ' -> ' + project + + let fileProject = allAppSchemasFileProjects[i] + //console.log(fileProject, project) + if (fileProject === project) { + /* If the project of the file is the same as the project found, then we consider this a match*/ + hits = 1 + continue + } + } + } + + if (hits === 0) { + console.log('Problem With No Solution #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject) + console.log('This Node Type was NOT FOUND at any project. ' + menuItem.relatedUiObject) + continue + } + if (hits === 1) { + console.log('Problem With One Solution #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject, ' Found Project:' + foundProject) + + menuItem.relatedUiObjectProject = foundProject + wasUpdated = true + continue + } + console.log('Problem With MULTIPLE Solutions #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject, ' Found at these Projects:' + multiProject) + } + } + + if (wasUpdated === true) { + let fileContent = JSON.stringify(schemaDocument, undefined, 4) + let filePath = allAppSchemasFilePaths[i] + //console.log('Saving File at ' + filePath) + //console.log(fileContent) + //fs.writeFileSync(filePath, fileContent) + } + } + } catch (err) { + console.log(err.stack) + } + } + + break + } + } + + function respondWithDocsObject(docs, error) { + + if (error.message !== undefined) { + docs.placeholder.errorMessage = { + style: 'Error', + text: error.message + } + } + if (error.stack !== undefined) { + docs.placeholder.errorStack = { + style: 'Javascript', + text: error.stack + } + } + if (error.code !== undefined) { + docs.placeholder.errorCode = { + style: 'Json', + text: error.code + } + } + + docs.placeholder.errorDetails = { + style: 'Json', + text: JSON.stringify(error, undefined, 4) + } + + let customResponse = { + result: global.CUSTOM_FAIL_RESPONSE.result, + docs: docs + } + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) + + } + } + break + case 'GOV': { + /* + This is the Governance endpoint at the Http Interface. All methods + related to the Governance System are implemented here and routed + to the backend Servers that can process them. + */ + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let params = JSON.parse(body) + + switch (params.method) { + case 'getGithubStars': { + + let serverResponse = await PL.servers.GITHUB_SERVER.getGithubStars( + params.repository, + params.username, + params.token + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'getGithubWatchers': { + + let serverResponse = await PL.servers.GITHUB_SERVER.getGithubWatchers( + params.repository, + params.username, + params.token + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'getGithubForks': { + + let serverResponse = await PL.servers.GITHUB_SERVER.getGithubForks( + params.repository, + params.username, + params.token + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + return + } + case 'mergePullRequests': { + + let serverResponse = await PL.servers.GITHUB_SERVER.mergePullRequests( + params.commitMessage, + params.username, + params.token + ) + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) + + setInterval( + PL.servers.GITHUB_SERVER.mergePullRequests, + 60000, + params.commitMessage, + params.username, + params.token + ) + + return + } + + case 'UserProfile': { + try { + + let mess = unescape(params.commitMessage) + const username = unescape(params.username) + const token = unescape(params.token) + const currentBranch = unescape(params.currentBranch) + const contributionsBranch = unescape(params.contributionsBranch) + + let error + + await updateUser() + + async function updateUser() { + + await doGithubUser() if (error !== undefined) { let docs = { - project: 'Foundations', + project: 'Governance', category: 'Topic', - type: 'App Error - Contribution Not Sent', + type: 'Gov Error - Contribution Not Sent', anchor: undefined, placeholder: {} } @@ -700,740 +1338,55 @@ exports.newHttpInterface = function newHttpInterface() { return } SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } - } - async function doGit() { - const simpleGit = SA.nodeModules.simpleGit - const options = { - baseDir: process.cwd(), - binary: 'git', - maxConcurrentProcesses: 6, - } - const git = simpleGit(options) + async function doGithubUser() { - try { - await git.add('./*') - await git.commit(commitMessage) - await git.push('origin', currentBranch) - } catch (err) { - console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> commitMessage = ' + commitMessage) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGit -> contributionsBranch = ' + contributionsBranch) - console.log('') - console.log('Troubleshooting Tips:') - console.log('') - console.log('1. Make sure that you have set up your Github Username and Token at the APIs -> Github API node at the workspace.') - console.log('2. Make sure you are running the latest version of Git available for your OS.') - console.log('3. Make sure that you have cloned your Superalgos repository fork, and not the main Superalgos repository.') - console.log('4. If your fork is old, you might need to do an app.update and also a node setup at every branch. If you just reforked all is good.') - error = err - } - } + const {Octokit} = SA.nodeModules.octokit - async function doGithub() { + const octokit = new Octokit({ + auth: token, + userAgent: 'Superalgos v.1.0' + }) - const { Octokit } = SA.nodeModules.octokit + const repo = 'Superalgos' + const owner = 'Superalgos' + const head = username + ':' + contributionsBranch + const base = currentBranch + const title = 'Contribution: ' + mess + const path = 'Projects/Governance/Plugins/User-Profiles/' + username + '.json'; - const octokit = new Octokit({ - auth: token, - userAgent: 'Superalgos Beta 12' - }) + const sha = await getSHA(path); - const repo = 'Superalgos' - const owner = 'Superalgos' - const head = username + ':' + contributionsBranch - const base = currentBranch - const title = 'Contribution: ' + commitMessage - - try { - await octokit.pulls.create({ - owner, - repo, - title, - head, - base, - }); - } catch (err) { - if (err.stack.indexOf('A pull request already exists') >= 0) { + if (sha === undefined) { + console.log('***** Abort GOV.USERPROFILE *****') return - } else { - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> commitMessage = ' + commitMessage) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> username = ' + username) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> App -> Contribute -> doGithub -> contributionsBranch = ' + contributionsBranch) - error = err } - } - } - } catch (err) { - console.log('[ERROR] httpInterface -> App -> Contribute -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Contribute -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> App -> Contribute -> commitMessage = ' + commitMessage) - console.log('[ERROR] httpInterface -> App -> Contribute -> username = ' + username) - console.log('[ERROR] httpInterface -> App -> Contribute -> token starts with = ' + token.substring(0, 10) + '...') - console.log('[ERROR] httpInterface -> App -> Contribute -> token ends with = ' + '...' + token.substring(token.length - 10)) - console.log('[ERROR] httpInterface -> App -> Contribute -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> App -> Contribute -> contributionsBranch = ' + contributionsBranch) + let file = await SA.projects.communityPlugins.utilities.plugins.getPluginFileContent( + 'Governance', + 'User-Profiles', + username + '.json' + ) - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - break - } + let buff = new Buffer.from(file, 'utf-8'); + let encodedFile = buff.toString('base64'); - case 'Update': { - try { - const currentBranch = unescape(requestPath[3]) - update() - - async function update() { - const { lookpath } = SA.nodeModules.lookpath - const gitpath = await lookpath('git'); - if (gitpath === undefined) { - console.log('[ERROR] `git` not installed.') - } else { - let result = await doGit() - - if (result.error === undefined) { - let customResponse = { - result: global.CUSTOM_OK_RESPONSE.result, - message: result.message - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) - } else { - - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'App Error - Update Failed', - anchor: undefined, - placeholder: {} - } - - respondWithDocsObject(docs, result.error) - - } - } - } - - async function doGit() { - const simpleGit = SA.nodeModules.simpleGit - const options = { - baseDir: process.cwd(), - binary: 'git', - maxConcurrentProcesses: 6, - } - const git = simpleGit(options) - - let message - try { - message = await git.pull('https://github.com/Superalgos/Superalgos', currentBranch) - return { message: message } - } catch (err) { - console.log('[ERROR] Error updating ' + currentBranch) - console.log(err.stack) - return { error: err } - } - } - - } catch (err) { - console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - break - } - - case 'Checkout': { - try { - const currentBranch = unescape(requestPath[3]) - let error - - checkout() - - async function checkout() { - const { lookpath } = SA.nodeModules.lookpath - const gitpath = await lookpath('git'); - if (gitpath === undefined) { - console.log('[ERROR] `git` not installed.') - } else { - await doGit() - - if (error === undefined) { - // Run node setup to prepare instance for branch change - await runNodeSetup() - // Return to UI that Branch is successfully changed - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } else { - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'Switching Branches - Current Branch Not Changed', - anchor: undefined, - placeholder: {} - } - - respondWithDocsObject(docs, error) - } - } - } - - async function doGit() { - const simpleGit = SA.nodeModules.simpleGit - const options = { - baseDir: process.cwd(), - binary: 'git', - maxConcurrentProcesses: 6, - } - const git = simpleGit(options) - try { - await git.checkout(currentBranch) - - // Check to see it main repo has been set as upstream - let remotes = await git.getRemotes(); - let isUpstreamSet - for (let remote in remotes) { - if (remotes[remote].name === 'upstream') { - isUpstreamSet = true + try { + await octokit.repos.createOrUpdateFileContents({ + owner: username, + repo: "Superalgos", + path, + message: title, + content: encodedFile, + sha, + branch: base + }); + } catch (err) { + if (err.stack.indexOf('Error User Commit') >= 0) { + return } else { - isUpstreamSet = false - } - } - // If upstream has not been set. Set it now - if (isUpstreamSet === false) { - await git.addRemote('upstream', 'https://github.com/Superalgos/Superalgos'); - } - // Pull branch from main repo - await git.pull('upstream', currentBranch); - // Reset branch to match main repo - let upstreamLocation = `upstream/${currentBranch}` - await git.reset('hard', [upstreamLocation]) - - } catch (err) { - console.log('[ERROR] Error changing current branch to ' + currentBranch) - console.log(err.stack) - error = err - } - } - - async function runNodeSetup() { - console.log("Running Node setup to adjust for new Branch") - const process = SA.nodeModules.process - const childProcess = SA.nodeModules.childProcess - - let dir = process.cwd() - let command = "node setup noShortcuts"; - let stdout = childProcess.execSync(command, - { - cwd: dir - }).toString(); - - console.log("Node Setup has completed with the following result:", stdout) - } - - } catch (err) { - console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - break - } - - case 'Branch': { - try { - branch() - - async function branch() { - const { lookpath } = SA.nodeModules.lookpath - const gitpath = await lookpath('git'); - if (gitpath === undefined) { - console.log('[ERROR] `git` not installed.') - } else { - let result = await doGit() - - if (result.error === undefined) { - let customResponse = { - result: global.CUSTOM_OK_RESPONSE.result, - message: result - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) - } else { - let docs = { - project: 'Foundations', - category: 'Topic', - type: 'App Error - Could Not Get Current Branch', - anchor: undefined, - placeholder: {} - } - - respondWithDocsObject(docs, error) - } - } - } - - async function doGit() { - const simpleGit = SA.nodeModules.simpleGit - const options = { - baseDir: process.cwd(), - binary: 'git', - maxConcurrentProcesses: 6, - } - const git = simpleGit(options) - try { - return await git.branch() - } catch (err) { - console.log('[ERROR] Error reading current branch.') - console.log(err.stack) - } - } - - } catch (err) { - console.log('[ERROR] httpInterface -> App -> Update -> Method call produced an error.') - console.log('[ERROR] httpInterface -> App -> Update -> err.stack = ' + err.stack) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - break - } - - case 'FixAppSchema': { - /* - We will use this process when we have moved APP SCHEMA files from one project to another, and we need to fix the - actions where this node was referenced, so that it points to the new project where the node has moved to. - */ - let customResponse = { - result: global.CUSTOM_OK_RESPONSE.result, - message: '' - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) - - console.log('Fixing App Schemas...') - - let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) - let PROJECTS_MAP = new Map() - let directoryCount = 0 - let allAppSchemas = [] - let allAppSchemasFilePaths = [] - let allAppSchemasFileProjects = [] - - for (let i = 0; i < projects.length; i++) { - let project = projects[i] - - - - const fs = SA.nodeModules.fs - let folder = 'App-Schema' - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Schemas/' - SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(filePath + folder, onFilesReady) - - function onFilesReady(files) { - try { - let SCHEMA_MAP = new Map() - - console.log('files.length... ' + files.length) - - for (let k = 0; k < files.length; k++) { - let name = files[k] - let nameSplitted = name.split(folder) - let fileName = nameSplitted[1] - for (let i = 0; i < 10; i++) { - fileName = fileName.replace('\\', '/') - } - let fileToRead = filePath + folder + fileName - - console.log('Reading file... ' + fileToRead) - - let fileContent = fs.readFileSync(fileToRead) - let schemaDocument - try { - schemaDocument = JSON.parse(fileContent) - SCHEMA_MAP.set(schemaDocument.type, schemaDocument) - allAppSchemas.push(schemaDocument) - allAppSchemasFilePaths.push(fileToRead) - allAppSchemasFileProjects.push(project) - } catch (err) { - console.log('[ERROR] sendSchema -> Error Parsing JSON File: ' + fileToRead + ' .Error = ' + err.stack) - return - } - } - PROJECTS_MAP.set(project, SCHEMA_MAP) - directoryCount++ - - console.log('directoryCount = ' + directoryCount, 'projects.length = ' + projects.length) - //console.log(Array.from(PROJECTS_MAP.get(project).keys())) - if (directoryCount === projects.length) { - fixSchemas() - } - } catch (err) { - console.log(err.stack) - } - } - } - - function fixSchemas() { - try { - console.log('fixSchemas...' + allAppSchemas.length) - let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) - const fs = SA.nodeModules.fs - let needFixing = 0 - for (let i = 0; i < allAppSchemas.length; i++) { - let schemaDocument = allAppSchemas[i] - let wasUpdated = false - for (let j = 0; j < schemaDocument.menuItems.length; j++) { - let menuItem = schemaDocument.menuItems[j] - if (menuItem.relatedUiObject !== undefined && menuItem.relatedUiObjectProject === undefined) { - needFixing++ - - let hits = 0 - let foundProject - let multiProject = '' - for (let k = 0; k < projects.length; k++) { - let project = projects[k] - - let testDocument = PROJECTS_MAP.get(project).get(menuItem.relatedUiObject) - if (testDocument !== undefined) { - hits++ - foundProject = project - multiProject = multiProject + ' -> ' + project - - let fileProject = allAppSchemasFileProjects[i] - //console.log(fileProject, project) - if (fileProject === project) { - /* If the project of the file is the same as the project found, then we consider this a match*/ - hits = 1 - continue - } - } - } - - if (hits === 0) { - console.log('Problem With No Solution #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject) - console.log('This Node Type was NOT FOUND at any project. ' + menuItem.relatedUiObject) - continue - } - if (hits === 1) { - console.log('Problem With One Solution #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject, ' Found Project:' + foundProject) - - menuItem.relatedUiObjectProject = foundProject - wasUpdated = true - continue - } - console.log('Problem With MULTIPLE Solutions #' + needFixing, ' Type: ' + schemaDocument.type, ' Action: ' + menuItem.action, ' Related UI Object: ' + menuItem.relatedUiObject, ' Found at these Projects:' + multiProject) - } - } - - if (wasUpdated === true) { - let fileContent = JSON.stringify(schemaDocument, undefined, 4) - let filePath = allAppSchemasFilePaths[i] - //console.log('Saving File at ' + filePath) - //console.log(fileContent) - //fs.writeFileSync(filePath, fileContent) - } - } - } catch (err) { - console.log(err.stack) - } - } - - break - } - } - - function respondWithDocsObject(docs, error) { - - if (error.message !== undefined) { - docs.placeholder.errorMessage = { - style: 'Error', - text: error.message - } - } - if (error.stack !== undefined) { - docs.placeholder.errorStack = { - style: 'Javascript', - text: error.stack - } - } - if (error.code !== undefined) { - docs.placeholder.errorCode = { - style: 'Json', - text: error.code - } - } - - docs.placeholder.errorDetails = { - style: 'Json', - text: JSON.stringify(error, undefined, 4) - } - - let customResponse = { - result: global.CUSTOM_FAIL_RESPONSE.result, - docs: docs - } - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(customResponse), httpResponse) - - } - } - break - case 'GOV': - { - /* - This is the Governance endpoint at the Http Interface. All methods - related to the Governance System are implemented here and routed - to the backend Servers that can process them. - */ - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let params = JSON.parse(body) - - switch (params.method) { - case 'getGithubStars': { - - let serverResponse = await PL.servers.GITHUB_SERVER.getGithubStars( - params.repository, - params.username, - params.token - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'getGithubWatchers': { - - let serverResponse = await PL.servers.GITHUB_SERVER.getGithubWatchers( - params.repository, - params.username, - params.token - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'getGithubForks': { - - let serverResponse = await PL.servers.GITHUB_SERVER.getGithubForks( - params.repository, - params.username, - params.token - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - return - } - case 'mergePullRequests': { - - let serverResponse = await PL.servers.GITHUB_SERVER.mergePullRequests( - params.commitMessage, - params.username, - params.token - ) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(serverResponse), httpResponse) - - setInterval( - PL.servers.GITHUB_SERVER.mergePullRequests, - 60000, - params.commitMessage, - params.username, - params.token - ) - - return - } - - case 'UserProfile': { - try { - - let mess = unescape(params.commitMessage) - const username = unescape(params.username) - const token = unescape(params.token) - const currentBranch = unescape(params.currentBranch) - const contributionsBranch = unescape(params.contributionsBranch) - - let error - - await updateUser() - - async function updateUser() { - - await doGithubUser() - if (error !== undefined) { - - let docs = { - project: 'Governance', - category: 'Topic', - type: 'Gov Error - Contribution Not Sent', - anchor: undefined, - placeholder: {} - } - console.log('respond with docs ') - - respondWithDocsObject(docs, error) - return - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - - } - - async function doGithubUser() { - - const { Octokit } = SA.nodeModules.octokit - - const octokit = new Octokit({ - auth: token, - userAgent: 'Superalgos Beta 12' - }) - - const repo = 'Superalgos' - const owner = 'Superalgos' - const head = username + ':' + contributionsBranch - const base = currentBranch - const title = 'Contribution: ' + mess - const path = 'Projects/Governance/Plugins/User-Profiles/' + username + '.json' ; - - const sha = await getSHA(path); - - if (sha === undefined){ - console.log('***** Abort GOV.USERPROFILE *****') - return - } - - let file = await SA.projects.communityPlugins.utilities.plugins.getPluginFileContent( - 'Governance', - 'User-Profiles', - username + '.json' - ) - - let buff = new Buffer.from(file, 'utf-8'); - let encodedFile = buff.toString('base64'); - - try { - await octokit.repos.createOrUpdateFileContents({ - owner: username, - repo: "Superalgos", - path, - message: title, - content: encodedFile, - sha, - branch: base - }); - } catch (err) { - if (err.stack.indexOf('Error User Commit') >= 0) { - return - } else { - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> commitMessage = ' + mess) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> username = ' + username) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> contributionsBranch = ' + contributionsBranch) - error = err - } - } - - try { - await octokit.pulls.create({ - owner, - repo, - title, - head, - base, - }); - } catch (err) { - if (err.stack.indexOf('A pull request already exists') >= 0) { - return - } else { - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> commitMessage = ' + mess) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> username = ' + username) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> contributionsBranch = ' + contributionsBranch) - error = err - } - - } - - - } - - async function getSHA(path) { - let sha = '' - const { graphql } = SA.nodeModules.graphql - - try{ - - const { repository } = await graphql( - '{ ' + - ' repository(name: "SuperAlgos", owner: "' + username + '") {' + - ' object(expression: "develop:' + path +'") {' + - ' ... on Blob {' + - ' oid' + - ' }' + - ' }' + - ' name' + - ' }' + - '}', - { - headers: { - authorization: 'token ' + token - }, - } - ) - - if (repository.name === undefined){ - console.log('***** Token permission needed : User:READ *****') - sha = undefined - error = '***** Token permission needed : User:READ *****' - return sha - } - - if(repository.object === null ){ - console.log("[User Not Found] -> Creating new user") - return sha - } - sha = repository.object.oid - return sha - - } catch (err) { - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> Method call produced an error.') console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> err.stack = ' + err.stack) console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> commitMessage = ' + mess) @@ -1442,531 +1395,597 @@ exports.newHttpInterface = function newHttpInterface() { console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> currentBranch = ' + currentBranch) console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> contributionsBranch = ' + contributionsBranch) - return sha - + error = err } } - } catch (err) { - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> Method call produced an error.') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> commitMessage = ' + mess) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> username = ' + username) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> token starts with = ' + token.substring(0, 10) + '...') - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> token ends with = ' + '...' + token.substring(token.length - 10)) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> currentBranch = ' + currentBranch) - console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> contributionsBranch = ' + contributionsBranch) + try { + await octokit.pulls.create({ + owner, + repo, + title, + head, + base, + }); + } catch (err) { + if (err.stack.indexOf('A pull request already exists') >= 0) { + return + } else { + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> commitMessage = ' + mess) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> username = ' + username) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> contributionsBranch = ' + contributionsBranch) + error = err + } - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + + } - break - } - case 'payContributors': { - console.log('----------------------------------------------------------------------------------------------') - console.log('DISTRIBUTION PROCESS STARTED') - console.log('----------------------------------------------------------------------------------------------') + async function getSHA(path) { + let sha = '' + const {graphql} = SA.nodeModules.graphql - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + try { + const {repository} = await graphql( + '{ ' + + ' repository(name: "SuperAlgos", owner: "' + username + '") {' + + ' object(expression: "develop:' + path + '") {' + + ' ... on Blob {' + + ' oid' + + ' }' + + ' }' + + ' name' + + ' }' + + '}', + { + headers: { + authorization: 'token ' + token + }, + } + ) - await PL.servers.WEB3_SERVER.payContributors( - params.contractAddress, - params.contractAbi, - params.paymentsArray, - params.mnemonic - ) + if (repository.name === undefined) { + console.log('***** Token permission needed : User:READ *****') + sha = undefined + error = '***** Token permission needed : User:READ *****' + return sha + } - return - } - default: { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify({ error: 'Method ' + params.method + ' is invalid.' }), httpResponse) + if (repository.object === null) { + console.log("[User Not Found] -> Creating new user") + return sha + } + sha = repository.object.oid + return sha + + } catch (err) { + + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> commitMessage = ' + mess) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> username = ' + username) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token starts with = ' + token.substring(0, 10) + '...') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> token ends with = ' + '...' + token.substring(token.length - 10)) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> doGithub -> contributionsBranch = ' + contributionsBranch) + return sha + + } + } + + } catch (err) { + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> Method call produced an error.') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> commitMessage = ' + mess) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> username = ' + username) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> token starts with = ' + token.substring(0, 10) + '...') + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> token ends with = ' + '...' + token.substring(token.length - 10)) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> currentBranch = ' + currentBranch) + console.log('[ERROR] httpInterface -> Gov -> contributeUserProfile -> contributionsBranch = ' + contributionsBranch) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } + break } + + case 'payContributors': { + console.log('----------------------------------------------------------------------------------------------') + console.log('DISTRIBUTION PROCESS STARTED') + console.log('----------------------------------------------------------------------------------------------') + + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + + + await PL.servers.WEB3_SERVER.payContributors( + params.contractAddress, + params.contractAbi, + params.paymentsArray, + params.mnemonic + ) + + return + } + default: { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify({error: 'Method ' + params.method + ' is invalid.'}), httpResponse) + } + } + } catch (err) { + console.log('[ERROR] httpInterface -> GOV -> Method call produced an error.') + console.log('[ERROR] httpInterface -> GOV -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> GOV -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + try { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } catch (err) { - console.log('[ERROR] httpInterface -> GOV -> Method call produced an error.') - console.log('[ERROR] httpInterface -> GOV -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> GOV -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - try { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } catch (err) { - // we just try to reponnd to the web app, but maybe the response has already been sent. - } + // we just try to reponnd to the web app, but maybe the response has already been sent. } } } + } break - case 'LegacyPlotter.js': - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/LegacyPlotter.js', httpResponse) - } + case 'LegacyPlotter.js': { + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/LegacyPlotter.js', httpResponse) + } break - case 'PlotterPanel.js': - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/PlotterPanel.js', httpResponse) - } + case 'PlotterPanel.js': { + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/PlotterPanel.js', httpResponse) + } break case 'Images': // This means the Images folder. - { - let path = global.env.PATH_TO_PLATFORM + '/WebServer/Images/' + requestPath[2] + { + let path = global.env.PATH_TO_PLATFORM + '/WebServer/Images/' + requestPath[2] - if (requestPath[3] !== undefined) { - path = path + '/' + requestPath[3] - } - - if (requestPath[4] !== undefined) { - path = path + '/' + requestPath[4] - } - - if (requestPath[5] !== undefined) { - path = path + '/' + requestPath[5] - } - - path = unescape(path) - - SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + if (requestPath[3] !== undefined) { + path = path + '/' + requestPath[3] } + + if (requestPath[4] !== undefined) { + path = path + '/' + requestPath[4] + } + + if (requestPath[5] !== undefined) { + path = path + '/' + requestPath[5] + } + + path = unescape(path) + + SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + } break case 'Icons': // This means the Icons folder under Projects. - { - let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/Icons' + { + let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/Icons' - if (requestPath[3] !== undefined) { - path = path + '/' + requestPath[3] - } - - if (requestPath[4] !== undefined) { - path = path + '/' + requestPath[4] - } - - if (requestPath[5] !== undefined) { - path = path + '/' + requestPath[5] - } - - path = unescape(path) - - SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + if (requestPath[3] !== undefined) { + path = path + '/' + requestPath[3] } + + if (requestPath[4] !== undefined) { + path = path + '/' + requestPath[4] + } + + if (requestPath[5] !== undefined) { + path = path + '/' + requestPath[5] + } + + path = unescape(path) + + SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + } break case 'GIFs': // This means the GIFs folder under Projects. - { - let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/GIFs' + { + let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/GIFs' - if (requestPath[3] !== undefined) { - path = path + '/' + requestPath[3] - } - - if (requestPath[4] !== undefined) { - path = path + '/' + requestPath[4] - } - - if (requestPath[5] !== undefined) { - path = path + '/' + requestPath[5] - } - - path = unescape(path) - SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + if (requestPath[3] !== undefined) { + path = path + '/' + requestPath[3] } + + if (requestPath[4] !== undefined) { + path = path + '/' + requestPath[4] + } + + if (requestPath[5] !== undefined) { + path = path + '/' + requestPath[5] + } + + path = unescape(path) + SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + } break case 'PNGs': // This means the PNGs folder under Projects. - { - let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/PNGs' + { + let path = global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/PNGs' - if (requestPath[3] !== undefined) { - path = path + '/' + requestPath[3] - } - - if (requestPath[4] !== undefined) { - path = path + '/' + requestPath[4] - } - - if (requestPath[5] !== undefined) { - path = path + '/' + requestPath[5] - } - - path = unescape(path) - SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + if (requestPath[3] !== undefined) { + path = path + '/' + requestPath[3] } + + if (requestPath[4] !== undefined) { + path = path + '/' + requestPath[4] + } + + if (requestPath[5] !== undefined) { + path = path + '/' + requestPath[5] + } + + path = unescape(path) + SA.projects.foundations.utilities.httpResponses.respondWithImage(path, httpResponse) + } break case 'WebServer': // This means the WebServer folder. - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/' + requestPath[2], httpResponse) - } + { + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/' + requestPath[2], httpResponse) + } break case 'externalScripts': // This means the WebServer folder. - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/externalScripts/' + requestPath[2], httpResponse) + { + // This allows to have sub-folders in externalScripts + let fullPath = '' + for (let i = 2; i < requestPath.length; i++) { + fullPath += requestPath[i] + if (i !== requestPath.length - 1) { + fullPath += '/' + } } + + /** + * Sometimes libs will call fonts/images etc. by themselves thus we should have a filter for file type to respond with the correct content and headers, but from the externalScripts folder + * This code should be improved when needed with specific file types + */ + + let requestedFileExtension = requestPath[requestPath.length - 1].split('.').pop() + switch (requestedFileExtension) { + case 'otf': + case 'ttf': + case 'eot': + case 'woff': + case 'woff2': + SA.projects.foundations.utilities.httpResponses.respondWithFont(global.env.PATH_TO_PLATFORM + '/WebServer/externalScripts/' + fullPath, httpResponse) + break + default: + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/WebServer/externalScripts/' + fullPath, httpResponse) + } + + } break case 'Plotters': // This means the plotter folder, not to be confused with the Plotters script! - { - let project = requestPath[2] - let dataMine = requestPath[3] - let codeName = requestPath[4] - let moduleName = requestPath[5] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/' + 'Bots-Plotters-Code' + '/' + dataMine + '/plotters/' + codeName + '/' + moduleName - SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) - } + { + let project = requestPath[2] + let dataMine = requestPath[3] + let codeName = requestPath[4] + let moduleName = requestPath[5] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/' + 'Bots-Plotters-Code' + '/' + dataMine + '/plotters/' + codeName + '/' + moduleName + SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) + } break - case 'ChartLayers': - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/UI/' + endpointOrFile + '/' + requestPath[2], httpResponse) - } + case 'ChartLayers': { + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/UI/' + endpointOrFile + '/' + requestPath[2], httpResponse) + } break - case 'Files': - { - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/UI/Data-Files/' + requestPath[2], httpResponse) - } + case 'Files': { + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_PLATFORM + '/UI/Data-Files/' + requestPath[2], httpResponse) + } break - case 'Fonts': - { - SA.projects.foundations.utilities.httpResponses.respondWithFont(global.env.PATH_TO_FONTS + '/' + requestPath[2], httpResponse) - } + case 'Fonts': { + SA.projects.foundations.utilities.httpResponses.respondWithFont(global.env.PATH_TO_FONTS + '/' + requestPath[2], httpResponse) + } break - case 'Schema': - { - sendSchema(global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/Schemas/', requestPath[3]) + case 'Schema': { + sendSchema(global.env.PATH_TO_PROJECTS + '/' + requestPath[2] + '/Schemas/', requestPath[3]) - function sendSchema(filePath, schemaType) { - let fs = SA.nodeModules.fs - try { - let folder = '' - switch (schemaType) { - case 'AppSchema': { - folder = 'App-Schema' - break - } - case 'DocsNodeSchema': { - folder = 'Docs-Nodes' - break - } - case 'DocsConceptSchema': { - folder = 'Docs-Concepts' - break - } - case 'DocsTopicSchema': { - folder = 'Docs-Topics' - break - } - case 'DocsTutorialSchema': { - folder = 'Docs-Tutorials' - break - } - case 'DocsReviewSchema': { - folder = 'Docs-Reviews' - break - } - case 'DocsBookSchema': { - folder = 'Docs-Books' - break - } + function sendSchema(filePath, schemaType) { + let fs = SA.nodeModules.fs + try { + let folder = '' + switch (schemaType) { + case 'AppSchema': { + folder = 'App-Schema' + break } - SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(filePath + folder, onFilesReady) - function onFilesReady(files) { - - let schemaArray = [] - for (let k = 0; k < files.length; k++) { - let name = files[k] - let nameSplitted = name.split(folder) - let fileName = nameSplitted[1] - for (let i = 0; i < 10; i++) { - fileName = fileName.replace('\\', '/') - } - let fileToRead = filePath + folder + fileName - - let fileContent = fs.readFileSync(fileToRead) - let schemaDocument - try { - schemaDocument = JSON.parse(fileContent) - } catch (err) { - console.log('[ERROR] sendSchema -> Error Parsing JSON File: ' + fileToRead + ' .Error = ' + err.stack) - SA.projects.foundations.utilities.httpResponses.respondWithContent("[]", httpResponse) - return - } - schemaArray.push(schemaDocument) - } - let schema = JSON.stringify(schemaArray) - SA.projects.foundations.utilities.httpResponses.respondWithContent(schema, httpResponse) + case 'DocsNodeSchema': { + folder = 'Docs-Nodes' + break } - } catch (err) { - if (err.message.indexOf('no such file or directory') < 0) { - console.log('Could not send Schema:', filePath, schemaType) - console.log(err.stack) + case 'DocsConceptSchema': { + folder = 'Docs-Concepts' + break + } + case 'DocsTopicSchema': { + folder = 'Docs-Topics' + break + } + case 'DocsTutorialSchema': { + folder = 'Docs-Tutorials' + break + } + case 'DocsReviewSchema': { + folder = 'Docs-Reviews' + break + } + case 'DocsBookSchema': { + folder = 'Docs-Books' + break } - SA.projects.foundations.utilities.httpResponses.respondWithContent("[]", httpResponse) } + SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(filePath + folder, onFilesReady) + + function onFilesReady(files) { + + let schemaArray = [] + for (let k = 0; k < files.length; k++) { + let name = files[k] + let nameSplitted = name.split(folder) + let fileName = nameSplitted[1] + for (let i = 0; i < 10; i++) { + fileName = fileName.replace('\\', '/') + } + let fileToRead = filePath + folder + fileName + + let fileContent = fs.readFileSync(fileToRead) + let schemaDocument + try { + schemaDocument = JSON.parse(fileContent) + } catch (err) { + console.log('[ERROR] sendSchema -> Error Parsing JSON File: ' + fileToRead + ' .Error = ' + err.stack) + SA.projects.foundations.utilities.httpResponses.respondWithContent("[]", httpResponse) + return + } + schemaArray.push(schemaDocument) + } + let schema = JSON.stringify(schemaArray) + SA.projects.foundations.utilities.httpResponses.respondWithContent(schema, httpResponse) + } + } catch (err) { + if (err.message.indexOf('no such file or directory') < 0) { + console.log('Could not send Schema:', filePath, schemaType) + console.log(err.stack) + } + SA.projects.foundations.utilities.httpResponses.respondWithContent("[]", httpResponse) } } + } break - case 'DirContent': - { - let folderPath = unescape(requestPath[2]) - if (requestPath[3] !== undefined) { - folderPath = folderPath + '/' + requestPath[3] - } + case 'DirContent': { + let folderPath = unescape(requestPath[2]) + if (requestPath[3] !== undefined) { + folderPath = folderPath + '/' + requestPath[3] + } - if (requestPath[4] !== undefined) { - folderPath = folderPath + '/' + requestPath[4] - } + if (requestPath[4] !== undefined) { + folderPath = folderPath + '/' + requestPath[4] + } - if (requestPath[5] !== undefined) { - folderPath = folderPath + '/' + requestPath[5] - } - let folder - if (requestPath[2] === 'Root') { - folder = folderPath.replace('Root', '../Superalgos/') - } else { - folder = global.env.PATH_TO_PROJECTS + '/' + folderPath - } + if (requestPath[5] !== undefined) { + folderPath = folderPath + '/' + requestPath[5] + } + let folder + if (requestPath[2] === 'Root') { + folder = folderPath.replace('Root', '../Superalgos/') + } else { + folder = global.env.PATH_TO_PROJECTS + '/' + folderPath + } + + SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(folder, onFilesReady) + + function onFilesReady(files) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(files), httpResponse) + } + } + break + case 'IconNames': { + let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) + let icons = [] + let totalProjects = projects.length + let projectCounter = 0 + + for (let i = 0; i < projects.length; i++) { + let project = projects[i] + + const folder = global.env.PATH_TO_PROJECTS + '/' + project + '/Icons/' SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(folder, onFilesReady) function onFilesReady(files) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(files), httpResponse) - } - } - break - case 'IconNames': - { - let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) - let icons = [] - let totalProjects = projects.length - let projectCounter = 0 - - for (let i = 0; i < projects.length; i++) { - let project = projects[i] - - const folder = global.env.PATH_TO_PROJECTS + '/' + project + '/Icons/' - - SA.projects.foundations.utilities.filesAndDirectories.getAllFilesInDirectoryAndSubdirectories(folder, onFilesReady) - - function onFilesReady(files) { - for (let j = 0; j < files.length; j++) { - let file = files[j] - for (let i = 0; i < 10; i++) { - file = file.replace('/', '\\') - } - icons.push([project, file]) + for (let j = 0; j < files.length; j++) { + let file = files[j] + for (let i = 0; i < 10; i++) { + file = file.replace('/', '\\') } + icons.push([project, file]) + } - projectCounter++ - if (projectCounter === totalProjects) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(icons), httpResponse) - } + projectCounter++ + if (projectCounter === totalProjects) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(icons), httpResponse) } } } + } break - case 'PluginFileNames': - { - processRequest() + case 'PluginFileNames': { + processRequest() - async function processRequest(body) { - try { - let project = unescape(requestPath[2]) - let folder = unescape(requestPath[3]) + async function processRequest(body) { + try { + let project = unescape(requestPath[2]) + let folder = unescape(requestPath[3]) - let response = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames( - project, - folder - ).catch(err => { - console.log('[ERROR] httpInterface -> PluginFileNames -> err.stack = ' + err.stack) - }) - - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(response), httpResponse) - - } catch (err) { - console.log('[ERROR] httpInterface -> PluginFileNames -> Method call produced an error.') + let response = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames( + project, + folder + ).catch(err => { console.log('[ERROR] httpInterface -> PluginFileNames -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> PluginFileNames -> Params Received = ' + body) + }) - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(response), httpResponse) + + } catch (err) { + console.log('[ERROR] httpInterface -> PluginFileNames -> Method call produced an error.') + console.log('[ERROR] httpInterface -> PluginFileNames -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> PluginFileNames -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } } + } break - case 'LoadPlugin': - { - processRequest() + case 'LoadPlugin': { + processRequest() - async function processRequest(body) { - try { - let project = unescape(requestPath[2]) - let folder = unescape(requestPath[3]) - let fileName = unescape(requestPath[4]) + async function processRequest(body) { + try { + let project = unescape(requestPath[2]) + let folder = unescape(requestPath[3]) + let fileName = unescape(requestPath[4]) - /*Beta 12 Refactoring Code: Remove this before releasing beta 12.*/ - if (fileName === 'Superalgos-CL.json') { - fileName = 'Superalgos-PL.json' - } + /*v.1.0 Refactoring Code: Remove this before releasing v.1.0.*/ + if (fileName === 'Superalgos-CL.json') { + fileName = 'Superalgos-PL.json' + } - await SA.projects.communityPlugins.utilities.plugins.getPluginFileContent( - project, - folder, - fileName - ) - .then(response => { + await SA.projects.communityPlugins.utilities.plugins.getPluginFileContent( + project, + folder, + fileName + ) + .then(response => { SA.projects.foundations.utilities.httpResponses.respondWithContent(response, httpResponse) } - ) - .catch(err => { - let error = { - result: 'Fail Because', - message: err - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - return - }) - - } catch (err) { - console.log('[ERROR] httpInterface -> LoadPlugin -> Method call produced an error.') - console.log('[ERROR] httpInterface -> LoadPlugin -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> LoadPlugin -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - } - break - case 'SavePlugin': - { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - - async function processRequest(body) { - try { - if (body === undefined) { return } - - let plugin = JSON.parse(body) - let project = requestPath[2] - let folder = requestPath[3] - let fileName = requestPath[4] - let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Plugins/' + folder - let fileContent = JSON.stringify(plugin, undefined, 4) - const fs = SA.nodeModules.fs - fs.writeFileSync(filePath + '/' + fileName + '.json', fileContent) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) - } catch (err) { - console.log('[ERROR] httpInterface -> SavePlugin -> Method call produced an error.') - console.log('[ERROR] httpInterface -> SavePlugin -> err.stack = ' + err.stack) - console.log('[ERROR] httpInterface -> SavePlugin -> Params Received = ' + body) - - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - } - break - case 'Workspace.js': - { - let fs = SA.nodeModules.fs - - try { - let filePath = global.env.PATH_TO_DEFAULT_WORKSPACE + '/Getting-Started-Tutorials.json' - fs.readFile(filePath, onFileRead) - } catch (e) { - console.log('[ERROR] Error reading the Workspace.', e) - } - - function onFileRead(err, workspace) { - if (err) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(undefined, httpResponse) - } else { - let responseContent = 'function getWorkspace(){ return ' + workspace + '}' - SA.projects.foundations.utilities.httpResponses.respondWithContent(responseContent, httpResponse) - } - } - } - break - case 'ListWorkspaces': - { - let allWorkspaces = [] - let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) - let projectsCount = 0 - - for (let i = 0; i < projects.length; i++) { - let project = projects[i] - readPluginWorkspaces() - function readPluginWorkspaces() { - let dirPath = global.env.PATH_TO_PROJECTS + '/' + project + '/Plugins/Workspaces' - try { - let fs = SA.nodeModules.fs - fs.readdir(dirPath, onDirRead) - - function onDirRead(err, fileList) { - let updatedFileList = [] - - if (err) { - /* - If we have a problem reading this folder we will assume that it is - because this project does not need this folder and that's it. - */ - //console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) - } else { - for (let i = 0; i < fileList.length; i++) { - let name = 'Plugin \u2192 ' + fileList[i] - updatedFileList.push([project, name]) - } - } - allWorkspaces = allWorkspaces.concat(updatedFileList) - projectsCount++ - if (projectsCount === projects.length) { - readMyWorkspaces() - } + ) + .catch(err => { + let error = { + result: 'Fail Because', + message: err } - } catch (err) { - console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) - console.log('[ERROR] err.stack = ' + err.stack) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) return - } - } - } + }) - function readMyWorkspaces() { - let dirPath = global.env.PATH_TO_MY_WORKSPACES + } catch (err) { + console.log('[ERROR] httpInterface -> LoadPlugin -> Method call produced an error.') + console.log('[ERROR] httpInterface -> LoadPlugin -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> LoadPlugin -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + } + break + case 'SavePlugin': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + try { + if (body === undefined) { + return + } + + let plugin = JSON.parse(body) + let project = requestPath[2] + let folder = requestPath[3] + let fileName = requestPath[4] + let filePath = global.env.PATH_TO_PROJECTS + '/' + project + '/Plugins/' + folder + let fileContent = JSON.stringify(plugin, undefined, 4) + const fs = SA.nodeModules.fs + fs.writeFileSync(filePath + '/' + fileName + '.json', fileContent) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } catch (err) { + console.log('[ERROR] httpInterface -> SavePlugin -> Method call produced an error.') + console.log('[ERROR] httpInterface -> SavePlugin -> err.stack = ' + err.stack) + console.log('[ERROR] httpInterface -> SavePlugin -> Params Received = ' + body) + + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } + } + } + break + case 'Workspace.js': { + let fs = SA.nodeModules.fs + + try { + let filePath = global.env.PATH_TO_DEFAULT_WORKSPACE + '/Getting-Started-Tutorials.json' + fs.readFile(filePath, onFileRead) + } catch (e) { + console.log('[ERROR] Error reading the Workspace.', e) + } + + function onFileRead(err, workspace) { + if (err) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(undefined, httpResponse) + } else { + let responseContent = 'function getWorkspace(){ return ' + workspace + '}' + SA.projects.foundations.utilities.httpResponses.respondWithContent(responseContent, httpResponse) + } + } + } + break + case 'ListWorkspaces': { + let allWorkspaces = [] + let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) + let projectsCount = 0 + + for (let i = 0; i < projects.length; i++) { + let project = projects[i] + readPluginWorkspaces() + + function readPluginWorkspaces() { + let dirPath = global.env.PATH_TO_PROJECTS + '/' + project + '/Plugins/Workspaces' try { let fs = SA.nodeModules.fs fs.readdir(dirPath, onDirRead) function onDirRead(err, fileList) { + let updatedFileList = [] + if (err) { - // This happens the first time you run the software. - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allWorkspaces), httpResponse) - return + /* + If we have a problem reading this folder we will assume that it is + because this project does not need this folder and that's it. + */ + //console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) } else { - let updatedFileList = [] for (let i = 0; i < fileList.length; i++) { - let name = fileList[i] - updatedFileList.push(['', name]) + let name = 'Plugin \u2192 ' + fileList[i] + updatedFileList.push([project, name]) } - allWorkspaces = allWorkspaces.concat(updatedFileList) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allWorkspaces), httpResponse) - return + } + allWorkspaces = allWorkspaces.concat(updatedFileList) + projectsCount++ + if (projectsCount === projects.length) { + readMyWorkspaces() } } } catch (err) { @@ -1977,172 +1996,197 @@ exports.newHttpInterface = function newHttpInterface() { } } } - break - case 'LoadMyWorkspace': - { - let fileName = unescape(requestPath[2]) - let filePath = global.env.PATH_TO_MY_WORKSPACES + '/' + fileName + '.json' - SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) - } - break - case 'SaveWorkspace': - { - SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) - async function processRequest(body) { + function readMyWorkspaces() { + let dirPath = global.env.PATH_TO_MY_WORKSPACES + try { + let fs = SA.nodeModules.fs + fs.readdir(dirPath, onDirRead) - if (body === undefined) { return } - - let fileContent = body - let fileName = unescape(requestPath[2]) - let filePath = global.env.PATH_TO_MY_WORKSPACES + '/' + fileName + '.json' - - try { - let fs = SA.nodeModules.fs - let dir = global.env.PATH_TO_MY_WORKSPACES; - - /* Create Dir if it does not exist */ - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, {recursive: true}); - } - - fs.writeFile(filePath, fileContent, onFileWritten) - - function onFileWritten(err) { - if (err) { - console.log('[ERROR] SaveWorkspace -> onFileWritten -> Error writing the Workspace file. fileName = ' + fileName) - console.log('[ERROR] SaveWorkspace -> onFileWritten -> err.stack = ' + err.stack) - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } else { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + function onDirRead(err, fileList) { + if (err) { + // This happens the first time you run the software. + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allWorkspaces), httpResponse) + return + } else { + let updatedFileList = [] + for (let i = 0; i < fileList.length; i++) { + let name = fileList[i] + updatedFileList.push(['', name]) } - } - - } catch (err) { - console.log('[ERROR] SaveWorkspace -> Error writing the Workspace file. fileName = ' + fileName) - console.log('[ERROR] SaveWorkspace -> err.stack = ' + err.stack) - let error = { - result: 'Fail Because', - message: err.message, - stack: err.stack - } - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) - } - } - } - break - case 'ProjectsSchema': - { - let path = global.env.PATH_TO_PROJECTS + '/' + 'ProjectsSchema.json' - SA.projects.foundations.utilities.httpResponses.respondWithFile(path, httpResponse) - } - break - case 'ListSpaceFiles': - { - let fs = SA.nodeModules.fs - let allFiles = [] - let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) - let dirCount = 0 - let totalDirs = 0 - - for (let i = 0; i < projects.length; i++) { - let project = projects[i] - - let dirPath = project + '/UI/Spaces' - let spaces = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS + '/' + dirPath) - - for (let j = 0; j < spaces.length; j++) { - let space = spaces[j] - readDirectory(dirPath + '/' + space) - } - - function readDirectory(path) { - try { - - totalDirs++ - fs.readdir(global.env.PATH_TO_PROJECTS + '/' + path, onDirRead) - - let otherDirs = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS + '/' + path) - for (let m = 0; m < otherDirs.length; m++) { - let otherDir = otherDirs[m] - readDirectory(path + '/' + otherDir) - } - - function onDirRead(err, fileList) { - if (err) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) - } else { - let updatedFileList = [] - for (let k = 0; k < fileList.length; k++) { - let name = fileList[k] - if (name.indexOf('.js') < 0) { continue } - updatedFileList.push(path + '/' + name) - } - allFiles = allFiles.concat(updatedFileList) - dirCount++ - if (dirCount === totalDirs) { - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allFiles), httpResponse) - } - } - } - } catch (err) { - console.log('[ERROR] Error reading a directory content. filePath = ' + path) - console.log('[ERROR] err.stack = ' + err.stack) - SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + allWorkspaces = allWorkspaces.concat(updatedFileList) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allWorkspaces), httpResponse) return } } + } catch (err) { + console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) + console.log('[ERROR] err.stack = ' + err.stack) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + return } } + } break - case 'ListFunctionLibraries': - { - SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Function-Libraries', 'UI') - } + case 'LoadMyWorkspace': { + let fileName = unescape(requestPath[2]) + let filePath = global.env.PATH_TO_MY_WORKSPACES + '/' + fileName + '.json' + SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) + } break - case 'ListUtilitiesFiles': - { - SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Utilities', 'UI') - } - break - case 'ListGlobalFiles': - { - SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Globals', 'UI') - } - break - case 'Projects': - { - let path = '' - for (let i = 2; i < 10; i++) { - if (requestPath[i] !== undefined) { - let parameter = unescape(requestPath[i]) - path = path + '/' + parameter + case 'SaveWorkspace': { + SA.projects.foundations.utilities.httpRequests.getRequestBody(httpRequest, httpResponse, processRequest) + + async function processRequest(body) { + + if (body === undefined) { + return + } + + let fileContent = body + let fileName = unescape(requestPath[2]) + let filePath = global.env.PATH_TO_MY_WORKSPACES + '/' + fileName + '.json' + + try { + let fs = SA.nodeModules.fs + let dir = global.env.PATH_TO_MY_WORKSPACES; + + /* Create Dir if it does not exist */ + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, {recursive: true}); } + fs.writeFile(filePath, fileContent, onFileWritten) + + function onFileWritten(err) { + if (err) { + console.log('[ERROR] SaveWorkspace -> onFileWritten -> Error writing the Workspace file. fileName = ' + fileName) + console.log('[ERROR] SaveWorkspace -> onFileWritten -> err.stack = ' + err.stack) + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) + } else { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), httpResponse) + } + } + + } catch (err) { + console.log('[ERROR] SaveWorkspace -> Error writing the Workspace file. fileName = ' + fileName) + console.log('[ERROR] SaveWorkspace -> err.stack = ' + err.stack) + let error = { + result: 'Fail Because', + message: err.message, + stack: err.stack + } + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse) } - let filePath = global.env.PATH_TO_PROJECTS + path - SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) } + } break - case 'Storage': - { - let pathToFile = httpRequest.url.substring(9) - /* Unsavping # */ - for (let i = 0; i < 10; i++) { - pathToFile = pathToFile.replace('_HASHTAG_', '#') + case 'ProjectsSchema': { + let path = global.env.PATH_TO_PROJECTS + '/' + 'ProjectsSchema.json' + SA.projects.foundations.utilities.httpResponses.respondWithFile(path, httpResponse) + } + break + case 'ListSpaceFiles': { + let fs = SA.nodeModules.fs + let allFiles = [] + let projects = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS) + let dirCount = 0 + let totalDirs = 0 + + for (let i = 0; i < projects.length; i++) { + let project = projects[i] + + let dirPath = project + '/UI/Spaces' + let spaces = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS + '/' + dirPath) + + for (let j = 0; j < spaces.length; j++) { + let space = spaces[j] + readDirectory(dirPath + '/' + space) + } + + function readDirectory(path) { + try { + + totalDirs++ + fs.readdir(global.env.PATH_TO_PROJECTS + '/' + path, onDirRead) + + let otherDirs = SA.projects.foundations.utilities.filesAndDirectories.getDirectories(global.env.PATH_TO_PROJECTS + '/' + path) + for (let m = 0; m < otherDirs.length; m++) { + let otherDir = otherDirs[m] + readDirectory(path + '/' + otherDir) + } + + function onDirRead(err, fileList) { + if (err) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + } else { + let updatedFileList = [] + for (let k = 0; k < fileList.length; k++) { + let name = fileList[k] + if (name.indexOf('.js') < 0) { + continue + } + updatedFileList.push(path + '/' + name) + } + allFiles = allFiles.concat(updatedFileList) + dirCount++ + if (dirCount === totalDirs) { + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(allFiles), httpResponse) + } + } + } + } catch (err) { + console.log('[ERROR] Error reading a directory content. filePath = ' + path) + console.log('[ERROR] err.stack = ' + err.stack) + SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), httpResponse) + return + } } - SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_DATA_STORAGE + '/' + pathToFile, httpResponse) } + } break - default: - { - SA.projects.foundations.utilities.httpResponses.respondWithWebFile(httpResponse, endpointOrFile, global.env.PATH_TO_PLATFORM) + case 'ListFunctionLibraries': { + SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Function-Libraries', 'UI') + } + break + case 'ListUtilitiesFiles': { + SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Utilities', 'UI') + } + break + case 'ListGlobalFiles': { + SA.projects.foundations.utilities.httpResponses.respondWithProjectFolderFileList(httpResponse, 'Globals', 'UI') + } + break + case 'Projects': { + let path = '' + for (let i = 2; i < 10; i++) { + if (requestPath[i] !== undefined) { + let parameter = unescape(requestPath[i]) + path = path + '/' + parameter + } + } + let filePath = global.env.PATH_TO_PROJECTS + path + SA.projects.foundations.utilities.httpResponses.respondWithFile(filePath, httpResponse) + } + break + case 'Storage': { + let pathToFile = httpRequest.url.substring(9) + /* Unsavping # */ + for (let i = 0; i < 10; i++) { + pathToFile = pathToFile.replace('_HASHTAG_', '#') + } + SA.projects.foundations.utilities.httpResponses.respondWithFile(global.env.PATH_TO_DATA_STORAGE + '/' + pathToFile, httpResponse) + } + break + default: { + SA.projects.foundations.utilities.httpResponses.respondWithWebFile(httpResponse, endpointOrFile, global.env.PATH_TO_PLATFORM) + } } } catch (err) { if (err.stack !== undefined) { diff --git a/Platform/Client/web3Server.js b/Platform/Client/web3Server.js index e3f7d5888..c156b7e14 100644 --- a/Platform/Client/web3Server.js +++ b/Platform/Client/web3Server.js @@ -5,6 +5,7 @@ exports.newWeb3Server = function newWeb3Server() { let thisObject = { getNetworkClientStatus: getNetworkClientStatus, createWalletAccount: createWalletAccount, + getUserWalletBalance: getUserWalletBalance, getWalletBalances: getWalletBalances, signData: signData, hashData: hashData, @@ -82,6 +83,31 @@ exports.newWeb3Server = function newWeb3Server() { } } + async function getUserWalletBalance(walletAddress, contractAddress) { + + const bscUri = 'https://bsc-dataseed.binance.org/' + const web3 = new Web3(bscUri) + + let balance + + let ABI = [{ "constant": true, "inputs": [], "name": "name", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "approve", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transferFrom", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "unpause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "account", "type": "address" }, { "name": "amount", "type": "uint256" }], "name": "mint", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_value", "type": "uint256" }], "name": "burn", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "paused", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_subtractedValue", "type": "uint256" }], "name": "decreaseApproval", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_owner", "type": "address" }], "name": "balanceOf", "outputs": [{ "name": "balance", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "listAddress", "type": "address" }, { "name": "isBlackListed", "type": "bool" }], "name": "blackListAddress", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [], "name": "pause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transfer", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_addedValue", "type": "uint256" }], "name": "increaseApproval", "outputs": [{ "name": "success", "type": "bool" }], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" }], "name": "allowance", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "name": "_name", "type": "string" }, { "name": "_symbol", "type": "string" }, { "name": "_decimals", "type": "uint256" }, { "name": "_supply", "type": "uint256" }, { "name": "tokenOwner", "type": "address" }], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Mint", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "burner", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Burn", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Pause", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Unpause", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" }], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "blackListed", "type": "address" }, { "indexed": false, "name": "value", "type": "bool" }], "name": "Blacklist", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Transfer", "type": "event" }] + + const contractInst = new web3.eth.Contract(ABI, contractAddress) + + async function getBalance() { + balance = await contractInst.methods.balanceOf(walletAddress).call().then(result => web3.utils.fromWei(result, 'ether')) + return balance + } + + await getBalance() + + return { + walletAddress: walletAddress, + balance: balance, + result: 'Ok' + } + } + async function getWalletBalances(host, port, interface, walletDefinition) { let key = 'host (' + host + ') at port (' + port + ') via interface (' + interface + ')' @@ -303,7 +329,7 @@ exports.newWeb3Server = function newWeb3Server() { async function sendTokens(number, userProfile, fromAddress, toAddress, tokenAmount) { try { - + tokenAmount = Math.trunc(tokenAmount / 1000000000000000000) console.log('') @@ -361,12 +387,12 @@ exports.newWeb3Server = function newWeb3Server() { console.log('Transaction:', rawTransaction) let result - + result = await web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex')) .catch(err => { console.log('[ERROR] sendSignedTransaction -> err =' + JSON.stringify(err)) }) - + console.log('Result:', result) return result } catch (err) { diff --git a/Platform/PlatformApp.js b/Platform/PlatformApp.js index d156752dd..61d4013e4 100644 --- a/Platform/PlatformApp.js +++ b/Platform/PlatformApp.js @@ -142,7 +142,7 @@ exports.newPlatformApp = function newPlatformApp() { console.log('Http Interface .............................................. Listening at port ' + global.env.PLATFORM_HTTP_INTERFACE_PORT) console.log('') - console.log("You are running Superalgos Beta 12") + console.log("You are running Superalgos Platform v.1.0") console.log('') console.log("What's new? These are the main new features in this version:") console.log('') @@ -154,7 +154,7 @@ exports.newPlatformApp = function newPlatformApp() { console.log('Superalgos P2P Network ...................................... Will allow algo-traders to share trading signals with Superalgos users consuming these signals via a mobile app.') console.log('Real-time Trading Signals ................................... Will allow users to emit trading signals and be rewarded with SA Tokens.') console.log('Superalgos Mobile ........................................... Will allow users to consume trading signals for free and autonomously execute trades from their mobile phones.') - console.log('Ethereum Integration ........................................ Will allow mining data from an Ethereum network node, and bring it into the Superalgos workflow. [Looking for an Ethereum dev that would like to continue this line of development.]') + console.log('Portfolio Manager ........................................... Will allow a Portfolio Manager bot to supervize Trading Bots deciding where and when to increase or decrease their position sizes.]') console.log('') diff --git a/Platform/UI/Canvas.js b/Platform/UI/Canvas.js index 7a2d09b74..459e3e675 100644 --- a/Platform/UI/Canvas.js +++ b/Platform/UI/Canvas.js @@ -56,6 +56,7 @@ function newCanvas() { UI.projects.foundations.spaces.sideSpace.finalize() UI.projects.foundations.spaces.chartingSpace.finalize() UI.projects.foundations.spaces.floatingSpace.finalize() + UI.projects.foundations.spaces.codeEditorSpace.finalize() thisObject.shorcutNumbers = undefined if (browserCanvas.removeEventListener) { @@ -385,6 +386,11 @@ function newCanvas() { if (UI.projects.education !== undefined && UI.projects.education.spaces.docsSpace.isVisible === true) { return } + /* When the Code Editor is Visible, we do not process key down events of the Designer Space. */ + if (UI.projects.foundations.spaces.codeEditorSpace.isVisible === true) { + return + } + thisObject.mouse.event = event thisObject.mouse.action = 'key down' diff --git a/Platform/UI/Globals.js b/Platform/UI/Globals.js index 1f34fc0a0..84b558b77 100644 --- a/Platform/UI/Globals.js +++ b/Platform/UI/Globals.js @@ -261,6 +261,11 @@ let CURRENT_PANORAMA_POSITION = 0 let CAN_SPACES_DRAW = false // This global variable regulates when spaces can or can not draw their contents. +const codeEditorType = { + CODE: "code", + CONFIG: "config" +} + function toRadians(angle) { return angle * (Math.PI / 180); } diff --git a/Platform/WebServer/Images/sa-v10-logo-horiz-dark.png b/Platform/WebServer/Images/sa-v10-logo-horiz-dark.png new file mode 100644 index 000000000..2eab06ccc Binary files /dev/null and b/Platform/WebServer/Images/sa-v10-logo-horiz-dark.png differ diff --git a/Platform/WebServer/css/code-editor.css b/Platform/WebServer/css/code-editor.css new file mode 100644 index 000000000..c030c8170 --- /dev/null +++ b/Platform/WebServer/css/code-editor.css @@ -0,0 +1,15 @@ +.code-editor-page { + font: 400 17px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + color: #365558; + line-height: 150%; + margin: 20 25 20 30px; +} + +.editor{ + height: 70vh; + overflow: hidden; +} + +#code-path { + margin-bottom: 15px; +} \ No newline at end of file diff --git a/Platform/WebServer/externalScripts/min-maps/vs/base/worker/workerMain.js.map b/Platform/WebServer/externalScripts/min-maps/vs/base/worker/workerMain.js.map new file mode 100644 index 000000000..5504b7895 --- /dev/null +++ b/Platform/WebServer/externalScripts/min-maps/vs/base/worker/workerMain.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["out-editor/vs/base/worker/fake","out-editor/vs/base/worker/vs/loader.js","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/diff/diffChange.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/errors.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/functional.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/iterator.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/keyCodes.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/lifecycle.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/linkedList.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/platform.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/process.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/path.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/stopwatch.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/event.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/cancellation.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/strings.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/hash.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/diff/diff.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/types.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/uint.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/uri.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/common/worker/simpleWorker.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/core/characterClassifier.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/core/position.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/core/range.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/core/selection.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/core/token.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/diff/diffComputer.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/model/wordHelper.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/modes/linkComputer.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/modes/supports/inplaceReplaceSupport.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/standalone/standaloneEnums.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/standalone/standaloneBase.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/viewModel/prefixSumComputer.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/model/mirrorTextModel.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/editor/common/services/editorSimpleWorker.ts","out-editor/vs/base/worker/file:/Users/alex/src/vscode2/out-editor-src/vs/base/worker/workerMain.ts"],"sourcesContent":["}).call(this);","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n/*---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n * Please make sure to make edits in the .ts file at https://github.com/microsoft/vscode-loader/\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *---------------------------------------------------------------------------------------------\n *--------------------------------------------------------------------------------------------*/\nvar _amdLoaderGlobal = this;\nvar _commonjsGlobal = typeof global === 'object' ? global : {};\nvar AMDLoader;\n(function (AMDLoader) {\n AMDLoader.global = _amdLoaderGlobal;\n var Environment = /** @class */ (function () {\n function Environment() {\n this._detected = false;\n this._isWindows = false;\n this._isNode = false;\n this._isElectronRenderer = false;\n this._isWebWorker = false;\n this._isElectronNodeIntegrationWebWorker = false;\n }\n Object.defineProperty(Environment.prototype, \"isWindows\", {\n get: function () {\n this._detect();\n return this._isWindows;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Environment.prototype, \"isNode\", {\n get: function () {\n this._detect();\n return this._isNode;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Environment.prototype, \"isElectronRenderer\", {\n get: function () {\n this._detect();\n return this._isElectronRenderer;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Environment.prototype, \"isWebWorker\", {\n get: function () {\n this._detect();\n return this._isWebWorker;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(Environment.prototype, \"isElectronNodeIntegrationWebWorker\", {\n get: function () {\n this._detect();\n return this._isElectronNodeIntegrationWebWorker;\n },\n enumerable: false,\n configurable: true\n });\n Environment.prototype._detect = function () {\n if (this._detected) {\n return;\n }\n this._detected = true;\n this._isWindows = Environment._isWindows();\n this._isNode = (typeof module !== 'undefined' && !!module.exports);\n this._isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer');\n this._isWebWorker = (typeof AMDLoader.global.importScripts === 'function');\n this._isElectronNodeIntegrationWebWorker = this._isWebWorker && (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'worker');\n };\n Environment._isWindows = function () {\n if (typeof navigator !== 'undefined') {\n if (navigator.userAgent && navigator.userAgent.indexOf('Windows') >= 0) {\n return true;\n }\n }\n if (typeof process !== 'undefined') {\n return (process.platform === 'win32');\n }\n return false;\n };\n return Environment;\n }());\n AMDLoader.Environment = Environment;\n})(AMDLoader || (AMDLoader = {}));\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar AMDLoader;\n(function (AMDLoader) {\n var LoaderEvent = /** @class */ (function () {\n function LoaderEvent(type, detail, timestamp) {\n this.type = type;\n this.detail = detail;\n this.timestamp = timestamp;\n }\n return LoaderEvent;\n }());\n AMDLoader.LoaderEvent = LoaderEvent;\n var LoaderEventRecorder = /** @class */ (function () {\n function LoaderEventRecorder(loaderAvailableTimestamp) {\n this._events = [new LoaderEvent(1 /* LoaderAvailable */, '', loaderAvailableTimestamp)];\n }\n LoaderEventRecorder.prototype.record = function (type, detail) {\n this._events.push(new LoaderEvent(type, detail, AMDLoader.Utilities.getHighPerformanceTimestamp()));\n };\n LoaderEventRecorder.prototype.getEvents = function () {\n return this._events;\n };\n return LoaderEventRecorder;\n }());\n AMDLoader.LoaderEventRecorder = LoaderEventRecorder;\n var NullLoaderEventRecorder = /** @class */ (function () {\n function NullLoaderEventRecorder() {\n }\n NullLoaderEventRecorder.prototype.record = function (type, detail) {\n // Nothing to do\n };\n NullLoaderEventRecorder.prototype.getEvents = function () {\n return [];\n };\n NullLoaderEventRecorder.INSTANCE = new NullLoaderEventRecorder();\n return NullLoaderEventRecorder;\n }());\n AMDLoader.NullLoaderEventRecorder = NullLoaderEventRecorder;\n})(AMDLoader || (AMDLoader = {}));\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar AMDLoader;\n(function (AMDLoader) {\n var Utilities = /** @class */ (function () {\n function Utilities() {\n }\n /**\n * This method does not take care of / vs \\\n */\n Utilities.fileUriToFilePath = function (isWindows, uri) {\n uri = decodeURI(uri).replace(/%23/g, '#');\n if (isWindows) {\n if (/^file:\\/\\/\\//.test(uri)) {\n // This is a URI without a hostname => return only the path segment\n return uri.substr(8);\n }\n if (/^file:\\/\\//.test(uri)) {\n return uri.substr(5);\n }\n }\n else {\n if (/^file:\\/\\//.test(uri)) {\n return uri.substr(7);\n }\n }\n // Not sure...\n return uri;\n };\n Utilities.startsWith = function (haystack, needle) {\n return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle;\n };\n Utilities.endsWith = function (haystack, needle) {\n return haystack.length >= needle.length && haystack.substr(haystack.length - needle.length) === needle;\n };\n // only check for \"?\" before \"#\" to ensure that there is a real Query-String\n Utilities.containsQueryString = function (url) {\n return /^[^\\#]*\\?/gi.test(url);\n };\n /**\n * Does `url` start with http:// or https:// or file:// or / ?\n */\n Utilities.isAbsolutePath = function (url) {\n return /^((http:\\/\\/)|(https:\\/\\/)|(file:\\/\\/)|(\\/))/.test(url);\n };\n Utilities.forEachProperty = function (obj, callback) {\n if (obj) {\n var key = void 0;\n for (key in obj) {\n if (obj.hasOwnProperty(key)) {\n callback(key, obj[key]);\n }\n }\n }\n };\n Utilities.isEmpty = function (obj) {\n var isEmpty = true;\n Utilities.forEachProperty(obj, function () {\n isEmpty = false;\n });\n return isEmpty;\n };\n Utilities.recursiveClone = function (obj) {\n if (!obj || typeof obj !== 'object' || obj instanceof RegExp) {\n return obj;\n }\n if (!Array.isArray(obj) && Object.getPrototypeOf(obj) !== Object.prototype) {\n // only clone \"simple\" objects\n return obj;\n }\n var result = Array.isArray(obj) ? [] : {};\n Utilities.forEachProperty(obj, function (key, value) {\n if (value && typeof value === 'object') {\n result[key] = Utilities.recursiveClone(value);\n }\n else {\n result[key] = value;\n }\n });\n return result;\n };\n Utilities.generateAnonymousModule = function () {\n return '===anonymous' + (Utilities.NEXT_ANONYMOUS_ID++) + '===';\n };\n Utilities.isAnonymousModule = function (id) {\n return Utilities.startsWith(id, '===anonymous');\n };\n Utilities.getHighPerformanceTimestamp = function () {\n if (!this.PERFORMANCE_NOW_PROBED) {\n this.PERFORMANCE_NOW_PROBED = true;\n this.HAS_PERFORMANCE_NOW = (AMDLoader.global.performance && typeof AMDLoader.global.performance.now === 'function');\n }\n return (this.HAS_PERFORMANCE_NOW ? AMDLoader.global.performance.now() : Date.now());\n };\n Utilities.NEXT_ANONYMOUS_ID = 1;\n Utilities.PERFORMANCE_NOW_PROBED = false;\n Utilities.HAS_PERFORMANCE_NOW = false;\n return Utilities;\n }());\n AMDLoader.Utilities = Utilities;\n})(AMDLoader || (AMDLoader = {}));\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar AMDLoader;\n(function (AMDLoader) {\n function ensureError(err) {\n if (err instanceof Error) {\n return err;\n }\n var result = new Error(err.message || String(err) || 'Unknown Error');\n if (err.stack) {\n result.stack = err.stack;\n }\n return result;\n }\n AMDLoader.ensureError = ensureError;\n ;\n var ConfigurationOptionsUtil = /** @class */ (function () {\n function ConfigurationOptionsUtil() {\n }\n /**\n * Ensure configuration options make sense\n */\n ConfigurationOptionsUtil.validateConfigurationOptions = function (options) {\n function defaultOnError(err) {\n if (err.phase === 'loading') {\n console.error('Loading \"' + err.moduleId + '\" failed');\n console.error(err);\n console.error('Here are the modules that depend on it:');\n console.error(err.neededBy);\n return;\n }\n if (err.phase === 'factory') {\n console.error('The factory method of \"' + err.moduleId + '\" has thrown an exception');\n console.error(err);\n return;\n }\n }\n options = options || {};\n if (typeof options.baseUrl !== 'string') {\n options.baseUrl = '';\n }\n if (typeof options.isBuild !== 'boolean') {\n options.isBuild = false;\n }\n if (typeof options.paths !== 'object') {\n options.paths = {};\n }\n if (typeof options.config !== 'object') {\n options.config = {};\n }\n if (typeof options.catchError === 'undefined') {\n options.catchError = false;\n }\n if (typeof options.recordStats === 'undefined') {\n options.recordStats = false;\n }\n if (typeof options.urlArgs !== 'string') {\n options.urlArgs = '';\n }\n if (typeof options.onError !== 'function') {\n options.onError = defaultOnError;\n }\n if (!Array.isArray(options.ignoreDuplicateModules)) {\n options.ignoreDuplicateModules = [];\n }\n if (options.baseUrl.length > 0) {\n if (!AMDLoader.Utilities.endsWith(options.baseUrl, '/')) {\n options.baseUrl += '/';\n }\n }\n if (typeof options.cspNonce !== 'string') {\n options.cspNonce = '';\n }\n if (typeof options.preferScriptTags === 'undefined') {\n options.preferScriptTags = false;\n }\n if (!Array.isArray(options.nodeModules)) {\n options.nodeModules = [];\n }\n if (options.nodeCachedData && typeof options.nodeCachedData === 'object') {\n if (typeof options.nodeCachedData.seed !== 'string') {\n options.nodeCachedData.seed = 'seed';\n }\n if (typeof options.nodeCachedData.writeDelay !== 'number' || options.nodeCachedData.writeDelay < 0) {\n options.nodeCachedData.writeDelay = 1000 * 7;\n }\n if (!options.nodeCachedData.path || typeof options.nodeCachedData.path !== 'string') {\n var err = ensureError(new Error('INVALID cached data configuration, \\'path\\' MUST be set'));\n err.phase = 'configuration';\n options.onError(err);\n options.nodeCachedData = undefined;\n }\n }\n return options;\n };\n ConfigurationOptionsUtil.mergeConfigurationOptions = function (overwrite, base) {\n if (overwrite === void 0) { overwrite = null; }\n if (base === void 0) { base = null; }\n var result = AMDLoader.Utilities.recursiveClone(base || {});\n // Merge known properties and overwrite the unknown ones\n AMDLoader.Utilities.forEachProperty(overwrite, function (key, value) {\n if (key === 'ignoreDuplicateModules' && typeof result.ignoreDuplicateModules !== 'undefined') {\n result.ignoreDuplicateModules = result.ignoreDuplicateModules.concat(value);\n }\n else if (key === 'paths' && typeof result.paths !== 'undefined') {\n AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.paths[key2] = value2; });\n }\n else if (key === 'config' && typeof result.config !== 'undefined') {\n AMDLoader.Utilities.forEachProperty(value, function (key2, value2) { return result.config[key2] = value2; });\n }\n else {\n result[key] = AMDLoader.Utilities.recursiveClone(value);\n }\n });\n return ConfigurationOptionsUtil.validateConfigurationOptions(result);\n };\n return ConfigurationOptionsUtil;\n }());\n AMDLoader.ConfigurationOptionsUtil = ConfigurationOptionsUtil;\n var Configuration = /** @class */ (function () {\n function Configuration(env, options) {\n this._env = env;\n this.options = ConfigurationOptionsUtil.mergeConfigurationOptions(options);\n this._createIgnoreDuplicateModulesMap();\n this._createNodeModulesMap();\n this._createSortedPathsRules();\n if (this.options.baseUrl === '') {\n if (this.options.nodeRequire && this.options.nodeRequire.main && this.options.nodeRequire.main.filename && this._env.isNode) {\n var nodeMain = this.options.nodeRequire.main.filename;\n var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\\\'));\n this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1);\n }\n if (this.options.nodeMain && this._env.isNode) {\n var nodeMain = this.options.nodeMain;\n var dirnameIndex = Math.max(nodeMain.lastIndexOf('/'), nodeMain.lastIndexOf('\\\\'));\n this.options.baseUrl = nodeMain.substring(0, dirnameIndex + 1);\n }\n }\n }\n Configuration.prototype._createIgnoreDuplicateModulesMap = function () {\n // Build a map out of the ignoreDuplicateModules array\n this.ignoreDuplicateModulesMap = {};\n for (var i = 0; i < this.options.ignoreDuplicateModules.length; i++) {\n this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[i]] = true;\n }\n };\n Configuration.prototype._createNodeModulesMap = function () {\n // Build a map out of nodeModules array\n this.nodeModulesMap = Object.create(null);\n for (var _i = 0, _a = this.options.nodeModules; _i < _a.length; _i++) {\n var nodeModule = _a[_i];\n this.nodeModulesMap[nodeModule] = true;\n }\n };\n Configuration.prototype._createSortedPathsRules = function () {\n var _this = this;\n // Create an array our of the paths rules, sorted descending by length to\n // result in a more specific -> less specific order\n this.sortedPathsRules = [];\n AMDLoader.Utilities.forEachProperty(this.options.paths, function (from, to) {\n if (!Array.isArray(to)) {\n _this.sortedPathsRules.push({\n from: from,\n to: [to]\n });\n }\n else {\n _this.sortedPathsRules.push({\n from: from,\n to: to\n });\n }\n });\n this.sortedPathsRules.sort(function (a, b) {\n return b.from.length - a.from.length;\n });\n };\n /**\n * Clone current configuration and overwrite options selectively.\n * @param options The selective options to overwrite with.\n * @result A new configuration\n */\n Configuration.prototype.cloneAndMerge = function (options) {\n return new Configuration(this._env, ConfigurationOptionsUtil.mergeConfigurationOptions(options, this.options));\n };\n /**\n * Get current options bag. Useful for passing it forward to plugins.\n */\n Configuration.prototype.getOptionsLiteral = function () {\n return this.options;\n };\n Configuration.prototype._applyPaths = function (moduleId) {\n var pathRule;\n for (var i = 0, len = this.sortedPathsRules.length; i < len; i++) {\n pathRule = this.sortedPathsRules[i];\n if (AMDLoader.Utilities.startsWith(moduleId, pathRule.from)) {\n var result = [];\n for (var j = 0, lenJ = pathRule.to.length; j < lenJ; j++) {\n result.push(pathRule.to[j] + moduleId.substr(pathRule.from.length));\n }\n return result;\n }\n }\n return [moduleId];\n };\n Configuration.prototype._addUrlArgsToUrl = function (url) {\n if (AMDLoader.Utilities.containsQueryString(url)) {\n return url + '&' + this.options.urlArgs;\n }\n else {\n return url + '?' + this.options.urlArgs;\n }\n };\n Configuration.prototype._addUrlArgsIfNecessaryToUrl = function (url) {\n if (this.options.urlArgs) {\n return this._addUrlArgsToUrl(url);\n }\n return url;\n };\n Configuration.prototype._addUrlArgsIfNecessaryToUrls = function (urls) {\n if (this.options.urlArgs) {\n for (var i = 0, len = urls.length; i < len; i++) {\n urls[i] = this._addUrlArgsToUrl(urls[i]);\n }\n }\n return urls;\n };\n /**\n * Transform a module id to a location. Appends .js to module ids\n */\n Configuration.prototype.moduleIdToPaths = function (moduleId) {\n if (this._env.isNode) {\n var isNodeModule = ((this.nodeModulesMap[moduleId] === true)\n || (this.options.amdModulesPattern instanceof RegExp && !this.options.amdModulesPattern.test(moduleId)));\n if (isNodeModule) {\n // This is a node module...\n if (this.isBuild()) {\n // ...and we are at build time, drop it\n return ['empty:'];\n }\n else {\n // ...and at runtime we create a `shortcut`-path\n return ['node|' + moduleId];\n }\n }\n }\n var result = moduleId;\n var results;\n if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.isAbsolutePath(result)) {\n results = this._applyPaths(result);\n for (var i = 0, len = results.length; i < len; i++) {\n if (this.isBuild() && results[i] === 'empty:') {\n continue;\n }\n if (!AMDLoader.Utilities.isAbsolutePath(results[i])) {\n results[i] = this.options.baseUrl + results[i];\n }\n if (!AMDLoader.Utilities.endsWith(results[i], '.js') && !AMDLoader.Utilities.containsQueryString(results[i])) {\n results[i] = results[i] + '.js';\n }\n }\n }\n else {\n if (!AMDLoader.Utilities.endsWith(result, '.js') && !AMDLoader.Utilities.containsQueryString(result)) {\n result = result + '.js';\n }\n results = [result];\n }\n return this._addUrlArgsIfNecessaryToUrls(results);\n };\n /**\n * Transform a module id or url to a location.\n */\n Configuration.prototype.requireToUrl = function (url) {\n var result = url;\n if (!AMDLoader.Utilities.isAbsolutePath(result)) {\n result = this._applyPaths(result)[0];\n if (!AMDLoader.Utilities.isAbsolutePath(result)) {\n result = this.options.baseUrl + result;\n }\n }\n return this._addUrlArgsIfNecessaryToUrl(result);\n };\n /**\n * Flag to indicate if current execution is as part of a build.\n */\n Configuration.prototype.isBuild = function () {\n return this.options.isBuild;\n };\n /**\n * Test if module `moduleId` is expected to be defined multiple times\n */\n Configuration.prototype.isDuplicateMessageIgnoredFor = function (moduleId) {\n return this.ignoreDuplicateModulesMap.hasOwnProperty(moduleId);\n };\n /**\n * Get the configuration settings for the provided module id\n */\n Configuration.prototype.getConfigForModule = function (moduleId) {\n if (this.options.config) {\n return this.options.config[moduleId];\n }\n };\n /**\n * Should errors be caught when executing module factories?\n */\n Configuration.prototype.shouldCatchError = function () {\n return this.options.catchError;\n };\n /**\n * Should statistics be recorded?\n */\n Configuration.prototype.shouldRecordStats = function () {\n return this.options.recordStats;\n };\n /**\n * Forward an error to the error handler.\n */\n Configuration.prototype.onError = function (err) {\n this.options.onError(err);\n };\n return Configuration;\n }());\n AMDLoader.Configuration = Configuration;\n})(AMDLoader || (AMDLoader = {}));\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nvar AMDLoader;\n(function (AMDLoader) {\n /**\n * Load `scriptSrc` only once (avoid multiple @@ -21,6 +22,10 @@ + + + -
-

-

-

-

The UI is loading...

+ style="overflow:hidden; background: url(Images/superalgos-platform.jpg); background-size: cover;" + onresize="onResize()"> +
+

+

+

+

The UI is loading...

+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
- -
-
-
 
+
+
+ +
+
+
 
- -
-
-
- - - - - - - -
- - - - - - - -
-
-
+ +
+
+
+ + + + + + + +
+ + + + + + + +
+
+
-