@xuda.io/xuda-dbs-plugin-xuda 1.0.317 → 1.0.319

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/xuda-dbs-plugin-xuda",
3
- "version": "1.0.317",
3
+ "version": "1.0.319",
4
4
  "description": "Xuda Database Socket for Xuda's proprietary structure powered by CouchDB",
5
5
  "scripts": {
6
6
  "pub": "npm version patch --force && npm publish --access public"
@@ -17,6 +17,6 @@
17
17
  "dependencies": {
18
18
  "@xuda.io/xu_cast": "^1.0.3",
19
19
  "lodash": "^4.17.21",
20
- "nano": "^10.0.0"
20
+ "nano": "^10.0.4"
21
21
  }
22
22
  }
@@ -1,5 +1,8 @@
1
- const _ = require('lodash');
2
- const crypto = require('node:crypto');
1
+ import { createRequire } from 'module';
2
+ import _ from 'lodash';
3
+ import crypto from 'node:crypto';
4
+
5
+ const require = createRequire(import.meta.url);
3
6
 
4
7
  const check_unique = async function (e, docP, table_obj, db, app_id_reference) {
5
8
  var len = docP.udfIndex.length;
@@ -43,7 +46,6 @@ const check_unique = async function (e, docP, table_obj, db, app_id_reference) {
43
46
  var keyValue = [];
44
47
 
45
48
  for await (const [keySegment, valSegment] of Object.entries(keysArr)) {
46
- // run on key segment
47
49
  let _fieldType = find_item_by_key(table_obj.tableFields, 'field_id', valSegment).props.fieldType;
48
50
  let _val = await get_cast_val('check_unique', valSegment, _fieldType, val.keyValue[Number(keySegment)]);
49
51
  keyValue.push(_val);
@@ -55,8 +57,6 @@ const check_unique = async function (e, docP, table_obj, db, app_id_reference) {
55
57
  const ret = await query_db(e, db, app_id_reference, table_obj);
56
58
  const json = ret.data;
57
59
 
58
- // var data;
59
-
60
60
  if (json.code > 0) {
61
61
  var data = json.data;
62
62
  if (data?.rows?.length) {
@@ -70,7 +70,6 @@ const check_unique = async function (e, docP, table_obj, db, app_id_reference) {
70
70
  }
71
71
  }
72
72
  }
73
- // throw json.data;
74
73
  return { code: 1, data: 'ok' };
75
74
  } catch (msg) {
76
75
  console.error(msg);
@@ -89,22 +88,15 @@ const get_index_json = async function (docInP, table_obj) {
89
88
  var key_val = [];
90
89
 
91
90
  if (docInP.udfData && table_obj) {
92
- // check for udf data array
93
91
  if (table_obj.tableIndexes) {
94
- // console.log(udfDicIndexT.rows);
95
92
  for await (var valIndex of table_obj.tableIndexes) {
96
- // run on index rows
97
- keysArr = valIndex.data.keys; // create array from keys string segment
93
+ keysArr = valIndex.data.keys;
98
94
  key_val = [];
99
95
  for await (var valSegment of keysArr) {
100
- // run on key segment
101
- // find keys values
102
96
  if (docInP.udfData.data[valSegment]) {
103
97
  key_val.push(docInP.udfData.data[valSegment]);
104
98
  continue;
105
99
  }
106
- // put the value
107
- // debugger;
108
100
  const field_obj = find_item_by_key(table_obj.tableFields, 'field_id', valSegment);
109
101
  if (!field_obj) {
110
102
  throw 'field not found in key: ' + valSegment;
@@ -121,7 +113,6 @@ const get_index_json = async function (docInP, table_obj) {
121
113
  keyValue: key_val,
122
114
  });
123
115
  }
124
- // );
125
116
  }
126
117
  }
127
118
  return { code: 1, data: index_json };
@@ -249,7 +240,6 @@ const get_opt = function (e, table_obj) {
249
240
  }
250
241
  opt.fields = fields;
251
242
  }
252
- // fix names
253
243
 
254
244
  for (const [key, val] of Object.entries(opt.fields)) {
255
245
  opt.fields[key] = 'udfData.data.' + val;
@@ -257,9 +247,7 @@ const get_opt = function (e, table_obj) {
257
247
 
258
248
  const _sort_model = typeof e.sortModel === 'string' ? JSON.parse(e.sortModel) : e.sortModel;
259
249
 
260
- // if (!e?.sortModel || !JSON.parse(e.sortModel).length) {
261
250
  if (!e?.sortModel || !_sort_model.length) {
262
- // added 2021 09 10
263
251
  if (opt.sort) {
264
252
  for (const [key, val] of Object.entries(opt.sort)) {
265
253
  opt.sort[key] = {
@@ -276,68 +264,51 @@ const get_opt = function (e, table_obj) {
276
264
  return e?.data?.field_id;
277
265
  });
278
266
 
279
- // Helper function to recursively process the query object
280
267
  function recursiveReplace(obj) {
281
268
  if (typeof obj === 'object' && obj !== null) {
282
- // Create a new object to store the modified query
283
269
  let newObj = Array.isArray(obj) ? [] : {};
284
270
 
285
- // Traverse through the object
286
271
  for (let key in obj) {
287
272
  if (obj.hasOwnProperty(key)) {
288
- // If the key is in the keys_to_replace array, replace it
289
273
  let newKey = keys_to_replace.includes(key) ? `udfData.data.${key}` : key;
290
-
291
- // Recursively process nested objects
292
274
  newObj[newKey] = recursiveReplace(obj[key]);
293
275
  }
294
276
  }
295
277
 
296
278
  return newObj;
297
279
  } else {
298
- // If it's not an object or array, return the value as is
299
280
  return obj;
300
281
  }
301
282
  }
302
283
 
303
- // Start the recursive replacement
304
284
  return recursiveReplace(query);
305
285
  }
306
286
 
307
287
  function replaceRegexOptions(query) {
308
- // Helper function to recursively process the query object
309
288
  function recursiveReplace(obj) {
310
289
  if (typeof obj === 'object' && obj !== null) {
311
- // Create a new object to store the modified query
312
290
  let newObj = Array.isArray(obj) ? [] : {};
313
291
 
314
- // Traverse through the object
315
292
  for (let key in obj) {
316
293
  if (obj.hasOwnProperty(key)) {
317
294
  if (key === '$regex') {
318
295
  newObj[key] = obj.$options ? `(?${obj.$options})${obj[key]}` : obj[key];
319
296
  return newObj;
320
297
  }
321
-
322
- // Recursively process nested objects
323
-
324
298
  newObj[key] = recursiveReplace(obj[key]);
325
299
  }
326
300
  }
327
301
 
328
302
  return newObj;
329
303
  } else {
330
- // If it's not an object or array, return the value as is
331
304
  return obj;
332
305
  }
333
306
  }
334
307
 
335
- // Start the recursive replacement
336
308
  return recursiveReplace(query);
337
309
  }
338
310
 
339
311
  if (e.dataSourceFilterModelType === 'query' && e.filterModelMongo) {
340
- // selector_new['$and'] = [replaceRegexOptions(replaceKeysInQuery(JSON.parse(e.filterModelMongo)))];
341
312
  selector_new['$and'] = [replaceRegexOptions(replaceKeysInQuery(typeof e.filterModelMongo === 'string' ? JSON.parse(e.filterModelMongo) : e.filterModelMongo))];
342
313
  }
343
314
 
@@ -438,7 +409,6 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
438
409
  });
439
410
  }
440
411
  } else {
441
- // no index
442
412
  rows.push({ key: '', value: body.docs.length });
443
413
  }
444
414
  return { code: 1, data: { rows: rows, total_rows: rows.length, opt } };
@@ -523,9 +493,9 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
523
493
  }
524
494
 
525
495
  if (typeof totals_obj[field_id][value] === 'undefined') {
526
- totals_obj[field_id][value] = 1; //value;
496
+ totals_obj[field_id][value] = 1;
527
497
  } else {
528
- totals_obj[field_id][value]++; //+= value;
498
+ totals_obj[field_id][value]++;
529
499
  }
530
500
 
531
501
  break;
@@ -545,30 +515,54 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
545
515
  return raw_data();
546
516
  };
547
517
 
548
- // xuda
518
+ const get_mango_index_fields = function (selector) {
519
+ const fields = new Set();
520
+ const add_selector_fields = function (obj) {
521
+ if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
522
+ return;
523
+ }
524
+ for (const [key, val] of Object.entries(obj)) {
525
+ if (['$and', '$or', '$nor'].includes(key)) {
526
+ if (Array.isArray(val)) {
527
+ val.forEach(add_selector_fields);
528
+ }
529
+ continue;
530
+ }
531
+ if (key.startsWith('$')) {
532
+ continue;
533
+ }
534
+ fields.add(key);
535
+ }
536
+ };
537
+ add_selector_fields(selector);
538
+ return [...fields];
539
+ };
540
+
541
+ const create_mango_index_for_selector = async function () {
542
+ const index = get_mango_index_fields(opt.selector);
543
+ if (!index.length) {
544
+ return;
545
+ }
546
+ const index_suffix = index.join('_').replace(/[^a-zA-Z0-9_]+/g, '_').slice(0, 80) || 'selector';
547
+ const mango_index_obj = {
548
+ index: {
549
+ fields: index,
550
+ },
551
+ name: `index_${e.table_id}_${index_suffix}`,
552
+ ddoc: `mango_index_table_${e.table_id}_${index_suffix}`,
553
+ };
554
+ try {
555
+ await db.createIndex(mango_index_obj);
556
+ } catch (err) {
557
+ // The read already succeeded; index creation is only an optimization.
558
+ }
559
+ };
549
560
 
550
561
  try {
551
562
  try {
552
- // console.log("opt", opt);
553
563
  const doc = await db.find(opt);
554
- var mango_index_obj;
555
564
  if (doc?.warning?.includes('No matching index found')) {
556
- const index_name = `index_${e.table_id}_${new Date().valueOf().toString()}`;
557
- var index = [];
558
-
559
- for (const [key, val] of Object.entries(opt.selector)) {
560
- index.push(key);
561
- }
562
- mango_index_obj = {
563
- index: {
564
- fields: index,
565
- },
566
- name: index_name,
567
- ddoc: `mango_index_table_${e.table_id}`,
568
- };
569
- db.createIndex(mango_index_obj).then((result) => {
570
- console.log(result);
571
- });
565
+ await create_mango_index_for_selector();
572
566
  }
573
567
  return await done(doc);
574
568
  } catch (err) {
@@ -577,7 +571,7 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
577
571
  const _selector = _.cloneDeep(opt.selector);
578
572
  delete _selector['$and'];
579
573
  const _sort = _.cloneDeep(opt.sort);
580
- mango_index_obj = {
574
+ const mango_index_obj = {
581
575
  index: {
582
576
  fields: Object.keys(
583
577
  _.reduce(
@@ -691,34 +685,9 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
691
685
  rows.push({
692
686
  id: val.id,
693
687
  value: val.doc.udfData,
694
- // value: { udfData: val.doc.udfData, _id: val.id },
695
688
  });
696
689
  }
697
690
 
698
- // const reduce_rows = () => {
699
- // const reduce_obj = body.docs.reduce(
700
- // (params, data) => {
701
- // const fx = (val, idx) => {
702
- // const group_by_field = data[params.sort[idx]];
703
-
704
- // if (params.sort[idx + 1]) {
705
- // val[group_by_field] = val[group_by_field] ?? {};
706
- // val[group_by_field][data[params.sort[idx + 1]]] = 0;
707
- // idx++;
708
- // fx(val[group_by_field], idx);
709
- // return;
710
- // }
711
-
712
- // val[group_by_field] = val[group_by_field] ?? 0;
713
- // val[group_by_field] += 1;
714
- // };
715
- // fx(params.group, 0);
716
-
717
- // return params;
718
- // },
719
- // { sort: opt.sort, group: {} }
720
- // );}
721
-
722
691
  return { code: 1, data: { rows: rows, total_rows: rows.length, opt } };
723
692
  } catch (err) {
724
693
  return { code: -1, data: err.message };
@@ -751,14 +720,13 @@ const query_db = async function (e, db, app_id_reference, table_obj) {
751
720
  }
752
721
 
753
722
  if (e.count && !e.filter_from) {
754
- // count tables
755
723
  return await count_tables();
756
724
  }
757
725
 
758
726
  return await runtime_get_mango_data();
759
727
  };
760
728
 
761
- exports.create = async (params, setup_doc, resolve, reject) => {
729
+ export const create = async (params, setup_doc, resolve, reject) => {
762
730
  const e = params.e;
763
731
  const db = params.db;
764
732
  const app_id_reference = params.app_id_reference;
@@ -852,7 +820,8 @@ exports.create = async (params, setup_doc, resolve, reject) => {
852
820
  }
853
821
  return await single();
854
822
  };
855
- exports.read = async (params, setup_doc, resolve, reject) => {
823
+
824
+ export const read = async (params, setup_doc, resolve, reject) => {
856
825
  const e = params.e;
857
826
  const db = params.db;
858
827
  const app_id_reference = params.app_id_reference;
@@ -865,23 +834,22 @@ exports.read = async (params, setup_doc, resolve, reject) => {
865
834
 
866
835
  return resolve(ret.data);
867
836
  };
868
- exports.update = async (params, setup_doc, resolve, reject) => {
837
+
838
+ export const update = async (params, setup_doc, resolve, reject) => {
869
839
  const e = params.e;
870
840
  const db = params.db;
871
841
  const app_id_reference = params.app_id_reference;
872
842
  const table_obj = params.table_obj;
873
843
  try {
874
844
  if (e.row_id === 'newRecord') {
875
- return this.create(params, setup_doc, resolve, reject);
845
+ return create(params, setup_doc, resolve, reject);
876
846
  }
877
847
  var doc = await db.get(e.row_id, {});
878
- // let data = doc.udfData.data;
879
848
  var error = undefined;
880
849
  if (!e.field_id && !e.table_data) {
881
850
  error = 'Invalid field_id or table_data object to save';
882
851
  return reject(error);
883
852
  }
884
- // single value save
885
853
  if (e.field_id) {
886
854
  let _tableFieldsObj = find_item_by_key(table_obj.tableFields, 'field_id', e.field_id);
887
855
  if (!_tableFieldsObj || _.isEmpty(_tableFieldsObj)) {
@@ -891,9 +859,7 @@ exports.update = async (params, setup_doc, resolve, reject) => {
891
859
  doc.udfData.data[e.field_id] = await get_cast_val('dbs_update', e.field_id, _tableFieldsObj.props.fieldType, e.field_value);
892
860
  }
893
861
 
894
- // object value save
895
862
  if (e.table_data) {
896
- // data = {};
897
863
  for await (const [key, val] of Object.entries(e.table_data)) {
898
864
  let _tableFieldsObj = find_item_by_key(table_obj.tableFields, 'field_id', key);
899
865
  if (!_tableFieldsObj || _.isEmpty(_tableFieldsObj)) {
@@ -928,7 +894,8 @@ exports.update = async (params, setup_doc, resolve, reject) => {
928
894
  return reject(error);
929
895
  }
930
896
  };
931
- exports.delete = async (params, setup_doc, resolve, reject) => {
897
+
898
+ export const deleteFunc = async (params, setup_doc, resolve, reject) => {
932
899
  const e = params.e;
933
900
  const db = params.db;
934
901
  const app_id_reference = params.app_id_reference;
@@ -961,7 +928,9 @@ exports.delete = async (params, setup_doc, resolve, reject) => {
961
928
  }
962
929
  };
963
930
 
964
- exports.restore = async (params, setup_doc, resolve, reject) => {
931
+ export { deleteFunc as delete }; // Renaming export to avoid reserved keyword conflict
932
+
933
+ export const restore = async (params, setup_doc, resolve, reject) => {
965
934
  const e = params.e;
966
935
  const db = params.db;
967
936
  const app_id_reference = params.app_id_reference;
@@ -986,7 +955,8 @@ exports.restore = async (params, setup_doc, resolve, reject) => {
986
955
  return reject(error);
987
956
  }
988
957
  };
989
- exports.check_unique = async (params, setup_doc, resolve, reject) => {
958
+
959
+ export const check_unique_export = async (params, setup_doc, resolve, reject) => {
990
960
  const e = params.e;
991
961
  const db = params.db;
992
962
  const app_id_reference = params.app_id_reference;
@@ -1003,7 +973,10 @@ exports.check_unique = async (params, setup_doc, resolve, reject) => {
1003
973
  return reject(error);
1004
974
  }
1005
975
  };
1006
- exports.get_connection = async (params, setup_doc, resolve, reject) => {
976
+
977
+ export { check_unique_export as check_unique };
978
+
979
+ export const get_connection = async (params, setup_doc, resolve, reject) => {
1007
980
  try {
1008
981
  if (!setup_doc.db_connection_string) throw 'db_connection_string missing';
1009
982
  const nano = require('nano')(setup_doc.db_connection_string);
package/studio.mjs CHANGED
@@ -587,44 +587,66 @@ const query_db = async function (e, db, table_obj) {
587
587
  };
588
588
 
589
589
  // xuda
590
+ const get_mango_index_fields = function (selector) {
591
+ const fields = new Set();
592
+ const add_selector_fields = function (obj) {
593
+ if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
594
+ return;
595
+ }
596
+ for (const [key, val] of Object.entries(obj)) {
597
+ if (['$and', '$or', '$nor'].includes(key)) {
598
+ if (Array.isArray(val)) {
599
+ val.forEach(add_selector_fields);
600
+ }
601
+ continue;
602
+ }
603
+ if (key.startsWith('$')) {
604
+ continue;
605
+ }
606
+ fields.add(key);
607
+ }
608
+ };
609
+ add_selector_fields(selector);
610
+ return [...fields];
611
+ };
612
+
613
+ const create_mango_index_for_selector = async function () {
614
+ const index = get_mango_index_fields(opt.selector);
615
+ if (!index.length) {
616
+ return;
617
+ }
618
+ const index_suffix = index.join('_').replace(/[^a-zA-Z0-9_]+/g, '_').slice(0, 80) || 'selector';
619
+ const mango_index_obj = {
620
+ index: {
621
+ fields: index,
622
+ },
623
+ name: `index_${e.table_id}_${index_suffix}`,
624
+ ddoc: `mango_index_table_${e.table_id}_${index_suffix}`,
625
+ };
626
+ try {
627
+ await db.createIndex(mango_index_obj);
628
+ } catch (err) {
629
+ // The read already succeeded; index creation is only an optimization.
630
+ }
631
+ };
590
632
 
591
633
  try {
592
634
  try {
593
635
  // console.log("opt", opt);
594
636
 
595
637
  const doc = await db.find(opt);
596
- var mango_index_obj;
597
638
  if (doc?.warning?.includes('No matching index found')) {
598
- try {
599
- const index_name = `index_${e.table_id}_${new Date().valueOf().toString()}`;
600
- var index = [];
601
-
602
- for (const [key, val] of Object.entries(opt.selector)) {
603
- index.push(key);
604
- }
605
- mango_index_obj = {
606
- index: {
607
- fields: index,
608
- },
609
- name: index_name,
610
- ddoc: `mango_index_table_${e.table_id}`,
611
- };
612
- const result = await db.createIndex(mango_index_obj);
613
- // console.log("createIndex", result);
614
- throw new Error('creating index in progress');
615
- } catch (err) {
616
- return { code: -1, data: err.message };
617
- }
639
+ await create_mango_index_for_selector();
618
640
  }
619
641
  return await done(doc);
620
642
  } catch (err) {
621
- if (err.message.includes('Cannot sort on field')) {
643
+ if (err?.message?.includes('Cannot sort on field')) {
622
644
  const index_name = `index_${e.table_id}_${new Date().valueOf().toString()}`;
623
645
 
624
646
  // const _selector = _.cloneDeep(opt.selector);
625
647
  let _sort = _.cloneDeep(opt.sort);
626
648
 
627
- mango_index_obj = {
649
+ const mango_index_obj = {
628
650
  index: {
629
651
  fields: [],
630
652
  },
@@ -655,32 +677,17 @@ const query_db = async function (e, db, table_obj) {
655
677
 
656
678
  try {
657
679
  const result = await db.createIndex(mango_index_obj);
658
- // const monitor_indexing = async function () {
659
- // return new Promise((resolve, reject) => {
660
- // db.on("indexing", function (event) {
661
- // // called when indexes are updated
662
- // console.log("indexes event", event);
663
- // // resolve();
664
- // });
665
- // setTimeout(() => {
666
- // resolve();
667
- // }, 5000);
668
- // });
669
- // };
670
- // await monitor_indexing();
671
- // throw new Error({ code: -88, data: "creating index" });
672
- throw new Error('creating index in progress');
673
- // const doc = await db.find(opt);
674
- // return await done(doc);
680
+ const doc = await db.find(opt);
681
+ return await done(doc);
675
682
  } catch (err) {
676
683
  return { code: -1, data: err.message };
677
684
  }
678
685
  } else {
679
- return { code: -1, data: err.message };
686
+ return { code: -1, data: err?.message || err };
680
687
  }
681
688
  }
682
689
  } catch (err) {
683
- return { code: -1, data: err.message };
690
+ return { code: -1, data: err?.message || err };
684
691
  }
685
692
  };
686
693