Skip to content

Commit

Permalink
fix(basic.gblib): COPY and CONVERT is now generating good JS.
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigorodriguez committed Jan 20, 2021
1 parent 8614ff4 commit 3f13609
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 63 deletions.
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"sequelize": "5.21.5",
"sequelize-typescript": "1.1.0",
"simple-git": "2.23.0",
"speakingurl": "^14.0.1",
"sppull": "2.6.7",
"strict-password-generator": "1.1.2",
"swagger-client": "2.1.18",
Expand Down
20 changes: 18 additions & 2 deletions packages/admin.gbapp/services/GBAdminService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { GuaribasAdmin } from '../models/AdminModel';
const Path = require('path');
const msRestAzure = require('ms-rest-azure');
const PasswordGenerator = require('strict-password-generator').default;
const crypto = require("crypto");

/**
* Services for server administration.
Expand Down Expand Up @@ -145,6 +146,21 @@ export class GBAdminService implements IGBAdminService {
return passwordGenerator.generatePassword(options);
}

/**
* @see https://stackoverflow.com/a/52171480
*/
public static getHash(str, seed = 0) {
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}

public static async undeployPackageCommand(text: any, min: GBMinInstance) {
const packageName = text.split(' ')[1];
const importer = new GBImporter(min.core);
Expand Down Expand Up @@ -176,7 +192,7 @@ export class GBAdminService implements IGBAdminService {
// .gbot packages are handled using storage API, so no download
// of local resources is required.


if (!localFolder.endsWith('.gbot')) {
GBLog.warn(`${GBConfigService.get('CLOUD_USERNAME')} must be authorized on SharePoint related site to download to: ${localFolder}`);
await s.downloadFolder(
Expand Down Expand Up @@ -261,7 +277,7 @@ export class GBAdminService implements IGBAdminService {
const refreshToken = await this.getValue(instanceId, 'refreshToken');
const resource = 'https://graph.microsoft.com';
const authenticationContext = new AuthenticationContext(authorizationUrl);

authenticationContext.acquireTokenWithRefreshToken(
refreshToken,
instance.marketplaceId,
Expand Down
13 changes: 7 additions & 6 deletions packages/basic.gblib/services/GBVMService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,12 @@ export class GBVMService extends GBService {
return `sendFile (step, ${$3})\n`;
});

code = code.replace(/(COPY)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `sys().copyFile (step, ${$3})\n`;
code = code.replace(/(copy)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `sys().copyFile(step, ${$3})\n`;
});

code = code.replace(/(convert)(\s*)(.*)/gi, ($0, $1, $2, $3) => {
return `sys().convert(step, ${$3})\n`;
});

code = code.replace(/(save)(\s)(.*)/gi, ($0, $1, $2, $3) => {
Expand Down Expand Up @@ -433,9 +437,6 @@ export class GBVMService extends GBService {
code = code.replace(/("[^"]*"|'[^']*')|\bsendFileTo\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.sendFileTo' : $1;
});
code = code.replace(/("[^"]*"|'[^']*')|\bcopyFile\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.copyFile' : $1;
});
code = code.replace(/("[^"]*"|'[^']*')|\bsendFile\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.sendFile' : $1;
});
Expand All @@ -448,7 +449,7 @@ export class GBVMService extends GBService {
code = code.replace(/("[^"]*"|'[^']*')|\bmenu\b/gi, ($0, $1) => {
return $1 === undefined ? 'this.menu' : $1;
});

// await insertion.

code = code.replace(/this\./gm, 'await this.');
Expand Down
57 changes: 32 additions & 25 deletions packages/core.gbapp/services/GBDeployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export class GBDeployer implements IGBDeployer {
const instances = await core.loadInstances();
await CollectionUtil.asyncForEach(instances, async instance => {
this.mountGBKBAssets(`${instance.botId}.gbkb`,
instance.botId, `${instance.botId}.gbkb`);
instance.botId, `${instance.botId}.gbkb`);
});

GBLog.info(`Package deployment done.`);
Expand Down Expand Up @@ -320,7 +320,7 @@ export class GBDeployer implements IGBDeployer {
public async publishNLP(instance: IGBInstance): Promise<void> {
const service = new AzureDeployerService(this);
const res = await service.publishNLP(instance.cloudLocation, instance.nlpAppId,
instance.nlpAuthoringKey);
instance.nlpAuthoringKey);
if (res.status !== 200 && res.status !== 201) { throw res.bodyAsText; }
}

Expand Down Expand Up @@ -371,29 +371,29 @@ export class GBDeployer implements IGBDeployer {
const libraryId = process.env.STORAGE_LIBRARY;

GBLog.info(`Connecting to Config.xslx (siteId: ${siteId}, libraryId: ${libraryId})...`);

// Connects to MSFT storage.

const token = await min.adminService.acquireElevatedToken(min.instance.instanceId);
const client = MicrosoftGraph.Client.init({
authProvider: done => {
done(null, token);
}
});

// Retrieves all files in .bot folder.

const botId = min.instance.botId;
const path = `/${botId}.gbai/${botId}.gbot`;
let url = `https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root:${path}:/children`;

GBLog.info(`Loading .gbot from Excel: ${url}`);
const res = await client
.api(url)
.get();
.api(url)
.get();

// Finds Config.xlsx.

const document = res.value.filter(m => {
return m.name === 'Config.xlsx';
});
Expand Down Expand Up @@ -496,14 +496,14 @@ export class GBDeployer implements IGBDeployer {
if (handled) {
return pck;
}

// Deploy platform packages here accordingly to their extension.

switch (packageType) {
case '.gbot':

// Extracts configuration information from .gbot files.

if (process.env.ENABLE_PARAMS_ONLINE === 'false') {
if (Fs.existsSync(localPath)) {
GBLog.info(`Loading .gbot from ${localPath}.`);
Expand All @@ -512,9 +512,9 @@ export class GBDeployer implements IGBDeployer {
} else {
min.instance.params = await this.loadParamsFromTabular(min);
}

// Updates instance object.

await this.core.saveInstance(min.instance);

break;
Expand Down Expand Up @@ -561,6 +561,7 @@ export class GBDeployer implements IGBDeployer {
break;

default:

const err = GBError.create(`Unhandled package type: ${packageType}.`);
Promise.reject(err);
break;
Expand All @@ -581,6 +582,7 @@ export class GBDeployer implements IGBDeployer {
// Removes objects from storage, cloud resources and local files if any.

switch (packageType) {

case '.gbot':
const packageObject = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'package.json'), 'utf8'));
await this.undeployBot(packageObject.botId, packageName);
Expand All @@ -596,17 +598,17 @@ export class GBDeployer implements IGBDeployer {
break;

case '.gbtheme':
rimraf.sync(localPath);
break;

case '.gbdialog':
rimraf.sync(localPath);
break;

case '.gblib':
break;

case '.gbapp':
break;

default:
const err = GBError.create(`Unhandled package type: ${packageType}.`);
Promise.reject(err);
Expand Down Expand Up @@ -647,6 +649,7 @@ export class GBDeployer implements IGBDeployer {
}

// Removes the index.

try {
await search.deleteIndex();
} catch (err) {
Expand All @@ -659,6 +662,7 @@ export class GBDeployer implements IGBDeployer {
}

// Creates the data source and index on the cloud.

try {
await search.createDataSource(dsName, dsName, 'GuaribasQuestion', 'azuresql', connectionString);
} catch (err) {
Expand Down Expand Up @@ -694,23 +698,26 @@ export class GBDeployer implements IGBDeployer {

if (!Fs.existsSync(`${root}/build`) && process.env.DISABLE_WEB !== 'true') {

// Write a .env required to fix some bungs in create-react-app facility.
// Write a .env required to fix some bungs in create-react-app tool.

Fs.writeFileSync(`${root}/.env`, 'SKIP_PREFLIGHT_CHECK=true');

// Install modules and compiles the web app.

GBLog.info(`Installing modules default.gbui (It may take a few minutes)...`);
child_process.execSync(`${npm} install`, { cwd: root });

GBLog.info(`Transpiling default.gbui...`);
child_process.execSync(`${npm} run build`, { cwd: root });
}

// Clean up node_modules folder as it is only needed during compile time.

GBLog.info(`Cleaning default.gbui node_modules...`);
const nodeModules = urlJoin(root, 'node_modules');
rimraf.sync(nodeModules);
if (Fs.existsSync(nodeModules)) {
rimraf.sync(nodeModules);
GBLog.info(`Cleaning default.gbui node_modules...`);
}
}

/**
Expand All @@ -729,13 +736,13 @@ export class GBDeployer implements IGBDeployer {

const gbaiName = `${botId}.gbai`;
GBServer.globals.server.use(`/kb/${gbaiName}/${packageName}/assets`,
express.static(urlJoin('work', gbaiName, filename, 'assets')));
express.static(urlJoin('work', gbaiName, filename, 'assets')));
GBServer.globals.server.use(`/kb/${gbaiName}/${packageName}/images`,
express.static(urlJoin('work', gbaiName, filename, 'images')));
express.static(urlJoin('work', gbaiName, filename, 'images')));
GBServer.globals.server.use(`/kb/${gbaiName}/${packageName}/audios`,
express.static(urlJoin('work', gbaiName, filename, 'audios')));
express.static(urlJoin('work', gbaiName, filename, 'audios')));
GBServer.globals.server.use(`/kb/${gbaiName}/${packageName}/videos`,
express.static(urlJoin('work', gbaiName, filename, 'videos')));
express.static(urlJoin('work', gbaiName, filename, 'videos')));

GBLog.info(`KB (.gbkb) assets accessible at: /kb/${botId}.gbai/${packageName}.`);
}
Expand Down
37 changes: 30 additions & 7 deletions packages/core.gbapp/services/GBMinService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export class GBMinService {
public async buildMin(instances: IGBInstance[]) {

// Servers default UI on root address '/' if web enabled.

if (process.env.DISABLE_WEB !== 'true') {
const url = GBServer.globals.wwwroot
? GBServer.globals.wwwroot
Expand All @@ -139,6 +140,8 @@ export class GBMinService {
GBServer.globals.server.use('/', express.static(url));
}



// Servers the bot information object via HTTP so clients can get
// instance information stored on server.

Expand Down Expand Up @@ -216,12 +219,13 @@ export class GBMinService {

await this.invokeLoadBot(GBServer.globals.appPackages, GBServer.globals.sysPackages, min);

// Serves individual URL for each bot conversational interface...
// Serves individual URL for each bot conversational interface.

const url = `/api/messages/${instance.botId}`;
GBServer.globals.server.post(url, async (req, res) => {
const receiver = async (req, res) => {
await this.receiver(adapter, req, res, conversationState, min, instance, GBServer.globals.appPackages);
});
};
const url = `/api/messages/${instance.botId}`;
GBServer.globals.server.post(url, receiver);
GBLog.info(`GeneralBots(${instance.engineName}) listening on: ${url}.`);

// Serves individual URL for each bot user interface.
Expand All @@ -237,7 +241,14 @@ export class GBMinService {
uiUrlAlt,
express.static(urlJoin(GBDeployer.deployFolder, GBMinService.uiPackage, 'build'))
);

const domain = min.core.getParam(min.instance, 'Domain', null);
if (domain) {
GBServer.globals.server.use(
domain,
express.static(urlJoin(GBDeployer.deployFolder, GBMinService.uiPackage, 'build'))
);
GBLog.info(`Bot UI ${GBMinService.uiPackage} accessible at custom domain: ${domain}.`);
}
GBLog.info(`Bot UI ${GBMinService.uiPackage} accessible at: ${uiUrl} and ${uiUrlAlt}.`);
}

Expand Down Expand Up @@ -512,7 +523,12 @@ export class GBMinService {
speechToken: speechToken,
conversationId: webchatTokenContainer.conversationId,
authenticatorTenant: instance.authenticatorTenant,
authenticatorClientId: instance.marketplaceId
authenticatorClientId: instance.marketplaceId,
paramLogoImageUrl: this.core.getParam(instance, 'Logo Image Url', null),
paramLogoImageAlt: this.core.getParam(instance, 'Logo Image Alt', null),
paramLogoImageWidth: this.core.getParam(instance, 'Logo Image Width', null),
paramLogoImageHeight: this.core.getParam(instance, 'Logo Image Height', null),
paramLogoImageType: this.core.getParam(instance, 'Logo Image Type', null)
})
);
} else {
Expand Down Expand Up @@ -603,6 +619,7 @@ export class GBMinService {
if (GBServer.globals.minBoot === undefined) {
GBServer.globals.minBoot = min;
}

// TODO: min.appPackages = core.getPackagesByInstanceId(min.instance.instanceId);

// Creates a hub of services available in .gbapps.
Expand Down Expand Up @@ -735,14 +752,20 @@ export class GBMinService {
user.welcomed = false;
firstTime = true;

// Sends loadInstance event to .gbui clients.
// Sends loadInstance event to .gbui clients and loads FAQ.

await min.conversationalService.sendEvent(min, step, 'loadInstance', {
instanceId: instance.instanceId,
botId: instance.botId,
theme: instance.theme ? instance.theme : 'default.gbtheme',
secret: instance.webchatKey
});
const service = new KBService(min.core.sequelize);
const data = await service.getFaqBySubjectArray('faq', undefined);
await min.conversationalService.sendEvent(min, step, 'play', {
playerType: 'bullet',
data: data.slice(0, 10)
});

// This same event is dispatched either to all participants
// including the bot, that is filtered bellow.
Expand Down

0 comments on commit 3f13609

Please sign in to comment.