bonsaif 1.10.37 → 1.10.38

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.
@@ -732,38 +732,195 @@ const distinct = async (options, db, collection, query) => {
732
732
  }
733
733
  };
734
734
 
735
+ /**
736
+ * DBS - Listar todas las bases de datos
737
+ */
738
+ const dbs = async (options) => {
739
+ const start = Date.now();
740
+
741
+ try {
742
+ const mongoose = require('mongoose');
743
+ await connect(options);
744
+
745
+ const adminDb = mongoose.connection.db.admin();
746
+ const result = await adminDb.listDatabases();
747
+
748
+ const end = Date.now();
749
+ const time = end - start;
750
+
751
+ return {
752
+ result: {
753
+ dml: 'dbs',
754
+ headers: 'name|sizeOnDisk|empty',
755
+ time: utl.milisegundosASegundos(time),
756
+ code: 200,
757
+ error: 0
758
+ },
759
+ results: { totalSize: result.totalSize || 0 },
760
+ data: result.databases || []
761
+ };
762
+ } catch (e) {
763
+ const end = Date.now();
764
+ const time = end - start;
765
+ utl.log(`${tag} dbs error:`, e);
766
+ return {
767
+ result: {
768
+ dml: 'dbs',
769
+ time: utl.milisegundosASegundos(time),
770
+ code: 500,
771
+ error: 1,
772
+ msg: e.message
773
+ },
774
+ data: []
775
+ };
776
+ }
777
+ };
778
+
779
+ /**
780
+ * COLLECTIONS - Listar todas las colecciones de una base de datos
781
+ */
782
+ const collections = async (options, db) => {
783
+ const start = Date.now();
784
+
785
+ try {
786
+ const mongoose = require('mongoose');
787
+ await connect(options);
788
+
789
+ const dbConn = mongoose.connection.useDb(db);
790
+ const colls = await dbConn.db.listCollections().toArray();
791
+
792
+ const end = Date.now();
793
+ const time = end - start;
794
+
795
+ return {
796
+ result: {
797
+ dml: 'collections',
798
+ headers: 'name|type',
799
+ db,
800
+ time: utl.milisegundosASegundos(time),
801
+ code: 200,
802
+ error: 0
803
+ },
804
+ results: colls,
805
+ data: colls
806
+ };
807
+ } catch (e) {
808
+ const end = Date.now();
809
+ const time = end - start;
810
+ utl.log(`${tag} collections error:`, e);
811
+ return {
812
+ result: {
813
+ dml: 'collections',
814
+ time: utl.milisegundosASegundos(time),
815
+ code: 500,
816
+ error: 1,
817
+ msg: e.message
818
+ },
819
+ data: []
820
+ };
821
+ }
822
+ };
823
+
824
+ /**
825
+ * DROP - Eliminar una colección completa
826
+ */
827
+ const drop = async (options, db, collection) => {
828
+ const start = Date.now();
829
+
830
+ try {
831
+ const mongoose = require('mongoose');
832
+ await connect(options);
833
+
834
+ const dbConn = mongoose.connection.useDb(db);
835
+ const result = await dbConn.db.dropCollection(collection);
836
+
837
+ const end = Date.now();
838
+ const time = end - start;
839
+
840
+ return {
841
+ result: {
842
+ dml: 'drop',
843
+ collection,
844
+ db,
845
+ time: utl.milisegundosASegundos(time),
846
+ code: 200,
847
+ error: 0
848
+ },
849
+ results: result,
850
+ data: { drop: result }
851
+ };
852
+ } catch (e) {
853
+ const end = Date.now();
854
+ const time = end - start;
855
+ utl.log(`${tag} drop error:`, e);
856
+ return {
857
+ result: {
858
+ dml: 'drop',
859
+ time: utl.milisegundosASegundos(time),
860
+ code: 500,
861
+ error: 1,
862
+ msg: e.message
863
+ },
864
+ data: { drop: false }
865
+ };
866
+ }
867
+ };
868
+
735
869
  /**
736
870
  * API - Router principal para todas las operaciones
737
871
  */
738
872
  const api = async (options, db, body) => {
739
873
  let { dml = '', collection = '' } = body;
740
874
 
741
- // Compatibilidad con formato MongoDB: collection puede venir en json.[dml]
742
- if (!collection && dml) {
743
- collection = body[dml] || '';
744
- }
745
-
746
- // Si aún no hay collection, intentar extraer del body
747
- if (!collection) {
748
- const possibleDmls = ['find', 'findOne', 'insert', 'update', 'updateMany',
749
- 'delete', 'deleteMany', 'upsert', 'count', 'aggregate', 'distinct'];
875
+ // Si dml es 'api', buscar el DML real en el body
876
+ if (dml === 'api' || !dml) {
877
+ const possibleDmls = ['find', 'findOne', 'insert', 'insertMany', 'update', 'updateMany',
878
+ 'delete', 'deleteMany', 'upsert', 'count', 'aggregate', 'distinct',
879
+ 'dbs', 'collections', 'drop'];
750
880
  for (const possibleDml of possibleDmls) {
751
- if (body[possibleDml]) {
881
+ if (body[possibleDml] !== undefined) {
752
882
  dml = possibleDml;
753
- collection = body[possibleDml];
883
+ // En formato MongoDB, la colección viene en body.[dml]
884
+ if (typeof body[possibleDml] === 'string') {
885
+ collection = body[possibleDml];
886
+ }
754
887
  break;
755
888
  }
756
889
  }
757
890
  }
758
891
 
759
- if (!collection) {
892
+ // Compatibilidad con formato MongoDB: collection puede venir en json.[dml]
893
+ if (!collection && dml && dml !== 'api') {
894
+ collection = body[dml] || '';
895
+ }
896
+
897
+ // Si aún no hay collection pero hay document/documents, usar dml por defecto
898
+ if (!collection && body.document) {
899
+ dml = dml || 'insert';
900
+ }
901
+
902
+ // Validar que collection tenga un valor (excepto para dbs y collections que no lo necesitan)
903
+ const requiresCollection = !['dbs', 'collections'].includes(dml);
904
+
905
+ if (requiresCollection && (!collection || collection === '')) {
906
+ const errorMsg = collection === ''
907
+ ? 'La "collection" está vacía. Asegúrate de que la variable tenga un valor válido.'
908
+ : 'Se requiere especificar "collection" en body.collection o body.[dml]';
909
+
760
910
  return {
761
911
  result: {
762
912
  dml: dml || 'unknown',
763
913
  time: 0,
764
914
  code: 400,
765
915
  error: 1,
766
- msg: 'Se requiere especificar "collection" en body.collection o body.[dml]'
916
+ msg: errorMsg,
917
+ debug: {
918
+ receivedDml: body.dml,
919
+ detectedDml: dml,
920
+ collectionValue: collection,
921
+ collectionIsEmpty: collection === '',
922
+ bodyKeys: Object.keys(body)
923
+ }
767
924
  },
768
925
  data: []
769
926
  };
@@ -784,6 +941,9 @@ const api = async (options, db, body) => {
784
941
  case 'deleteMany': r = await deleteMany(options, db, collection, body); break;
785
942
  case 'aggregate': r = await aggregate(options, db, collection, body); break;
786
943
  case 'distinct': r = await distinct(options, db, collection, body); break;
944
+ case 'dbs': r = await dbs(options); break;
945
+ case 'collections': r = await collections(options, db); break;
946
+ case 'drop': r = await drop(options, db, collection); break;
787
947
  default:
788
948
  r = {
789
949
  result: {
@@ -796,7 +956,7 @@ const api = async (options, db, body) => {
796
956
  supportedOperations: [
797
957
  'find', 'findOne', 'count', 'insert', 'insertMany',
798
958
  'update', 'updateMany', 'upsert', 'delete', 'deleteMany',
799
- 'aggregate', 'distinct'
959
+ 'aggregate', 'distinct', 'dbs', 'collections', 'drop'
800
960
  ]
801
961
  };
802
962
  }
@@ -820,6 +980,9 @@ module.exports = {
820
980
  deleteMany,
821
981
  aggregate,
822
982
  distinct,
983
+ dbs,
984
+ collections,
985
+ drop,
823
986
  connect,
824
987
  getModel
825
988
  };
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "name": "bonsaif",
17
17
  "description": "bonsaif is a library to connect to bonsaif apis",
18
- "version": "1.10.37",
18
+ "version": "1.10.38",
19
19
  "main": "index.js",
20
20
  "directories": {
21
21
  "lib": "lib"