new(basic.gblib): VBS to JS directly now and minor fixes.

This commit is contained in:
rodrigorodriguez 2023-01-29 12:02:14 -03:00
parent 786fc7ea1c
commit 3d6bc56eca
11 changed files with 190 additions and 429 deletions

View file

@ -1,7 +1,7 @@
dist: focal
language: node_js
node_js:
- 19.4.0
- 19.5.0
notifications:

View file

@ -14,7 +14,7 @@
"Dário Vieira <dario.junior3@gmail.com>"
],
"engines": {
"node": "=19.4.0"
"node": "=19.5.0"
},
"license": "AGPL-3.0",
"preferGlobal": true,

View file

@ -312,7 +312,6 @@ export class AdminDialog extends IGBDialog {
}
await CollectionUtil.asyncForEach(packages, async packageName => {
try {
let cmd1;
if (packageName.indexOf('.') !== -1) {
cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`;
@ -328,14 +327,6 @@ export class AdminDialog extends IGBDialog {
}
await GBAdminService.deployPackageCommand(min, cmd1, deployer);
await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`);
} catch (error) {
GBLog.error(error);
if (!skipError) {
await min.conversationalService.sendText(min, step, `ERROR: ${error}`);
return await step.replaceDialog('/ask', { isReturning: true });
}
}
});
await min.conversationalService.sendText(min, step, Messages[locale].publish_success);
if (!step.activeDialog.state.options.confirm) {

View file

@ -37,7 +37,7 @@
'use strict';
import { AuthenticationContext, TokenResponse } from 'adal-node';
import { GBMinInstance, IGBAdminService, IGBCoreService, IGBDeployer, IGBInstance } from 'botlib';
import { GBError, GBLog, GBMinInstance, IGBAdminService, IGBCoreService, IGBDeployer, IGBInstance } from 'botlib';
import { FindOptions } from 'sequelize/types';
import urlJoin from 'url-join';
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService.js';
@ -205,18 +205,23 @@ export class GBAdminService implements IGBAdminService {
const options = <FindOptions>{ where: {} };
options.where = { key: key, instanceId: instanceId };
const obj = await GuaribasAdmin.findOne(options);
return obj.value;
}
public async acquireElevatedToken(instanceId: number): Promise<string> {
const minBoot = GBServer.globals.minBoot;
instanceId = minBoot.instance.instanceId;
let expiresOnV;
try {
expiresOnV = await this.getValue(instanceId, 'expiresOn');
} catch (error) {
throw new Error(`/setupSecurity is required before running /publish.`);
}
return new Promise<string>(async (resolve, reject) => {
const instance = await this.core.loadInstanceById(instanceId);
const expiresOn = new Date(await this.getValue(instanceId, 'expiresOn'));
const expiresOn = new Date(expiresOnV);
if (expiresOn.getTime() > new Date().getTime()) {
const accessToken = await this.getValue(instanceId, 'accessToken');
resolve(accessToken);

View file

@ -42,7 +42,7 @@ import { CognitiveServicesManagementClient } from '@azure/arm-cognitiveservices'
import { ResourceManagementClient } from '@azure/arm-resources';
import { SubscriptionClient } from '@azure/arm-subscriptions';
import { SearchManagementClient } from '@azure/arm-search';
import { SqlManagementClient } from '@azure/arm-sql';
import { Server, SqlManagementClient } from '@azure/arm-sql';
import { WebSiteManagementClient } from '@azure/arm-appservice';
import { AppServicePlan, Site, SiteLogsConfig, SiteSourceControl } from '@azure/arm-appservice';
import { GBLog, IGBInstallationDeployer, IGBInstance, IGBDeployer, IGBCoreService } from 'botlib';
@ -52,12 +52,10 @@ import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigS
import { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer.js';
import { Account } from '@azure/arm-cognitiveservices';
import MicrosoftGraph from '@microsoft/microsoft-graph-client';
import {Spinner} from 'cli-spinner';
import { Spinner } from 'cli-spinner';
import * as publicIp from 'public-ip';
import { AccessToken, TokenCredential } from '@azure/core-auth';
const WebSiteResponseTimeout = 900;
const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png';
/**
@ -82,13 +80,11 @@ export class AzureDeployerService implements IGBInstallationDeployer {
public core: IGBCoreService;
private freeTier: boolean;
public async runSearch (instance: IGBInstance) {
public async runSearch(instance: IGBInstance) {
await this.deployer.rebuildIndex(instance, this.getKBSearchSchema(instance.searchIndex));
}
public static async createInstance (deployer: GBDeployer, freeTier: boolean = true): Promise<AzureDeployerService> {
public static async createInstance(deployer: GBDeployer, freeTier: boolean = true): Promise<AzureDeployerService> {
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
@ -106,7 +102,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return service;
}
private static createRequestObject (url: string, accessToken: string, verb: HttpMethods, body: string) {
private static createRequestObject(url: string, accessToken: string, verb: HttpMethods, body: string) {
const req = new WebResource();
req.method = verb;
req.url = url;
@ -118,13 +114,13 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return req;
}
public async getSubscriptions (credentials) {
public async getSubscriptions(credentials) {
const subscriptionClient = new SubscriptionClient(credentials);
return subscriptionClient.subscriptions.list();
}
public getKBSearchSchema (indexName: any) {
public getKBSearchSchema(indexName: any) {
return {
name: indexName,
fields: [
@ -235,7 +231,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
};
}
public async botExists (botId: string) {
public async botExists(botId: string) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
@ -257,7 +253,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return !res.parsedBody.valid;
}
public async updateBotProxy (botId: string, group: string, endpoint: string) {
public async updateBotProxy(botId: string, group: string, endpoint: string) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
@ -272,9 +268,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
}
};
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req);
@ -285,7 +279,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot proxy updated at: ${endpoint}.`);
}
public async updateBot (botId: string, group: string, name: string, description: string, endpoint: string) {
public async updateBot(botId: string, group: string, name: string, description: string, endpoint: string) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
@ -303,9 +297,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
}
};
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req);
@ -316,7 +308,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot updated at: ${endpoint}.`);
}
public async deleteBot (botId: string, group: string) {
public async deleteBot(botId: string, group: string) {
const baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD');
@ -325,9 +317,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
const httpClient = new ServiceClient();
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'DELETE', undefined);
const res = await httpClient.sendRequest(req);
@ -338,10 +328,9 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot ${botId} was deleted from the provider.`);
}
public async openStorageFirewall (groupName: string, serverName: string) {
public async openStorageFirewall(groupName: string, serverName: string) {
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
const ip = await publicIp.publicIpv4();
let params = {
startIpAddress: ip,
@ -350,7 +339,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
await this.storageClient.firewallRules.createOrUpdate(groupName, serverName, 'gb', params);
}
public async deployFarm (
public async deployFarm(
proxyAddress: string,
instance: IGBInstance,
credentials: any,
@ -474,7 +463,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return instance;
}
public async deployToCloud (
public async deployToCloud(
title: string,
username: string,
password: string,
@ -505,13 +494,13 @@ export class AzureDeployerService implements IGBInstallationDeployer {
/**
* @see https://github.com/Azure/azure-rest-api-specs/blob/master/specification/botservice/resource-manager/Microsoft.BotService/preview/2017-12-01/botservice.json
*/
public async internalDeployBot (
public async internalDeployBot(
instance,
accessToken: string,
botId: string,
name: string,
group,
description: string ,
description: string,
endpoint,
location,
nlpAppId,
@ -550,9 +539,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
};
const httpClient = new ServiceClient();
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
let url = urlJoin(baseUrl, query);
let req = AzureDeployerService.createRequestObject(url, accessToken, 'PUT', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req);
@ -564,9 +551,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
try {
//tslint:disable-next-line:max-line-length
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${
this.apiVersion
}`;
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${this.apiVersion}`;
url = urlJoin(baseUrl, query);
req = AzureDeployerService.createRequestObject(url, accessToken, 'POST', JSON.stringify(parameters));
const resChannel = await httpClient.sendRequest(req);
@ -578,27 +563,24 @@ export class AzureDeployerService implements IGBInstallationDeployer {
reject(error);
}
});
}
public async syncBotServerRepository (group: string, name: string) {
}
public async syncBotServerRepository(group: string, name: string) {
await this.webSiteClient.webApps.syncRepository(group, name);
}
public async initServices (accessToken: string, expiresOnTimestamp, subscriptionId: string) {
public async initServices(accessToken: string, expiresOnTimestamp, subscriptionId: string) {
this.accessToken = accessToken;
class AccessToken2 implements AccessToken
{
public expiresOnTimestamp: number;
public token: string;
class AccessToken2 implements AccessToken {
public expiresOnTimestamp: number;
public token: string;
}
class StaticAccessToken implements TokenCredential {
public getToken(): Promise<AccessToken> {
return new Promise<AccessToken>(async (resolve, reject) => {
const t = new AccessToken2();
t.token = accessToken;
t.token = accessToken;
t.expiresOnTimestamp = expiresOnTimestamp;
resolve(t);
});
@ -614,15 +596,30 @@ export class AzureDeployerService implements IGBInstallationDeployer {
this.searchClient = new SearchManagementClient(token, subscriptionId);
}
private async createStorageServer (group: string, name: string, administratorLogin: string, administratorPassword: string, serverName: string, location: string) {
private async createStorageServer(
group: string,
name: string,
administratorLogin: string,
administratorPassword: string,
serverName: string,
location: string
) {
const params = {
location: location,
administratorLogin: administratorLogin,
administratorLoginPassword: administratorPassword,
fullyQualifiedDomainName: serverName
fullyQualifiedDomainName: serverName,
requestOptions: { timeout: 60 * 1000 * 5 }
};
const database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
let database: Server;
try {
database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
} catch (error) {
// Try again (MSFT issues).
GBLog.info('Storage (server) creation failed. Retrying...');
database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
}
// AllowAllWindowsAzureIps must be created that way, so the Azure Search can
// access SQL Database to index its contents.
@ -636,7 +633,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return database;
}
public async createApplication (token: string, name: string) {
public async createApplication(token: string, name: string) {
return new Promise<string>((resolve, reject) => {
let client = MicrosoftGraph.Client.init({
authProvider: done => {
@ -657,7 +654,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
});
}
public async createApplicationSecret (token: string, appId: string) {
public async createApplicationSecret(token: string, appId: string) {
return new Promise<string>((resolve, reject) => {
let client = MicrosoftGraph.Client.init({
authProvider: done => {
@ -680,7 +677,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
});
}
private async registerProviders (subscriptionId: string, baseUrl: string, accessToken: string) {
private async registerProviders(subscriptionId: string, baseUrl: string, accessToken: string) {
const query = `subscriptions/${subscriptionId}/providers/${this.provider}/register?api-version=2018-02-01`;
const requestUrl = urlJoin(baseUrl, query);
@ -693,7 +690,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
(req.headers as any).Authorization = `Bearer ${accessToken}`;
}
private async createNLPService (
private async createNLPService(
name: string,
description: string,
location: string,
@ -731,7 +728,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return id.replace(/\'/gi, '');
}
private async makeNlpRequest (
private async makeNlpRequest(
location: string,
authoringKey: string,
body: string,
@ -750,7 +747,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req);
}
public async refreshEntityList (location: string, nlpAppId: string, clEntityId: string, nlpKey: string, data: any) {
public async refreshEntityList(location: string, nlpAppId: string, clEntityId: string, nlpKey: string, data: any) {
const req = new WebResource();
req.method = 'PUT';
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/${nlpAppId}/versions/0.1/closedlists/${clEntityId}`;
@ -763,7 +760,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req);
}
public async trainNLP (location: string, nlpAppId: string, nlpAuthoringKey: string) {
public async trainNLP(location: string, nlpAppId: string, nlpAuthoringKey: string) {
const req = new WebResource();
req.method = 'POST';
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/${nlpAppId}/versions/0.1/train`;
@ -775,7 +772,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req);
}
public async publishNLP (location: string, nlpAppId: string, nlpAuthoringKey: string) {
public async publishNLP(location: string, nlpAppId: string, nlpAuthoringKey: string) {
const body = {
versionId: '0.1',
isStaging: false,
@ -793,7 +790,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req);
}
private async createSearch (group: string, name: string, location: string) {
private async createSearch(group: string, name: string, location: string) {
const params = {
sku: {
name: this.freeTier ? 'free' : 'standard'
@ -804,17 +801,26 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await this.searchClient.services.beginCreateOrUpdateAndWait(group, name, params as any);
}
private async createStorage (group: string, serverName: string, name: string, location: string) {
private async createStorage(group: string, serverName: string, name: string, location: string) {
const params = {
sku: { name: this.freeTier ? 'Free' : 'Basic' },
sku: { name: 'Basic' },
createMode: 'Default',
location: location
};
return await this.storageClient.databases.beginCreateOrUpdateAndWait(group, serverName, name, params);
let database;
try {
database = await this.storageClient.databases.beginCreateOrUpdateAndWait(group, serverName, name, params);
} catch (error) {
// Try again (MSFT issues).
GBLog.info('Storage (database) creation failed. Retrying...');
database = await this.storageClient.databases.beginCreateOrUpdateAndWait(group, serverName, name, params);
}
return database;
}
private async createCognitiveServices (group: string, name: string, location: string, kind: string): Promise<Account> {
private async createCognitiveServices(group: string, name: string, location: string, kind: string): Promise<Account> {
const params = {
sku: {
name: name
@ -840,40 +846,40 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await this.cognitiveClient.accounts.beginCreateAndWait(group, name, params);
}
private async createSpeech (group: string, name: string, location: string): Promise<Account> {
private async createSpeech(group: string, name: string, location: string): Promise<Account> {
return await this.createCognitiveServices(group, name, location, 'SpeechServices');
}
private async createNLP (group: string, name: string, location: string): Promise<Account> {
private async createNLP(group: string, name: string, location: string): Promise<Account> {
return await this.createCognitiveServices(group, name, location, 'LUIS');
}
private async createNLPAuthoring (group: string, name: string, location: string): Promise<Account> {
private async createNLPAuthoring(group: string, name: string, location: string): Promise<Account> {
return await this.createCognitiveServices(group, name, location, 'LUIS.Authoring');
}
private async createSpellChecker (group: string, name: string): Promise<Account> {
private async createSpellChecker(group: string, name: string): Promise<Account> {
return await this.createCognitiveServices(group, name, 'westus', 'CognitiveServices');
}
private async createTextAnalytics (group: string, name: string, location: string): Promise<Account> {
private async createTextAnalytics(group: string, name: string, location: string): Promise<Account> {
return await this.createCognitiveServices(group, name, location, 'TextAnalytics');
}
private async createDeployGroup (name: string, location: string) {
private async createDeployGroup(name: string, location: string) {
const params = { location: location };
return await this.cloud.resourceGroups.createOrUpdate(name, params);
}
private async enableResourceProviders (name: string) {
private async enableResourceProviders(name: string) {
const ret = await this.cloud.providers.get(name);
if (ret.registrationState === 'NotRegistered') {
await this.cloud.providers.register(name);
}
}
private async createHostingPlan (group: string, name: string, location: string): Promise<AppServicePlan> {
private async createHostingPlan(group: string, name: string, location: string): Promise<AppServicePlan> {
const params = {
serverFarmWithRichSkuName: name,
location: location,
@ -887,7 +893,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await this.webSiteClient.appServicePlans.beginCreateOrUpdateAndWait(group, name, params);
}
private async createServer (farmId: string, group: string, name: string, location: string) {
private async createServer(farmId: string, group: string, name: string, location: string) {
let tryed = false;
const create = async () => {
const parameters: Site = {
@ -937,7 +943,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
}
}
private async updateWebisteConfig (group: string, name: string, serverFarmId: string, instance: IGBInstance) {
private async updateWebisteConfig(group: string, name: string, serverFarmId: string, instance: IGBInstance) {
const parameters: Site = {
location: instance.cloudLocation,
serverFarmId: serverFarmId,

View file

@ -36,14 +36,12 @@ import { GBLog, GBMinInstance, GBService, IGBCoreService, GBDialogStep } from 'b
import * as Fs from 'fs';
import { GBServer } from '../../../src/app.js';
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
import { TSCompiler } from './TSCompiler.js';
import { CollectionUtil } from 'pragmatismo-io-framework';
import { ScheduleServices } from './ScheduleServices.js';
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
import urlJoin from 'url-join';
import { NodeVM, VMScript } from 'vm2';
import { createVm2Pool } from './vm2-process/index.js';
import * as vb2ts from './vbscript-to-typescript.js';
import textract from 'textract';
import walkPromise from 'walk-promise';
import child_process from 'child_process';
@ -208,21 +206,9 @@ export class GBVMService extends GBService {
Fs.writeFileSync(vbsFile, code);
Fs.writeFileSync(mapFile, JSON.stringify(jsonMap));
// 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', '');
const jsfile: string = `${filename}.js`;
if (Fs.existsSync(jsfile)) {
let code: string = Fs.readFileSync(jsfile, 'utf8');
@ -354,12 +340,9 @@ export class GBVMService extends GBService {
public async convertGBASICToVBS(min: GBMinInstance, code: string) {
// Start and End of VB2TS tags of processing.
code = `<%\n
${process.env.ENABLE_AUTH ? `hear gbLogin as login` : ``}
${code}
code = `
${process.env.ENABLE_AUTH ? `hear gbLogin as login` : ``}
${code}
`;
var allLines = code.split('\n');
@ -388,6 +371,14 @@ export class GBVMService extends GBService {
let keywords = [];
let i = 0;
const convertConditions = input => {
var result = input.replace(/ +and +/gi, ' && ');
result = result.replace(/ +or +/gi, ' || ');
result = result.replace(/ +<> +/gi, ' !== ');
result = result.replace(/ += +/gi, ' === ');
return result;
};
keywords[i++] = [
/^\s*(\w+)\s*\=\s*SELECT\s*(.*)/gim,
($0, $1, $2) => {
@ -397,6 +388,40 @@ export class GBVMService extends GBService {
}
];
keywords[i++] = [
/if +(.*?) +then/gi,
(input, group1) => {
var condition = convertConditions(group1);
return '\nif (' + condition + ') {\n';
}
];
keywords[i++] = [/end if/gi, '\n}\n'];
keywords[i++] = [/else(?!{)/gi, '\n}\nelse {\n'];
keywords[i++] = [/select case +(.*)/gi, '\nswitch ($1) {\n'];
keywords[i++] = [/end select/gi, '\n}\n'];
keywords[i++] = [/function +(.*)\((.*)\)/gi, '\n$1 = ($2) => {\n'];
keywords[i++] = [/end function/gi, '\n}\n'];
keywords[i++] = [/for +(.*to.*)/gi, '\nfor ($1) {\n'];
keywords[i++] = [/^ *next *$/gim, '}\n'];
keywords[i++] = [
/do while +(.*)/gi,
function (input, group1) {
var condition = convertConditions(group1);
return '\nwhile (' + condition + ') {\n';
}
];
keywords[i++] = [/^ *loop *$/gim, '}\n'];
keywords[i++] = [
/^\s*open\s*(.*)/gim,
($0, $1, $2) => {

View file

@ -1,102 +0,0 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| (˅) |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
| |
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
| Licensed under the AGPL-3.0. |
| |
| According to our dual licensing model, this program can be used either |
| under the terms of the GNU Affero General Public License, version 3, |
| or under a proprietary license. |
| |
| The texts of the GNU Affero General Public License with an additional |
| permission and of our proprietary license can be found at and |
| in the LICENSE file you have received along with this program. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Affero General Public License for more details. |
| |
| "General Bots" is a registered trademark of Pragmatismo.io. |
| The licensing of the program under the AGPLv3 does not imply a |
| trademark license. Therefore any rights, title and interest in |
| our trademarks remain entirely with us. |
| |
\*****************************************************************************/
/**
* @fileoverview General Bots server core.
*/
'use strict';
import { GBLog } from 'botlib';
import ts from 'typescript';
/**
* Wrapper for a TypeScript compiler.
*/
export class TSCompiler {
private static shouldIgnoreError (diagnostic) {
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (
message.indexOf('Cannot find name') >= 0 ||
message.indexOf('Cannot find module') >= 0 ||
message.indexOf('implicitly has an') >= 0 ||
message.indexOf('Cannot invoke an') >= 0 ||
message.indexOf('Cannot use imports, exports, or module') >= 0
) {
return true;
}
return false;
}
public compile (
fileNames: string[],
options: ts.CompilerOptions = {
noStrictGenericChecks: true,
noImplicitUseStrict: true,
noEmitOnError: false,
noImplicitAny: true,
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.None,
moduleResolution: ts.ModuleResolutionKind.Classic,
noEmitHelpers: true,
maxNodeModuleJsDepth: 0,
esModuleInterop: false
}
) {
const program = ts.createProgram(fileNames, options);
const emitResult = program.emit();
const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
allDiagnostics.forEach(diagnostic => {
if (!TSCompiler.shouldIgnoreError(diagnostic)) {
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (diagnostic.file !== undefined) {
if (
diagnostic.file.fileName.indexOf('readable-stream') == -1 &&
diagnostic.file.fileName.indexOf('request-promise') == -1
) {
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
GBLog.error(`BASIC error: ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
}
} else {
GBLog.error(`BASIC error: ${message}`);
}
}
});
return emitResult;
}
}

View file

@ -145,7 +145,7 @@ export class WebAutomationKeywords {
/**
* Find element on page DOM.
*
* @example GET page,"selector"
* @example GET "selector"
*/
public async getBySelector ({ handle, selector }) {
const page = this.getPageByHandle(handle);

View file

@ -1,156 +0,0 @@
// Source: https://github.com/uweg/vbscript-to-typescript
'use strict';
import fs_1 from 'fs';
import path from 'path';
export function convertFile (file) {
var extension = path.extname(file);
var withoutExtension = file.substr(0, file.length - extension.length);
var targetFile = withoutExtension + '.ts';
var baseName = path.basename(file, extension);
var content = fs_1.readFileSync(file, 'utf8');
var result = convert(content, baseName);
console.log('Writing to "' + targetFile + '"...');
fs_1.writeFileSync(targetFile, result);
}
export function convert (input, name) {
var result = convertImports(input, name);
return result;
}
function convertImports (input, name) {
var items = [];
var result = input.replace(/<!-- #include file="(.*?\/)?(.*?).asp" -->/gi, function (input, group1, group2) {
var path = group1 || './';
var file = '' + path + group2;
items.push({ name: group2, path: file });
return '<%\n' + group2 + '();\n%>';
});
result = convertCode(result);
result = convertExpressions(result);
result = convertStrings(result);
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
var item = items_1[_i];
result = 'import {' + item.name + '} from "' + item.path + '"\n' + result;
}
return result;
}
function convertCode (input) {
var result = input.replace(/<%([^=][\s\S]*?)%>/gi, function (input, group1) {
var code = group1;
code = convertComments(code);
code = convertIfStatements(code);
code = convertSwitchStatements(code);
code = convertFunctions(code);
code = convertForStatements(code);
code = convertLoops(code);
code = convertPRec(code);
code = convertPLan(code);
return '<%' + code + '%>';
});
return result;
}
function convertExpressions (input) {
var result = input.replace(/<%=([\s\S]*?)%>/gi, function (input, group1) {
var content = convertPRec(group1);
content = convertPLan(content);
return '${' + content + '}';
});
return result;
}
function convertStrings (input) {
var result = input.replace(/%>([\s\S]+?)<%/gi, '\nResponse.Write(`$1`);\n');
// Entire document is a string
if (result.indexOf('<%') === -1) {
result = 'Response.Write(`' + result + '`);';
}
// Start of the document is a string
var firstIndex = result.indexOf('<%');
if (firstIndex > 0) {
result = 'Response.Write(`' + result.substr(0, firstIndex) + '`);\n' + result.substring(firstIndex + 2);
}
result = result.replace(/%>$/, '');
// End of the document is a string
var lastIndex = result.lastIndexOf('%>');
if (lastIndex > -1 && lastIndex < result.length - 2) {
result = result.substr(0, lastIndex) + '\nResponse.Write(`' + result.substr(lastIndex + 3) + '`);';
}
result = result.replace(/^<%/, '');
return result;
}
function convertComments (input) {
var result = '';
var splitted = input.split(/(".*")/gim);
for (var _i = 0, splitted_1 = splitted; _i < splitted_1.length; _i++) {
var part = splitted_1[_i];
if (part.indexOf('"') === 0) {
result += part;
} else {
result += part.replace(/'/gi, '//');
}
}
return result;
}
function convertIfStatements (input) {
var result = input.replace(/if +(.*?) +then/gi, function (input, group1) {
var condition = convertConditions(group1);
return '\nif (' + condition + ') {\n';
});
result = result.replace(/end if/gi, '\n}\n');
result = result.replace(/else(?!{)/gi, '\n}\nelse {\n');
return result;
}
function convertSwitchStatements (input) {
var result = input.replace(/select case +(.*)/gi, '\nswitch ($1) {\n');
result = result.replace(/end select/gi, '\n}\n');
return result;
}
function convertFunctions (input) {
var result = input.replace(/function +(.*)\((.*)\)/gi, '\n$1 = ($2) => {\n');
result = result.replace(/end function/gi, '\n}\n');
return result;
}
function convertForStatements (input) {
var result = input.replace(/for +(.*to.*)/gi, '\nfor ($1) {\n');
result = result.replace(/^ *next *$/gim, '}\n');
return result;
}
function convertConditions (input) {
var result = input.replace(/ +and +/gi, ' && ');
result = result.replace(/ +or +/gi, ' || ');
result = result.replace(/ +<> +/gi, ' !== ');
result = result.replace(/ += +/gi, ' === ');
return result;
}
function convertLoops (input) {
var result = input.replace(/do while +(.*)/gi, function (input, group1) {
var condition = convertConditions(group1);
return '\nwhile (' + condition + ') {\n';
});
result = result.replace(/^ *loop *$/gim, '}\n');
return result;
}
function convertPRec (input) {
var result = input.replace(/(p_rec\("\S+?"\))/gi, '$1.Value');
return result;
}
function convertPLan (input) {
var result = input.replace(/(l_\S+?)\(p_lan\)/gi, '$1[p_lan]');
return result;
}

View file

@ -85,7 +85,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Deployer needs core and importer to be created.
*/
constructor (core: IGBCoreService, importer: GBImporter) {
constructor(core: IGBCoreService, importer: GBImporter) {
this.core = core;
this.importer = importer;
}
@ -94,16 +94,14 @@ export class GBDeployer implements IGBDeployer {
* Builds a connection string text to be used in direct
* use to database like the Indexer (Azure Search).
*/
public static getConnectionStringFromInstance (instance: IGBInstance) {
return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${
instance.storageUsername
};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
public static getConnectionStringFromInstance(instance: IGBInstance) {
return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${instance.storageUsername};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
}
/**
* Retrives token and initialize drive client API.
*/
public static async internalGetDriveClient (min: GBMinInstance) {
public static async internalGetDriveClient(min: GBMinInstance) {
const token = await min.adminService.acquireElevatedToken(min.instance.instanceId);
const siteId = process.env.STORAGE_SITE_ID;
const libraryId = process.env.STORAGE_LIBRARY;
@ -120,7 +118,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Performs package deployment in all .gbai or default.
*/
public async deployPackages (core: IGBCoreService, server: any, appPackages: IGBPackage[]) {
public async deployPackages(core: IGBCoreService, server: any, appPackages: IGBPackage[]) {
// Builds lists of paths to search for packages.
let paths = [urlJoin(process.env.PWD, GBDeployer.deployFolder), urlJoin(process.env.PWD, GBDeployer.workFolder)];
@ -132,7 +130,7 @@ export class GBDeployer implements IGBDeployer {
const gbappPackages: string[] = [];
const generalPackages: string[] = [];
async function scanPackageDirectory (path) {
async function scanPackageDirectory(path) {
// Gets all directories.
const isDirectory = source => Fs.lstatSync(source).isDirectory();
@ -201,7 +199,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Deploys a new blank bot to the database, cognitive services and other services.
*/
public async deployBlankBot (botId: string, mobile: string, email: string) {
public async deployBlankBot(botId: string, mobile: string, email: string) {
// Creates a new row on the GuaribasInstance table.
const instance = await this.importer.createBotInstance(botId);
@ -243,7 +241,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Verifies if bot exists on bot catalog.
*/
public async botExists (botId: string): Promise<boolean> {
public async botExists(botId: string): Promise<boolean> {
const service = await AzureDeployerService.createInstance(this);
return await service.botExists(botId);
@ -252,7 +250,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Performs all tasks of deploying a new bot on the cloud.
*/
public async deployBotFull (instance: IGBInstance, publicAddress: string): Promise<IGBInstance> {
public async deployBotFull(instance: IGBInstance, publicAddress: string): Promise<IGBInstance> {
// Reads base configuration from environent file.
const service = await AzureDeployerService.createInstance(this);
@ -322,7 +320,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Performs the NLP publishing process on remote service.
*/
public async publishNLP (instance: IGBInstance): Promise<void> {
public async publishNLP(instance: IGBInstance): Promise<void> {
const service = await AzureDeployerService.createInstance(this);
const res = await service.publishNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
if (res.status !== 200 && res.status !== 201) {
@ -333,7 +331,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Trains NLP on the remote service.
*/
public async trainNLP (instance: IGBInstance): Promise<void> {
public async trainNLP(instance: IGBInstance): Promise<void> {
const service = await AzureDeployerService.createInstance(this);
const res = await service.trainNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
if (res.status !== 200 && res.status !== 202) {
@ -350,7 +348,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Return a zip file for importing bot in apps, currently MS Teams.
*/
public async getBotManifest (instance: IGBInstance): Promise<Buffer> {
public async getBotManifest(instance: IGBInstance): Promise<Buffer> {
const s = new TeamsService();
const manifest = await s.getManifest(
instance.marketplaceId,
@ -367,7 +365,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Refreshes NLP entities on the remote service.
*/
public async refreshNLPEntity (instance: IGBInstance, listName, listData): Promise<void> {
public async refreshNLPEntity(instance: IGBInstance, listName, listData): Promise<void> {
const service = await AzureDeployerService.createInstance(this);
const res = await service.refreshEntityList(
instance.cloudLocation,
@ -384,7 +382,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Deploys a bot to the storage from a .gbot folder.
*/
public async deployBotFromLocalPath (localPath: string, publicAddress: string): Promise<void> {
public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise<void> {
const packageName = Path.basename(localPath);
const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
await this.deployBotFull(instance, publicAddress);
@ -393,7 +391,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Loads all para from tabular file Config.xlsx.
*/
public async loadParamsFromTabular (min: GBMinInstance): Promise<any> {
public async loadParamsFromTabular(min: GBMinInstance): Promise<any> {
const siteId = process.env.STORAGE_SITE_ID;
const libraryId = process.env.STORAGE_LIBRARY;
@ -433,9 +431,7 @@ export class GBDeployer implements IGBDeployer {
const results = await client
.api(
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${
document[0].id
}/workbook/worksheets('General')/range(address='A7:B100')`
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${document[0].id}/workbook/worksheets('General')/range(address='A7:B100')`
)
.get();
let index = 0,
@ -453,7 +449,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Loads all para from tabular file Config.xlsx.
*/
public async downloadFolder (
public async downloadFolder(
min: GBMinInstance,
localPath: string,
remotePath: string,
@ -535,7 +531,7 @@ export class GBDeployer implements IGBDeployer {
/**
* UndDeploys a bot to the storage.
*/
public async undeployBot (botId: string, packageName: string): Promise<void> {
public async undeployBot(botId: string, packageName: string): Promise<void> {
// Deletes Bot registration on cloud.
const service = await AzureDeployerService.createInstance(this);
@ -556,7 +552,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Deploys a new package to the database storage (just a group).
*/
public async deployPackageToStorage (instanceId: number, packageName: string): Promise<GuaribasPackage> {
public async deployPackageToStorage(instanceId: number, packageName: string): Promise<GuaribasPackage> {
return await GuaribasPackage.create(<GuaribasPackage>{
packageName: packageName,
instanceId: instanceId
@ -566,7 +562,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Deploys a folder into the bot storage.
*/
public async deployPackage (min: GBMinInstance, localPath: string) {
public async deployPackage(min: GBMinInstance, localPath: string) {
const packageType = Path.extname(localPath);
let handled = false;
let pck = null;
@ -575,28 +571,24 @@ export class GBDeployer implements IGBDeployer {
const _this = this;
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
try {
// If it will be handled, create a temporary service layer to be
// called by .gbapp and manage the associated package row.
// If it will be handled, create a temporary service layer to be
// called by .gbapp and manage the associated package row.
if (
(pck = await e.onExchangeData(min, 'handlePackage', {
name: localPath,
createPackage: async packageName => {
return await _this.deployPackageToStorage(min.instance.instanceId, packageName);
},
updatePackage: async (p: GuaribasPackage) => {
p.save();
},
existsPackage: async (packageName: string) => {
return await _this.getStoragePackageByName(min.instance.instanceId, packageName);
}
}))
) {
handled = true;
}
} catch (error) {
GBLog.error(error);
if (
(pck = await e.onExchangeData(min, 'handlePackage', {
name: localPath,
createPackage: async packageName => {
return await _this.deployPackageToStorage(min.instance.instanceId, packageName);
},
updatePackage: async (p: GuaribasPackage) => {
p.save();
},
existsPackage: async (packageName: string) => {
return await _this.getStoragePackageByName(min.instance.instanceId, packageName);
}
}))
) {
handled = true;
}
});
@ -663,16 +655,14 @@ export class GBDeployer implements IGBDeployer {
break;
default:
const err = GBError.create(`Unhandled package type: ${packageType}.`);
Promise.reject(err);
break;
}
throw GBError.create(`Unhandled package type: ${packageType}.`);
}
}
/**
* Removes the package from the storage and local work folders.
*/
public async undeployPackageFromLocalPath (instance: IGBInstance, localPath: string) {
public async undeployPackageFromLocalPath(instance: IGBInstance, localPath: string) {
// Gets information about the package.
const packageType = Path.extname(localPath);
@ -720,7 +710,7 @@ export class GBDeployer implements IGBDeployer {
* Performs automation of the Indexer (Azure Search) and rebuild
* its index based on .gbkb structure.
*/
public async rebuildIndex (instance: IGBInstance, searchSchema: any) {
public async rebuildIndex(instance: IGBInstance, searchSchema: any) {
// Prepares search.
const search = new AzureSearch(
@ -770,7 +760,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Finds a storage package by using package name.
*/
public async getStoragePackageByName (instanceId: number, packageName: string): Promise<GuaribasPackage> {
public async getStoragePackageByName(instanceId: number, packageName: string): Promise<GuaribasPackage> {
const where = { packageName: packageName, instanceId: instanceId };
return await GuaribasPackage.findOne({
@ -782,7 +772,7 @@ export class GBDeployer implements IGBDeployer {
* Prepares the React application inside default.gbui folder and
* makes this web application available as default web front-end.
*/
public setupDefaultGBUI () {
public setupDefaultGBUI() {
// Setups paths.
const root = 'packages/default.gbui';
@ -809,7 +799,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Servers bot storage assets to be used by web, WhatsApp and other channels.
*/
public static mountGBKBAssets (packageName: any, botId: string, filename: string) {
public static mountGBKBAssets(packageName: any, botId: string, filename: string) {
// Servers menu assets.
GBServer.globals.server.use(
@ -848,7 +838,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Invokes Type Script compiler for a given .gbapp package (Node.js based).
*/
public async callGBAppCompiler (
public async callGBAppCompiler(
gbappPath: string,
core: IGBCoreService,
appPackages: any[] = undefined,
@ -906,7 +896,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Determines if a given package is of system kind.
*/
private isSystemPackage (name: string): Boolean {
private isSystemPackage(name: string): Boolean {
const names = [
'analytics.gblib',
'console.gblib',
@ -930,7 +920,7 @@ export class GBDeployer implements IGBDeployer {
/**
* Performs the process of compiling all .gbapp folders.
*/
private async deployAppPackages (gbappPackages: string[], core: any, appPackages: any[]) {
private async deployAppPackages(gbappPackages: string[], core: any, appPackages: any[]) {
// Loops through all ready to load .gbapp packages.
let appPackagesProcessed = 0;

View file

@ -96,9 +96,11 @@ export class GBServer {
server.use(bodyParser.urlencoded({ extended: true }));
process.on('unhandledRejection', (err, p) => {
console.log('An unhandledRejection occurred');
console.log(`Rejected Promise: ${p}`);
console.log(`Rejection: ${err}`);
GBLog.error(`UNHANDLED_REJECTION(promises): ${p} ${err.toString()}`);
});
process.on('uncaughtException', (err, origin) => {
GBLog.error(`UNCAUGHT_EXCEPTION: ${err.toString()}`);
});
// Creates working directory.
@ -240,7 +242,7 @@ export class GBServer {
})();
};
//
//
if (process.env.CERTIFICATE_PFX) {
const options1 = {