@cocreate/utils 1.31.0 → 1.32.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.
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/src/index.js +185 -143
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
# [1.32.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.31.0...v1.32.0) (2024-01-17)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* getValueFromObject conditions and param names ([2fd7387](https://github.com/CoCreate-app/CoCreate-utils/commit/2fd73873cc42d0a22e43e04fee35f31227790f7b))
|
|
7
|
+
* 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))
|
|
8
|
+
* renamed isMatch to queryMatch ([b3c9429](https://github.com/CoCreate-app/CoCreate-utils/commit/b3c942950661b1d906c9f8a77a3bbd2f5693fd47))
|
|
9
|
+
* update to support new query system ([a267b52](https://github.com/CoCreate-app/CoCreate-utils/commit/a267b5260955a631330a2b22bd9fb316a00004c6))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* query() function to handle queries similar to mongodb ([164bf45](https://github.com/CoCreate-app/CoCreate-utils/commit/164bf45d44f620fe8e6a4cf75fe744be68277d6c))
|
|
15
|
+
* sort by multiple keys ([7872a53](https://github.com/CoCreate-app/CoCreate-utils/commit/7872a5308bcf510e40385c57b45c0d899a40295a))
|
|
16
|
+
|
|
1
17
|
# [1.31.0](https://github.com/CoCreate-app/CoCreate-utils/compare/v1.30.0...v1.31.0) (2024-01-08)
|
|
2
18
|
|
|
3
19
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -142,32 +142,36 @@
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
function getValueFromObject(
|
|
145
|
+
function getValueFromObject(object = {}, path = '', throwError = false) {
|
|
146
146
|
try {
|
|
147
|
-
if (
|
|
148
|
-
|
|
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
|
|
156
|
+
let data = object, subpath = path.split('.');
|
|
153
157
|
|
|
154
158
|
for (let i = 0; i < subpath.length; i++) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
return;
|
|
158
165
|
}
|
|
159
|
-
|
|
166
|
+
|
|
167
|
+
return data;
|
|
160
168
|
} catch (error) {
|
|
161
|
-
console.
|
|
162
|
-
|
|
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,153 @@
|
|
|
418
423
|
return selector
|
|
419
424
|
}
|
|
420
425
|
|
|
421
|
-
|
|
422
426
|
function queryData(data, query) {
|
|
423
|
-
if (
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
+
}
|
|
428
433
|
|
|
429
|
-
if (
|
|
430
|
-
|
|
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
|
+
}
|
|
431
440
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
+
}
|
|
436
447
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
|
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
|
+
}
|
|
455
454
|
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
456
457
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
dataValue = dataValue.toLowerCase()
|
|
462
|
-
if (typeof queryValue == 'string')
|
|
463
|
-
queryValue = queryValue.toLowerCase()
|
|
464
|
-
}
|
|
458
|
+
function queryMatch(data, query) {
|
|
459
|
+
for (let key of Object.keys(query)) {
|
|
460
|
+
// if (!data.hasOwnProperty(key))
|
|
461
|
+
// return false
|
|
465
462
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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;
|
|
463
|
+
let dataValue
|
|
464
|
+
try {
|
|
465
|
+
dataValue = getValueFromObject(data, key, true)
|
|
466
|
+
} catch (error) {
|
|
467
|
+
return false
|
|
468
|
+
}
|
|
536
469
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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));
|
|
547
552
|
break;
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
553
|
+
case '$regex':
|
|
554
|
+
if (typeof dataValue === 'string') {
|
|
555
|
+
let regex = new RegExp(queryValue);
|
|
556
|
+
queryStatus = regex.test(dataValue);
|
|
557
|
+
}
|
|
558
|
+
break;
|
|
559
|
+
default:
|
|
560
|
+
console.log('unknown operator')
|
|
561
|
+
break;
|
|
562
|
+
|
|
552
563
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
564
|
+
if (!queryStatus)
|
|
565
|
+
return false
|
|
566
|
+
|
|
567
|
+
}
|
|
556
568
|
}
|
|
569
|
+
return true
|
|
557
570
|
}
|
|
558
|
-
}
|
|
559
571
|
|
|
560
|
-
|
|
572
|
+
}
|
|
561
573
|
}
|
|
562
574
|
|
|
563
575
|
function isEqualArray(arr1, arr2) {
|
|
@@ -643,7 +655,38 @@
|
|
|
643
655
|
return true
|
|
644
656
|
}
|
|
645
657
|
|
|
658
|
+
|
|
646
659
|
function sortData(data, sort) {
|
|
660
|
+
return data.sort((a, b) => {
|
|
661
|
+
for (let i = 0; i < sort.length; i++) {
|
|
662
|
+
let key = sort[i].key;
|
|
663
|
+
if (a[key] == null && b[key] == null) continue;
|
|
664
|
+
if (a[key] == null)
|
|
665
|
+
return sort[i].direction === 'desc' ? -1 : 1;
|
|
666
|
+
if (b[key] == null)
|
|
667
|
+
return sort[i].direction === 'desc' ? 1 : -1;
|
|
668
|
+
|
|
669
|
+
if (typeof a[key] !== typeof b[key]) {
|
|
670
|
+
return typeof a[key] < typeof b[key] ? -1 : 1;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (a[key] !== b[key]) {
|
|
674
|
+
if (typeof a[key] === 'string') {
|
|
675
|
+
return sort[i].direction === 'desc' ?
|
|
676
|
+
b[key].localeCompare(a[key]) :
|
|
677
|
+
a[key].localeCompare(b[key]);
|
|
678
|
+
} else { // Assuming numeric or other comparable types
|
|
679
|
+
return sort[i].direction === 'desc' ?
|
|
680
|
+
(b[key] - a[key]) :
|
|
681
|
+
(a[key] - b[key]);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return 0;
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
function sortDataOld(data, sort) {
|
|
647
690
|
if (!Array.isArray(sort))
|
|
648
691
|
sort = [sort]
|
|
649
692
|
for (let i = 0; i < sort.length; i++) {
|
|
@@ -748,7 +791,6 @@
|
|
|
748
791
|
isValidDate,
|
|
749
792
|
dotNotationToObject,
|
|
750
793
|
getValueFromObject,
|
|
751
|
-
isObjectEmpty,
|
|
752
794
|
domParser,
|
|
753
795
|
parseTextToHtml,
|
|
754
796
|
escapeHtml,
|