new(all): Vm isolated working with IPC BASIC 3.0;

This commit is contained in:
rodrigorodriguez 2022-11-02 19:40:59 -03:00
parent 45f4a48f88
commit 4bbd384501
5 changed files with 335 additions and 320 deletions

View file

@ -141,7 +141,7 @@ export class DialogKeywords {
* *
* @example x = GET PAGE * @example x = GET PAGE
*/ */
public async getPage(url, username, password) { public async getPage({url, username, password}) {
GBLog.info(`BASIC: Web Automation GET PAGE ${url}.`); GBLog.info(`BASIC: Web Automation GET PAGE ${url}.`);
if (!this.browser) { if (!this.browser) {
this.browser = await createBrowser(null); this.browser = await createBrowser(null);
@ -167,7 +167,7 @@ export class DialogKeywords {
* @param legends * @param legends
* @see https://www.npmjs.com/package/plot * @see https://www.npmjs.com/package/plot
*/ */
public async chart(type, data, legends, transpose) { public async chart({type, data, legends, transpose}) {
let table = [[]]; let table = [[]];
@ -246,18 +246,18 @@ export class DialogKeywords {
/** /**
* Find element on page DOM. * Find element on page DOM.
* *
* @example GET page, "elementName" * @example GET page,"selector"
*/ */
public async getBySelector(page, elementName) { public async getBySelector({page, selector}) {
GBLog.info(`BASIC: Web Automation GET element: ${elementName}.`); GBLog.info(`BASIC: Web Automation GET element: ${selector}.`);
await page.waitForSelector(elementName) await page.waitForSelector(selector)
let elements = await page.$$(elementName); let elements = await page.$$(selector);
if (elements && elements.length > 1) { if (elements && elements.length > 1) {
return elements; return elements;
} }
else { else {
const el = elements[0]; const el = elements[0];
el['originalSelector'] = elementName; el['originalSelector'] = selector;
el['href'] = await page.evaluate(e => e.getAttribute('href'), el); el['href'] = await page.evaluate(e => e.getAttribute('href'), el);
el['value'] = await page.evaluate(e => e.getAttribute('value'), el); el['value'] = await page.evaluate(e => e.getAttribute('value'), el);
el['name'] = await page.evaluate(e => e.getAttribute('name'), el); el['name'] = await page.evaluate(e => e.getAttribute('name'), el);
@ -271,7 +271,7 @@ export class DialogKeywords {
* *
* @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}.`); GBLog.info(`BASIC: Web Automation GET element by frame: ${selector}.`);
await page.waitForSelector(frame) await page.waitForSelector(frame)
let frameHandle = await page.$(frame); let frameHandle = await page.$(frame);
@ -290,10 +290,10 @@ export class DialogKeywords {
/** /**
* Simulates a mouse hover an web page element. * Simulates a mouse hover an web page element.
*/ */
public async hover(page, idOrName) { public async hover({page, selector}) {
GBLog.info(`BASIC: Web Automation HOVER element: ${idOrName}.`); GBLog.info(`BASIC: Web Automation HOVER element: ${selector}.`);
await this.getBySelector(page, idOrName); await this.getBySelector({page, selector: selector});
await page.hover(idOrName); await page.hover(selector);
await this.debugStepWeb(page); await this.debugStepWeb(page);
} }
@ -302,7 +302,7 @@ export class DialogKeywords {
* *
* @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}.`); GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (selector) { if (selector) {
await page.waitForSelector(frameOrSelector) await page.waitForSelector(frameOrSelector)
@ -326,9 +326,10 @@ export class DialogKeywords {
} }
if (this.debugWeb && refresh) { if (this.debugWeb && refresh) {
const adminNumber = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null); const mobile = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null);
if (adminNumber) { const filename = page;
await this.sendFileTo(adminNumber, page, "General Bots Debugger"); if (mobile) {
await this.sendFileTo({mobile , filename, caption:"General Bots Debugger"});
} }
this.lastDebugWeb = new Date(); this.lastDebugWeb = new Date();
} }
@ -339,7 +340,7 @@ export class DialogKeywords {
* *
* @example PRESS ENTER ON page * @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}.`); GBLog.info(`BASIC: Web Automation PRESS ${char} ON element: ${frame}.`);
if (char.toLowerCase() === "enter") { if (char.toLowerCase() === "enter") {
char = '\n'; char = '\n';
@ -355,7 +356,7 @@ 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}.`); GBLog.info(`BASIC: Web Automation CLICK LINK TEXT: ${text} ${index}.`);
if (!index) { if (!index) {
index = 1 index = 1
@ -372,8 +373,8 @@ export class DialogKeywords {
* *
* @example file = SCREENSHOT page * @example file = SCREENSHOT page
*/ */
public async screenshot(page, idOrName) { public async screenshot({page, selector}) {
GBLog.info(`BASIC: Web Automation SCREENSHOT ${idOrName}.`); GBLog.info(`BASIC: Web Automation SCREENSHOT ${selector}.`);
const gbaiName = `${this.min.botId}.gbai`; const gbaiName = `${this.min.botId}.gbai`;
const localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`); 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. * Types the text into the text field.
* *
* @example SET page, "elementName", "text" * @example SET page,"selector","text"
*/ */
public async setElementText(page, idOrName, text) { public async setElementText({page, selector, text}) {
GBLog.info(`BASIC: Web Automation TYPE on ${idOrName}: ${text}.`); GBLog.info(`BASIC: Web Automation TYPE on ${selector}: ${text}.`);
const e = await this.getBySelector(page, idOrName); const e = await this.getBySelector({page, selector});
await e.click({ clickCount: 3 }); await e.click({ clickCount: 3 });
await page.keyboard.press('Backspace'); await page.keyboard.press('Backspace');
await e.type(text, { delay: 200 }); await e.type(text, { delay: 200 });
@ -410,7 +411,7 @@ export class DialogKeywords {
* Returns the OCR of image file. * Returns the OCR of image file.
* *
*/ */
public async getOCR(localFile) { public async getOCR({localFile}) {
GBLog.info(`BASIC: OCR processing on ${localFile}.`); GBLog.info(`BASIC: OCR processing on ${localFile}.`);
const tesseract = require("node-tesseract-ocr") const tesseract = require("node-tesseract-ocr")
@ -428,7 +429,7 @@ export class DialogKeywords {
* *
* @example x = TODAY * @example x = TODAY
*/ */
public async getToday() { public async getToday({}) {
let d = new Date(), let d = new Date(),
month = '' + (d.getMonth() + 1), month = '' + (d.getMonth() + 1),
day = '' + d.getDate(), day = '' + d.getDate(),
@ -460,7 +461,7 @@ export class DialogKeywords {
* *
* @example EXIT * @example EXIT
*/ */
public async exit() { public async exit({}) {
} }
@ -469,7 +470,7 @@ export class DialogKeywords {
* *
* @example list = ACTIVE TASKS * @example list = ACTIVE TASKS
*/ */
public async getActiveTasks() { public async getActiveTasks({}) {
let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY); let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY);
return await s.getActiveTasks(); return await s.getActiveTasks();
} }
@ -479,7 +480,7 @@ export class DialogKeywords {
* *
* @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 s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY);
let deal = await s.createDeal(dealName, contact, company, amount); let deal = await s.createDeal(dealName, contact, company, amount);
return deal; return deal;
@ -490,7 +491,7 @@ export class DialogKeywords {
* *
* @example list = FIND CONTACT "Sandra" * @example list = FIND CONTACT "Sandra"
*/ */
public async fndContact(name) { public async fndContact({name}) {
let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY); let s = new HubSpotServices(null, null, process.env.HUBSPOT_KEY);
return await s.searchContact(name); 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. // Checks if it is a GB FILE object.
@ -665,7 +666,7 @@ export class DialogKeywords {
* @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<string>( const contentLocale = this.min.core.getParam<string>(
this.min.instance, this.min.instance,
'Default Content Language', 'Default Content Language',
@ -692,7 +693,7 @@ export class DialogKeywords {
* 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 // tslint:disable-next-line:no-console
@ -732,9 +733,9 @@ export class DialogKeywords {
* @example SEND FILE TO "+199988887777","image.jpg",caption * @example SEND FILE TO "+199988887777","image.jpg",caption
* *
*/ */
public async sendFileTo(mobile, filename, caption) { public async sendFileTo({mobile, filename, caption}) {
GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`); GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`);
return await this.internalSendFile(mobile, filename, caption); return await this.internalSendFile({mobile, filename, caption});
} }
/** /**
@ -743,10 +744,10 @@ export class DialogKeywords {
* @example SEND FILE "image.jpg" * @example SEND FILE "image.jpg"
* *
*/ */
public async sendFile(filename, caption) { public async sendFile({filename, caption}) {
const mobile = await this.userMobile(); const mobile = await this.userMobile();
GBLog.info(`BASIC: SEND FILE (current: ${mobile},filename '${filename}'.`); GBLog.info(`BASIC: SEND FILE (current: ${mobile},filename '${filename}'.`);
return await this.internalSendFile(mobile, filename, caption); return await this.internalSendFile({mobile, filename, caption});
} }
/** /**
@ -755,7 +756,7 @@ export class DialogKeywords {
* @example SET LANGUAGE "pt" * @example SET LANGUAGE "pt"
* *
*/ */
public async setLanguage(language) { public async setLanguage({language}) {
const sec = new SecService(); const sec = new SecService();
await sec.updateUserLocale(this.user.userId, language); await sec.updateUserLocale(this.user.userId, language);
} }
@ -766,7 +767,7 @@ export class DialogKeywords {
* @example SET ID NUMBER * @example SET ID NUMBER
* *
*/ */
public async setIdGeneration(mode) { public async setIdGeneration({mode}) {
this['idGeneration'] = mode; this['idGeneration'] = mode;
this['id'] = await this.sys().getRandomId(); this['id'] = await this.sys().getRandomId();
} }
@ -777,7 +778,7 @@ export class DialogKeywords {
* @example SET MAX LINES 5000 * @example SET MAX LINES 5000
* *
*/ */
public async setMaxLines(count) { public async setMaxLines({count}) {
if (this.user) { if (this.user) {
// TODO: PARAM user.basicOptions.maxLines = count; // TODO: PARAM user.basicOptions.maxLines = count;
} }
@ -793,7 +794,7 @@ export class DialogKeywords {
* @example SET MAX COLUMNS 5000 * @example SET MAX COLUMNS 5000
* *
*/ */
public async setMaxColumns(count) { public async setMaxColumns({count}) {
// TODO: user.basicOptions.maxColumns = count; // TODO: user.basicOptions.maxColumns = count;
} }
@ -805,7 +806,7 @@ export class DialogKeywords {
* @example SET WHOLE WORD ON * @example SET WHOLE WORD ON
* *
*/ */
public async setWholeWord(on) { public async setWholeWord({on}) {
// TODO: user.basicOptions.wholeWord = (on.trim() === "on"); // TODO: user.basicOptions.wholeWord = (on.trim() === "on");
} }
@ -815,7 +816,7 @@ export class DialogKeywords {
* @example SET THEME "themename" * @example SET THEME "themename"
* *
*/ */
public async setTheme(theme) { public async setTheme({theme}) {
// TODO: user.basicOptions.theme = theme.trim(); // TODO: user.basicOptions.theme = theme.trim();
} }
@ -825,7 +826,7 @@ export class DialogKeywords {
* @example SET TRANSLATOR ON | OFF * @example SET TRANSLATOR ON | OFF
* *
*/ */
public async setTranslatorOn(on) { public async setTranslatorOn({on}) {
// TODO: user.basicOptions.translatorOn = (on.trim() === "on"); // TODO: user.basicOptions.translatorOn = (on.trim() === "on");
} }
@ -853,7 +854,7 @@ export class DialogKeywords {
* @example MENU * @example MENU
* *
*/ */
public async showMenu() { public async showMenu({}) {
// TODO: return await beginDialog('/menu'); // TODO: return await beginDialog('/menu');
} }
private static async downloadAttachmentAndWrite(attachment) { private static async downloadAttachmentAndWrite(attachment) {
@ -906,7 +907,7 @@ export class DialogKeywords {
* @example TRANSFER * @example TRANSFER
* *
*/ */
public async transferTo(to: string = null) { public async transferTo({to}) {
// TODO: return await beginDialog('/t',{ to: to }); // TODO: return await beginDialog('/t',{ to: to });
} }
@ -916,7 +917,15 @@ export class DialogKeywords {
* @example HEAR name * @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 { try {
@ -942,15 +951,16 @@ export class DialogKeywords {
let choices = []; let choices = [];
let i = 0; let i = 0;
args.forEach(arg => { await CollectionUtil.asyncForEach(args, async arg => {
i++; 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 { else {
@ -1019,8 +1029,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null) { if (value === null) {
await this.talk("Por favor, digite um e-mail válido."); await this.talk({text: "Por favor,digite um e-mail válido."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1034,8 +1044,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite um nome válido."); await this.talk({text:"Por favor,digite um nome válido."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1049,8 +1059,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite um número válido."); await this.talk({text:"Por favor,digite um número válido."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1063,8 +1073,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite uma data no formato 12/12/2020."); await this.talk({text:"Por favor,digite uma data no formato 12/12/2020."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1078,8 +1088,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite um horário no formato hh:ss."); await this.talk({text:"Por favor,digite um horário no formato hh:ss."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1099,8 +1109,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite um valor monetário."); await this.talk({text:"Por favor,digite um valor monetário."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value; result = value;
@ -1114,11 +1124,11 @@ export class DialogKeywords {
} catch (error) { } catch (error) {
await this.talk(Messages[locale].validation_enter_valid_mobile); 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)) { if (!phoneUtil.isPossibleNumber(phoneNumber)) {
await this.talk("Por favor, digite um número de telefone válido."); await this.talk({text:"Por favor,digite um número de telefone válido."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = phoneNumber; result = phoneNumber;
@ -1141,8 +1151,8 @@ export class DialogKeywords {
const value = extractEntity(text); const value = extractEntity(text);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk("Por favor, digite um valor monetário."); await this.talk({text:"Por favor, digite um CEP válido."});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
result = value[0]; result = value[0];
@ -1159,8 +1169,8 @@ export class DialogKeywords {
}); });
if (result === null) { if (result === null) {
await this.talk(`Escolha por favor um dos itens sugeridos.`); await this.talk({text:`Escolha por favor um dos itens sugeridos.`});
return await this.hear(kind, args); return await this.getHear({kind, arg});
} }
} }
else if (kind === "language") { else if (kind === "language") {
@ -1184,8 +1194,6 @@ export class DialogKeywords {
]; ];
// TODO: const text = step.context.activity['originalText'];
await CollectionUtil.asyncForEach(list, async item => { await CollectionUtil.asyncForEach(list, async item => {
if (GBConversationalService.kmpSearch(text.toLowerCase(), item.name.toLowerCase()) != -1 || if (GBConversationalService.kmpSearch(text.toLowerCase(), item.name.toLowerCase()) != -1 ||
GBConversationalService.kmpSearch(text.toLowerCase(), item.code.toLowerCase()) != -1) { GBConversationalService.kmpSearch(text.toLowerCase(), item.code.toLowerCase()) != -1) {
@ -1194,9 +1202,8 @@ export class DialogKeywords {
}); });
if (result === null) { if (result === null) {
// TODO: await this.talk({text:`Escolha por favor um dos itens sugeridos.`});
await this.min.conversationalService.sendText(this.min, null, `Escolha por favor um dos idiomas sugeridos.`); return await this.getHear({kind, arg});
return await this.hear(kind, args);
} }
} }
return result; return result;
@ -1208,7 +1215,7 @@ export class DialogKeywords {
/** /**
* Prepares the next dialog to be shown to the specified user. * 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) {
if (dialogName.charAt(0) === '/') { if (dialogName.charAt(0) === '/') {
// TODO: await step.beginDialog(fromOrDialogName); // TODO: await step.beginDialog(fromOrDialogName);
@ -1227,7 +1234,7 @@ export class DialogKeywords {
} }
} }
public async getSingleton() { public async getSingleton({}) {
return { return {
id: this.sys().getRandomId(), id: this.sys().getRandomId(),
username: this.userName(), username: this.userName(),
@ -1245,7 +1252,7 @@ export class DialogKeywords {
/** /**
* Talks to the user by using the specified text. * Talks to the user by using the specified text.
*/ */
public async talk(text: string) { public async talk({text}) {
GBLog.info(`BASIC: TALK '${text}'.`); GBLog.info(`BASIC: TALK '${text}'.`);
if (this.user) { if (this.user) {
const translate = this.user ? this.user.basicOptions.translatorOn : false; const translate = this.user ? this.user.basicOptions.translatorOn : false;
@ -1264,7 +1271,7 @@ export class DialogKeywords {
/** /**
* Processes the sending of the file. * 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.
@ -1319,7 +1326,7 @@ export class DialogKeywords {
} }
} }
public async getQRCode(text) { public async getQRCode({text}) {
const img = await qrcode.toDataURL(text); const img = await qrcode.toDataURL(text);
const data = img.replace(/^data:image\/\w+;base64,/, ""); const data = img.replace(/^data:image\/\w+;base64,/, "");
const buf = Buffer.from(data, "base64"); const buf = Buffer.from(data, "base64");

View file

@ -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) { public static getMethodNameFromVBSFilename(filename: string) {
let mainName = filename.replace(/\s|\-/gi, '').split('.')[0]; let mainName = filename.replace(/\s|\-/gi, '').split('.')[0];
return mainName.toLowerCase(); 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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, () => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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) => { 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`; return `await sys.saveFile(${$2}, ${$1})\n`;
}); });
code = code.replace(/(save)(\s)(.*)/gi, ($0, $1, $2, $3) => { 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) => { code = code.replace(/set\s(.*)/gi, ($0, $1, $2) => {
@ -562,137 +680,17 @@ export class GBVMService extends GBService {
return code; 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. * 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 // Creates a class DialogKeywords which is the *this* pointer
// in BASIC. // in BASIC.
const user = step ? await min.userProfile.get(step.context, {}) : null; 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<string>( const contentLocale = min.core.getParam<string>(
min.instance, min.instance,

View file

@ -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); return await GBVMService.callVM(text, min, step, deployer);
} }
public async append(...args) { public async append({args}) {
let array = [].concat(...args); let array = [].concat(...args);
return array.filter(function (item, pos) { return item; }); return array.filter(function (item, pos) { return item; });
} }
@ -107,7 +113,7 @@ export class SystemKeywords {
* @example SEE CAPTION OF url AS variable * @example SEE CAPTION OF url AS variable
* *
*/ */
public async seeCaption(url) { public async seeCaption({url}) {
const computerVisionClient = new ComputerVisionClient( const computerVisionClient = new ComputerVisionClient(
new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }), new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }),
process.env.VISION_ENDPOINT); process.env.VISION_ENDPOINT);
@ -135,7 +141,7 @@ export class SystemKeywords {
* @example SEE TEXT OF url AS variable * @example SEE TEXT OF url AS variable
* *
*/ */
public async seeText(url) { public async seeText({url}) {
const computerVisionClient = new ComputerVisionClient( const computerVisionClient = new ComputerVisionClient(
new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }), new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }),
process.env.VISION_ENDPOINT); process.env.VISION_ENDPOINT);
@ -160,7 +166,7 @@ export class SystemKeywords {
return final; return final;
} }
public async sortBy(array, memberName) { public async sortBy({array, memberName}) {
memberName = memberName.trim(); memberName = memberName.trim();
const contentLocale = this.min.core.getParam<string>( const contentLocale = this.min.core.getParam<string>(
this.min.instance, this.min.instance,
@ -345,18 +351,18 @@ export class SystemKeywords {
return [url, localName]; return [url, localName];
} }
public async asPDF(data, filename) { public async asPDF({data, filename}) {
let file = await this.renderTable(data, true, false); let file = await this.renderTable(data, true, false);
return file[0]; return file[0];
} }
public async asImage(data, filename) { public async asImage({data, filename}) {
let file = await this.renderTable(data, false, true); let file = await this.renderTable(data, false, true);
return file[0]; return file[0];
} }
public async executeSQL(data, sql, tableName) { public async executeSQL({data, sql, tableName}) {
let objectMode = false; let objectMode = false;
if (Object.keys(data[0])) { if (Object.keys(data[0])) {
@ -377,7 +383,7 @@ export class SystemKeywords {
/** /**
* Retrives the content of a given URL. * Retrives the content of a given URL.
*/ */
public async getFileContents(url, headers) { public async getFileContents({url, headers}) {
const options = { const options = {
url: url, url: url,
method: 'GET', method: 'GET',
@ -405,7 +411,7 @@ export class SystemKeywords {
/** /**
* Retrives stock inforation for a given symbol. * Retrives stock inforation for a given symbol.
*/ */
public async getStock(symbol) { public async getStock({symbol}) {
var options = { var options = {
uri: `http://live-nse.herokuapp.com/?symbol=${symbol}` uri: `http://live-nse.herokuapp.com/?symbol=${symbol}`
}; };
@ -421,7 +427,7 @@ export class SystemKeywords {
* @example WAIT 5 ' This will wait five seconds. * @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 // tslint:disable-next-line no-string-based-set-timeout
GBLog.info(`BASIC: WAIT for ${seconds} second(s).`); GBLog.info(`BASIC: WAIT for ${seconds} second(s).`);
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); 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" * @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). `); GBLog.info(`BASIC: Talking '${message}' to a specific user (${mobile}) (TALK TO). `);
await this.min.conversationalService.sendMarkdownToMobile(this.min, null, mobile, message); 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" * @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}'.`); GBLog.info(`BASIC: SEND SMS TO '${mobile}', message '${message}'.`);
await this.min.conversationalService.sendSms(this.min, mobile, message); await this.min.conversationalService.sendSms(this.min, mobile, message);
} }
@ -459,13 +465,14 @@ export class SystemKeywords {
* @example SET page, "elementHTMLSelector", "text" * @example SET page, "elementHTMLSelector", "text"
* *
*/ */
public async set(file: any, address: string, value: any): Promise<any> { public async set({file, address, value}): Promise<any> {
// Handles calls for HTML stuff // Handles calls for HTML stuff
if (file._javascriptEnabled) { if (file._javascriptEnabled) {
GBLog.info(`BASIC: Web automation setting ${file}' to '${value}' (SET). `); const page = file;
await this.dk.setElementText(file, address, value); GBLog.info(`BASIC: Web automation setting ${page}' to '${value}' (SET). `);
await this.dk.setElementText({page, selector: address, text: value});
return; return;
} }
@ -520,7 +527,7 @@ export class SystemKeywords {
* @exaple SAVE variable as "my.txt" * @exaple SAVE variable as "my.txt"
* *
*/ */
public async saveFile(file: any, data: any): Promise<any> { public async saveFile({file, data}): Promise<any> {
GBLog.info(`BASIC: Saving '${file}' (SAVE file).`); GBLog.info(`BASIC: Saving '${file}' (SAVE file).`);
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); 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 * @exaple SAVE "customers.xlsx", name, email, phone, address, city, state, country
* *
*/ */
public async save(file: string, ...args): Promise<any> { public async save({args}): Promise<any> {
const file = args[0];
args.shift();
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`); GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -597,11 +606,12 @@ export class SystemKeywords {
* @example value = GET "file.xlsx", "A2" * @example value = GET "file.xlsx", "A2"
* *
*/ */
public async get(file: string, addressOrHeaders: string, httpUsername, httpPs, qs, streaming): Promise<any> { public async get({file, addressOrHeaders, httpUsername, httpPs, qs, streaming}): Promise<any> {
if (file.startsWith('http')) { 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 { else {
GBLog.info(`BASIC: GET '${addressOrHeaders}' in '${file}'.`); 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<string>( const contentLocale = this.min.core.getParam<string>(
this.min.instance, this.min.instance,
'Default Content Language', 'Default Content Language',
@ -646,12 +656,12 @@ export class SystemKeywords {
return !isNaN(date.valueOf()); return !isNaN(date.valueOf());
} }
public isValidNumber(number) { public isValidNumber({number}) {
if (number === '') { return false } if (number === '') { return false }
return !isNaN(number); return !isNaN(number);
} }
public isValidHour(value) { public isValidHour({value}) {
return /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/.test(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 * // TODO: https://www.npmjs.com/package/parse-markdown-table
*/ */
public async find(file: string, ...args): Promise<any> { public async find({args}): Promise<any> {
const file = args[0];
args.shift();
GBLog.info(`BASIC: FIND running on ${file} and args: ${JSON.stringify(args)}...`); GBLog.info(`BASIC: FIND running on ${file} and args: ${JSON.stringify(args)}...`);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -1051,7 +1063,7 @@ export class SystemKeywords {
* *
* @example file = DOWNLOAD element, folder * @example file = DOWNLOAD element, folder
*/ */
public async download(element, folder) { public async download({element, folder}) {
const page = element['_page']; const page = element['_page'];
const container = element['_frame'] ? element['_frame'] : element['_page']; const container = element['_frame'] ? element['_frame'] : element['_page'];
@ -1142,7 +1154,7 @@ export class SystemKeywords {
* @example folder = CREATE FOLDER "notes\01" * @example folder = CREATE FOLDER "notes\01"
* *
*/ */
public async createFolder(name: string) { public async createFolder({name}) {
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -1199,7 +1211,7 @@ export class SystemKeywords {
* SHARE FOLDER folder, "nome@domain.com", "E-mail message" * 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); let [, client] = await GBDeployer.internalGetDriveClient(this.min);
const driveId = folderReference.parentReference.driveId; const driveId = folderReference.parentReference.driveId;
const itemId = folderReference.id; const itemId = folderReference.id;
@ -1224,7 +1236,7 @@ export class SystemKeywords {
* COPY "template.xlsx", "reports\" + customerName + "\final.xlsx" * 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}'`); GBLog.info(`BASIC: BEGINING COPY '${src}' to '${dest}'`);
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -1293,7 +1305,7 @@ export class SystemKeywords {
* CONVERT "customers.xlsx" TO "reports\" + today + ".pdf" * CONVERT "customers.xlsx" TO "reports\" + today + ".pdf"
* *
*/ */
public async convert(src, dest) { public async convert({src, dest}) {
GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`); GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`);
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min); let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -1375,7 +1387,7 @@ export class SystemKeywords {
* @example user = get "http://server/users/1" * @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 }; let options = { url: url };
if (headers) { if (headers) {
options['headers'] = headers; options['headers'] = headers;
@ -1415,7 +1427,7 @@ export class SystemKeywords {
* talk "The updated user area is" + user.area * talk "The updated user area is" + user.area
* *
*/ */
public async putByHttp(url: string, data, headers) { public async putByHttp({url, data, headers}) {
const options = { const options = {
uri: url, uri: url,
json: data, json: data,
@ -1436,7 +1448,7 @@ export class SystemKeywords {
* talk "The updated user area is" + user.area * talk "The updated user area is" + user.area
* *
*/ */
public async postByHttp(url: string, data, headers) { public async postByHttp({url, data, headers}) {
const options = { const options = {
uri: url, uri: url,
json: data, json: data,
@ -1460,7 +1472,7 @@ export class SystemKeywords {
* doc = FILL "templates/template.docx", data * doc = FILL "templates/template.docx", data
* *
*/ */
public async fill(templateName, data) { public async fill({templateName, data}) {
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
const gbaiName = `${botId}.gbai`; const gbaiName = `${botId}.gbai`;
@ -1555,7 +1567,7 @@ export class SystemKeywords {
* MERGE "second.xlsx" WITH data BY customer_id * MERGE "second.xlsx" WITH data BY customer_id
* *
*/ */
public async merge(file: string, data: [], key1, key2): Promise<any> { public async merge({file, data, key1, key2}): Promise<any> {
GBLog.info(`BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`); GBLog.info(`BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`);
const botId = this.min.instance.botId; const botId = this.min.instance.botId;
@ -1658,19 +1670,19 @@ export class SystemKeywords {
if (value !== found[columnName]) { if (value !== found[columnName]) {
await this.set(file, address, value); await this.set({file, address, value});
merges++; merges++;
} }
} }
} }
else { else {
let args = []; let args = [file];
let keys = Object.keys(row); let keys = Object.keys(row);
for (let j = 0; j < keys.length; j++) { for (let j = 0; j < keys.length; j++) {
args.push(row[keys[j]]); args.push(row[keys[j]]);
} }
await this.save(file, ...args); await this.save({args});
adds++; 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_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); 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); await client.v2.tweet(text);
GBLog.info(`Twitter Automation: ${text}.`); GBLog.info(`Twitter Automation: ${text}.`);
} }
} }

View file

@ -66,7 +66,7 @@ export class TSCompiler {
noImplicitUseStrict: true, noImplicitUseStrict: true,
noEmitOnError: false, noEmitOnError: false,
noImplicitAny: true, noImplicitAny: true,
target: ts.ScriptTarget.ES5, target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.None, module: ts.ModuleKind.None,
moduleResolution: ts.ModuleResolutionKind.Classic, moduleResolution: ts.ModuleResolutionKind.Classic,
noEmitHelpers: true, noEmitHelpers: true,

View file

@ -36,10 +36,10 @@ const server = net1.createServer((socket) => {
}); });
console.log(JSON.stringify({ result })); console.log(JSON.stringify({ result }));
debugger;
socket.write(JSON.stringify({ result }) + '\n'); socket.write(JSON.stringify({ result }) + '\n');
socket.end(); socket.end();
} catch (error) { } catch (error) {
console.log(`BASIC: RUNTIME: ${error.message}, ${error.stack}`)
socket.write(JSON.stringify({ error: error.message }) + '\n'); socket.write(JSON.stringify({ error: error.message }) + '\n');
socket.end(); socket.end();
} }