bonsaif 1.10.39 → 1.10.41

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.
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * ::: B[]NSAIF() ::: => 2024
3
3
  * Hookup para Mongoose (MongoDB ORM)
4
+ * Compatible con múltiples versiones de Node y Mongoose
4
5
  */
5
6
 
6
7
  'use strict';
@@ -9,15 +10,64 @@ const utl = require('../utl');
9
10
  let debug = false;
10
11
  let tag = ` ::: B[]NSAIF() ::: => mongoose.js `;
11
12
 
13
+ // Validar disponibilidad de Mongoose
14
+ let mongoose = null;
15
+ let isMongooseAvailable = false;
16
+ let mongooseVersion = null;
17
+
18
+ try {
19
+ mongoose = require('mongoose');
20
+ isMongooseAvailable = true;
21
+ mongooseVersion = mongoose.version;
22
+
23
+ // Validar versión de Node
24
+ const nodeVersion = process.version;
25
+ const nodeMajor = parseInt(nodeVersion.split('.')[0].substring(1));
26
+
27
+ if (nodeMajor < 12) {
28
+ utl.log(`${tag} WARNING: Node ${nodeVersion} no es compatible con Mongoose. Se requiere Node >= 12.0.0`);
29
+ isMongooseAvailable = false;
30
+ }
31
+
32
+ } catch (e) {
33
+ utl.log(`${tag} Mongoose no está instalado. Para usar mongoose, instala: npm install mongoose@"^6.12.0" (Node 12-14) o mongoose@"^8.0.0" (Node >= 16.20.1)`);
34
+ isMongooseAvailable = false;
35
+ }
36
+
12
37
  // Cache de modelos dinámicos por base de datos y colección
13
38
  const modelCache = new Map();
14
39
 
40
+ /**
41
+ * Validar que Mongoose esté disponible
42
+ */
43
+ const checkMongooseAvailable = () => {
44
+ if (!isMongooseAvailable) {
45
+ return {
46
+ result: {
47
+ dml: 'error',
48
+ time: 0,
49
+ code: 503,
50
+ error: 1,
51
+ msg: 'Mongoose no está disponible en este sistema',
52
+ details: {
53
+ nodeVersion: process.version,
54
+ mongooseInstalled: mongoose !== null,
55
+ recommendation: process.version.startsWith('v12') || process.version.startsWith('v14')
56
+ ? 'Instala: npm install mongoose@^6.12.0'
57
+ : 'Instala: npm install mongoose@^8.0.0 (requiere Node >= 16.20.1)'
58
+ }
59
+ },
60
+ data: []
61
+ };
62
+ }
63
+ return null;
64
+ };
65
+
15
66
  /**
16
67
  * Parsear schema dinámico recibido del cliente
17
68
  * Convierte definición simple a Schema de Mongoose
18
69
  */
19
70
  const parseSchema = (schemaDefinition) => {
20
- const mongoose = require('mongoose');
21
71
  const parsedSchema = {};
22
72
 
23
73
  for (const [field, def] of Object.entries(schemaDefinition)) {
@@ -72,7 +122,9 @@ const parseSchema = (schemaDefinition) => {
72
122
  * Conectar a MongoDB usando Mongoose
73
123
  */
74
124
  const connect = async (options) => {
75
- const mongoose = require('mongoose');
125
+ const availabilityError = checkMongooseAvailable();
126
+ if (availabilityError) throw new Error(availabilityError.result.msg);
127
+
76
128
  const { uri = '', poolSize = 10, debug: debugMode = false } = options.endpoint;
77
129
 
78
130
  try {
@@ -81,15 +133,31 @@ const connect = async (options) => {
81
133
  return mongoose.connection;
82
134
  }
83
135
 
84
- await mongoose.connect(uri, {
85
- maxPoolSize: poolSize,
86
- minPoolSize: 2,
136
+ // Opciones compatibles con múltiples versiones de Mongoose
137
+ const connectOptions = {
87
138
  serverSelectionTimeoutMS: 15000,
88
139
  socketTimeoutMS: 45000,
89
140
  connectTimeoutMS: 10000
90
- });
141
+ };
91
142
 
92
- debugMode ? utl.log(`${tag} [Mongoose] conectado a ${uri}`) : '';
143
+ // Mongoose 6.x y 7.x usan useNewUrlParser, useUnifiedTopology
144
+ // Mongoose 8.x los depreca
145
+ const majorVersion = parseInt(mongooseVersion.split('.')[0]);
146
+
147
+ if (majorVersion >= 6) {
148
+ // Mongoose 6.x, 7.x, 8.x
149
+ connectOptions.maxPoolSize = poolSize;
150
+ connectOptions.minPoolSize = 2;
151
+ } else {
152
+ // Mongoose 5.x
153
+ connectOptions.poolSize = poolSize;
154
+ connectOptions.useNewUrlParser = true;
155
+ connectOptions.useUnifiedTopology = true;
156
+ }
157
+
158
+ await mongoose.connect(uri, connectOptions);
159
+
160
+ debugMode ? utl.log(`${tag} [Mongoose ${mongooseVersion}] conectado a ${uri}`) : '';
93
161
  return mongoose.connection;
94
162
  } catch (e) {
95
163
  utl.log(`${tag} [Mongoose] error de conexión:`, e);
@@ -101,7 +169,6 @@ const connect = async (options) => {
101
169
  * Obtener o crear modelo dinámico para una colección
102
170
  */
103
171
  const getModel = (db, collection, schemaDefinition = null) => {
104
- const mongoose = require('mongoose');
105
172
  const cacheKey = schemaDefinition
106
173
  ? `${db}.${collection}.custom.${JSON.stringify(schemaDefinition)}`
107
174
  : `${db}.${collection}.generic`;
@@ -147,6 +214,9 @@ const getModel = (db, collection, schemaDefinition = null) => {
147
214
  * FIND - Búsqueda dinámica
148
215
  */
149
216
  const find = async (options, db, collection, query) => {
217
+ const availabilityError = checkMongooseAvailable();
218
+ if (availabilityError) return availabilityError;
219
+
150
220
  const start = Date.now();
151
221
 
152
222
  try {
@@ -200,6 +270,9 @@ const find = async (options, db, collection, query) => {
200
270
  * FINDONE - Buscar un solo documento
201
271
  */
202
272
  const findOne = async (options, db, collection, query) => {
273
+ const availabilityError = checkMongooseAvailable();
274
+ if (availabilityError) return availabilityError;
275
+
203
276
  const start = Date.now();
204
277
 
205
278
  try {
@@ -250,6 +323,9 @@ const findOne = async (options, db, collection, query) => {
250
323
  * COUNT - Contar documentos
251
324
  */
252
325
  const count = async (options, db, collection, query) => {
326
+ const availabilityError = checkMongooseAvailable();
327
+ if (availabilityError) return availabilityError;
328
+
253
329
  const start = Date.now();
254
330
 
255
331
  try {
@@ -295,6 +371,9 @@ const count = async (options, db, collection, query) => {
295
371
  * INSERT - Crear documento
296
372
  */
297
373
  const insert = async (options, db, collection, query) => {
374
+ const availabilityError = checkMongooseAvailable();
375
+ if (availabilityError) return availabilityError;
376
+
298
377
  const start = Date.now();
299
378
 
300
379
  try {
@@ -346,6 +425,9 @@ const insert = async (options, db, collection, query) => {
346
425
  * INSERTMANY - Crear múltiples documentos
347
426
  */
348
427
  const insertMany = async (options, db, collection, query) => {
428
+ const availabilityError = checkMongooseAvailable();
429
+ if (availabilityError) return availabilityError;
430
+
349
431
  const start = Date.now();
350
432
 
351
433
  try {
@@ -392,6 +474,9 @@ const insertMany = async (options, db, collection, query) => {
392
474
  * UPDATE - Actualizar documento(s)
393
475
  */
394
476
  const update = async (options, db, collection, query) => {
477
+ const availabilityError = checkMongooseAvailable();
478
+ if (availabilityError) return availabilityError;
479
+
395
480
  const start = Date.now();
396
481
 
397
482
  try {
@@ -442,6 +527,9 @@ const update = async (options, db, collection, query) => {
442
527
  * UPDATEMANY - Actualizar múltiples documentos
443
528
  */
444
529
  const updateMany = async (options, db, collection, query) => {
530
+ const availabilityError = checkMongooseAvailable();
531
+ if (availabilityError) return availabilityError;
532
+
445
533
  const start = Date.now();
446
534
 
447
535
  try {
@@ -492,6 +580,9 @@ const updateMany = async (options, db, collection, query) => {
492
580
  * UPSERT - Actualizar o insertar
493
581
  */
494
582
  const upsert = async (options, db, collection, query) => {
583
+ const availabilityError = checkMongooseAvailable();
584
+ if (availabilityError) return availabilityError;
585
+
495
586
  const start = Date.now();
496
587
 
497
588
  try {
@@ -554,6 +645,9 @@ const upsert = async (options, db, collection, query) => {
554
645
  * DELETE - Eliminar documento(s)
555
646
  */
556
647
  const deleteOne = async (options, db, collection, query) => {
648
+ const availabilityError = checkMongooseAvailable();
649
+ if (availabilityError) return availabilityError;
650
+
557
651
  const start = Date.now();
558
652
 
559
653
  try {
@@ -600,6 +694,9 @@ const deleteOne = async (options, db, collection, query) => {
600
694
  * DELETEMANY - Eliminar múltiples documentos
601
695
  */
602
696
  const deleteMany = async (options, db, collection, query) => {
697
+ const availabilityError = checkMongooseAvailable();
698
+ if (availabilityError) return availabilityError;
699
+
603
700
  const start = Date.now();
604
701
 
605
702
  try {
@@ -646,6 +743,9 @@ const deleteMany = async (options, db, collection, query) => {
646
743
  * AGGREGATE - Pipeline de agregación
647
744
  */
648
745
  const aggregate = async (options, db, collection, query) => {
746
+ const availabilityError = checkMongooseAvailable();
747
+ if (availabilityError) return availabilityError;
748
+
649
749
  const start = Date.now();
650
750
 
651
751
  try {
@@ -691,6 +791,9 @@ const aggregate = async (options, db, collection, query) => {
691
791
  * DISTINCT - Valores únicos
692
792
  */
693
793
  const distinct = async (options, db, collection, query) => {
794
+ const availabilityError = checkMongooseAvailable();
795
+ if (availabilityError) return availabilityError;
796
+
694
797
  const start = Date.now();
695
798
 
696
799
  try {
@@ -736,10 +839,12 @@ const distinct = async (options, db, collection, query) => {
736
839
  * DBS - Listar todas las bases de datos
737
840
  */
738
841
  const dbs = async (options) => {
842
+ const availabilityError = checkMongooseAvailable();
843
+ if (availabilityError) return availabilityError;
844
+
739
845
  const start = Date.now();
740
846
 
741
847
  try {
742
- const mongoose = require('mongoose');
743
848
  await connect(options);
744
849
 
745
850
  const adminDb = mongoose.connection.db.admin();
@@ -780,10 +885,12 @@ const dbs = async (options) => {
780
885
  * COLLECTIONS - Listar todas las colecciones de una base de datos
781
886
  */
782
887
  const collections = async (options, db) => {
888
+ const availabilityError = checkMongooseAvailable();
889
+ if (availabilityError) return availabilityError;
890
+
783
891
  const start = Date.now();
784
892
 
785
893
  try {
786
- const mongoose = require('mongoose');
787
894
  await connect(options);
788
895
 
789
896
  const dbConn = mongoose.connection.useDb(db);
@@ -825,10 +932,12 @@ const collections = async (options, db) => {
825
932
  * DROP - Eliminar una colección completa
826
933
  */
827
934
  const drop = async (options, db, collection) => {
935
+ const availabilityError = checkMongooseAvailable();
936
+ if (availabilityError) return availabilityError;
937
+
828
938
  const start = Date.now();
829
939
 
830
940
  try {
831
- const mongoose = require('mongoose');
832
941
  await connect(options);
833
942
 
834
943
  const dbConn = mongoose.connection.useDb(db);
@@ -870,6 +979,9 @@ const drop = async (options, db, collection) => {
870
979
  * API - Router principal para todas las operaciones
871
980
  */
872
981
  const api = async (options, db, body) => {
982
+ const availabilityError = checkMongooseAvailable();
983
+ if (availabilityError) return availabilityError;
984
+
873
985
  let { dml = '', collection = '' } = body;
874
986
 
875
987
  // Si dml es 'api', buscar el DML real en el body
@@ -984,5 +1096,7 @@ module.exports = {
984
1096
  collections,
985
1097
  drop,
986
1098
  connect,
987
- getModel
1099
+ getModel,
1100
+ isMongooseAvailable,
1101
+ mongooseVersion
988
1102
  };
@@ -13,19 +13,16 @@ const qson = async (o, alias, query,dml,ip)=>{
13
13
  let headers = '';
14
14
  const start = Date.now();
15
15
  let tipo = 'query';
16
-
17
16
  return new Promise(function(resolve, reject) {
17
+ //2022/08/27 VRSZ Se cambia el la utileria para consumirmo por mysql ya que mariadb no regresa los campos de las columnas
18
18
  const {port='', uri = '', user='', password='', debug=false } = o.endpoint ? o.endpoint:{};
19
19
  const {db=''} = o.options ? o.options : {};
20
20
 
21
21
  const { Client } = require('pg');
22
22
  const client = new Client({ host:uri, user, port , password, database :db });
23
-
24
23
  client.connect(function(e){
25
24
  if(e){
26
25
  utl.log(`${tag} [postgres] is OFFline`,e);
27
- resolve({"result":{dml, headers, time:0, code:e.code ? e.code:0, error:1, msg:e.message ? e.message:''}, results:e});
28
- return;
29
26
  }else{
30
27
  debug ? utl.log(`${tag} [postgres] connection is online `):'';
31
28
  }
@@ -35,6 +32,7 @@ const qson = async (o, alias, query,dml,ip)=>{
35
32
  tipo = 'select';
36
33
  }
37
34
 
35
+ //2023/11/07 Recuperar id
38
36
  if (query.toLowerCase().includes("insert ") && query.toLowerCase().includes(" into ")){
39
37
  query = query.replace(';','');
40
38
  query = query + ' RETURNING id';
@@ -44,40 +42,34 @@ const qson = async (o, alias, query,dml,ip)=>{
44
42
  client.query(query, function(err, res) {
45
43
  const end = Date.now();
46
44
  const time = end - start;
47
-
48
- try{
49
- if (err) {
50
- resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:err.code ? err.code:0, error:1, msg:err.routine ? err.routine:''}, results:err});
51
- }
52
- else {
53
- data = res.rows ? res.rows: [];
54
- let rowCount = res.rowCount ? res.rowCount:0;
55
-
56
- if (tipo!='select'){
57
- data =[{"insert_id":data[0] ? data[0].id : 0, "changed_rows":rowCount}];
58
- headers = 'insert_id|changed_rows';
59
- }else{
60
- if (data.length==0){
61
- let {fields=[]} = res ? res : {};
62
- for (let field of fields ){
63
- if (headers.length>0){
64
- headers = headers+'|';
65
- }
66
- headers = headers+field.name;
45
+ client.end(function(){
46
+ debug ? utl.log(`${tag} [postgres] connection is closing connection `):'';
47
+ });
48
+
49
+ if (err) {
50
+ resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:err.code ? err.code:0, error:1, msg:err.routine ? err.routine:''}, results:err});
51
+ }
52
+ else {
53
+ data = res.rows ? res.rows: [];
54
+ let rowCount = res.rowCount ? res.rowCount:0;
55
+
56
+ if (tipo!='select'){
57
+ data =[{"insert_id":data[0] ? data[0].id : 0, "changed_rows":rowCount}];
58
+ headers = 'insert_id|changed_rows';
59
+ }else{
60
+ if (data.length==0){
61
+ let {fields=[]} = res ? res : {};
62
+ for (let field of fields ){
63
+ if (headers.length>0){
64
+ headers = headers+'|';
67
65
  }
68
- }else{
69
- try{ headers = Object.keys(data[0]); headers = headers.join("|"); }catch(e){}
66
+ headers = headers+field.name;
70
67
  }
68
+ }else{
69
+ try{ headers = Object.keys(data[0]); headers = headers.join("|"); }catch(e){}
71
70
  }
72
- resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:200, error:0}, data});
73
- }
74
- }catch(e){
75
- resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:500, error:1, msg:e.message}, results:e});
76
- }finally{
77
- // Cerrar conexión SIEMPRE
78
- client.end(function(){
79
- debug ? utl.log(`${tag} [postgres] connection is closing connection `):'';
80
- });
71
+ }
72
+ resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:200, error:0}, data});
81
73
  }
82
74
  });
83
75
  });