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 dist: focal
language: node_js language: node_js
node_js: node_js:
- 19.4.0 - 19.5.0
notifications: notifications:

View file

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

View file

@ -312,7 +312,6 @@ export class AdminDialog extends IGBDialog {
} }
await CollectionUtil.asyncForEach(packages, async packageName => { await CollectionUtil.asyncForEach(packages, async packageName => {
try {
let cmd1; let cmd1;
if (packageName.indexOf('.') !== -1) { if (packageName.indexOf('.') !== -1) {
cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`; 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 GBAdminService.deployPackageCommand(min, cmd1, deployer);
await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`); 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); await min.conversationalService.sendText(min, step, Messages[locale].publish_success);
if (!step.activeDialog.state.options.confirm) { if (!step.activeDialog.state.options.confirm) {

View file

@ -37,7 +37,7 @@
'use strict'; 'use strict';
import { AuthenticationContext, TokenResponse } from 'adal-node'; 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 { FindOptions } from 'sequelize/types';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService.js'; import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService.js';
@ -205,18 +205,23 @@ export class GBAdminService implements IGBAdminService {
const options = <FindOptions>{ where: {} }; const options = <FindOptions>{ where: {} };
options.where = { key: key, instanceId: instanceId }; options.where = { key: key, instanceId: instanceId };
const obj = await GuaribasAdmin.findOne(options); const obj = await GuaribasAdmin.findOne(options);
return obj.value; return obj.value;
} }
public async acquireElevatedToken(instanceId: number): Promise<string> { public async acquireElevatedToken(instanceId: number): Promise<string> {
const minBoot = GBServer.globals.minBoot; const minBoot = GBServer.globals.minBoot;
instanceId = minBoot.instance.instanceId; 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) => { return new Promise<string>(async (resolve, reject) => {
const instance = await this.core.loadInstanceById(instanceId); 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()) { if (expiresOn.getTime() > new Date().getTime()) {
const accessToken = await this.getValue(instanceId, 'accessToken'); const accessToken = await this.getValue(instanceId, 'accessToken');
resolve(accessToken); resolve(accessToken);

View file

@ -42,7 +42,7 @@ import { CognitiveServicesManagementClient } from '@azure/arm-cognitiveservices'
import { ResourceManagementClient } from '@azure/arm-resources'; import { ResourceManagementClient } from '@azure/arm-resources';
import { SubscriptionClient } from '@azure/arm-subscriptions'; import { SubscriptionClient } from '@azure/arm-subscriptions';
import { SearchManagementClient } from '@azure/arm-search'; 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 { WebSiteManagementClient } from '@azure/arm-appservice';
import { AppServicePlan, Site, SiteLogsConfig, SiteSourceControl } from '@azure/arm-appservice'; import { AppServicePlan, Site, SiteLogsConfig, SiteSourceControl } from '@azure/arm-appservice';
import { GBLog, IGBInstallationDeployer, IGBInstance, IGBDeployer, IGBCoreService } from 'botlib'; 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 { GBDeployer } from '../../../packages/core.gbapp/services/GBDeployer.js';
import { Account } from '@azure/arm-cognitiveservices'; import { Account } from '@azure/arm-cognitiveservices';
import MicrosoftGraph from '@microsoft/microsoft-graph-client'; import MicrosoftGraph from '@microsoft/microsoft-graph-client';
import {Spinner} from 'cli-spinner'; import { Spinner } from 'cli-spinner';
import * as publicIp from 'public-ip'; import * as publicIp from 'public-ip';
import { AccessToken, TokenCredential } from '@azure/core-auth'; import { AccessToken, TokenCredential } from '@azure/core-auth';
const WebSiteResponseTimeout = 900; const WebSiteResponseTimeout = 900;
const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png'; 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; public core: IGBCoreService;
private freeTier: boolean; private freeTier: boolean;
public async runSearch(instance: IGBInstance) {
public async runSearch (instance: IGBInstance) {
await this.deployer.rebuildIndex(instance, this.getKBSearchSchema(instance.searchIndex)); 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 username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID'); const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
@ -106,7 +102,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return service; 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(); const req = new WebResource();
req.method = verb; req.method = verb;
req.url = url; req.url = url;
@ -118,13 +114,13 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return req; return req;
} }
public async getSubscriptions (credentials) { public async getSubscriptions(credentials) {
const subscriptionClient = new SubscriptionClient(credentials); const subscriptionClient = new SubscriptionClient(credentials);
return subscriptionClient.subscriptions.list(); return subscriptionClient.subscriptions.list();
} }
public getKBSearchSchema (indexName: any) { public getKBSearchSchema(indexName: any) {
return { return {
name: indexName, name: indexName,
fields: [ 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 baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
@ -257,7 +253,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return !res.parsedBody.valid; 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 baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
@ -272,9 +268,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} }
}; };
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query); const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters)); const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req); const res = await httpClient.sendRequest(req);
@ -285,7 +279,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot proxy updated at: ${endpoint}.`); 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 baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
@ -303,9 +297,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} }
}; };
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query); const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters)); const req = AzureDeployerService.createRequestObject(url, accessToken, 'PATCH', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req); const res = await httpClient.sendRequest(req);
@ -316,7 +308,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot updated at: ${endpoint}.`); 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 baseUrl = `https://management.azure.com/`;
const username = GBConfigService.get('CLOUD_USERNAME'); const username = GBConfigService.get('CLOUD_USERNAME');
const password = GBConfigService.get('CLOUD_PASSWORD'); const password = GBConfigService.get('CLOUD_PASSWORD');
@ -325,9 +317,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password); const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
const httpClient = new ServiceClient(); const httpClient = new ServiceClient();
const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ const query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
const url = urlJoin(baseUrl, query); const url = urlJoin(baseUrl, query);
const req = AzureDeployerService.createRequestObject(url, accessToken, 'DELETE', undefined); const req = AzureDeployerService.createRequestObject(url, accessToken, 'DELETE', undefined);
const res = await httpClient.sendRequest(req); const res = await httpClient.sendRequest(req);
@ -338,10 +328,9 @@ export class AzureDeployerService implements IGBInstallationDeployer {
GBLog.info(`Bot ${botId} was deleted from the provider.`); 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 subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
const ip = await publicIp.publicIpv4(); const ip = await publicIp.publicIpv4();
let params = { let params = {
startIpAddress: ip, startIpAddress: ip,
@ -350,7 +339,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
await this.storageClient.firewallRules.createOrUpdate(groupName, serverName, 'gb', params); await this.storageClient.firewallRules.createOrUpdate(groupName, serverName, 'gb', params);
} }
public async deployFarm ( public async deployFarm(
proxyAddress: string, proxyAddress: string,
instance: IGBInstance, instance: IGBInstance,
credentials: any, credentials: any,
@ -474,7 +463,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return instance; return instance;
} }
public async deployToCloud ( public async deployToCloud(
title: string, title: string,
username: string, username: string,
password: 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 * @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, instance,
accessToken: string, accessToken: string,
botId: string, botId: string,
name: string, name: string,
group, group,
description: string , description: string,
endpoint, endpoint,
location, location,
nlpAppId, nlpAppId,
@ -550,9 +539,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
}; };
const httpClient = new ServiceClient(); const httpClient = new ServiceClient();
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${ let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=${this.apiVersion}`;
this.provider
}/botServices/${botId}?api-version=${this.apiVersion}`;
let url = urlJoin(baseUrl, query); let url = urlJoin(baseUrl, query);
let req = AzureDeployerService.createRequestObject(url, accessToken, 'PUT', JSON.stringify(parameters)); let req = AzureDeployerService.createRequestObject(url, accessToken, 'PUT', JSON.stringify(parameters));
const res = await httpClient.sendRequest(req); const res = await httpClient.sendRequest(req);
@ -564,9 +551,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
try { try {
//tslint:disable-next-line:max-line-length //tslint:disable-next-line:max-line-length
query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${ query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/Microsoft.BotService/botServices/${botId}/channels/WebChatChannel/listChannelWithKeys?api-version=${this.apiVersion}`;
this.apiVersion
}`;
url = urlJoin(baseUrl, query); url = urlJoin(baseUrl, query);
req = AzureDeployerService.createRequestObject(url, accessToken, 'POST', JSON.stringify(parameters)); req = AzureDeployerService.createRequestObject(url, accessToken, 'POST', JSON.stringify(parameters));
const resChannel = await httpClient.sendRequest(req); const resChannel = await httpClient.sendRequest(req);
@ -580,21 +565,18 @@ export class AzureDeployerService implements IGBInstallationDeployer {
}); });
} }
public async syncBotServerRepository (group: string, name: string) { public async syncBotServerRepository(group: string, name: string) {
await this.webSiteClient.webApps.syncRepository(group, name); 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; this.accessToken = accessToken;
class AccessToken2 implements AccessToken class AccessToken2 implements AccessToken {
{
public expiresOnTimestamp: number; public expiresOnTimestamp: number;
public token: string; public token: string;
} }
class StaticAccessToken implements TokenCredential { class StaticAccessToken implements TokenCredential {
public getToken(): Promise<AccessToken> { public getToken(): Promise<AccessToken> {
return new Promise<AccessToken>(async (resolve, reject) => { return new Promise<AccessToken>(async (resolve, reject) => {
const t = new AccessToken2(); const t = new AccessToken2();
@ -614,15 +596,30 @@ export class AzureDeployerService implements IGBInstallationDeployer {
this.searchClient = new SearchManagementClient(token, subscriptionId); 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 = { const params = {
location: location, location: location,
administratorLogin: administratorLogin, administratorLogin: administratorLogin,
administratorLoginPassword: administratorPassword, 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 // AllowAllWindowsAzureIps must be created that way, so the Azure Search can
// access SQL Database to index its contents. // access SQL Database to index its contents.
@ -636,7 +633,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return database; return database;
} }
public async createApplication (token: string, name: string) { public async createApplication(token: string, name: string) {
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
let client = MicrosoftGraph.Client.init({ let client = MicrosoftGraph.Client.init({
authProvider: done => { 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) => { return new Promise<string>((resolve, reject) => {
let client = MicrosoftGraph.Client.init({ let client = MicrosoftGraph.Client.init({
authProvider: done => { 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 query = `subscriptions/${subscriptionId}/providers/${this.provider}/register?api-version=2018-02-01`;
const requestUrl = urlJoin(baseUrl, query); const requestUrl = urlJoin(baseUrl, query);
@ -693,7 +690,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
(req.headers as any).Authorization = `Bearer ${accessToken}`; (req.headers as any).Authorization = `Bearer ${accessToken}`;
} }
private async createNLPService ( private async createNLPService(
name: string, name: string,
description: string, description: string,
location: string, location: string,
@ -731,7 +728,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return id.replace(/\'/gi, ''); return id.replace(/\'/gi, '');
} }
private async makeNlpRequest ( private async makeNlpRequest(
location: string, location: string,
authoringKey: string, authoringKey: string,
body: string, body: string,
@ -750,7 +747,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req); 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(); const req = new WebResource();
req.method = 'PUT'; req.method = 'PUT';
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/${nlpAppId}/versions/0.1/closedlists/${clEntityId}`; 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); 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(); const req = new WebResource();
req.method = 'POST'; req.method = 'POST';
req.url = `https://${location}.api.cognitive.microsoft.com/luis/api/v2.0/apps/${nlpAppId}/versions/0.1/train`; 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); 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 = { const body = {
versionId: '0.1', versionId: '0.1',
isStaging: false, isStaging: false,
@ -793,7 +790,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await httpClient.sendRequest(req); 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 = { const params = {
sku: { sku: {
name: this.freeTier ? 'free' : 'standard' 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); 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 = { const params = {
sku: { name: this.freeTier ? 'Free' : 'Basic' }, sku: { name: 'Basic' },
createMode: 'Default', createMode: 'Default',
location: location 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 = { const params = {
sku: { sku: {
name: name name: name
@ -840,40 +846,40 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await this.cognitiveClient.accounts.beginCreateAndWait(group, name, params); 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'); 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'); 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'); 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'); 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'); 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 }; const params = { location: location };
return await this.cloud.resourceGroups.createOrUpdate(name, params); 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); const ret = await this.cloud.providers.get(name);
if (ret.registrationState === 'NotRegistered') { if (ret.registrationState === 'NotRegistered') {
await this.cloud.providers.register(name); 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 = { const params = {
serverFarmWithRichSkuName: name, serverFarmWithRichSkuName: name,
location: location, location: location,
@ -887,7 +893,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
return await this.webSiteClient.appServicePlans.beginCreateOrUpdateAndWait(group, name, params); 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; let tryed = false;
const create = async () => { const create = async () => {
const parameters: Site = { 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 = { const parameters: Site = {
location: instance.cloudLocation, location: instance.cloudLocation,
serverFarmId: serverFarmId, serverFarmId: serverFarmId,

View file

@ -36,14 +36,12 @@ import { GBLog, GBMinInstance, GBService, IGBCoreService, GBDialogStep } from 'b
import * as Fs from 'fs'; import * as Fs from 'fs';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
import { TSCompiler } from './TSCompiler.js';
import { CollectionUtil } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework';
import { ScheduleServices } from './ScheduleServices.js'; import { ScheduleServices } from './ScheduleServices.js';
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js'; import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { NodeVM, VMScript } from 'vm2'; import { NodeVM, VMScript } from 'vm2';
import { createVm2Pool } from './vm2-process/index.js'; import { createVm2Pool } from './vm2-process/index.js';
import * as vb2ts from './vbscript-to-typescript.js';
import textract from 'textract'; import textract from 'textract';
import walkPromise from 'walk-promise'; import walkPromise from 'walk-promise';
import child_process from 'child_process'; import child_process from 'child_process';
@ -208,21 +206,9 @@ export class GBVMService extends GBService {
Fs.writeFileSync(vbsFile, code); Fs.writeFileSync(vbsFile, code);
Fs.writeFileSync(mapFile, JSON.stringify(jsonMap)); 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. // Run JS into the GB context.
const jsfile = `${tsfile}.js`.replace('.ts', ''); const jsfile: string = `${filename}.js`;
if (Fs.existsSync(jsfile)) { if (Fs.existsSync(jsfile)) {
let code: string = Fs.readFileSync(jsfile, 'utf8'); let code: string = Fs.readFileSync(jsfile, 'utf8');
@ -354,12 +340,9 @@ export class GBVMService extends GBService {
public async convertGBASICToVBS(min: GBMinInstance, code: string) { public async convertGBASICToVBS(min: GBMinInstance, code: string) {
// Start and End of VB2TS tags of processing. // Start and End of VB2TS tags of processing.
code = `<%\n code = `
${process.env.ENABLE_AUTH ? `hear gbLogin as login` : ``} ${process.env.ENABLE_AUTH ? `hear gbLogin as login` : ``}
${code} ${code}
`; `;
var allLines = code.split('\n'); var allLines = code.split('\n');
@ -388,6 +371,14 @@ export class GBVMService extends GBService {
let keywords = []; let keywords = [];
let i = 0; 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++] = [ keywords[i++] = [
/^\s*(\w+)\s*\=\s*SELECT\s*(.*)/gim, /^\s*(\w+)\s*\=\s*SELECT\s*(.*)/gim,
($0, $1, $2) => { ($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++] = [ keywords[i++] = [
/^\s*open\s*(.*)/gim, /^\s*open\s*(.*)/gim,
($0, $1, $2) => { ($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. * Find element on page DOM.
* *
* @example GET page,"selector" * @example GET "selector"
*/ */
public async getBySelector ({ handle, selector }) { public async getBySelector ({ handle, selector }) {
const page = this.getPageByHandle(handle); 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. * Deployer needs core and importer to be created.
*/ */
constructor (core: IGBCoreService, importer: GBImporter) { constructor(core: IGBCoreService, importer: GBImporter) {
this.core = core; this.core = core;
this.importer = importer; this.importer = importer;
} }
@ -94,16 +94,14 @@ export class GBDeployer implements IGBDeployer {
* Builds a connection string text to be used in direct * Builds a connection string text to be used in direct
* use to database like the Indexer (Azure Search). * use to database like the Indexer (Azure Search).
*/ */
public static getConnectionStringFromInstance (instance: IGBInstance) { public static getConnectionStringFromInstance(instance: IGBInstance) {
return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${ return `Server=tcp:${instance.storageServer},1433;Database=${instance.storageName};User ID=${instance.storageUsername};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
instance.storageUsername
};Password=${instance.storagePassword};Trusted_Connection=False;Encrypt=True;Connection Timeout=30;`;
} }
/** /**
* Retrives token and initialize drive client API. * 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 token = await min.adminService.acquireElevatedToken(min.instance.instanceId);
const siteId = process.env.STORAGE_SITE_ID; const siteId = process.env.STORAGE_SITE_ID;
const libraryId = process.env.STORAGE_LIBRARY; const libraryId = process.env.STORAGE_LIBRARY;
@ -120,7 +118,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Performs package deployment in all .gbai or default. * 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. // Builds lists of paths to search for packages.
let paths = [urlJoin(process.env.PWD, GBDeployer.deployFolder), urlJoin(process.env.PWD, GBDeployer.workFolder)]; 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 gbappPackages: string[] = [];
const generalPackages: string[] = []; const generalPackages: string[] = [];
async function scanPackageDirectory (path) { async function scanPackageDirectory(path) {
// Gets all directories. // Gets all directories.
const isDirectory = source => Fs.lstatSync(source).isDirectory(); 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. * 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. // Creates a new row on the GuaribasInstance table.
const instance = await this.importer.createBotInstance(botId); const instance = await this.importer.createBotInstance(botId);
@ -243,7 +241,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Verifies if bot exists on bot catalog. * 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); const service = await AzureDeployerService.createInstance(this);
return await service.botExists(botId); 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. * 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. // Reads base configuration from environent file.
const service = await AzureDeployerService.createInstance(this); const service = await AzureDeployerService.createInstance(this);
@ -322,7 +320,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Performs the NLP publishing process on remote service. * 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 service = await AzureDeployerService.createInstance(this);
const res = await service.publishNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey); const res = await service.publishNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
if (res.status !== 200 && res.status !== 201) { if (res.status !== 200 && res.status !== 201) {
@ -333,7 +331,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Trains NLP on the remote service. * 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 service = await AzureDeployerService.createInstance(this);
const res = await service.trainNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey); const res = await service.trainNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
if (res.status !== 200 && res.status !== 202) { 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. * 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 s = new TeamsService();
const manifest = await s.getManifest( const manifest = await s.getManifest(
instance.marketplaceId, instance.marketplaceId,
@ -367,7 +365,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Refreshes NLP entities on the remote service. * 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 service = await AzureDeployerService.createInstance(this);
const res = await service.refreshEntityList( const res = await service.refreshEntityList(
instance.cloudLocation, instance.cloudLocation,
@ -384,7 +382,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Deploys a bot to the storage from a .gbot folder. * 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 packageName = Path.basename(localPath);
const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath); const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
await this.deployBotFull(instance, publicAddress); await this.deployBotFull(instance, publicAddress);
@ -393,7 +391,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Loads all para from tabular file Config.xlsx. * 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 siteId = process.env.STORAGE_SITE_ID;
const libraryId = process.env.STORAGE_LIBRARY; const libraryId = process.env.STORAGE_LIBRARY;
@ -433,9 +431,7 @@ export class GBDeployer implements IGBDeployer {
const results = await client const results = await client
.api( .api(
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${ `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/items/${document[0].id}/workbook/worksheets('General')/range(address='A7:B100')`
document[0].id
}/workbook/worksheets('General')/range(address='A7:B100')`
) )
.get(); .get();
let index = 0, let index = 0,
@ -453,7 +449,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Loads all para from tabular file Config.xlsx. * Loads all para from tabular file Config.xlsx.
*/ */
public async downloadFolder ( public async downloadFolder(
min: GBMinInstance, min: GBMinInstance,
localPath: string, localPath: string,
remotePath: string, remotePath: string,
@ -535,7 +531,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* UndDeploys a bot to the storage. * 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. // Deletes Bot registration on cloud.
const service = await AzureDeployerService.createInstance(this); 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). * 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>{ return await GuaribasPackage.create(<GuaribasPackage>{
packageName: packageName, packageName: packageName,
instanceId: instanceId instanceId: instanceId
@ -566,7 +562,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Deploys a folder into the bot storage. * 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); const packageType = Path.extname(localPath);
let handled = false; let handled = false;
let pck = null; let pck = null;
@ -575,7 +571,6 @@ export class GBDeployer implements IGBDeployer {
const _this = this; const _this = this;
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => { await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
try {
// If it will be handled, create a temporary service layer to be // If it will be handled, create a temporary service layer to be
// called by .gbapp and manage the associated package row. // called by .gbapp and manage the associated package row.
@ -595,9 +590,6 @@ export class GBDeployer implements IGBDeployer {
) { ) {
handled = true; handled = true;
} }
} catch (error) {
GBLog.error(error);
}
}); });
if (handled) { if (handled) {
@ -663,16 +655,14 @@ export class GBDeployer implements IGBDeployer {
break; break;
default: default:
const err = GBError.create(`Unhandled package type: ${packageType}.`); throw GBError.create(`Unhandled package type: ${packageType}.`);
Promise.reject(err); }
break;
}
} }
/** /**
* Removes the package from the storage and local work folders. * 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. // Gets information about the package.
const packageType = Path.extname(localPath); const packageType = Path.extname(localPath);
@ -720,7 +710,7 @@ export class GBDeployer implements IGBDeployer {
* Performs automation of the Indexer (Azure Search) and rebuild * Performs automation of the Indexer (Azure Search) and rebuild
* its index based on .gbkb structure. * its index based on .gbkb structure.
*/ */
public async rebuildIndex (instance: IGBInstance, searchSchema: any) { public async rebuildIndex(instance: IGBInstance, searchSchema: any) {
// Prepares search. // Prepares search.
const search = new AzureSearch( const search = new AzureSearch(
@ -770,7 +760,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Finds a storage package by using package name. * 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 }; const where = { packageName: packageName, instanceId: instanceId };
return await GuaribasPackage.findOne({ return await GuaribasPackage.findOne({
@ -782,7 +772,7 @@ export class GBDeployer implements IGBDeployer {
* Prepares the React application inside default.gbui folder and * Prepares the React application inside default.gbui folder and
* makes this web application available as default web front-end. * makes this web application available as default web front-end.
*/ */
public setupDefaultGBUI () { public setupDefaultGBUI() {
// Setups paths. // Setups paths.
const root = 'packages/default.gbui'; 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. * 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. // Servers menu assets.
GBServer.globals.server.use( 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). * Invokes Type Script compiler for a given .gbapp package (Node.js based).
*/ */
public async callGBAppCompiler ( public async callGBAppCompiler(
gbappPath: string, gbappPath: string,
core: IGBCoreService, core: IGBCoreService,
appPackages: any[] = undefined, appPackages: any[] = undefined,
@ -906,7 +896,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Determines if a given package is of system kind. * Determines if a given package is of system kind.
*/ */
private isSystemPackage (name: string): Boolean { private isSystemPackage(name: string): Boolean {
const names = [ const names = [
'analytics.gblib', 'analytics.gblib',
'console.gblib', 'console.gblib',
@ -930,7 +920,7 @@ export class GBDeployer implements IGBDeployer {
/** /**
* Performs the process of compiling all .gbapp folders. * 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. // Loops through all ready to load .gbapp packages.
let appPackagesProcessed = 0; let appPackagesProcessed = 0;

View file

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