From 45f4a48f8852e45b87cdeee3fc1d1b1bc4b63fe6 Mon Sep 17 00:00:00 2001 From: rodrigorodriguez Date: Wed, 2 Nov 2022 16:03:25 -0300 Subject: [PATCH] new(all): Vm isolated working with IPC BASIC 3.0; --- packages/basic.gblib/index.ts | 8 +- .../basic.gblib/services/DialogKeywords.ts | 21 +- packages/basic.gblib/services/GBVMService.ts | 425 +++++++----------- 3 files changed, 198 insertions(+), 256 deletions(-) diff --git a/packages/basic.gblib/index.ts b/packages/basic.gblib/index.ts index c73db920..4944176f 100644 --- a/packages/basic.gblib/index.ts +++ b/packages/basic.gblib/index.ts @@ -43,6 +43,7 @@ import { createServerRouter } from "typescript-rest-rpc/lib/server" import { DialogKeywords } from './services/DialogKeywords'; const Koa = require('koa'); import * as koaBody from "koa-body" +import { SystemKeywords } from './services/SystemKeywords'; const app = new Koa() /** @@ -76,8 +77,11 @@ export class GBBasicPackage implements IGBPackage { GBLog.verbose(`onExchangeData called.`); } public async loadBot(min: GBMinInstance): Promise { - const backendRouter = createServerRouter(`/api/v2/${min.botId}/dialog`, new DialogKeywords(min, null, null)); - app.use(backendRouter.routes()); + const dk = new DialogKeywords(min, null, null); + const dialogRouter = createServerRouter(`/api/v2/${min.botId}/dialog`, dk); + const sysRouter = createServerRouter(`/api/v2/${min.botId}/system`, new SystemKeywords(min, null, dk)); + app.use(dialogRouter.routes()); + app.use(sysRouter.routes()); } } diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index 0ff6ae98..fc39def4 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -407,9 +407,8 @@ export class DialogKeywords { } /** - * Returns the today data filled in dd/mm/yyyy or mm/dd/yyyy. + * Returns the OCR of image file. * - * @example x = TODAY */ public async getOCR(localFile) { GBLog.info(`BASIC: OCR processing on ${localFile}.`); @@ -511,7 +510,7 @@ export class DialogKeywords { } - public getCoded(value) { + public async getCoded(value) { // Checks if it is a GB FILE object. @@ -837,6 +836,7 @@ export class DialogKeywords { */ public async userName() { // TODO: WhatsappDirectLine.usernames[await this.userMobile()] : 'N/A'; + return this.sys().getRandomId(); } /** @@ -844,6 +844,7 @@ export class DialogKeywords { */ public async userMobile() { // TODO: return GBMinService.userMobile(); + return this.sys().getRandomId(); } /** @@ -1226,6 +1227,20 @@ export class DialogKeywords { } } + public async getSingleton() { + return { + id: this.sys().getRandomId(), + username: this.userName(), + mobile: this.userMobile(), + from: this.userMobile(), + ENTER: String.fromCharCode(13), + headers: {}, + data: {}, + list: [], + httpUsername: "", + httpPs: "" + } + }; /** * Talks to the user by using the specified text. diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index 422dd1e5..a239a80c 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -37,20 +37,20 @@ import * as fs from 'fs'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer'; import { TSCompiler } from './TSCompiler'; import { CollectionUtil } from 'pragmatismo-io-framework'; -const urlJoin = require('url-join'); import { DialogKeywords } from './DialogKeywords'; import { ScheduleServices } from './ScheduleServices'; import { GBConfigService } from '../../core.gbapp/services/GBConfigService'; //tslint:disable-next-line:no-submodule-imports +const urlJoin = require('url-join'); const { NodeVM, VMScript } = require('vm2'); const { createVm2Pool } = require('./vm2-process/index'); - const vb2ts = require('./vbscript-to-typescript'); const beautify = require('js-beautify').js; const textract = require('textract'); const walkPromise = require('walk-promise'); - +const child_process = require('child_process'); const Path = require('path'); + /** * @fileoverview Virtualization services for emulation of BASIC. * This alpha version is using a antipattern hack in form of converter to @@ -106,11 +106,40 @@ export class GBVMService extends GBService { fs.writeFileSync(urlJoin(folder, vbsFile), text); } + // Process node_modules install. + + const node_modules = urlJoin(folder, 'node_modules'); + if (!fs.existsSync(node_modules)) { + const packageJson = ` + { + "name": "${min.botId}.gbdialog", + "version": "1.0.0", + "description": "${min.botId} transpiled .gbdialog", + "author": "${min.botId} owner.", + "license": "ISC", + "dependencies": { + "encoding": "0.1.13", + "isomorphic-fetch": "3.0.0", + "punycode": "2.1.1", + "typescript-rest-rpc": "1.0.10", + "vm2": "3.9.11" + } + }`; + fs.writeFileSync(urlJoin(folder, 'package.json'), packageJson); + + GBLog.info(`BASIC: Installing .gbdialog node_modules for ${min.botId}...`); + const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm'); + child_process.execSync(`${npmPath} install`, { cwd: folder }); + } + + // Hot swap for .vbs files. + const fullFilename = urlJoin(folder, filename); - // TODO: Implement in development mode, how swap for .vbs files - // fs.watchFile(fullFilename, async () => { - // await this.run(fullFilename, min, deployer, mainName); - // }); + if (process.env.GBDIALOG_HOTSWAP) { + fs.watchFile(fullFilename, async () => { + await this.translateBASIC(fullFilename, min, deployer, mainName); + }); + } const compiledAt = fs.statSync(fullFilename); const jsfile = urlJoin(folder, `${filename}.js`); @@ -119,14 +148,14 @@ export class GBVMService extends GBService { const jsStat = fs.statSync(jsfile); const interval = 30000; // If compiled is older 30 seconds, then recompile. if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) { - await this.executeBASIC(fullFilename, min, deployer, mainName); + await this.translateBASIC(fullFilename, min, deployer, mainName); } else { const parsedCode: string = fs.readFileSync(jsfile, 'utf8'); - this.executeJS(min, deployer, parsedCode, mainName); + min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; } } else { - await this.executeBASIC(fullFilename, min, deployer, mainName); + await this.translateBASIC(fullFilename, min, deployer, mainName); } } }); @@ -168,35 +197,17 @@ export class GBVMService extends GBService { * * @param code General Bots BASIC */ - public convertGBASICToVBS(code: string) { + public convertGBASICToVBS(min: GBMinInstance, code: string) { + // Start and End of VB2TS tags of processing. - code = `<%\n - step=dk.step - id = sys().getRandomId() - username = step ? dk.userName(step) : sys().getRandomId(); - mobile = step ? dk.userMobile(step) : sys().getRandomId(); - from = mobile; - ENTER = String.fromCharCode(13); - ubound = function(array){return array.length}; - isarray = function(array){return Array.isArray(array) }; - weekday = dk.getWeekFromDate.bind(dk); - hour = dk.getHourFromDate.bind(dk); - base64 = dk.getCoded; - tolist = dk.getToLst; - headers = {}; - data = {}; - list = []; - httpUsername = ""; - httpPs = ""; + ${process.env.ENABLE_AUTH ? `hear gbLogin as login` : ``} ${code} - - `; // Keywords from General Bots BASIC. @@ -205,126 +216,124 @@ export class GBVMService extends GBService { let tableName = /\sFROM\s(\w+)/.exec($2)[1]; let sql = `SELECT ${$2}`.replace(tableName, '?'); - return `${$1} = sys().executeSQL(${$1}, "${sql}", "${tableName}")\n`; + return `${$1} = await sys.executeSQL(${$1}, "${sql}", "${tableName}")\n`; }); - code = code.replace(/(\w+)\s*\=\s*get html\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = getPage(step, ${$2})\n`; + return `${$1} = await dk.getPage(step, ${$2})\n`; }); + code = code.replace(/(set hear on)(\s*)(.*)/gi, ($0, $1, $2, $3) => { return `hrOn = ${$3}\n`; }); code = code.replace(/hear (\w+) as login/gi, ($0, $1) => { - return `${$1} = hear("login")`; + return `${$1} = await dk.hear("login")`; }); + code = code.replace(/hear (\w+) as email/gi, ($0, $1) => { - return `${$1} = hear("email")`; + return `${$1} = await dk.hear("email")`; }); code = code.replace(/hear (\w+) as integer/gi, ($0, $1, $2) => { - return `${$1} = hear("integer")`; + return `${$1} = await dk.hear("integer")`; }); code = code.replace(/hear (\w+) as file/gi, ($0, $1, $2) => { - return `${$1} = hear("file")`; + return `${$1} = await dk.hear("file")`; }); code = code.replace(/hear (\w+) as boolean/gi, ($0, $1, $2) => { - return `${$1} = hear("boolean")`; + return `${$1} = await dk.hear("boolean")`; }); code = code.replace(/hear (\w+) as name/gi, ($0, $1, $2) => { - return `${$1} = hear("name")`; + return `${$1} = await dk.hear("name")`; }); code = code.replace(/hear (\w+) as date/gi, ($0, $1, $2) => { - return `${$1} = hear("date")`; + return `${$1} = await dk.hear("date")`; }); code = code.replace(/hear (\w+) as hour/gi, ($0, $1, $2) => { - return `${$1} = hear("hour")`; + return `${$1} = await dk.hear("hour")`; }); code = code.replace(/hear (\w+) as phone/gi, ($0, $1, $2) => { - return `${$1} = hear("phone")`; + return `${$1} = await dk.hear("phone")`; }); code = code.replace(/hear (\w+) as money/gi, ($0, $1, $2) => { - return `${$1} = hear("money")`; + return `${$1} = await dk.hear("money")`; }); code = code.replace(/hear (\w+) as language/gi, ($0, $1, $2) => { - return `${$1} = hear("language")`; + return `${$1} = await dk.hear("language")`; }); code = code.replace(/hear (\w+) as zipcode/gi, ($0, $1, $2) => { - return `${$1} = hear("zipcode")`; + return `${$1} = await dk.hear("zipcode")`; }); code = code.replace(/hear (\w+) as (.*)/gi, ($0, $1, $2) => { - return `${$1} = hear("menu", ${$2})`; + return `${$1} = await dk.hear("menu", ${$2})`; }); code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => { - return `${$2} = hear()`; + return `${$2} = await dk.hear()`; }); code = code.replace(/(\w)\s*\=\s*find contact\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = fndContact(${$2})\n`; + return `${$1} = await dk.fndContact(${$2})\n`; }); code = code.replace(/(\w+)\s*=\s*find\s*(.*)\s*or talk\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = sys().find(${$2})\n + return `${$1} = await await sys.find(${$2})\n if (!${$1}) { - if (resolve){ - resolve(); - } - talk (${$3})\n; + await dk.talk (${$3})\n; return -1; } `; }); code = code.replace(/CALL\s*(.*)/gi, ($0, $1, $2, $3) => { - return `sys().callVM("${$1}", dk.getMin(), dk.getStep(), dk.getDeployer())\n`; + return `await sys.callVM("${$1}", dk.getMin(), dk.getStep(), dk.getDeployer())\n`; }); code = code.replace(/(\w)\s*\=\s*find\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = sys().find(${$2})\n`; + return `${$1} = await sys.find(${$2})\n`; }); code = code.replace(/(\w)\s*\=\s*create deal(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} =createDeal(${$3})\n`; + return `${$1} = await dk.createDeal(${$3})\n`; }); code = code.replace(/(\w)\s*\=\s*active tasks/gi, ($0, $1) => { - return `${$1} = getActiveTasks()\n`; + return `${$1} = await dk.getActiveTasks()\n`; }); code = code.replace(/(\w)\s*\=\s*append\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = 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) => { - return `${$1} = sys().sortBy(${$2}, "${$3}")\n`; + return `${$1} = await sys.sortBy(${$2}, "${$3}")\n`; }); code = code.replace(/see\s*text\s*of\s*(\w+)\s*as\s*(\w+)\s*/gi, ($0, $1, $2, $3) => { - return `${$2} = sys().seeText(${$1})\n`; + return `${$2} = await sys.seeText(${$1})\n`; }); code = code.replace(/see\s*caption\s*of\s*(\w+)\s*as(.*)/gi, ($0, $1, $2, $3) => { - return `${$2} = sys().seeCaption(${$1})\n`; + return `${$2} = await sys.seeCaption(${$1})\n`; }); code = code.replace(/(wait)\s*(\d+)/gi, ($0, $1, $2) => { - return `sys().wait(${$2})`; + return `await sys.wait(${$2})`; }); code = code.replace(/(get stock for )(.*)/gi, ($0, $1, $2) => { - return `stock = sys().getStock(${$2})`; + return `stock = await sys.getStock(${$2})`; }); code = code.replace(/(\w+)\s*\=\s*get\s(.*)/gi, ($0, $1, $2, $3) => { @@ -336,21 +345,21 @@ export class GBVMService extends GBService { if (count == 1) { - return `${$1} = this.getBySelector(${values[0]}, ${values[1]} )`; + return `${$1} = await dk.getBySelector(${values[0]}, ${values[1]} )`; } // Handles GET page, "frameSelector", "selector" else if (count == 2) { - return `${$1} = this.getByFrame(${values[0]}, ${values[1]}, ${values[2]} )`; + return `${$1} = await dk.getByFrame(${values[0]}, ${values[1]}, ${values[2]} )`; } // Handles the GET http version. else { - return `${$1} = sys().get (${$2}, headers, httpUsername, httpPs)`; + return `${$1} = await sys.get (${$2}, headers, httpUsername, httpPs)`; } }); @@ -365,11 +374,11 @@ export class GBVMService extends GBService { code = code.replace(/(go to)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `gotoDialog(step, ${$3})\n`; + return `await dk.gotoDialog(step, ${$3})\n`; }); code = code.replace(/(set language)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setLanguage (step, ${$3})\n`; + return `await dk.setLanguage (step, ${$3})\n`; }); code = code.replace(/set header\s*(.*)\sas\s(.*)/gi, ($0, $1, $2) => { @@ -385,176 +394,175 @@ export class GBVMService extends GBService { }); code = code.replace(/(datediff)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `dateDiff (step, ${$3})\n`; + return `await dk.dateDiff (step, ${$3})\n`; }); code = code.replace(/(dateadd)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `dateAdd (step, ${$3})\n`; + return `await dk.dateAdd (step, ${$3})\n`; }); code = code.replace(/(set max lines)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setMaxLines (step, ${$3})\n`; + return `await dk.setMaxLines (step, ${$3})\n`; }); code = code.replace(/(set max columns)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setMaxColumns (step, ${$3})\n`; + return `await dk.setMaxColumns (step, ${$3})\n`; }); code = code.replace(/(set translator)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setTranslatorOn (step, "${$3.toLowerCase()}")\n`; + return `await dk.setTranslatorOn (step, "${$3.toLowerCase()}")\n`; }); code = code.replace(/(set theme)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setTheme (step, "${$3.toLowerCase()}")\n`; + return `await dk.setTheme (step, "${$3.toLowerCase()}")\n`; }); code = code.replace(/(set whole word)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `setWholeWord (step, "${$3.toLowerCase()}")\n`; + return `await dk.setWholeWord (step, "${$3.toLowerCase()}")\n`; }); code = code.replace(/(\w+)\s*\=\s*post\s*(.*),\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = sys().postByHttp (${$2}, ${$3}, headers)`; + return `${$1} = await sys.postByHttp (${$2}, ${$3}, headers)`; }); code = code.replace(/(\w+)\s*\=\s*put\s*(.*),\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = sys().putByHttp (${$2}, ${$3}, headers)`; + return `${$1} = await sys.putByHttp (${$2}, ${$3}, headers)`; }); code = code.replace(/(\w+)\s*\=\s*download\s*(.*),\s*(.*)/gi, ($0, $1, $2, $3) => { - return `${$1} = sys().download (${$2}, ${$3})`; + return `${$1} = await sys.download (${$2}, ${$3})`; }); code = code.replace(/(\w+)\s*\=\s*CREATE FOLDER\s*(.*)/gi, ($0, $1, $2) => { - return `${$1} = sys().createFolder (${$2})`; + return `${$1} = await sys.createFolder (${$2})`; }); code = code.replace(/SHARE FOLDER\s*(.*)/gi, ($0, $1) => { - return `sys().shareFolder (${$1})`; + return `await sys.shareFolder (${$1})`; }); code = code.replace(/(create a bot farm using)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().createABotFarmUsing (${$3})`; + return `await sys.createABotFarmUsing (${$3})`; }); code = code.replace(/(chart)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `chart (step, ${$3})\n`; + return `await dk.chart (step, ${$3})\n`; }); code = code.replace(/(transfer to)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `transferTo (step, ${$3})\n`; + return `await dk.transferTo (step, ${$3})\n`; }); code = code.replace(/(\btransfer\b)(?=(?:[^"]|"[^"]*")*$)/gi, () => { - return `transferTo (step)\n`; + return `await dk.transferTo (step)\n`; }); code = code.replace(/(exit)/gi, () => { - return `if(resolve) {resolve();}\n`; + return ``; }); code = code.replace(/(show menu)/gi, () => { - return `showMenu (step)\n`; + return `await dk.showMenu (step)\n`; }); code = code.replace(/(talk to)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().talkTo(${$3})\n`; + return `await sys.talkTo(${$3})\n`; }); code = code.replace(/(talk)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `talk (step, ${$3})\n`; + return `await dk.talk (step, ${$3})\n`; }); code = code.replace(/(send sms to)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().sendSmsTo (${$3})\n`; + return `await sys.sendSmsTo (${$3})\n`; }); code = code.replace(/(send email)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sendEmail (${$3})\n`; + return `await dk.sendEmail (${$3})\n`; }); code = code.replace(/(send mail)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sendEmail (${$3})\n`; + return `await dk.sendEmail (${$3})\n`; }); code = code.replace(/(send file to)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sendFileTo (step, ${$3})\n`; + return `await dk.sendFileTo (step, ${$3})\n`; }); code = code.replace(/(hover)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `hover (step, ${$3})\n`; + return `await dk.hover (step, ${$3})\n`; }); code = code.replace(/(click link text)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `linkByText (step, ${$3})\n`; + return `await dk.linkByText (step, ${$3})\n`; }); code = code.replace(/(click)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `click (step, ${$3})\n`; + return `await dk.click (step, ${$3})\n`; }); code = code.replace(/(send file)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sendFile (step, ${$3})\n`; + return `await dk.sendFile (step, ${$3})\n`; }); code = code.replace(/(copy)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().copyFile(${$3})\n`; + return `await sys.copyFile(${$3})\n`; }); code = code.replace(/(convert)(\s*)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().convert(${$3})\n`; + return `await sys.convert(${$3})\n`; }); // TODO: AS CHART. // code = code.replace(/(\w+)\s*\=\s*(.*)\s*as chart/gi, ($0, $1, $2) => { - // return `${$1} = sys().asImage(${$2})\n`; + // return `${$1} = await sys.asImage(${$2})\n`; // }); code = code.replace(/MERGE\s(.*)\sWITH\s(.*)BY\s(.*)/gi, ($0, $1, $2, $3) => { - return `sys().merge(${$1}, ${$2}, ${$3})\n`; + return `await sys.merge(${$1}, ${$2}, ${$3})\n`; }); code = code.replace(/PRESS\s(.*)\sON\s(.*)/gi, ($0, $1, $2) => { - return `pressKey(step, ${$2}, ${$1})\n`; + return `await dk.pressKey(step, ${$2}, ${$1})\n`; }); code = code.replace(/SCREENSHOT\s(.*)/gi, ($0, $1, $2) => { - return `screenshot(step, ${$1})\n`; + return `await dk.screenshot(step, ${$1})\n`; }); code = code.replace(/TWEET\s(.*)/gi, ($0, $1, $2) => { - return `sys().tweet(step, ${$1})\n`; + return `await sys.tweet(step, ${$1})\n`; }); code = code.replace(/(\w+)\s*\=\s*(.*)\s*as image/gi, ($0, $1, $2) => { - return `${$1} = sys().asImage(${$2})\n`; + return `${$1} = await sys.asImage(${$2})\n`; }); code = code.replace(/(\w+)\s*\=\s*(.*)\s*as pdf/gi, ($0, $1, $2) => { - return `${$1} = sys().asPdf(${$2})\n`; + return `${$1} = await sys.asPdf(${$2})\n`; }); code = code.replace(/(\w+)\s*\=\s*FILL\s(.*)\sWITH\s(.*)/gi, ($0, $1, $2, $3) => { - return `${1} = sys().fill(${$2}, ${$3})\n`; + return `${1} = await sys.fill(${$2}, ${$3})\n`; }); code = code.replace(/save\s(.*)\sas\s(.*)/gi, ($0, $1, $2, $3) => { - return `sys().saveFile(${$2}, ${$1})\n`; + return `await sys.saveFile(${$2}, ${$1})\n`; }); code = code.replace(/(save)(\s)(.*)/gi, ($0, $1, $2, $3) => { - return `sys().save(${$3})\n`; + return `await sys.save(${$3})\n`; }); code = code.replace(/set\s(.*)/gi, ($0, $1, $2) => { - return `sys().set (${$1})`; + return `await sys.set (${$1})`; }); - code = `${code}\n%>`; return code; } - public async executeBASIC(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) { + public async translateBASIC(filename: any, min: GBMinInstance, deployer: GBDeployer, mainName: string) { // Converts General Bots BASIC into regular VBS @@ -592,7 +600,7 @@ export class GBVMService extends GBService { } } while (include); - const vbsCode = this.convertGBASICToVBS(basicCode); + const vbsCode = this.convertGBASICToVBS(min, basicCode); const vbsFile = `${filename}.compiled`; fs.writeFileSync(vbsFile, vbsCode); @@ -618,131 +626,61 @@ export class GBVMService extends GBService { 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. - let parsedCode = code; - - parsedCode = this.handleThisAndAwait(parsedCode); - - parsedCode = parsedCode.replace(/(\bnow\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'await dk.getNow()'); - parsedCode = parsedCode.replace(/(\btoday\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'await dk.getToday(step)'); - parsedCode = parsedCode.replace(/(\bweekday\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'weekday'); - parsedCode = parsedCode.replace(/(\bhour\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'hour'); - parsedCode = parsedCode.replace(/(\btolist\b)(?=(?:[^"]|"[^"]*")*$)/gi, 'tolist'); - - parsedCode = beautify(parsedCode, { indent_size: 2, space_in_empty_paren: true }); + const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true }); fs.writeFileSync(jsfile, parsedCode); - this.executeJS(min, deployer, parsedCode, mainName); + min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; + GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${parsedCode}`); } } - private executeJS(min: GBMinInstance, deployer: GBDeployer, parsedCode: string, mainName: string) { - try { - min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; - } catch (error) { - GBLog.error(`[GBVMService] ERROR loading ${error}`); - } - } - - private handleThisAndAwait(code: string) { - // this insertion. - - code = code.replace(/sys\(\)/gi, 'dk.sys()'); - code = code.replace(/("[^"]*"|'[^']*')|\btalk\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.talk' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bhear\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.hear' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\baskEmail\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.askEmail' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsendFileTo\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.sendFileTo' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsendFile\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.sendFile' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsetLanguage\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.setLanguage' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bdateAdd\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.dateAdd' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bdateDiff\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.dateDiff' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bgotoDialog\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.gotoDialog' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsetMaxLines\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.setMaxLines' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsetTranslatorOn\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.setTranslatorOn' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsetTheme\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.setTheme' : $1; - }); - - code = code.replace(/("[^"]*"|'[^']*')|\bsetWholeWord\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.setWholeWord' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\btransferTo\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.transferTo' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bchart\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.chart' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bcreateDeal\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.createDeal' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bfndContact\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.fndContact' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bgetActiveTasks\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.getActiveTasks' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bmenu\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.menu' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bgetPage\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.getPage' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bclick\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.click' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\blinkByText\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.linkByText' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bpressKey\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.pressKey' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bscreenshot\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.screenshot' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bhover\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.hover' : $1; - }); - code = code.replace(/("[^"]*"|'[^']*')|\bsendEmail\b/gi, ($0, $1) => { - return $1 === undefined ? 'dk.sendEmail' : $1; - }); - // await insertion. - - code = code.replace(/dk\./gm, 'await dk.'); - code = code.replace(/\nfunction/i, 'async function'); - code = code.replace('ubound = async', 'ubound ='); // TODO: Improve this. - code = code.replace('hour = await', 'hour ='); // TODO: Improve this. - code = code.replace('weekday = await', 'weekday ='); // TODO: Improve this. - code = code.replace('tolist = await', 'tolist ='); // TODO: Improve this. - code = code.replace('isarray = async', 'isarray ='); // TODO: Waiting for a compiler. - code = code.replace('isArray = async', 'isarray ='); // TODO: Waiting for a compiler. - code = code.replace('base64 = await', 'base64 ='); // TODO: Waiting for a compiler. - - return code; - } /** * Executes the converted JavaScript from BASIC code inside execution context. @@ -754,7 +692,7 @@ export class GBVMService extends GBService { const user = step ? await min.userProfile.get(step.context, {}) : null; - const sandbox: DialogKeywords = new DialogKeywords(min, deployer, user.systemUser); + const sandbox = { user: user.ssystemUser }; const contentLocale = min.core.getParam( min.instance, @@ -782,7 +720,7 @@ export class GBVMService extends GBService { let code = min.sandBoxMap[text]; - if (GBConfigService.get('VM3')==='true'){ + if (GBConfigService.get('VM3') === 'true') { try { const vm1 = new NodeVM({ @@ -805,22 +743,6 @@ export class GBVMService extends GBService { } } else { - - // { - // "name": "dev-rodriguez.gbdialog", - // "version": "1.0.0", - // "description": "", - // "author": "", - // "license": "ISC", - // "dependencies": { - // "encoding": "^0.1.13", - // "isomorphic-fetch": "^3.0.0", - // "punycode": "^2.1.1", - // "typescript-rest-rpc": "^1.0.10", - // "vm2": "^3.9.11" - // } - // } - const runnerPath = urlJoin(process.cwd(), 'dist', 'packages', 'basic.gblib', 'services', 'vm2-process', 'vm2ProcessRunner.js'); try { @@ -828,15 +750,16 @@ export class GBVMService extends GBService { min: 1, max: 1, cpu: 100, - memory: 120000, - time: 5520000, + memory: 50000, + time: 60 * 60 * 24 * 14, cwd: gbdialogPath, script: runnerPath }); - const result = await run(code, { filename: scriptPath }); + const result = await run(code, { filename: scriptPath, sandbox: sandbox }); drain(); + return result; } catch (error) { throw new Error(`BASIC RUNTIME ERR: ${error.message ? error.message : error}\n Stack:${error.stack}`); }