@cocreate/utils 1.31.0 → 1.33.0

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/package.json +1 -1
  3. package/src/index.js +202 -183
package/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ # [1.33.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.32.0...v1.33.0) (2024-01-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * removed sortDataOld ([9755f81](https://github.com/CoCreate-app/CoCreate-utils/commit/9755f815fedd5156ea4a9c2b11b4896c10441424))
7
+ * supput values null, false, undefined, 0 ([954c126](https://github.com/CoCreate-app/CoCreate-utils/commit/954c1262b37c42d8f0badf9fe1c5855f4e244b8e))
8
+
9
+
10
+ ### Features
11
+
12
+ * queryData $type, $mod, $where operators ([94684a0](https://github.com/CoCreate-app/CoCreate-utils/commit/94684a0959fbf353d77ae363b522d5e17f209af0))
13
+
14
+ # [1.32.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.31.0...v1.32.0) (2024-01-17)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * getValueFromObject conditions and param names ([2fd7387](https://github.com/CoCreate-app/CoCreate-utils/commit/2fd73873cc42d0a22e43e04fee35f31227790f7b))
20
+ * getValueFromObject param trowError boolean will trow erro if property does not exist vs returning undefined ([39a9cab](https://github.com/CoCreate-app/CoCreate-utils/commit/39a9cabb9e109d1aae6a695ba47d76c95c8581f6))
21
+ * renamed isMatch to queryMatch ([b3c9429](https://github.com/CoCreate-app/CoCreate-utils/commit/b3c942950661b1d906c9f8a77a3bbd2f5693fd47))
22
+ * update to support new query system ([a267b52](https://github.com/CoCreate-app/CoCreate-utils/commit/a267b5260955a631330a2b22bd9fb316a00004c6))
23
+
24
+
25
+ ### Features
26
+
27
+ * query() function to handle queries similar to mongodb ([164bf45](https://github.com/CoCreate-app/CoCreate-utils/commit/164bf45d44f620fe8e6a4cf75fe744be68277d6c))
28
+ * sort by multiple keys ([7872a53](https://github.com/CoCreate-app/CoCreate-utils/commit/7872a5308bcf510e40385c57b45c0d899a40295a))
29
+
1
30
  # [1.31.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.30.0...v1.31.0) (2024-01-08)
2
31
 
3
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/utils",
3
- "version": "1.31.0",
3
+ "version": "1.33.0",
4
4
  "description": "A simple utils component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "utils",
package/src/index.js CHANGED
@@ -142,32 +142,36 @@
142
142
  }
143
143
  }
144
144
 
145
- function getValueFromObject(json, path) {
145
+ function getValueFromObject(object = {}, path = '', throwError = false) {
146
146
  try {
147
- if (typeof json == 'undefined' || !path)
148
- return;
147
+ if (!Object.keys(object).length || !path) {
148
+ if (throwError)
149
+ throw new Error("Invalid input to getValueFromObject");
150
+ return
151
+
152
+ }
149
153
 
150
154
  path = path.replace(/\[(\d+)\]/g, '.$1');
151
155
 
152
- let jsonData = json, subpath = path.split('.');
156
+ let data = object, subpath = path.split('.');
153
157
 
154
158
  for (let i = 0; i < subpath.length; i++) {
155
- jsonData = jsonData[subpath[i]];
156
- if (!jsonData)
157
- return jsonData;
159
+ if (throwError && !(subpath[i] in data))
160
+ throw new Error("Key not found in object: " + subpath[i]);
161
+
162
+ data = data[subpath[i]];
163
+ if (!data)
164
+ break;
158
165
  }
159
- return jsonData;
166
+
167
+ return data;
160
168
  } catch (error) {
161
- console.log("Error in getValueFromObject", error);
162
- return;
169
+ // console.error("Error in getValueFromObject:", error);
170
+ if (throwError)
171
+ throw error;
163
172
  }
164
173
  }
165
174
 
166
- function isObjectEmpty(obj) {
167
- for (var x in obj) { return false }
168
- return true;
169
- }
170
-
171
175
  function domParser(str) {
172
176
  try {
173
177
  var mainTag = str.match(/\<(?<tag>[a-z0-9]+)(.*?)?\>/).groups.tag;
@@ -298,6 +302,7 @@
298
302
  }
299
303
 
300
304
  if (Selector) {
305
+ // let selectors = Selector.split(/,(?![^()]*\))/g);
301
306
 
302
307
  let selectors = Selector.split(',');
303
308
  for (let j = 0; j < selectors.length; j++) {
@@ -418,146 +423,176 @@
418
423
  return selector
419
424
  }
420
425
 
421
-
422
426
  function queryData(data, query) {
423
- if (!data)
424
- return false;
427
+ if (query.$and) {
428
+ for (let i = 0; i < query.$and.length; i++) {
429
+ if (!queryData(data, query.$and[i]))
430
+ return false
431
+ }
432
+ }
425
433
 
426
- if (!Array.isArray(data))
427
- data = [data]
434
+ if (query.$nor) {
435
+ for (let i = 0; i < query.$nor.length; i++) {
436
+ if (queryData(data, query.$nor[i]))
437
+ return false;
438
+ }
439
+ }
428
440
 
429
- if (!query)
430
- return true
441
+ for (let key of Object.keys(query)) {
442
+ if (key === '$and' || key === '$or')
443
+ continue
444
+ if (!queryMatch(data, { [key]: query[key] }))
445
+ return false
446
+ }
431
447
 
432
- if (!Array.isArray(query))
433
- query = [query]
434
- if (!query.length)
435
- return true
448
+ if (query.$or) {
449
+ for (let i = 0; i < query.$or.length; i++) {
450
+ if (queryData(data, query.$or[i]))
451
+ return true
452
+ }
453
+ }
436
454
 
437
- let queryResult = false
438
- for (let n = 0; n < data.length; n++) {
439
- for (let i = 0; i < query.length; i++) {
440
- let dataValue
441
- if (query[i].key.includes('.') || /\[([0-9]*)\]/g.test(query[i].key))
442
- dataValue = getValueFromObject(data[n], query[i].key)
443
- else
444
- dataValue = data[n][query[i].key]
445
- if (dataValue == undefined)
446
- dataValue = ''
447
- let logicalOperator = query[i].logicalOperator || 'and'
448
- let queryValues = query[i].value
449
-
450
- let queryIsArray = false
451
- if (!Array.isArray(queryValues))
452
- queryValues = [queryValues]
453
- else
454
- queryIsArray = true
455
+ return true;
456
+ }
455
457
 
458
+ function queryMatch(data, query) {
459
+ for (let key of Object.keys(query)) {
460
+ // if (!data.hasOwnProperty(key))
461
+ // return false
456
462
 
457
- let queryStatus = false
458
- for (let queryValue of queryValues) {
459
- if (query[i].caseSensitive != 'true' || query[i].caseSensitive != true) {
460
- if (typeof dataValue == 'string')
461
- dataValue = dataValue.toLowerCase()
462
- if (typeof queryValue == 'string')
463
- queryValue = queryValue.toLowerCase()
464
- }
463
+ let dataValue
464
+ try {
465
+ dataValue = getValueFromObject(data, key, true)
466
+ } catch (error) {
467
+ return false
468
+ }
465
469
 
466
- if (isValidDate(dataValue) && isValidDate(queryValue)) {
467
- dataValue = new Date(dataValue)
468
- queryValue = new Date(queryValue)
469
- }
470
- switch (query[i].operator) {
471
- case '$includes':
472
- case 'includes':
473
- if (dataValue.includes(queryValue))
474
- queryStatus = true
475
- // if (queryValue === "" && logicalOperator === 'and') {
476
- // if (dataValue !== "")
477
- // queryStatus = false
478
- // }
479
- break;
480
- case '$eq':
481
- if (dataValue == queryValue)
482
- queryStatus = true
483
- break;
484
- case '$ne':
485
- if (Array.isArray(dataValue)) {
486
- // Check if the entire array is different from queryValue
487
- queryStatus = !isEqualArray(dataValue, queryValue);
488
- } else if (Array.isArray(queryValue)) {
489
- // If queryValue is an array, check if dataValue is different from this array
490
- queryStatus = !isEqualArray(queryValue, dataValue);
491
- } else {
492
- // If neither is an array, simple comparison
493
- queryStatus = (dataValue != queryValue);
494
- }
495
- break;
496
- case '$lt':
497
- if (dataValue < queryValue)
498
- queryStatus = true
499
- break;
500
- case '$lte':
501
- if (dataValue <= queryValue)
502
- queryStatus = true
503
- break;
504
- case '$gt':
505
- if (dataValue > queryValue)
506
- queryStatus = true
507
- break;
508
- case '$gte':
509
- if (dataValue >= queryValue)
510
- queryStatus = true
511
- break;
512
- case '$in':
513
- if (Array.isArray(dataValue)) {
514
- queryStatus = dataValue.some(element => queryValue.includes(element));
515
- } else {
516
- queryStatus = queryValue.includes(dataValue);
517
- }
518
- break;
519
- case '$nin':
520
- if (Array.isArray(dataValue)) {
521
- queryStatus = !dataValue.some(element => queryValue.includes(element));
522
- } else {
523
- queryStatus = !queryValue.includes(dataValue);
524
- }
525
- break;
526
- case '$range':
527
- if (queryValue[0] !== null && queryValue[1] !== null) {
528
- if (dataValue >= queryValue[0] && dataValue <= queryValue[1])
529
- queryStatus = true
530
- } else if (queryValue[0] == null && dataValue <= queryValue[1]) {
531
- queryStatus = true
532
- } else if (queryValue[1] == null && dataValue >= queryValue[0]) {
533
- queryStatus = true
534
- }
535
- break;
470
+ if (typeof query[key] === 'string' || typeof query[key] === 'number' || typeof query[key] === 'boolean') {
471
+ if (Array.isArray(dataValue))
472
+ return dataValue.includes(query[key])
473
+ else
474
+ return dataValue === query[key]
475
+ } else if (Array.isArray(query[key])) {
476
+ if (Array.isArray(dataValue)) {
477
+ return isEqualArray(dataValue, query[key]);
478
+ } else {
479
+ return false;
480
+ }
481
+ } else {
482
+ for (let property of Object.keys(query[key])) {
483
+ if (!property.startsWith('$')) {
484
+ if (typeof dataValue !== 'object') {
485
+ return false;
486
+ } else
487
+ return queryMatch({ [property]: getValueFromObject(dataValue, property) }, { [property]: query[key][property] })
488
+ } else {
489
+ let queryValue = query[key][property]
490
+ let queryStatus = false
491
+ switch (property) {
492
+ case '$eq':
493
+ if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
494
+ queryStatus = isEqualArray(dataValue, queryValue);
495
+ } else {
496
+ queryStatus = (dataValue === queryValue);
497
+ }
498
+ break;
499
+ case '$ne':
500
+ if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
501
+ queryStatus = !isEqualArray(dataValue, queryValue);
502
+ } else {
503
+ queryStatus = (dataValue !== queryValue);
504
+ }
505
+ break;
506
+ case '$not':
507
+ queryStatus = !queryMatch(data, { [key]: query[key]['$not'] });
508
+ break;
509
+ case '$lt':
510
+ queryStatus = (dataValue < queryValue)
511
+ break;
512
+ case '$lte':
513
+ queryStatus = (dataValue <= queryValue)
514
+ break;
515
+ case '$gt':
516
+ queryStatus = (dataValue > queryValue)
517
+ break;
518
+ case '$gte':
519
+ queryStatus = (dataValue >= queryValue)
520
+ break;
521
+ case '$in':
522
+ if (Array.isArray(dataValue)) {
523
+ queryStatus = dataValue.some(element => queryValue.includes(element));
524
+ } else {
525
+ queryStatus = queryValue.includes(dataValue);
526
+ }
527
+ break;
528
+ case '$nin':
529
+ if (Array.isArray(dataValue)) {
530
+ queryStatus = !dataValue.some(element => queryValue.includes(element));
531
+ } else {
532
+ queryStatus = !queryValue.includes(dataValue);
533
+ }
534
+ break;
535
+ case '$all':
536
+ if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
537
+ queryStatus = queryValue.every(element => dataValue.includes(element));
538
+ }
539
+ break;
540
+ case '$elemMatch':
541
+ if (Array.isArray(data[key])) {
542
+ queryStatus = data[key].some(element => queryMatch(element, query[key][property]));
543
+ }
544
+ break;
545
+ case '$size':
546
+ if (Array.isArray(dataValue)) {
547
+ queryStatus = (dataValue.length === queryValue);
548
+ }
549
+ break;
550
+ case '$exists':
551
+ queryStatus = (queryValue ? data.hasOwnProperty(key) : !data.hasOwnProperty(key));
552
+ break;
553
+ case '$regex':
554
+ if (typeof dataValue === 'string') {
555
+ let regex = new RegExp(queryValue);
556
+ queryStatus = regex.test(dataValue);
557
+ }
558
+ break;
559
+ case '$type':
560
+ let dataType = typeof dataValue;
561
+ if (Array.isArray(dataValue)) {
562
+ dataType = 'array';
563
+ }
564
+ queryStatus = (dataType === queryValue);
565
+ break;
566
+ case '$mod':
567
+ if (typeof dataValue === 'number' && Array.isArray(queryValue) && queryValue.length === 2) {
568
+ const [divisor, remainder] = queryValue;
569
+ queryStatus = (dataValue % divisor === remainder);
570
+ }
571
+ break;
572
+ case '$where':
573
+ if (typeof queryValue === 'function') {
574
+ try {
575
+ // queryStatus = queryValue.call(data);
576
+ } catch (error) {
577
+ console.error('Error in queryData $where function:', error);
578
+ }
579
+ }
580
+ break;
536
581
 
537
- default:
538
- if (dataValue.includes(queryValue))
539
- queryStatus = true
540
- break;
541
- }
542
- if (!queryIsArray || query[i].operator === "$nin") {
543
- switch (logicalOperator) {
544
- case 'and':
545
- if (queryStatus == false)
546
- return false
582
+ default:
583
+ console.log('unknown operator')
547
584
  break;
548
- // case 'or':
549
- // if (queryStatus == true)
550
- // queryResult = queryStatus
551
- // break;
585
+
552
586
  }
553
- } else if (queryStatus && query[i].operator === "$in")
554
- return true
555
- queryResult = queryStatus
587
+ if (!queryStatus)
588
+ return false
589
+
590
+ }
556
591
  }
592
+ return true
557
593
  }
558
- }
559
594
 
560
- return queryResult;
595
+ }
561
596
  }
562
597
 
563
598
  function isEqualArray(arr1, arr2) {
@@ -643,50 +678,35 @@
643
678
  return true
644
679
  }
645
680
 
681
+
646
682
  function sortData(data, sort) {
647
- if (!Array.isArray(sort))
648
- sort = [sort]
649
- for (let i = 0; i < sort.length; i++) {
650
- let key = sort[i].key
651
- if (key) {
652
- try {
653
- data.sort((a, b) => {
654
- if (sort[i].direction == 'desc') {
655
- switch (typeof b[key]) {
656
- case 'string':
657
- if (!b[key])
658
- b[key] = ""
659
- return b[key].localeCompare(a[key])
660
- case 'number':
661
- if (!b[key])
662
- b[key] = 0
663
- return b[key] - a[key]
664
- case 'array':
665
- case 'object':
666
- break;
667
- }
668
- } else {
669
- switch (typeof a[key]) {
670
- case 'string':
671
- if (!a[key])
672
- a[key] = ""
673
- return a[key].localeCompare(b[key])
674
- case 'number':
675
- if (!a[key])
676
- a[key] = 0
677
- return a[key] - b[key]
678
- case 'array':
679
- case 'object':
680
- break;
681
- }
682
- }
683
- });
684
- } catch (error) {
685
- console.log(error)
683
+ return data.sort((a, b) => {
684
+ for (let i = 0; i < sort.length; i++) {
685
+ let key = sort[i].key;
686
+ if (a[key] == null && b[key] == null) continue;
687
+ if (a[key] == null)
688
+ return sort[i].direction === 'desc' ? -1 : 1;
689
+ if (b[key] == null)
690
+ return sort[i].direction === 'desc' ? 1 : -1;
691
+
692
+ if (typeof a[key] !== typeof b[key]) {
693
+ return typeof a[key] < typeof b[key] ? -1 : 1;
694
+ }
695
+
696
+ if (a[key] !== b[key]) {
697
+ if (typeof a[key] === 'string') {
698
+ return sort[i].direction === 'desc' ?
699
+ b[key].localeCompare(a[key]) :
700
+ a[key].localeCompare(b[key]);
701
+ } else { // Assuming numeric or other comparable types
702
+ return sort[i].direction === 'desc' ?
703
+ (b[key] - a[key]) :
704
+ (a[key] - b[key]);
705
+ }
686
706
  }
687
707
  }
688
- }
689
- return data;
708
+ return 0;
709
+ });
690
710
  }
691
711
 
692
712
  function getAttributes(el) {
@@ -748,7 +768,6 @@
748
768
  isValidDate,
749
769
  dotNotationToObject,
750
770
  getValueFromObject,
751
- isObjectEmpty,
752
771
  domParser,
753
772
  parseTextToHtml,
754
773
  escapeHtml,