fix(all): Fixes #399 tabs missing from JS output.

This commit is contained in:
Rodrigo Rodriguez 2023-12-29 21:43:48 -03:00
parent 2dc6e327e8
commit c23f025d6a
2 changed files with 157 additions and 151 deletions

View file

@ -121,6 +121,7 @@
"ibm-watson": "7.1.2", "ibm-watson": "7.1.2",
"join-images-updated": "1.1.4", "join-images-updated": "1.1.4",
"js-md5": "0.8.3", "js-md5": "0.8.3",
"just-indent": "0.0.1",
"keyv": "4.5.2", "keyv": "4.5.2",
"koa": "2.13.4", "koa": "2.13.4",
"koa-body": "6.0.1", "koa-body": "6.0.1",

View file

@ -32,8 +32,9 @@
'use strict'; 'use strict';
import { GBMinInstance, GBService, IGBCoreService, GBDialogStep, GBLog, GBError } from 'botlib'; import { GBMinInstance, GBService, IGBCoreService, GBLog } from 'botlib';
import * as Fs from 'fs'; import * as Fs from 'fs';
import * as ji from 'just-indent'
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 { CollectionUtil } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework';
@ -52,10 +53,9 @@ import { KeywordsExpressions } from './KeywordsExpressions.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
import { GuaribasUser } from '../../security.gbapp/models/index.js'; import { GuaribasUser } from '../../security.gbapp/models/index.js';
import { SystemKeywords } from './SystemKeywords.js'; import { SystemKeywords } from './SystemKeywords.js';
import lineReplace from 'line-replace'; import { Sequelize, QueryTypes } from '@sequelize/core';
import { Sequelize, DataTypes, QueryTypes } from '@sequelize/core';
import { table } from 'console';
import { SequelizeOptions } from 'sequelize-typescript';
/** /**
* @fileoverview Decision was to priorize security(isolation) and debugging, * @fileoverview Decision was to priorize security(isolation) and debugging,
@ -485,172 +485,171 @@ export class GBVMService extends GBService {
const jsfile: string = `${filename}.js`; const jsfile: string = `${filename}.js`;
code = ` code = `
return (async () => { return (async () => {
// Imports npm packages for this .gbdialog conversational application. // Imports npm packages for this .gbdialog conversational application.
require('isomorphic-fetch'); require('isomorphic-fetch');
const http = require('node:http'); const http = require('node:http');
const retry = require('async-retry'); const retry = require('async-retry');
const createRpcClient = require("@push-rpc/core").createRpcClient; const createRpcClient = require("@push-rpc/core").createRpcClient;
const createHttpClient = require("@push-rpc/http").createHttpClient; const createHttpClient = require("@push-rpc/http").createHttpClient;
// Unmarshalls Local variables from server VM. // Unmarshalls Local variables from server VM.
const pid = this.pid; const pid = this.pid;
let id = this.id; let id = this.id;
let username = this.username; let username = this.username;
let mobile = this.mobile; let mobile = this.mobile;
let from = this.from; let from = this.from;
const channel = this.channel; const channel = this.channel;
const ENTER = this.ENTER; const ENTER = this.ENTER;
const headers = this.headers; const headers = this.headers;
let data = this.data; let data = this.data;
let list = this.list; let list = this.list;
let httpUsername = this.httpUsername; let httpUsername = this.httpUsername;
let httpPs = this.httpPs; let httpPs = this.httpPs;
let today = this.today; let today = this.today;
let now = this.now; let now = this.now;
let date = new Date(); let date = new Date();
let page = null; let page = null;
const files = []; const files = [];
let col = 1; let col = 1;
let index = 1; let index = 1;
// Makes objects in BASIC insensitive. // Makes objects in BASIC insensitive.
const caseInsensitive = (listOrRow) => { const caseInsensitive = (listOrRow) => {
if (!listOrRow) { if (!listOrRow) {
return listOrRow; return listOrRow;
};
const lowercase = (oldKey) => typeof oldKey === 'string' ? oldKey.toLowerCase() : oldKey;
const createCaseInsensitiveProxy = (obj) => {
const propertiesMap = new Map(Object.keys(obj).map(propKey => [lowercase(propKey), obj[propKey]]));
const caseInsensitiveGetHandler = {
get: (target, property) => propertiesMap.get(lowercase(property))
}; };
return new Proxy(obj, caseInsensitiveGetHandler);
};
if (listOrRow.length) { const lowercase = (oldKey) => typeof oldKey === 'string' ? oldKey.toLowerCase() : oldKey;
return listOrRow.map(row => createCaseInsensitiveProxy(row));
} else {
return createCaseInsensitiveProxy(listOrRow);
}
};
// Transfers auto variables into global object. const createCaseInsensitiveProxy = (obj) => {
const propertiesMap = new Map(Object.keys(obj).map(propKey => [lowercase(propKey), obj[propKey]]));
const caseInsensitiveGetHandler = {
get: (target, property) => propertiesMap.get(lowercase(property))
};
return new Proxy(obj, caseInsensitiveGetHandler);
};
for(__indexer in this.variables) { if (listOrRow.length) {
global[__indexer] = this.variables[__indexer]; return listOrRow.map(row => createCaseInsensitiveProxy(row));
} } else {
return createCaseInsensitiveProxy(listOrRow);
// Defines local utility BASIC functions.
const ubound = (gbarray) => {
let length = 0;
if (gbarray){
length = gbarray.length;
if (length > 0){
if(gbarray[0].gbarray){
return length - 1;
} }
} };
}
return length;
}
const isarray = (gbarray) => {return Array.isArray(gbarray) }; // Transfers auto variables into global object.
// Proxies remote functions as BASIC functions. for(__indexer in this.variables) {
global[__indexer] = this.variables[__indexer];
const weekday = (v) => { return (async () => { return await dk.getWeekFromDate({v}) })(); };
const hour = (v) => { return (async () => { return await dk.getHourFromDate({v}) })(); };
const base64 = (v) => { return (async () => { return await dk.getCoded({v}) })(); };
const tolist = (v) => { return (async () => { return await dk.getToLst({v}) })(); };
const uuid = () => {
var dt = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
var r = (dt + Math.random()*16)%16 | 0;
dt = Math.floor(dt/16);
return (c=='x' ? r :(r&0x3|0x8)).toString(16);
});
return uuid;
};
const random = () => { return Number.parseInt((Math.random() * 8) % 8 * 100000000)};
// Setups interprocess communication from .gbdialog run-time to the BotServer API.
const optsRPC = {callTimeout: this.callTimeout};
let url;
const agent = http.Agent({ keepAlive: true });
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/dk';
const dk = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/sys';
const sys = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/wa';
const wa = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/img';
const img = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
const timeout = (ms)=> {
return new Promise(resolve => setTimeout(resolve, ms));
}
const ensureTokens = async (firstTime) => {
const tokens = this.tokens ? this.tokens.split(',') : [];
for(__indexer in tokens) {
const tokenName = tokens[__indexer];
// Auto update Bearar authentication for the first token.
const expiresOn = new Date(global[tokenName + "_expiresOn"]);
const expiration = expiresOn.getTime() - (10 * 60 * 1000);
// Expires token 10min. before or if it the first time, load it.
if (expiration < new Date().getTime() || firstTime) {
console.log ('Expired. Refreshing token...');
const {token, expiresOn} = await sys.getCustomToken({pid, tokenName});
global[tokenName] = token;
global[tokenName + "_expiresOn"]= expiresOn;
} }
if (__indexer == 0) {
headers['Authorization'] = 'Bearer ' + global[tokenName]; // Defines local utility BASIC functions.
const ubound = (gbarray) => {
let length = 0;
if (gbarray){
length = gbarray.length;
if (length > 0){
if(gbarray[0].gbarray){
return length - 1;
}
}
}
return length;
} }
}
};
try{ const isarray = (gbarray) => {return Array.isArray(gbarray) };
await ensureTokens(true); // Proxies remote functions as BASIC functions.
${code} // ISSUE: #339, tabify this. const weekday = (v) => { return (async () => { return await dk.getWeekFromDate({v}) })(); };
} const hour = (v) => { return (async () => { return await dk.getHourFromDate({v}) })(); };
catch(e){ const base64 = (v) => { return (async () => { return await dk.getCoded({v}) })(); };
console.log(e); const tolist = (v) => { return (async () => { return await dk.getToLst({v}) })(); };
} const uuid = () => {
finally{ var dt = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
var r = (dt + Math.random()*16)%16 | 0;
dt = Math.floor(dt/16);
return (c=='x' ? r :(r&0x3|0x8)).toString(16);
});
return uuid;
};
const random = () => { return Number.parseInt((Math.random() * 8) % 8 * 100000000)};
// Closes handles if any.
await wa.closeHandles({pid: pid}); // Setups interprocess communication from .gbdialog run-time to the BotServer API.
await sys.closeHandles({pid: pid});
} const optsRPC = {callTimeout: this.callTimeout};
let url;
const agent = http.Agent({ keepAlive: true });
})(); url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/dk';
const dk = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/sys';
const sys = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/wa';
const wa = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/${min.botId}/img';
const img = (await createRpcClient(() => createHttpClient(url, {agent: agent}), optsRPC)).remote;
const timeout = (ms)=> {
return new Promise(resolve => setTimeout(resolve, ms));
}
const ensureTokens = async (firstTime) => {
const tokens = this.tokens ? this.tokens.split(',') : [];
for(__indexer in tokens) {
const tokenName = tokens[__indexer];
// Auto update Bearar authentication for the first token.
const expiresOn = new Date(global[tokenName + "_expiresOn"]);
const expiration = expiresOn.getTime() - (10 * 60 * 1000);
// Expires token 10min. before or if it the first time, load it.
if (expiration < new Date().getTime() || firstTime) {
console.log ('Expired. Refreshing token...');
const {token, expiresOn} = await sys.getCustomToken({pid, tokenName});
global[tokenName] = token;
global[tokenName + "_expiresOn"]= expiresOn;
}
if (__indexer == 0) {
headers['Authorization'] = 'Bearer ' + global[tokenName];
}
}
};
try{
await ensureTokens(true);
${ code }
}
catch(e){
console.log(e);
}
finally{
// Closes handles if any.
await wa.closeHandles({pid: pid});
await sys.closeHandles({pid: pid});
}
})();
`; `;
code = ji.default(code, ' ');
Fs.writeFileSync(jsfile, code); Fs.writeFileSync(jsfile, code);
GBLogEx.info(min, `[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${code}`); GBLogEx.info(min, `[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${code}`);
@ -800,6 +799,8 @@ export class GBVMService extends GBService {
let fields = {}; let fields = {};
let tables = []; let tables = [];
const outputLines = [];
let emmitIndex = 1;
for (let i = 1; i <= lines.length; i++) { for (let i = 1; i <= lines.length; i++) {
let line = lines[i - 1]; let line = lines[i - 1];
@ -866,8 +867,12 @@ export class GBVMService extends GBService {
let add = emmit ? line.split(/\r\n|\r|\n/).length : 0; let add = emmit ? line.split(/\r\n|\r|\n/).length : 0;
current = current + (add ? add : 0); current = current + (add ? add : 0);
map[i] = current;
lines[i - 1] = emmit ? line : ''; if (emmit){
emmitIndex ++;
map[emmitIndex] = current;
outputLines[emmitIndex - 1] = line;
}
} }
if (tables) { if (tables) {
@ -877,7 +882,7 @@ export class GBVMService extends GBService {
} }
code = `${lines.join('\n')}\n`; code = `${outputLines.join('\n')}\n`;
let metadata = GBVMService.getMetadata(mainName, properties, description); let metadata = GBVMService.getMetadata(mainName, properties, description);