bonsaif 1.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/execute.js ADDED
@@ -0,0 +1,389 @@
1
+ /**
2
+ * ::: B[]NSAIF() ::: => 2022
3
+ */
4
+
5
+ 'use strict';
6
+
7
+
8
+ const utl = require('./utl');
9
+ let debug = false;
10
+ let tag = ` ::: B[]NSAIF() ::: => `;
11
+
12
+ /**
13
+ *
14
+ * @param {object} o Objeto con optiones y configuracion para bonsaif api
15
+ * @returns {data} informacion con estructura similar a un resulset
16
+ */
17
+ const query = async (o)=>{
18
+ const {endpoint=''} = o;
19
+ if (endpoint==''){
20
+ utl.log(tag+'debe ingresar configuracion de endpoint');
21
+ return;
22
+ }
23
+
24
+ const {options=''} = o;
25
+ if (options==''){
26
+ utl.log(tag+'debe ingresar opciones de configuracion');
27
+ return;
28
+ }
29
+
30
+ const {uri='', user = '', password='', debug=false , client=''} = endpoint;
31
+ //let requerido = ['uri','user','password','client'];
32
+ let requerido = ['uri','client'];
33
+ let aviso = '';
34
+ this.debug = debug ? true : false;
35
+ o.endpoint.client = client.toLowerCase();
36
+
37
+ for (let x of requerido){
38
+ eval(` if (${x}=='') { aviso = aviso + '${x}. ' } `)
39
+ }
40
+ if (aviso!=''){
41
+ utl.log(tag+'Required: '+aviso);
42
+ return;
43
+ }
44
+ let rs;
45
+ switch(o.endpoint.client){
46
+ case 'mariadb': rs = await mariadb(o); break;
47
+ case 'mongodb': rs = await mongodb(o); break;
48
+ case 'redis': rs = await redis(o); break;
49
+ case 'api': rs = await api(o); break;
50
+ case 'postgres': rs = await postgres(o); break;
51
+ default: rs = tag+' No Client: '+client;
52
+ }
53
+
54
+ return new Promise((resolve, reject)=>{
55
+ resolve( rs );
56
+ //2023/08/18 VRSZ push Webhook
57
+ try{
58
+ if (o.webhook){
59
+ webhook(o, rs);
60
+ }
61
+ }catch(e){
62
+ }
63
+ });
64
+ }
65
+
66
+ /**
67
+ *
68
+ * @param {object} o Configuracion de mariadb
69
+ * @returns
70
+ */
71
+ const mariadb= async(o)=>{
72
+ const { user, client, local=false } = o.endpoint;
73
+ const { dml='query', db = '', callback='', resultFormat=true} = o.options;
74
+ const { tag='', query = ''} = o;
75
+
76
+ if (local){
77
+ let mariadb = require("../lib/hookup/mariadb");
78
+ //const api=(options,db,query,dml,ip,tag,callback)=>{
79
+ let r= await mariadb.api(o,db, query, dml, 'local', tag, callback );
80
+ try{ r.query = o.query }catch(e){}
81
+ return resultFormat ? resultSet(r) : r ;
82
+ }else{
83
+ o.body={
84
+ "tag":tag,
85
+ "dml":dml,
86
+ "client":client,
87
+ "query":o.query,
88
+ "db": db,
89
+ "traceId":utl.traceId(user)
90
+ }
91
+ return new Promise((resolve, reject)=>{
92
+ backend(o)
93
+ .then(r=>{
94
+ try{ r.query = o.query }catch(e){}
95
+ resolve(resultFormat ? resultSet(r) : r );
96
+ });
97
+ });
98
+ }
99
+ }
100
+
101
+ /**
102
+ *
103
+ * @param {object} o Configuracion de mongodb
104
+ * @returns
105
+ */
106
+ const mongodb= async(o)=>{
107
+ const { local=false } = o.endpoint;
108
+ const { db = '', resultFormat=true} = o.options;
109
+ o.options.dml = 'api';
110
+ o.body = o.query;
111
+
112
+ if (local){
113
+ let mongodb = require("../lib/hookup/mongodb");
114
+ let r= await mongodb.api(o,db,o.body);
115
+ try{ r.query = o.query }catch(e){}
116
+ return resultFormat ? resultSet(r) : r ;
117
+ }else{
118
+ return new Promise((resolve, reject)=>{
119
+ backend(o)
120
+ .then(r=>{
121
+ try{ r.query = o.query }catch(e){}
122
+ resolve(resultFormat ? resultSet(r) : r);
123
+ });
124
+ });
125
+ }
126
+ }
127
+
128
+ /**
129
+ *
130
+ * @param {object} o Configuracion de redis
131
+ * @returns
132
+ */
133
+ const redis= async(o)=>{
134
+ const { local=false } = o.endpoint;
135
+ const { db = ''} = o.options;
136
+ o.options.dml = 'api';
137
+ o.body = o.query;
138
+
139
+ if (local){
140
+ let redis = require("../lib/hookup/redis");
141
+ let r= await redis.api(o,db,o.body);
142
+ try{ r.query = o.query }catch(e){}
143
+ return r;
144
+ }else{
145
+ return new Promise((resolve, reject)=>{
146
+ backend(o)
147
+ .then(r=>{
148
+ try{ r.query = o.query }catch(e){}
149
+ resolve(r);
150
+ });
151
+ });
152
+ }
153
+ }
154
+
155
+ /**
156
+ *
157
+ * @param {Object} o Conexion api
158
+ * @returns
159
+ */
160
+ const backend=(o)=>{
161
+ const qs = require('qs');
162
+ const {uri, user, password} = o.endpoint;
163
+ // 2024/09/05 VRSZ retries y timeout 2 min
164
+ const {sys, retries=3, timeout=120000} = o;
165
+ let authorization = 'Basic ' + Buffer.from(user + ':' + password).toString('base64');
166
+
167
+ let url_ = sys=='opti'? uri.replace('/rbe','') : uri;
168
+
169
+ url_ = url_+'?'+qs.stringify(o.options)+"&rd="+utl.random({string:true, length:8});
170
+
171
+ const options = {
172
+ url: url_,
173
+ timeout,
174
+ headers: {
175
+ 'Content-Type': 'application/json',
176
+ 'authorization': authorization
177
+ },
178
+ body: JSON.stringify(o.body)
179
+ };
180
+
181
+
182
+ return new Promise(async (resolve, reject)=>{
183
+ // 2024/07/24 VRSZ Se cambia el metodo apix para aplicar reintentos
184
+ let r = await utl.apix({method:'post', options, time:2, retries, async:true, status_ok:[200,401]});
185
+ let {err} = r ? r : {};
186
+ let {code:statusCode=0, errno:reason=''} = err ? err : {};
187
+ try{
188
+ if (r.statusCode==200) {
189
+ resolve(JSON.parse(r.body));
190
+ }else{
191
+ utl.log(`${tag} [${url_}] statusCode: ${statusCode} reason: ${reason} body: ${r.body}`, o.body);
192
+ resolve({err, code:statusCode, reason});
193
+ }
194
+ }catch(e){
195
+ resolve({err, code:0, reason});
196
+ }
197
+ });
198
+ }
199
+ /**
200
+ *
201
+ * @param {json} data Objeto json con 2 arreglos
202
+ * @returns Regresa la estructura similar a resulset
203
+ */
204
+ //2022/06/12 VRSZ Se obtine reason
205
+ const resultSet = (data)=>{
206
+ data=!null?data:data={};
207
+ if (data.result==null){data.result = {};}
208
+ if (data.data==null){data.data = {};}
209
+
210
+ //2023/08/17 VRSZ Se parse error
211
+ if (data.err!=null){
212
+ const {errno='500', code='ups. error de conexion'} = data.err;
213
+ data.result.error = 1;
214
+ data.result.headers = 'mensaje';
215
+ data.result.code = errno;
216
+ data.result.msg = code;
217
+ data.data=[{mensaje:code}];
218
+ }
219
+
220
+ const {results=''} = data;
221
+ let {dml='',headers='',columns=0, time=0, code=200, error=0, msg=''} = data.result;
222
+ const rows = data.data;
223
+ const irows = rows.length?rows.length:0;
224
+ try{delete rows.meta;}catch(e){}
225
+ let ltheaders = headers.split('|');
226
+ columns = columns==0 ? ltheaders.length : columns;
227
+ //2023/08/23 VRSZ Info extra en la respuesta del servicio
228
+ let extra = {};
229
+ try {
230
+ extra = { ...data };
231
+ try{delete extra.result;}catch(e){}
232
+ try{delete extra.data;}catch(e){}
233
+ try{delete extra.results;}catch(e){}
234
+ }catch(e){
235
+ }
236
+ return {
237
+ dml,
238
+ time,
239
+ headers,
240
+ ltheaders,
241
+ columns,
242
+ rows,
243
+ irows,
244
+ nextIndex : 0,
245
+ row:{},
246
+ next:function(){
247
+ if (this.nextIndex < this.rows.length){
248
+ this.row = this.rows[this.nextIndex++];
249
+ return true;
250
+ }else{
251
+ return false;
252
+ }
253
+ },
254
+ get:function(x){
255
+ if (!isNaN(x)){
256
+ x = this.ltheaders[x];
257
+ }
258
+ return this.row[x]!=null?this.row[x]:'';
259
+ },
260
+ reset:function(){
261
+ this.nextIndex = 0;
262
+ },
263
+ results,
264
+ code,
265
+ error,
266
+ msg,
267
+ extra
268
+ }
269
+ }
270
+
271
+ /**
272
+ *
273
+ * @param {Object} o Conexion api
274
+ * @returns
275
+ */
276
+ const api=async(o)=>{
277
+ const { db = '', resultFormat=true} = o.options;
278
+ return new Promise((resolve, reject)=>{
279
+ service(o)
280
+ .then(r=>{
281
+ resolve(resultFormat ? resultSet(r) : r);
282
+ });
283
+ });
284
+ }
285
+
286
+ const service=(o)=>{
287
+ const qs = require('qs');
288
+ const {uri, user, password, resultFormat=true} = o.endpoint;
289
+ const {sys, ...body } = o.options;
290
+ let authorization = 'Basic ' + Buffer.from(user + ':' + password).toString('base64');
291
+ let url_ = uri;
292
+ url_= url_+'?sys='+sys+'&'+qs.stringify(o.params?o.params:'')+"&rd="+utl.random({string:true, length:8});
293
+ o.body = {...body};
294
+ const options = {
295
+ url: url_,
296
+ headers: {
297
+ 'Content-Type': 'application/json',
298
+ 'authorization': authorization
299
+ },
300
+ body: JSON.stringify(o.body)
301
+ };
302
+
303
+ return new Promise(async (resolve, reject)=>{
304
+ // 2024/07/24 VRSZ Se cambia el metodo apix para aplicar reintentos
305
+ let r = await utl.apix({method:'post', options, time:2, async:true, status_ok:[200,401]});
306
+ let {err} = r ? r : {};
307
+ let {code:statusCode=0, errno:reason=''} = err ? err : {};
308
+ try{
309
+ if (r.statusCode==200) {
310
+ resolve(JSON.parse(r.body));
311
+ }else{
312
+ utl.log(`${tag} [${url_}] statusCode: ${statusCode} reason: ${reason} body: ${r.body}`, o.body);
313
+ resolve({err, code:statusCode, reason});
314
+ }
315
+ }catch(e){
316
+ resolve({err, code:0, reason});
317
+ }
318
+ });
319
+ }
320
+
321
+ const webhook=(o, rs)=>{
322
+ try{
323
+ let {webhook} = o ? o : {};
324
+ let {result} = rs ? rs : {};
325
+ let {uri='', data={}} = webhook ? webhook : {};
326
+ try{delete result.headers} catch(e){}
327
+ let out = {};
328
+ out.result = result;
329
+ out.data = data;
330
+ if (uri!=''){
331
+ const options = {
332
+ url: uri,
333
+ headers: {
334
+ 'Content-Type': 'application/json',
335
+ },
336
+ body: JSON.stringify(out)
337
+ };
338
+ const request = require('request');
339
+ request.post(options, (err, r, body) => {
340
+ if (err){
341
+ utl.log('webhook.post.err ',err);
342
+ }
343
+ });
344
+ }
345
+ }catch(e){
346
+ utl.log('webhook.err',e);
347
+ }
348
+ }
349
+
350
+
351
+ /**
352
+ *
353
+ * @param {object} o Configuracion de postgres
354
+ * @returns
355
+ */
356
+ const postgres= async(o)=>{
357
+ const { user, client, local=false } = o.endpoint;
358
+ const { dml='query', db = '', callback='', resultFormat=true} = o.options;
359
+ const { tag='', query = ''} = o;
360
+
361
+ if (local){
362
+ let postgres = require("../lib/hookup/postgres");
363
+ let r= await postgres.api(o, db, query, dml, 'local', tag, callback );
364
+ try{ r.query = o.query }catch(e){}
365
+ return resultFormat ? resultSet(r) : r ;
366
+ }else{
367
+ o.body={
368
+ "tag":tag,
369
+ "dml":dml,
370
+ "client":client,
371
+ "query":o.query,
372
+ "db": db,
373
+ "traceId":utl.traceId(user)
374
+ }
375
+ return new Promise((resolve, reject)=>{
376
+ backend(o)
377
+ .then(r=>{
378
+ try{ r.query = o.query }catch(e){}
379
+ resolve(resultFormat ? resultSet(r) : r );
380
+ });
381
+ });
382
+ }
383
+ }
384
+
385
+ module.exports={
386
+ query,
387
+ backend,
388
+ api
389
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * ::: B[]NSAIF() ::: => 2022
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const utl = require('../utl');
8
+ let debug = false;
9
+ let tag = ` ::: B[]NSAIF() ::: => exec.js `;
10
+
11
+ module.exports = {
12
+ redisConn: async function (o){
13
+
14
+ let dbRedis;
15
+ try{
16
+ const {port='', uri = '', debug=false } = o.endpoint;
17
+ this.debug = debug;
18
+ let redis = require('redis');
19
+ dbRedis = redis.createClient({url: uri});
20
+ dbRedis.on("error", function (err) {
21
+ utl.log(`${tag} [Redis] error encountered`, err);
22
+ dbRedis.quit();
23
+ });
24
+ dbRedis.on('connect', function() {
25
+ debug ? utl.log(`${tag} [Redis] connection is online Port[${port}] uri[${uri}]`):'';
26
+ });
27
+
28
+ }catch(e){
29
+ utl.log(`${tag} [Redis] err.exec.redisConn`,e);
30
+ }
31
+ return dbRedis;
32
+ },
33
+
34
+ redisClose: async function (bd){
35
+ this.debug ? utl.log(`${tag} [Redis] closing connection`) : '';
36
+ bd.quit();
37
+ },
38
+
39
+ mongoConn: async function(o){
40
+ try{
41
+ let mongo = require('mongodb');
42
+ let MongoClient = mongo.MongoClient;
43
+ const {port='', uri = '', password = '', poolSize= 8, debug=false } = o.endpoint;
44
+ this.debug = debug;
45
+ let mongoclient = await MongoClient.connect(uri, { useNewUrlParser: true, poolSize: poolSize, serverSelectionTimeoutMS:15000, useUnifiedTopology: true } );
46
+ debug ? utl.log(`${tag} [Mongo] connection is online ${uri} poolSize[${poolSize}] mongoclient: [${mongoclient}]`) : '';
47
+ return mongoclient;
48
+ }catch(e){
49
+ utl.log(`${tag} [Mongo] err.exec.mongoConn`,e);
50
+ return null;
51
+ }
52
+ },
53
+
54
+ mongoClose: async function (mongoclient){
55
+ try{
56
+ mongoclient.then(function(mongoclient){mongoclient.close();});
57
+ this.debug ? utl.log(`${tag} [Mongo] closing connection`) : '';
58
+ }catch(e){
59
+ utl.log(`${tag} [Mongo] err.exec.mongoClose`,e);
60
+ }
61
+ },
62
+
63
+ mariadbConn: async function(o){
64
+ return new Promise( (resolve, reject) => {
65
+ const {port='', uri = '', user='', password='', debug=false } = o.endpoint;
66
+ const {db=''} = o.options;
67
+ this.debug = debug;
68
+ const mysql = require('mysql');
69
+ const conn = mysql.createConnection({
70
+ host:uri, user, port , password, database :db
71
+ });
72
+ conn.connect(function(e){
73
+ if(e){
74
+ utl.log(`${tag} [mariaDB] is OFFline`,e);
75
+ reject(e);
76
+ }else{
77
+ debug ? utl.log(`${tag} [mariaDB] connection is online `,conn.threadId):'';
78
+ resolve(conn);
79
+ }
80
+ });
81
+
82
+ });
83
+ },
84
+
85
+ mariadbClose: async function(conn){
86
+ try{
87
+ this.debug ? utl.log(`${tag} [mariaDB] closing connection`) : '';
88
+ conn.end();
89
+ }catch(e){
90
+ utl.log(`${tag} [mariaDB] err.exec.mongoClose`,e);
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * ::: B[]NSAIF() ::: => 2022
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const utl = require('../utl');
8
+ let debug = false;
9
+ let tag = ` ::: B[]NSAIF() ::: => mariadb.js `;
10
+
11
+ const qson = async (alias, conn, query,dml,ip)=>{
12
+
13
+ const exec = require("./exec");
14
+ let data;
15
+ let obj_json ={};
16
+ let headers = '';
17
+ const start = Date.now();
18
+ return new Promise(function(resolve, reject) {
19
+ //2022/08/27 VRSZ Se cambia el la utileria para consumirmo por mysql ya que mariadb no regresa los campos de las columnas
20
+ conn.query(query, function (err, rows, fields) {
21
+ const end = Date.now();
22
+ const time = end - start;
23
+ // cerrar conexion
24
+ try{
25
+ exec.mariadbClose(conn);
26
+ }catch(e){
27
+ utl.log('err.qson close '+e);
28
+ }
29
+ try{
30
+ if (err){
31
+ resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:err.errno, error:1, msg:err.sqlMessage}, results:err});
32
+ }else{
33
+ let tipo = 'query';
34
+ if (fields){
35
+ if (fields[0][0]){
36
+ tipo = 'store';
37
+ obj_json= fields[0];
38
+ }else{
39
+ obj_json= fields;
40
+ }
41
+ obj_json.forEach(x => {
42
+ if (x){
43
+ if (headers.length>0){
44
+ headers = headers +'|';
45
+ }
46
+ headers = headers + x.name;
47
+ }
48
+ });
49
+ }else{
50
+ tipo = 'insert';
51
+ headers = 'insert_id|changed_rows';
52
+ }
53
+ //Remove RowDataPacket {} Object.values(JSON.parse(JSON.stringify(rows)))
54
+ switch(tipo){
55
+ case 'store': data = Object.values(JSON.parse(JSON.stringify(rows[0]))); break;
56
+ case 'insert': data =[{"insert_id":rows.insertId, "changed_rows":rows.changedRows}]; break;
57
+ default: data = Object.values(JSON.parse(JSON.stringify(rows)));
58
+ }
59
+ resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:200, error:0}, data});
60
+ }
61
+ }catch(e){
62
+ console.log(e);
63
+ }
64
+ });
65
+ });
66
+ }
67
+
68
+ const api=async (options,db,query,dml,ip,tag,callback)=>{
69
+ //Inicializar conexiones a bases
70
+ tag = tag == null ? '': tag;
71
+ const exec = require("./exec");
72
+
73
+ let r ={result:{"alias":"", dml:"", headers:"" },error: 1, code:404, msg:'', };
74
+ let con;
75
+ try{
76
+ con = await exec.mariadbConn(options);
77
+ r = await qson(db,con,query,dml,ip);
78
+ }catch(e){
79
+ r.result.headers = 'err';
80
+ r.data=[{'err':e}];
81
+ }finally {
82
+ try{
83
+ let code = r.result.code;
84
+ let msg = r.result.msg;
85
+ if (code!=200){
86
+ let qErr = "insert into aw_log (Sentencia, ErrorCode,Error, Fecha, id_pw, IP, alias) values (\""+query.replace(/\"/g,"\"\"")+"\",\""+code+"\",\""+msg.replace(/\"/g,"\"\"")+"\", NOW(), \""+tag+"\", \""+ip+"\", \""+db+"\" );";
87
+ const execErr = require("./exec");
88
+ let connErr = await execErr.mariadbConn(options);
89
+ try{
90
+ let rerr = await qson(db,connErr,qErr,dml,ip);
91
+ }catch(e){
92
+ }
93
+ }
94
+ }catch(e){
95
+ utl.log('api.finally err '+e);
96
+ }
97
+ }
98
+ return new Promise((resolve, reject)=>{
99
+ resolve (r);
100
+ });
101
+ }
102
+
103
+ module.exports ={
104
+ api,
105
+ qson
106
+ }