new(all): Vm isolated working with IPC BASIC 3.0;
This commit is contained in:
parent
fa0324dc06
commit
25230816b0
7 changed files with 2191 additions and 395 deletions
2456
package-lock.json
generated
2456
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -83,11 +83,13 @@
|
|||
"botframework-connector": "4.11.0",
|
||||
"botlib": "1.10.9",
|
||||
"c3-chart-maker": "^0.2.8",
|
||||
"chrome-remote-interface": "^0.31.3",
|
||||
"cli-progress": "^3.11.2",
|
||||
"cli-spinner": "0.2.10",
|
||||
"core-js": "3.14.0",
|
||||
"data-forge": "^1.9.5",
|
||||
"date-diff": "0.2.2",
|
||||
"debugger-api": "^0.1.2",
|
||||
"docxtemplater": "^3.31.1",
|
||||
"dotenv-extended": "2.9.0",
|
||||
"exceljs": "4.2.1",
|
||||
|
|
|
@ -482,7 +482,7 @@ export class DialogKeywords {
|
|||
/**
|
||||
* Returns current time in format hh:dd.
|
||||
*
|
||||
* @example SAVE "file.xlsx",name,email,NOW
|
||||
* @example SAVE "contacts.xlsx", name, email, NOW
|
||||
*
|
||||
*/
|
||||
public async getNow({}) {
|
||||
|
|
|
@ -51,6 +51,8 @@ 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
|
||||
|
@ -168,12 +170,17 @@ export class GBVMService extends GBService {
|
|||
let basicCode: string = fs.readFileSync(filename, 'utf8');
|
||||
|
||||
// Processes END keyword, removing extracode, useful
|
||||
// for development.
|
||||
// for development in .gbdialog.
|
||||
|
||||
// TODO: let end = /(\nend\n)/gi.exec(basicCode);
|
||||
// if (end) {
|
||||
// basicCode = basicCode.substring(0, end.index);
|
||||
// }
|
||||
if (process.env.GBDIALOG_NOEND === 'true') {
|
||||
basicCode = basicCode.replace(/(^|\W)END(\W|\n)/gi, '');
|
||||
}
|
||||
else {
|
||||
let end = /(^|\W)END(\W|\n)/gi.exec(basicCode);
|
||||
if (end) {
|
||||
basicCode = basicCode.substring(0, end.index);
|
||||
}
|
||||
}
|
||||
|
||||
// Removes comments.
|
||||
|
||||
|
@ -274,7 +281,7 @@ export class GBVMService extends GBService {
|
|||
`;
|
||||
// Finds all hear calls.
|
||||
|
||||
const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true });
|
||||
const parsedCode = beautify(code, { indent_size: 2, space_in_empty_paren: true, preserve_newlines: true, wrap_line_length: 240 });
|
||||
fs.writeFileSync(jsfile, parsedCode);
|
||||
|
||||
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
|
||||
|
@ -332,13 +339,24 @@ export class GBVMService extends GBService {
|
|||
|
||||
`;
|
||||
|
||||
const getParams = async (text, names) => {
|
||||
// Split all params by comma, not inside strings.
|
||||
|
||||
const getParams = (text, names) => {
|
||||
|
||||
let ret = {};
|
||||
const items = text.split(','); // TODO: NOT IN STRING.
|
||||
const items = text.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g);
|
||||
|
||||
await CollectionUtil.asyncForEach(names, async name => {
|
||||
ret[name] = items[0];
|
||||
let i = 0;
|
||||
names.forEach(name => {
|
||||
let value = items[i];
|
||||
|
||||
// Add string to JSON without quotes.
|
||||
|
||||
if (value && (value.charAt(0) === '"' || value.charAt(0) === '\'')) {
|
||||
value = value.substr(1, value.length - 2);
|
||||
}
|
||||
ret[name] = value;
|
||||
i++;
|
||||
});
|
||||
|
||||
return JSON.stringify(ret);
|
||||
|
@ -352,8 +370,13 @@ export class GBVMService extends GBService {
|
|||
return `${$1} = await sys.executeSQL({data:${$1}, sql:"${sql}", tableName:"${tableName}"})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/get html\s*(.*)/gi, ($0, $1, $2) => {
|
||||
const params = getParams($2, ['url', 'username', 'password']);
|
||||
code = code.replace(/open\s*(.*)/gi, ($0, $1, $2) => {
|
||||
|
||||
if (!$1.startsWith("\"") && $1.startsWith("\'")) {
|
||||
$1 = `"${$1}"`;
|
||||
}
|
||||
const params = getParams($1, ['url', 'username', 'password']);
|
||||
|
||||
return `page = await wa.getPage(${params})\n`;
|
||||
});
|
||||
|
||||
|
@ -410,7 +433,7 @@ export class GBVMService extends GBService {
|
|||
});
|
||||
|
||||
code = code.replace(/hear (\w+) as (.*)/gi, ($0, $1, $2) => {
|
||||
return `${$1} = await dk.getHear({kind:"menu", [${$2}])}`;
|
||||
return `${$1} = await dk.getHear({kind:"menu", args: [${$2}])}`;
|
||||
});
|
||||
|
||||
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
||||
|
@ -430,8 +453,8 @@ export class GBVMService extends GBService {
|
|||
`;
|
||||
});
|
||||
|
||||
code = code.replace(/CALL\s*(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `await sys.callVM("${$1}", dk.getMin(), dk.getStep(), dk.getDeployer())\n`;
|
||||
code = code.replace(/CALL\s*(.*)/gi, ($0, $1) => {
|
||||
return `await ${$1}\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/(\w)\s*\=\s*find\s*(.*)/gi, ($0, $1, $2, $3) => {
|
||||
|
@ -583,12 +606,6 @@ export class GBVMService extends GBService {
|
|||
return `await sys.createABotFarmUsing ({${$3}})`;
|
||||
});
|
||||
|
||||
code = code.replace(/(chart)(\s)(.*)/gi, ($0, $1, $2, $3) => {
|
||||
|
||||
const params = getParams($3, ['type', 'data', 'legends', 'transpose']);
|
||||
return `await dk.chart (${params})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/(transfer to)(\s)(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `await dk.transferTo ({to:${$3}})\n`;
|
||||
});
|
||||
|
@ -667,10 +684,14 @@ export class GBVMService extends GBService {
|
|||
return `await sys.convert (${params})\n`;
|
||||
});
|
||||
|
||||
// TODO: AS CHART.
|
||||
// code = code.replace(/(\w+)\s*\=\s*(.*)\s*as chart/gi, ($0, $1, $2) => {
|
||||
// return `${$1} = await sys.asImage({${$2})\n`;
|
||||
// });
|
||||
code = code.replace(/(\w+)\s*\=\s*(.*)\s*as chart/gi, ($0, $1, $2) => {
|
||||
return `await dk.chart ({type:'bar', data: ${2}, legends:null, transpose: false})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/(chart)(\s)(.*)/gi, ($0, $1, $2, $3) => {
|
||||
const params = getParams($3, ['type', 'data', 'legends', 'transpose']);
|
||||
return `await dk.chart (${params})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/MERGE\s(.*)\sWITH\s(.*)BY\s(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `await sys.merge({file: ${$1}, data: ${$2}, key1: ${$3}})\n`;
|
||||
|
@ -697,14 +718,14 @@ export class GBVMService extends GBService {
|
|||
});
|
||||
|
||||
code = code.replace(/(\w+)\s*\=\s*FILL\s(.*)\sWITH\s(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `${1} = await sys.fill({templateName: ${$2}, data: ${$3}})\n`;
|
||||
return `${$1} = await sys.fill({templateName: ${$2}, data: ${$3}})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/save\s(.*)\sas\s(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `await sys.saveFile({file: ${$2}, data: ${$1})\n`;
|
||||
});
|
||||
code = code.replace(/(save)(\s)(.*)/gi, ($0, $1, $2, $3) => {
|
||||
return `await sys.save({[${$3}]})\n`;
|
||||
return `await sys.save({args: [${$3}]})\n`;
|
||||
});
|
||||
|
||||
code = code.replace(/set\s(.*)/gi, ($0, $1, $2) => {
|
||||
|
@ -784,6 +805,7 @@ export class GBVMService extends GBService {
|
|||
const { run, drain } = createVm2Pool({
|
||||
min: 1,
|
||||
max: 1,
|
||||
debuggerPort: 9222,
|
||||
cpu: 100,
|
||||
memory: 50000,
|
||||
time: 60 * 60 * 24 * 14,
|
||||
|
@ -791,6 +813,7 @@ export class GBVMService extends GBService {
|
|||
script: runnerPath
|
||||
});
|
||||
|
||||
const port = run.port;
|
||||
const result = await run(code, { filename: scriptPath, sandbox: sandbox });
|
||||
|
||||
drain();
|
||||
|
|
|
@ -554,7 +554,6 @@ export class SystemKeywords {
|
|||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1121,14 +1120,16 @@ export class SystemKeywords {
|
|||
* SHARE FOLDER folder, "nome@domain.com", "E-mail message"
|
||||
*
|
||||
*/
|
||||
public async shareFolder({folderReference, email, message}) {
|
||||
public async shareFolder({folder, email, message}) {
|
||||
let [baseUrl, client] = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const srcFile = await client.api(
|
||||
`${baseUrl}/drive/root:/${folder}`)
|
||||
const root = urlJoin(`/${this.min.botId}.gbai/${this.min.botId}.gbdrive`, folder);
|
||||
|
||||
const src = await client.api(
|
||||
`${baseUrl}/drive/root:/${root}`)
|
||||
.get();
|
||||
|
||||
const driveId = folderReference.parentReference.driveId;
|
||||
const itemId = folderReference.id;
|
||||
const driveId = src.parentReference.driveId;
|
||||
const itemId = src.id;
|
||||
const body = {
|
||||
"recipients": [{ "email": email }],
|
||||
"message": message,
|
||||
|
|
|
@ -2,7 +2,7 @@ const crypto2 = require('crypto');
|
|||
const Fs = require('fs');
|
||||
const Path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const CDP = require('chrome-remote-interface');
|
||||
const { } = require('child_process');
|
||||
const { dirname } = require('path');
|
||||
const { fileURLToPath } = require('url');
|
||||
|
@ -50,7 +50,7 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
|||
const runner = spawn('cpulimit', [
|
||||
'-ql', limits.cpu,
|
||||
'--',
|
||||
'node', `--experimental-fetch`, `--max-old-space-size=${limits.memory}`,
|
||||
'node', `--inspect-brk=${limits.debuggerPort} --experimental-fetch`, `--max-old-space-size=${limits.memory}`,
|
||||
limits.script
|
||||
, ref
|
||||
], { cwd: limits.cwd, shell: false });
|
||||
|
@ -79,6 +79,25 @@ const createVm2Pool = ({ min, max, ...limits }) => {
|
|||
const run = async (code, scope) => {
|
||||
const childProcess = await pool.acquire();
|
||||
|
||||
CDP(async (client) => {
|
||||
const { Debugger, Runtime } = client;
|
||||
try {
|
||||
client.Debugger.paused(() => {
|
||||
client.Debugger.resume();
|
||||
client.close();
|
||||
});
|
||||
await client.Runtime.runIfWaitingForDebugger();
|
||||
await client.Debugger.enable();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}).on('error', (err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
|
||||
await waitUntil(() => childProcess.socket);
|
||||
|
||||
const socket = net.createConnection(childProcess.socket);
|
||||
|
|
13
src/app.ts
13
src/app.ts
|
@ -53,7 +53,7 @@ import { GBDeployer } from '../packages/core.gbapp/services/GBDeployer';
|
|||
import { GBImporter } from '../packages/core.gbapp/services/GBImporterService';
|
||||
import { GBMinService } from '../packages/core.gbapp/services/GBMinService';
|
||||
var auth = require('basic-auth');
|
||||
|
||||
const child_process = require('child_process');
|
||||
|
||||
/**
|
||||
* Global shared server data;
|
||||
|
@ -83,12 +83,21 @@ export class GBServer {
|
|||
|
||||
public static run() {
|
||||
|
||||
|
||||
|
||||
GBLog.info(`The Bot Server is in STARTING mode...`);
|
||||
GBServer.globals = new RootData();
|
||||
GBConfigService.init();
|
||||
const port = GBConfigService.getServerPort();
|
||||
|
||||
if (process.env.TEST_SHELL)
|
||||
{
|
||||
GBLog.info(`Running TEST_SHELL: ${process.env.TEST_SHELL}...`);
|
||||
try{
|
||||
child_process.execSync(process.env.TEST_SHELL);
|
||||
}catch(error){
|
||||
GBLog.error(`Running TEST_SHELL ERROR: ${error}...`);
|
||||
}
|
||||
}
|
||||
|
||||
const server = express();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue