From 4bbd38450186899d3a55e38e3c31b4c22fe00584 Mon Sep 17 00:00:00 2001 From: rodrigorodriguez Date: Wed, 2 Nov 2022 19:40:59 -0300 Subject: [PATCH] new(all): Vm isolated working with IPC BASIC 3.0; --- .../basic.gblib/services/DialogKeywords.ts | 245 +++++++------- packages/basic.gblib/services/GBVMService.ts | 316 +++++++++--------- .../basic.gblib/services/SystemKeywords.ts | 90 ++--- packages/basic.gblib/services/TSCompiler.ts | 2 +- .../services/vm2-process/vm2ProcessRunner.ts | 2 +- 5 files changed, 335 insertions(+), 320 deletions(-) diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index fc39def4..6aa5b71d 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -2,7 +2,7 @@ | ( )_ _ | | _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | | ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ | -| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__,\| (˅) |( (_) ) | | | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | | | | ( )_) | | | (_) \___/' | @@ -10,22 +10,22 @@ | General Bots Copyright (c) Pragmatismo.io. All rights reserved. | | Licensed under the AGPL-3.0. | | | -| According to our dual licensing model, this program can be used either | -| under the terms of the GNU Affero General Public License, version 3, | +| According to our dual licensing model,this program can be used either | +| under the terms of the GNU Affero General Public License,version 3, | | or under a proprietary license. | | | | The texts of the GNU Affero General Public License with an additional | | permission and of our proprietary license can be found at and | | in the LICENSE file you have received along with this program. | | | -| This program is distributed in the hope that it will be useful, | -| but WITHOUT ANY WARRANTY, without even the implied warranty of | +| This program is distributed in the hope that it will be useful, | +| but WITHOUT ANY WARRANTY,without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | GNU Affero General Public License for more details. | | | | "General Bots" is a registered trademark of Pragmatismo.io. | | The licensing of the program under the AGPLv3 does not imply a | -| trademark license. Therefore any rights, title and interest in | +| trademark license. Therefore any rights,title and interest in | | our trademarks remain entirely with us. | | | \*****************************************************************************/ @@ -99,7 +99,7 @@ export class DialogKeywords { lastDebugWeb: Date; /** - * SYSTEM account maxLines, when used with impersonated contexts (eg. running in SET SCHEDULE). + * SYSTEM account maxLines,when used with impersonated contexts (eg. running in SET SCHEDULE). */ maxLines: number = 2000; @@ -112,7 +112,7 @@ export class DialogKeywords { } /** - * When creating this keyword facade, a bot instance is + * When creating this keyword facade,a bot instance is * specified among the deployer service. */ constructor(min: GBMinInstance, deployer: GBDeployer, user) { @@ -129,7 +129,7 @@ export class DialogKeywords { } /** - * Base reference of system keyword facade, called directly + * Base reference of system keyword facade,called directly * by the script. */ public sys(): SystemKeywords { @@ -141,7 +141,7 @@ export class DialogKeywords { * * @example x = GET PAGE */ - public async getPage(url, username, password) { + public async getPage({url, username, password}) { GBLog.info(`BASIC: Web Automation GET PAGE ${url}.`); if (!this.browser) { this.browser = await createBrowser(null); @@ -157,9 +157,9 @@ export class DialogKeywords { /** * * - * Data = [10, 20, 30] + * Data = [10,20,30] * Legends = "Steve;Yui;Carlos" - * img = CHART "pie", data, legends + * img = CHART "pie",data,legends * * https://c3js.org/examples.html * @@ -167,7 +167,7 @@ export class DialogKeywords { * @param legends * @see https://www.npmjs.com/package/plot */ - public async chart(type, data, legends, transpose) { + public async chart({type, data, legends, transpose}) { let table = [[]]; @@ -177,8 +177,8 @@ export class DialogKeywords { // Columns and data are merged like: // columns: [ - // ['data1', 30, 200, 100, 400, 150, 250], - // ['data2', 50, 20, 10, 40, 15, 25] + // ['data1',30,200,100,400,150,250], + // ['data2',50,20,10,40,15,25] // ] for (let i = 0; i < legends_.length; i++) { @@ -246,18 +246,18 @@ export class DialogKeywords { /** * Find element on page DOM. * - * @example GET page, "elementName" + * @example GET page,"selector" */ - public async getBySelector(page, elementName) { - GBLog.info(`BASIC: Web Automation GET element: ${elementName}.`); - await page.waitForSelector(elementName) - let elements = await page.$$(elementName); + public async getBySelector({page, selector}) { + GBLog.info(`BASIC: Web Automation GET element: ${selector}.`); + await page.waitForSelector(selector) + let elements = await page.$$(selector); if (elements && elements.length > 1) { return elements; } else { const el = elements[0]; - el['originalSelector'] = elementName; + el['originalSelector'] = selector; el['href'] = await page.evaluate(e => e.getAttribute('href'), el); el['value'] = await page.evaluate(e => e.getAttribute('value'), el); el['name'] = await page.evaluate(e => e.getAttribute('name'), el); @@ -269,9 +269,9 @@ export class DialogKeywords { /** * Find element on page DOM. * - * @example GET page, "frameSelector, "elementSelector" + * @example GET page,"frameSelector,"elementSelector" */ - public async getByFrame(page, frame, selector) { + public async getByFrame({page, frame, selector}) { GBLog.info(`BASIC: Web Automation GET element by frame: ${selector}.`); await page.waitForSelector(frame) let frameHandle = await page.$(frame); @@ -290,19 +290,19 @@ export class DialogKeywords { /** * Simulates a mouse hover an web page element. */ - public async hover(page, idOrName) { - GBLog.info(`BASIC: Web Automation HOVER element: ${idOrName}.`); - await this.getBySelector(page, idOrName); - await page.hover(idOrName); + public async hover({page, selector}) { + GBLog.info(`BASIC: Web Automation HOVER element: ${selector}.`); + await this.getBySelector({page, selector: selector}); + await page.hover(selector); await this.debugStepWeb(page); } /** * Clicks on an element in a web page. * - * @example CLICK page, "#idElement" + * @example CLICK page,"#idElement" */ - public async click(page, frameOrSelector, selector) { + public async click({page, frameOrSelector, selector}) { GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`); if (selector) { await page.waitForSelector(frameOrSelector) @@ -326,20 +326,21 @@ export class DialogKeywords { } if (this.debugWeb && refresh) { - const adminNumber = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null); - if (adminNumber) { - await this.sendFileTo(adminNumber, page, "General Bots Debugger"); + const mobile = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null); + const filename = page; + if (mobile) { + await this.sendFileTo({mobile , filename, caption:"General Bots Debugger"}); } this.lastDebugWeb = new Date(); } } /** - * Press ENTER in a web page, useful for logins. + * Press ENTER in a web page,useful for logins. * * @example PRESS ENTER ON page */ - public async pressKey(page, char, frame) { + public async pressKey({page, char, frame}) { GBLog.info(`BASIC: Web Automation PRESS ${char} ON element: ${frame}.`); if (char.toLowerCase() === "enter") { char = '\n'; @@ -355,12 +356,12 @@ export class DialogKeywords { } } - public async linkByText(page, text, index) { + public async linkByText({page, text, index}) { GBLog.info(`BASIC: Web Automation CLICK LINK TEXT: ${text} ${index}.`); if (!index) { index = 1 } - const els = await page.$x(`//a[contains(., '${text}')]`); + const els = await page.$x(`//a[contains(.,'${text}')]`); await els[index - 1].click(); await this.debugStepWeb(page); } @@ -372,8 +373,8 @@ export class DialogKeywords { * * @example file = SCREENSHOT page */ - public async screenshot(page, idOrName) { - GBLog.info(`BASIC: Web Automation SCREENSHOT ${idOrName}.`); + public async screenshot({page, selector}) { + GBLog.info(`BASIC: Web Automation SCREENSHOT ${selector}.`); const gbaiName = `${this.min.botId}.gbai`; const localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`); @@ -395,11 +396,11 @@ export class DialogKeywords { /** * Types the text into the text field. * - * @example SET page, "elementName", "text" + * @example SET page,"selector","text" */ - public async setElementText(page, idOrName, text) { - GBLog.info(`BASIC: Web Automation TYPE on ${idOrName}: ${text}.`); - const e = await this.getBySelector(page, idOrName); + public async setElementText({page, selector, text}) { + GBLog.info(`BASIC: Web Automation TYPE on ${selector}: ${text}.`); + const e = await this.getBySelector({page, selector}); await e.click({ clickCount: 3 }); await page.keyboard.press('Backspace'); await e.type(text, { delay: 200 }); @@ -410,7 +411,7 @@ export class DialogKeywords { * Returns the OCR of image file. * */ - public async getOCR(localFile) { + public async getOCR({localFile}) { GBLog.info(`BASIC: OCR processing on ${localFile}.`); const tesseract = require("node-tesseract-ocr") @@ -428,7 +429,7 @@ export class DialogKeywords { * * @example x = TODAY */ - public async getToday() { + public async getToday({}) { let d = new Date(), month = '' + (d.getMonth() + 1), day = '' + d.getDate(), @@ -456,11 +457,11 @@ export class DialogKeywords { } /** - * Quits the dialog, currently required to get out of VM context. + * Quits the dialog,currently required to get out of VM context. * * @example EXIT */ - public async exit() { + public async exit({}) { } @@ -469,7 +470,7 @@ export class DialogKeywords { * * @example list = ACTIVE TASKS */ - public async getActiveTasks() { + public async getActiveTasks({}) { let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY); return await s.getActiveTasks(); } @@ -477,9 +478,9 @@ export class DialogKeywords { /** * Creates a new deal. * - * @example CREATE DEAL dealname, contato, empresa, amount + * @example CREATE DEAL dealname,contato,empresa,amount */ - public async createDeal(dealName, contact, company, amount) { + public async createDeal({dealName, contact, company, amount}) { let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY); let deal = await s.createDeal(dealName, contact, company, amount); return deal; @@ -490,7 +491,7 @@ export class DialogKeywords { * * @example list = FIND CONTACT "Sandra" */ - public async fndContact(name) { + public async fndContact({name}) { let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY); return await s.searchContact(name); } @@ -510,7 +511,7 @@ export class DialogKeywords { } - public async getCoded(value) { + public async getCoded({value}) { // Checks if it is a GB FILE object. @@ -552,9 +553,9 @@ export class DialogKeywords { /** * Returns an object ready to get information about difference in several ways - * like years, months or days. + * like years,months or days. * - * @example days = DATEDIFF date1, date2, mode + * @example days = DATEDIFF date1,date2,mode * */ public dateDiff(date1, date2, mode) { @@ -580,7 +581,7 @@ export class DialogKeywords { /** * Returns specified date week day in format 'Mon'. * - * @example DATEADD date, "minute", 60 + * @example DATEADD date,"minute",60 * * https://stackoverflow.com/a/1214753/18511 */ @@ -610,7 +611,7 @@ export class DialogKeywords { /** * Returns specified list member separated by comma. * - * @example TALK TOLIST (array, member) + * @example TALK TOLIST (array,member) * */ public getToLst(array, member) { @@ -623,7 +624,7 @@ export class DialogKeywords { array = array.filter((v, i, a) => a.findIndex(t => (t[member] === v[member])) === i); array = array.filter(function (item, pos) { return item != undefined; }); array = array.map((item) => { return item[member]; }) - array = array.join(", "); + array = array.join(","); return array; } @@ -662,10 +663,10 @@ export class DialogKeywords { /** * Returns current time in format hh:dd. * - * @example SAVE "file.xlsx", name, email, NOW + * @example SAVE "file.xlsx",name,email,NOW * */ - public async getNow() { + public async getNow({}) { const contentLocale = this.min.core.getParam( this.min.instance, 'Default Content Language', @@ -689,14 +690,14 @@ export class DialogKeywords { * * @example * - * SEND MAIL "email@domain.com", "Subject", "Message text." + * SEND MAIL "email@domain.com","Subject", "Message text." * */ - public async sendEmail(to, subject, body) { + public async sendEmail({to, subject, body}) { // tslint:disable-next-line:no-console - GBLog.info(`[E-mail]: to:${to}, subject: ${subject}, body: ${body}.`); + GBLog.info(`[E-mail]: to:${to},subject: ${subject},body: ${body}.`); const emailToken = process.env.EMAIL_API_KEY; // Inline word document used as e-mail body. @@ -729,12 +730,12 @@ export class DialogKeywords { /** * Sends a file to a given mobile. * - * @example SEND FILE TO "+199988887777", "image.jpg", caption + * @example SEND FILE TO "+199988887777","image.jpg",caption * */ - public async sendFileTo(mobile, filename, caption) { - GBLog.info(`BASIC: SEND FILE TO '${mobile}', filename '${filename}'.`); - return await this.internalSendFile(mobile, filename, caption); + public async sendFileTo({mobile, filename, caption}) { + GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`); + return await this.internalSendFile({mobile, filename, caption}); } /** @@ -743,10 +744,10 @@ export class DialogKeywords { * @example SEND FILE "image.jpg" * */ - public async sendFile(filename, caption) { + public async sendFile({filename, caption}) { const mobile = await this.userMobile(); - GBLog.info(`BASIC: SEND FILE (current: ${mobile}, filename '${filename}'.`); - return await this.internalSendFile(mobile, filename, caption); + GBLog.info(`BASIC: SEND FILE (current: ${mobile},filename '${filename}'.`); + return await this.internalSendFile({mobile, filename, caption}); } /** @@ -755,7 +756,7 @@ export class DialogKeywords { * @example SET LANGUAGE "pt" * */ - public async setLanguage(language) { + public async setLanguage({language}) { const sec = new SecService(); await sec.updateUserLocale(this.user.userId, language); } @@ -766,7 +767,7 @@ export class DialogKeywords { * @example SET ID NUMBER * */ - public async setIdGeneration(mode) { + public async setIdGeneration({mode}) { this['idGeneration'] = mode; this['id'] = await this.sys().getRandomId(); } @@ -777,7 +778,7 @@ export class DialogKeywords { * @example SET MAX LINES 5000 * */ - public async setMaxLines(count) { + public async setMaxLines({count}) { if (this.user) { // TODO: PARAM user.basicOptions.maxLines = count; } @@ -793,7 +794,7 @@ export class DialogKeywords { * @example SET MAX COLUMNS 5000 * */ - public async setMaxColumns(count) { + public async setMaxColumns({count}) { // TODO: user.basicOptions.maxColumns = count; } @@ -805,7 +806,7 @@ export class DialogKeywords { * @example SET WHOLE WORD ON * */ - public async setWholeWord(on) { + public async setWholeWord({on}) { // TODO: user.basicOptions.wholeWord = (on.trim() === "on"); } @@ -815,7 +816,7 @@ export class DialogKeywords { * @example SET THEME "themename" * */ - public async setTheme(theme) { + public async setTheme({theme}) { // TODO: user.basicOptions.theme = theme.trim(); } @@ -825,7 +826,7 @@ export class DialogKeywords { * @example SET TRANSLATOR ON | OFF * */ - public async setTranslatorOn(on) { + public async setTranslatorOn({on}) { // TODO: user.basicOptions.translatorOn = (on.trim() === "on"); } @@ -853,14 +854,14 @@ export class DialogKeywords { * @example MENU * */ - public async showMenu() { + public async showMenu({}) { // TODO: return await beginDialog('/menu'); } private static async downloadAttachmentAndWrite(attachment) { const url = attachment.contentUrl; - const localFolder = Path.join('work'); // TODO: , '${botId}', 'uploads'); + const localFolder = Path.join('work'); // TODO: ,'${botId}','uploads'); const localFileName = Path.join(localFolder, attachment.name); try { @@ -892,7 +893,7 @@ export class DialogKeywords { console.error(error); return undefined; } - // If no error was thrown while writing to disk, return the attachment's name + // If no error was thrown while writing to disk,return the attachment's name // and localFilePath for the response back to the user. return { fileName: attachment.name, @@ -906,8 +907,8 @@ export class DialogKeywords { * @example TRANSFER * */ - public async transferTo(to: string = null) { - // TODO: return await beginDialog('/t', { to: to }); + public async transferTo({to}) { + // TODO: return await beginDialog('/t',{ to: to }); } /** @@ -916,7 +917,15 @@ export class DialogKeywords { * @example HEAR name * */ - public async hear(kind, ...args) { + public async getHear({kind, arg}) { + + // Handles first arg as an array of args. + + let args = []; + if (arg && arg.length) { + args = arg; + } + try { @@ -942,15 +951,16 @@ export class DialogKeywords { let choices = []; let i = 0; - args.forEach(arg => { + await CollectionUtil.asyncForEach(args, async arg => { i++; - choices.push({ body: arg, id: `button${i}` }); + // DISABLED: choices.push({ body: arg, id: `button${i}` }); + await this.talk(arg); }); - const button = new Buttons(Messages[locale].choices, choices, ' ', ' '); + // DISABLED const button = new Buttons(Messages[locale].choices, choices, ' ', ' '); + // await this.talk(button); - await this.talk(button); - GBLog.info(`BASIC: HEAR with ${args.toString()} (Asking for input).`); + GBLog.info(`BASIC: HEAR with [${args.toString()}] (Asking for input).`); } else { @@ -974,7 +984,7 @@ export class DialogKeywords { const text = this.min.cbMap[userId].promise; if (kind === "file") { - // await prompt('attachmentPrompt', {}); + // await prompt('attachmentPrompt',{}); // // Prepare Promises to download each attachment and then execute each Promise. // const promises = step.context.activity.attachments.map( @@ -983,11 +993,11 @@ export class DialogKeywords { // async function replyForReceivedAttachments(localAttachmentData) { // if (localAttachmentData) { - // // Because the TurnContext was bound to this function, the bot can call + // // Because the TurnContext was bound to this function,the bot can call // // `TurnContext.sendActivity` via `this.sendActivity`; // await this.sendActivity(`Upload OK.`); // } else { - // await this.sendActivity('Error uploading file. Please, start again.'); + // await this.sendActivity('Error uploading file. Please,start again.'); // } // } @@ -1019,8 +1029,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null) { - await this.talk("Por favor, digite um e-mail válido."); - return await this.hear(kind, args); + await this.talk({text: "Por favor,digite um e-mail válido."}); + return await this.getHear({kind, arg}); } result = value; @@ -1034,8 +1044,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite um nome válido."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite um nome válido."}); + return await this.getHear({kind, arg}); } result = value; @@ -1049,8 +1059,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite um número válido."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite um número válido."}); + return await this.getHear({kind, arg}); } result = value; @@ -1063,8 +1073,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite uma data no formato 12/12/2020."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite uma data no formato 12/12/2020."}); + return await this.getHear({kind, arg}); } result = value; @@ -1078,8 +1088,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite um horário no formato hh:ss."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite um horário no formato hh:ss."}); + return await this.getHear({kind, arg}); } result = value; @@ -1099,8 +1109,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite um valor monetário."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite um valor monetário."}); + return await this.getHear({kind, arg}); } result = value; @@ -1114,11 +1124,11 @@ export class DialogKeywords { } catch (error) { await this.talk(Messages[locale].validation_enter_valid_mobile); - return await this.hear(kind, args); + return await this.getHear({kind, arg}); } if (!phoneUtil.isPossibleNumber(phoneNumber)) { - await this.talk("Por favor, digite um número de telefone válido."); - return await this.hear(kind, args); + await this.talk({text:"Por favor,digite um número de telefone válido."}); + return await this.getHear({kind, arg}); } result = phoneNumber; @@ -1141,8 +1151,8 @@ export class DialogKeywords { const value = extractEntity(text); if (value === null || value.length != 1) { - await this.talk("Por favor, digite um valor monetário."); - return await this.hear(kind, args); + await this.talk({text:"Por favor, digite um CEP válido."}); + return await this.getHear({kind, arg}); } result = value[0]; @@ -1159,8 +1169,8 @@ export class DialogKeywords { }); if (result === null) { - await this.talk(`Escolha por favor um dos itens sugeridos.`); - return await this.hear(kind, args); + await this.talk({text:`Escolha por favor um dos itens sugeridos.`}); + return await this.getHear({kind, arg}); } } else if (kind === "language") { @@ -1184,8 +1194,6 @@ export class DialogKeywords { ]; - // TODO: const text = step.context.activity['originalText']; - await CollectionUtil.asyncForEach(list, async item => { if (GBConversationalService.kmpSearch(text.toLowerCase(), item.name.toLowerCase()) != -1 || GBConversationalService.kmpSearch(text.toLowerCase(), item.code.toLowerCase()) != -1) { @@ -1194,9 +1202,8 @@ export class DialogKeywords { }); if (result === null) { - // TODO: - await this.min.conversationalService.sendText(this.min, null, `Escolha por favor um dos idiomas sugeridos.`); - return await this.hear(kind, args); + await this.talk({text:`Escolha por favor um dos itens sugeridos.`}); + return await this.getHear({kind, arg}); } } return result; @@ -1208,7 +1215,7 @@ export class DialogKeywords { /** * Prepares the next dialog to be shown to the specified user. */ - public async gotoDialog(fromOrDialogName: string, dialogName: string) { + public async gotoDialog({fromOrDialogName, dialogName}) { if (dialogName) { if (dialogName.charAt(0) === '/') { // TODO: await step.beginDialog(fromOrDialogName); @@ -1227,7 +1234,7 @@ export class DialogKeywords { } } - public async getSingleton() { + public async getSingleton({}) { return { id: this.sys().getRandomId(), username: this.userName(), @@ -1245,7 +1252,7 @@ export class DialogKeywords { /** * Talks to the user by using the specified text. */ - public async talk(text: string) { + public async talk({text}) { GBLog.info(`BASIC: TALK '${text}'.`); if (this.user) { const translate = this.user ? this.user.basicOptions.translatorOn : false; @@ -1264,9 +1271,9 @@ export class DialogKeywords { /** * Processes the sending of the file. */ - private async internalSendFile(mobile, filename, caption) { + private async internalSendFile({mobile, filename, caption}) { - // Handles SEND FILE TO mobile, element in Web Automation. + // Handles SEND FILE TO mobile,element in Web Automation. const element = filename._page ? filename._page : (filename.screenshot ? filename : null); @@ -1319,7 +1326,7 @@ export class DialogKeywords { } } - public async getQRCode(text) { + public async getQRCode({text}) { const img = await qrcode.toDataURL(text); const data = img.replace(/^data:image\/\w+;base64,/, ""); const buf = Buffer.from(data, "base64"); diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index a239a80c..a8035a02 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -161,6 +161,124 @@ export class GBVMService extends GBService { }); } + public async translateBASIC(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) { + + // Converts General Bots BASIC into regular VBS + + let basicCode: string = fs.readFileSync(filename, 'utf8'); + + // Processes END keyword, removing extracode, useful + // for development. + + let end = /(\nend\n)/gi.exec(basicCode); + if (end) { + basicCode = basicCode.substring(0, end.index); + } + + // Removes comments. + + basicCode = basicCode.replace(/((^|\W)REM.*\n)/gi, ''); + + // Process INCLUDE keyword to include another + // dialog inside the dialog. + + let include = null; + do { + include = /^include\b(.*)$/gmi.exec(basicCode); + + if (include) { + let includeName = include[1].trim(); + includeName = Path.join(Path.dirname(filename), includeName); + includeName = includeName.substr(0, includeName.lastIndexOf(".")) + ".vbs"; + + // To use include, two /publish will be necessary (for now) + // because of alphabet order may raise not found errors. + + let includeCode: string = fs.readFileSync(includeName, 'utf8'); + basicCode = basicCode.replace(/^include\b.*$/gmi, includeCode); + } + } while (include); + + const vbsCode = this.convertGBASICToVBS(min, basicCode); + const vbsFile = `${filename}.compiled`; + fs.writeFileSync(vbsFile, vbsCode); + + // Converts VBS into TS. + + vb2ts.convertFile(vbsFile); + + // Convert TS into JS. + + const tsfile: string = `${filename}.ts`; + let tsCode: string = fs.readFileSync(tsfile, 'utf8'); + fs.writeFileSync(tsfile, tsCode); + const tsc = new TSCompiler(); + tsc.compile([tsfile]); + + // Run JS into the GB context. + + const jsfile = `${tsfile}.js`.replace('.ts', ''); + + if (fs.existsSync(jsfile)) { + let code: string = fs.readFileSync(jsfile, 'utf8'); + + code = code.replace(/^.*exports.*$/gm, ''); + + code = ` + + return (async () => { + require('isomorphic-fetch'); + const rest = require ('typescript-rest-rpc/lib/client'); + + // Interprocess communication from local HTTP to the BotServer. + + const dk = rest.createClient('http://localhost:1111/api/v2/${min.botId}/dialog'); + const sys = rest.createClient('http://localhost:1111/api/v2/${min.botId}/system'); + + // Local variables. + + const gb = await dk.getSingleton(); + const id = gb.id; + const username = gb.username; + const mobile = gb.mobile; + const from = gb.from; + const ENTER = gb.ENTER; + const headers = gb.headers; + const data = gb.data; + const list = gb.list; + const httpUsername = gb.httpUsername; + const httpPs = gb.httpPs; + + // Local functions. + + const ubound = (array) => {return array.length}; + const isarray = (array) => {return Array.isArray(array) }; + + // Remote functions. + + const weekday = (v) => { return (async () => { return await client.getWeekFromDate(v) })(); }; + const hour = (v) => { return (async () => { return await client.getHourFromDate(v) })(); }; + const base64 = (v) => { return (async () => { return await client.getCoded(v) })(); }; + const tolist = (v) => { return (async () => { return await client.getToLst(v) })(); }; + const now = (v) => { return (async () => { return await client.getNow(v) })(); }; + const today = (v) => { return (async () => { return await client.getToday(v) })(); }; + + ${code} + + })(); + + `; + // Finds all hear calls. + + const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true }); + fs.writeFileSync(jsfile, parsedCode); + + min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; + + GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${parsedCode}`); + } + } + public static getMethodNameFromVBSFilename(filename: string) { let mainName = filename.replace(/\s|\-/gi, '').split('.')[0]; return mainName.toLowerCase(); @@ -220,7 +338,7 @@ export class GBVMService extends GBService { }); code = code.replace(/(\w+)\s*\=\s*get html\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = await dk.getPage(step, ${$2})\n`; + return `${$1} = await dk.getPage(${$2})\n`; }); code = code.replace(/(set hear on)(\s*)(.*)/gi, ($0, $1, $2, $3) => { @@ -228,59 +346,59 @@ export class GBVMService extends GBService { }); code = code.replace(/hear (\w+) as login/gi, ($0, $1) => { - return `${$1} = await dk.hear("login")`; + return `${$1} = await dk.getHear({{"login"})`; }); code = code.replace(/hear (\w+) as email/gi, ($0, $1) => { - return `${$1} = await dk.hear("email")`; + return `${$1} = await dk.getHear({"email"})`; }); code = code.replace(/hear (\w+) as integer/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("integer")`; + return `${$1} = await dk.getHear({"integer"})`; }); code = code.replace(/hear (\w+) as file/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("file")`; + return `${$1} = await dk.getHear({"file"})`; }); code = code.replace(/hear (\w+) as boolean/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("boolean")`; + return `${$1} = await dk.getHear({"boolean"})`; }); code = code.replace(/hear (\w+) as name/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("name")`; + return `${$1} = await dk.getHear({"name"})`; }); code = code.replace(/hear (\w+) as date/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("date")`; + return `${$1} = await dk.getHear({"date"})`; }); code = code.replace(/hear (\w+) as hour/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("hour")`; + return `${$1} = await dk.getHear({"hour"})`; }); code = code.replace(/hear (\w+) as phone/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("phone")`; + return `${$1} = await dk.getHear({"phone"})`; }); code = code.replace(/hear (\w+) as money/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("money")`; + return `${$1} = await dk.getHear({"money")}`; }); code = code.replace(/hear (\w+) as language/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("language")`; + return `${$1} = await dk.getHear({"language")}`; }); code = code.replace(/hear (\w+) as zipcode/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("zipcode")`; + return `${$1} = await dk.getHear({"zipcode")}`; }); code = code.replace(/hear (\w+) as (.*)/gi, ($0, $1, $2) => { - return `${$1} = await dk.hear("menu", ${$2})`; + return `${$1} = await dk.getHear({"menu", [${$2}])}`; }); code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => { - return `${$2} = await dk.hear()`; + return `${$2} = await dk.getHear({})`; }); code = code.replace(/(\w)\s*\=\s*find contact\s*(.*)/gi, ($0, $1, $2, $3) => { @@ -313,7 +431,7 @@ export class GBVMService extends GBService { }); code = code.replace(/(\w)\s*\=\s*append\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = await sys.append(${$2})\n`; + return `${$1} = await sys.append([${$2}])\n`; }); code = code.replace(/(\w+)\s*\=\s*sort\s*(\w+)\s*by(.*)/gi, ($0, $1, $2, $3) => { @@ -374,11 +492,11 @@ export class GBVMService extends GBService { code = code.replace(/(go to)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.gotoDialog(step, ${$3})\n`; + return `await dk.gotoDialog(${$3})\n`; }); code = code.replace(/(set language)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setLanguage (step, ${$3})\n`; + return `await dk.setLanguage (${$3})\n`; }); code = code.replace(/set header\s*(.*)\sas\s(.*)/gi, ($0, $1, $2) => { @@ -394,31 +512,31 @@ export class GBVMService extends GBService { }); code = code.replace(/(datediff)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.dateDiff (step, ${$3})\n`; + return `await dk.dateDiff (${$3})\n`; }); code = code.replace(/(dateadd)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.dateAdd (step, ${$3})\n`; + return `await dk.dateAdd (${$3})\n`; }); code = code.replace(/(set max lines)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setMaxLines (step, ${$3})\n`; + return `await dk.setMaxLines (${$3})\n`; }); code = code.replace(/(set max columns)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setMaxColumns (step, ${$3})\n`; + return `await dk.setMaxColumns (${$3})\n`; }); code = code.replace(/(set translator)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setTranslatorOn (step, "${$3.toLowerCase()}")\n`; + return `await dk.setTranslatorOn ("${$3.toLowerCase()}")\n`; }); code = code.replace(/(set theme)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setTheme (step, "${$3.toLowerCase()}")\n`; + return `await dk.setTheme ("${$3.toLowerCase()}")\n`; }); code = code.replace(/(set whole word)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.setWholeWord (step, "${$3.toLowerCase()}")\n`; + return `await dk.setWholeWord ("${$3.toLowerCase()}")\n`; }); code = code.replace(/(\w+)\s*\=\s*post\s*(.*),\s*(.*)/gi, ($0, $1, $2, $3) => { @@ -446,11 +564,11 @@ export class GBVMService extends GBService { }); code = code.replace(/(chart)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.chart (step, ${$3})\n`; + return `await dk.chart (${$3})\n`; }); code = code.replace(/(transfer to)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.transferTo (step, ${$3})\n`; + return `await dk.transferTo (${$3})\n`; }); code = code.replace(/(\btransfer\b)(?=(?:[^"]|"[^"]*")*$)/gi, () => { @@ -470,7 +588,7 @@ export class GBVMService extends GBService { }); code = code.replace(/(talk)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.talk (step, ${$3})\n`; + return `await dk.talk (${$3})\n`; }); code = code.replace(/(send sms to)(\s*)(.*)/gi, ($0, $1, $2, $3) => { @@ -486,23 +604,23 @@ export class GBVMService extends GBService { }); code = code.replace(/(send file to)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.sendFileTo (step, ${$3})\n`; + return `await dk.sendFileTo (${$3})\n`; }); code = code.replace(/(hover)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.hover (step, ${$3})\n`; + return `await dk.hover (${$3})\n`; }); code = code.replace(/(click link text)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.linkByText (step, ${$3})\n`; + return `await dk.linkByText (${$3})\n`; }); code = code.replace(/(click)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.click (step, ${$3})\n`; + return `await dk.click (${$3})\n`; }); code = code.replace(/(send file)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `await dk.sendFile (step, ${$3})\n`; + return `await dk.sendFile (${$3})\n`; }); code = code.replace(/(copy)(\s*)(.*)/gi, ($0, $1, $2, $3) => { @@ -523,15 +641,15 @@ export class GBVMService extends GBService { }); code = code.replace(/PRESS\s(.*)\sON\s(.*)/gi, ($0, $1, $2) => { - return `await dk.pressKey(step, ${$2}, ${$1})\n`; + return `await dk.pressKey(${$2}, ${$1})\n`; }); code = code.replace(/SCREENSHOT\s(.*)/gi, ($0, $1, $2) => { - return `await dk.screenshot(step, ${$1})\n`; + return `await dk.screenshot(${$1})\n`; }); code = code.replace(/TWEET\s(.*)/gi, ($0, $1, $2) => { - return `await sys.tweet(step, ${$1})\n`; + return `await sys.tweet(${$1})\n`; }); code = code.replace(/(\w+)\s*\=\s*(.*)\s*as image/gi, ($0, $1, $2) => { @@ -550,7 +668,7 @@ export class GBVMService extends GBService { return `await sys.saveFile(${$2}, ${$1})\n`; }); code = code.replace(/(save)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `await sys.save(${$3})\n`; + return `await sys.save([${$3}])\n`; }); code = code.replace(/set\s(.*)/gi, ($0, $1, $2) => { @@ -562,137 +680,17 @@ export class GBVMService extends GBService { return code; } - public async translateBASIC(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) { - - // Converts General Bots BASIC into regular VBS - - let basicCode: string = fs.readFileSync(filename, 'utf8'); - - // Processes END keyword, removing extracode, useful - // for development. - - let end = /(\nend\n)/gi.exec(basicCode); - if (end) { - basicCode = basicCode.substring(0, end.index); - } - - // Removes comments. - - basicCode = basicCode.replace(/((^|\W)REM.*\n)/gi, ''); - - // Process INCLUDE keyword to include another - // dialog inside the dialog. - - let include = null; - do { - include = /^include\b(.*)$/gmi.exec(basicCode); - - if (include) { - let includeName = include[1].trim(); - includeName = Path.join(Path.dirname(filename), includeName); - includeName = includeName.substr(0, includeName.lastIndexOf(".")) + ".vbs"; - - // To use include, two /publish will be necessary (for now) - // because of alphabet order may raise not found errors. - - let includeCode: string = fs.readFileSync(includeName, 'utf8'); - basicCode = basicCode.replace(/^include\b.*$/gmi, includeCode); - } - } while (include); - - const vbsCode = this.convertGBASICToVBS(min, basicCode); - const vbsFile = `${filename}.compiled`; - fs.writeFileSync(vbsFile, vbsCode); - - // Converts VBS into TS. - - vb2ts.convertFile(vbsFile); - - // Convert TS into JS. - - const tsfile: string = `${filename}.ts`; - let tsCode: string = fs.readFileSync(tsfile, 'utf8'); - tsCode = tsCode + `let resolve;`; - fs.writeFileSync(tsfile, tsCode); - const tsc = new TSCompiler(); - tsc.compile([tsfile]); - - // Run JS into the GB context. - - const jsfile = `${tsfile}.js`.replace('.ts', ''); - - if (fs.existsSync(jsfile)) { - let code: string = fs.readFileSync(jsfile, 'utf8'); - - code = code.replace(/^.*exports.*$/gm, ''); - - code = ` - - return (async () => { - require('isomorphic-fetch); - const rest = require ('typescript-rest-rpc/lib/client'); - - // Interprocess communication from local HTTP to the BotServer. - - dk = rest.createClient('http://localhost:1111/api/v2/${min.botId}/dialog'); - sys = rest.createClient('http://localhost:1111/api/v2/${min.botId}/system'); - - // Local variables. - - gb = dk.getSingleton(url); - const id = gb.id; - const username = gb.username; - const mobile = gb.mobile; - const from = gb.from; - const ENTER = gb.ENTER; - const headers = gb.headers; - const data = gb.data; - const list = gb.list; - const httpUsername = gb.httpUsername; - const httpPs = gb.httpPs; - - // Local functions. - - const ubound = (array) => {return array.length}; - const isarray = (array) => {return Array.isArray(array) }; - - // Remote functions. - - const weekday = (v) => { (async () => { await client.getWeekFromDate(v) })(); }; - const hour = (v) => { (async () => { await client.getHourFromDate(v) })(); }; - const base64 = (v) => { (async () => { await client.getCoded(v) })(); }; - const tolist = (v) => { (async () => { await client.getToLst(v) })(); }; - const now = (v) => { (async () => { await client.getNow(v) })(); }; - const today = (v) => { (async () => { await client.getToday(v) })(); }; - - ${code} - - })(); - - `; - // Finds all hear calls. - - const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true }); - fs.writeFileSync(jsfile, parsedCode); - - min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; - - GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${parsedCode}`); - } - } - - /** * Executes the converted JavaScript from BASIC code inside execution context. */ - public static async callVM(text: string, min: GBMinInstance, step: GBDialogStep, deployer: GBDeployer) { + public static async callVM(text: string, min: GBMinInstance, step, GBDialogdeployer: GBDeployer) { // Creates a class DialogKeywords which is the *this* pointer // in BASIC. const user = step ? await min.userProfile.get(step.context, {}) : null; - const sandbox = { user: user.ssystemUser }; + const sandbox = { user: user.systemUser }; const contentLocale = min.core.getParam( min.instance, diff --git a/packages/basic.gblib/services/SystemKeywords.ts b/packages/basic.gblib/services/SystemKeywords.ts index 5e9c16d7..89ca30e4 100644 --- a/packages/basic.gblib/services/SystemKeywords.ts +++ b/packages/basic.gblib/services/SystemKeywords.ts @@ -92,11 +92,17 @@ export class SystemKeywords { } - public async callVM(text: string, min: GBMinInstance, step, deployer: GBDeployer) { + public async callVM({text}) { + + // TODO: + const min = null; + const step = null; + const deployer = null; + return await GBVMService.callVM(text, min, step, deployer); } - public async append(...args) { + public async append({args}) { let array = [].concat(...args); return array.filter(function (item, pos) { return item; }); } @@ -107,7 +113,7 @@ export class SystemKeywords { * @example SEE CAPTION OF url AS variable * */ - public async seeCaption(url) { + public async seeCaption({url}) { const computerVisionClient = new ComputerVisionClient( new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }), process.env.VISION_ENDPOINT); @@ -135,7 +141,7 @@ export class SystemKeywords { * @example SEE TEXT OF url AS variable * */ - public async seeText(url) { + public async seeText({url}) { const computerVisionClient = new ComputerVisionClient( new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }), process.env.VISION_ENDPOINT); @@ -160,7 +166,7 @@ export class SystemKeywords { return final; } - public async sortBy(array, memberName) { + public async sortBy({array, memberName}) { memberName = memberName.trim(); const contentLocale = this.min.core.getParam( this.min.instance, @@ -345,18 +351,18 @@ export class SystemKeywords { return [url, localName]; } - public async asPDF(data, filename) { + public async asPDF({data, filename}) { let file = await this.renderTable(data, true, false); return file[0]; } - public async asImage(data, filename) { + public async asImage({data, filename}) { let file = await this.renderTable(data, false, true); return file[0]; } - public async executeSQL(data, sql, tableName) { + public async executeSQL({data, sql, tableName}) { let objectMode = false; if (Object.keys(data[0])) { @@ -377,7 +383,7 @@ export class SystemKeywords { /** * Retrives the content of a given URL. */ - public async getFileContents(url, headers) { + public async getFileContents({url, headers}) { const options = { url: url, method: 'GET', @@ -405,7 +411,7 @@ export class SystemKeywords { /** * Retrives stock inforation for a given symbol. */ - public async getStock(symbol) { + public async getStock({symbol}) { var options = { uri: `http://live-nse.herokuapp.com/?symbol=${symbol}` }; @@ -421,7 +427,7 @@ export class SystemKeywords { * @example WAIT 5 ' This will wait five seconds. * */ - public async wait(seconds: number) { + public async wait({seconds}) { // tslint:disable-next-line no-string-based-set-timeout GBLog.info(`BASIC: WAIT for ${seconds} second(s).`); const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); @@ -434,7 +440,7 @@ export class SystemKeywords { * @example TALK TO "+199988887777", "Message text here" * */ - public async talkTo(mobile: any, message: string) { + public async talkTo({mobile, message}) { GBLog.info(`BASIC: Talking '${message}' to a specific user (${mobile}) (TALK TO). `); await this.min.conversationalService.sendMarkdownToMobile(this.min, null, mobile, message); } @@ -445,7 +451,7 @@ export class SystemKeywords { * @example SEND SMS TO "+199988887777", "Message text here" * */ - public async sendSmsTo(mobile, message) { + public async sendSmsTo({mobile, message}) { GBLog.info(`BASIC: SEND SMS TO '${mobile}', message '${message}'.`); await this.min.conversationalService.sendSms(this.min, mobile, message); } @@ -459,13 +465,14 @@ export class SystemKeywords { * @example SET page, "elementHTMLSelector", "text" * */ - public async set(file: any, address: string, value: any): Promise { + public async set({file, address, value}): Promise { // Handles calls for HTML stuff if (file._javascriptEnabled) { - GBLog.info(`BASIC: Web automation setting ${file}' to '${value}' (SET). `); - await this.dk.setElementText(file, address, value); + const page = file; + GBLog.info(`BASIC: Web automation setting ${page}' to '${value}' (SET). `); + await this.dk.setElementText({page, selector: address, text: value}); return; } @@ -520,7 +527,7 @@ export class SystemKeywords { * @exaple SAVE variable as "my.txt" * */ - public async saveFile(file: any, data: any): Promise { + public async saveFile({file, data}): Promise { GBLog.info(`BASIC: Saving '${file}' (SAVE file).`); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); @@ -556,7 +563,9 @@ export class SystemKeywords { * @exaple SAVE "customers.xlsx", name, email, phone, address, city, state, country * */ - public async save(file: string, ...args): Promise { + public async save({args}): Promise { + const file = args[0]; + args.shift(); GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); const botId = this.min.instance.botId; @@ -597,11 +606,12 @@ export class SystemKeywords { * @example value = GET "file.xlsx", "A2" * */ - public async get(file: string, addressOrHeaders: string, httpUsername, httpPs, qs, streaming): Promise { + public async get({file, addressOrHeaders, httpUsername, httpPs, qs, streaming}): Promise { if (file.startsWith('http')) { - return await this.getByHttp(file, addressOrHeaders, httpUsername, httpPs, qs, streaming); + return await this.getByHttp({url:file, headers: addressOrHeaders, username: httpUsername, + ps: httpPs, qs, streaming}); } else { GBLog.info(`BASIC: GET '${addressOrHeaders}' in '${file}'.`); @@ -627,7 +637,7 @@ export class SystemKeywords { } } - public isValidDate(dt) { + public isValidDate({dt}) { const contentLocale = this.min.core.getParam( this.min.instance, 'Default Content Language', @@ -646,12 +656,12 @@ export class SystemKeywords { return !isNaN(date.valueOf()); } - public isValidNumber(number) { + public isValidNumber({number}) { if (number === '') { return false } return !isNaN(number); } - public isValidHour(value) { + public isValidHour({value}) { return /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/.test(value); } @@ -671,7 +681,9 @@ export class SystemKeywords { * * // TODO: https://www.npmjs.com/package/parse-markdown-table */ - public async find(file: string, ...args): Promise { + public async find({args}): Promise { + const file = args[0]; + args.shift(); GBLog.info(`BASIC: FIND running on ${file} and args: ${JSON.stringify(args)}...`); const botId = this.min.instance.botId; @@ -1051,7 +1063,7 @@ export class SystemKeywords { * * @example file = DOWNLOAD element, folder */ - public async download(element, folder) { + public async download({element, folder}) { const page = element['_page']; const container = element['_frame'] ? element['_frame'] : element['_page']; @@ -1142,7 +1154,7 @@ export class SystemKeywords { * @example folder = CREATE FOLDER "notes\01" * */ - public async createFolder(name: string) { + public async createFolder({name}) { let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); const botId = this.min.instance.botId; @@ -1199,7 +1211,7 @@ export class SystemKeywords { * SHARE FOLDER folder, "nome@domain.com", "E-mail message" * */ - public async shareFolder(folderReference, email: string, message: string) { + public async shareFolder({folderReference, email, message}) { let [, client] = await GBDeployer.internalGetDriveClient(this.min); const driveId = folderReference.parentReference.driveId; const itemId = folderReference.id; @@ -1224,7 +1236,7 @@ export class SystemKeywords { * COPY "template.xlsx", "reports\" + customerName + "\final.xlsx" * */ - public async copyFile(src, dest) { + public async copyFile({src, dest}) { GBLog.info(`BASIC: BEGINING COPY '${src}' to '${dest}'`); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); const botId = this.min.instance.botId; @@ -1293,7 +1305,7 @@ export class SystemKeywords { * CONVERT "customers.xlsx" TO "reports\" + today + ".pdf" * */ - public async convert(src, dest) { + public async convert({src, dest}) { GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); const botId = this.min.instance.botId; @@ -1375,7 +1387,7 @@ export class SystemKeywords { * @example user = get "http://server/users/1" * */ - public async getByHttp(url: string, headers: any, username: string, ps: string, qs: any, streaming = false) { + public async getByHttp({url, headers, username, ps, qs, streaming}) { let options = { url: url }; if (headers) { options['headers'] = headers; @@ -1415,7 +1427,7 @@ export class SystemKeywords { * talk "The updated user area is" + user.area * */ - public async putByHttp(url: string, data, headers) { + public async putByHttp({url, data, headers}) { const options = { uri: url, json: data, @@ -1436,7 +1448,7 @@ export class SystemKeywords { * talk "The updated user area is" + user.area * */ - public async postByHttp(url: string, data, headers) { + public async postByHttp({url, data, headers}) { const options = { uri: url, json: data, @@ -1460,7 +1472,7 @@ export class SystemKeywords { * doc = FILL "templates/template.docx", data * */ - public async fill(templateName, data) { + public async fill({templateName, data}) { const botId = this.min.instance.botId; const gbaiName = `${botId}.gbai`; @@ -1555,7 +1567,7 @@ export class SystemKeywords { * MERGE "second.xlsx" WITH data BY customer_id * */ - public async merge(file: string, data: [], key1, key2): Promise { + public async merge({file, data, key1, key2}): Promise { GBLog.info(`BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`); const botId = this.min.instance.botId; @@ -1658,19 +1670,19 @@ export class SystemKeywords { if (value !== found[columnName]) { - await this.set(file, address, value); + await this.set({file, address, value}); merges++; } } } else { - let args = []; + let args = [file]; let keys = Object.keys(row); for (let j = 0; j < keys.length; j++) { args.push(row[keys[j]]); } - await this.save(file, ...args); + await this.save({args}); adds++; } } @@ -1684,7 +1696,7 @@ export class SystemKeywords { } } - public async tweet(text: string) { + public async tweet({text}) { const consumer_key = this.min.core.getParam(this.min.instance, 'Twitter Consumer Key', null); const consumer_secret = this.min.core.getParam(this.min.instance, 'Twitter Consumer Key Secret', null); @@ -1704,7 +1716,5 @@ export class SystemKeywords { await client.v2.tweet(text); GBLog.info(`Twitter Automation: ${text}.`); - } - } diff --git a/packages/basic.gblib/services/TSCompiler.ts b/packages/basic.gblib/services/TSCompiler.ts index db1e26bb..34964260 100644 --- a/packages/basic.gblib/services/TSCompiler.ts +++ b/packages/basic.gblib/services/TSCompiler.ts @@ -66,7 +66,7 @@ export class TSCompiler { noImplicitUseStrict: true, noEmitOnError: false, noImplicitAny: true, - target: ts.ScriptTarget.ES5, + target: ts.ScriptTarget.ESNext, module: ts.ModuleKind.None, moduleResolution: ts.ModuleResolutionKind.Classic, noEmitHelpers: true, diff --git a/packages/basic.gblib/services/vm2-process/vm2ProcessRunner.ts b/packages/basic.gblib/services/vm2-process/vm2ProcessRunner.ts index 51c8bdec..5f32f6c6 100644 --- a/packages/basic.gblib/services/vm2-process/vm2ProcessRunner.ts +++ b/packages/basic.gblib/services/vm2-process/vm2ProcessRunner.ts @@ -36,10 +36,10 @@ const server = net1.createServer((socket) => { }); console.log(JSON.stringify({ result })); - debugger; socket.write(JSON.stringify({ result }) + '\n'); socket.end(); } catch (error) { + console.log(`BASIC: RUNTIME: ${error.message}, ${error.stack}`) socket.write(JSON.stringify({ error: error.message }) + '\n'); socket.end(); }