@libs-ui/utils 0.2.307-0 → 0.2.309-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.
@@ -1,9 +1,9 @@
1
1
  import DeviceDetector from 'device-detector-js';
2
2
  import Quill from 'quill';
3
- import { fromEvent, tap, takeUntil, mergeMap, startWith, finalize, lastValueFrom, timer, Subject, filter, Observable } from 'rxjs';
3
+ import { fromEvent, tap, takeUntil, mergeMap, startWith, finalize, lastValueFrom, timer, Observable, Subject, filter } from 'rxjs';
4
4
  import CryptoES from 'crypto-es';
5
5
  import { HttpParams } from '@angular/common/http';
6
- import { isSignal, TemplateRef, ElementRef, signal, InjectionToken } from '@angular/core';
6
+ import { TemplateRef, ElementRef, isSignal, signal, InjectionToken } from '@angular/core';
7
7
  import dayjs from 'dayjs';
8
8
  import 'dayjs/locale/en';
9
9
  import 'dayjs/locale/vi';
@@ -630,83 +630,143 @@ const uuid = () => {
630
630
  };
631
631
 
632
632
  /* eslint-disable @typescript-eslint/no-explicit-any */
633
- const UtilsHttpParamsRequestInstance = (options, instance) => {
634
- return new UtilsHttpParamsRequest(options, instance);
635
- };
636
- class UtilsHttpParamsRequest extends HttpParams {
637
- params = new HttpParams();
638
- constructor(options, instance) {
639
- super(options);
640
- if (!instance) {
641
- this.params = new HttpParams(options);
642
- return;
643
- }
644
- if (instance instanceof UtilsHttpParamsRequest) {
645
- this.params = instance.getInstance();
646
- return;
647
- }
648
- if (instance instanceof HttpParams) {
649
- this.params = instance;
650
- return;
651
- }
652
- }
653
- getInstance() {
654
- return this.params;
655
- }
656
- setInstance(instance) {
657
- if (instance instanceof UtilsHttpParamsRequest) {
658
- this.params = instance.getInstance();
659
- return;
660
- }
661
- if (instance instanceof HttpParams) {
662
- this.params = instance;
663
- return;
664
- }
665
- }
666
- set(param, value) {
667
- this.params = this.params.set(param, value);
668
- return this;
633
+ /**
634
+ * Danh sách các constructor name nguy hiểm
635
+ */
636
+ const DANGEROUS_CONSTRUCTOR_NAMES = ['Window', 'Document', 'HTMLDocument', 'HTMLElement', 'Element', 'Node', 'Location', 'Navigator', 'Screen', 'History', 'Storage', 'Console', 'Performance'];
637
+ /**
638
+ * Kiểm tra xem đối tượng có phải là browser global object không
639
+ */
640
+ const isBrowserGlobalObject = (obj) => {
641
+ if (obj === null || typeof obj !== 'object') {
642
+ return false;
669
643
  }
670
- has(param) {
671
- return this.params.has(param);
644
+ return obj instanceof Window || obj instanceof Document || obj === window || obj === document || obj === globalThis;
645
+ };
646
+ /**
647
+ * Kiểm tra xem đối tượng có phải là DOM object không
648
+ */
649
+ const isDOMObject = (obj) => {
650
+ if (obj === null || typeof obj !== 'object') {
651
+ return false;
672
652
  }
673
- get(param) {
674
- return this.params.get(param);
653
+ return obj instanceof HTMLElement || obj instanceof Node || obj instanceof Element;
654
+ };
655
+ /**
656
+ * Kiểm tra xem đối tượng có phải là browser API object không
657
+ */
658
+ const isBrowserAPIObject = (obj) => {
659
+ if (obj === null || typeof obj !== 'object' || typeof window === 'undefined') {
660
+ return false;
675
661
  }
676
- getAll(param) {
677
- return this.params.getAll(param);
662
+ return obj === window.location || obj === window.navigator || obj === window.screen || obj === window.history || obj === window.localStorage || obj === window.sessionStorage || obj === window.console || obj === window.performance;
663
+ };
664
+ /**
665
+ * Kiểm tra constructor name có nằm trong danh sách nguy hiểm không
666
+ */
667
+ const hasDangerousConstructorName = (obj) => {
668
+ if (obj === null || typeof obj !== 'object') {
669
+ return false;
678
670
  }
679
- keys() {
680
- return this.params.keys();
671
+ const constructorName = obj.constructor?.name;
672
+ return constructorName && DANGEROUS_CONSTRUCTOR_NAMES.includes(constructorName);
673
+ };
674
+ /**
675
+ * Kiểm tra xem đối tượng có phải là DOM object hoặc browser object nguy hiểm không
676
+ * Những đối tượng này có thể gây ra circular reference và maximum call stack
677
+ */
678
+ const isDangerousObject = (obj) => {
679
+ if (obj === null || typeof obj !== 'object') {
680
+ return false;
681
681
  }
682
- append(param, value) {
683
- this.params = this.params.append(param, value);
684
- return this;
682
+ return isBrowserGlobalObject(obj) || isDOMObject(obj) || isBrowserAPIObject(obj) || hasDangerousConstructorName(obj);
683
+ };
684
+ /**
685
+ * Kiểm tra đối tượng có phải là Angular/Framework object không
686
+ */
687
+ const isFrameworkObject = (obj) => {
688
+ if (obj === null || typeof obj !== 'object') {
689
+ return false;
685
690
  }
686
- appendAll(params) {
687
- this.params = this.params.appendAll(params);
688
- return this;
691
+ return obj instanceof TemplateRef || obj instanceof ElementRef;
692
+ };
693
+ /**
694
+ * Kiểm tra đối tượng có phải là File/Blob object không
695
+ */
696
+ const isFileObject = (obj) => {
697
+ if (obj === null || typeof obj !== 'object') {
698
+ return false;
689
699
  }
690
- delete(param, value) {
691
- this.params = this.params.delete(param, value);
692
- return this;
700
+ return obj instanceof File || obj instanceof Blob || Object.prototype.toString.call(obj) === '[object File]';
701
+ };
702
+ /**
703
+ * Kiểm tra đối tượng có phải là Built-in object không
704
+ */
705
+ const isBuiltInObject = (obj) => {
706
+ if (obj === null || typeof obj !== 'object') {
707
+ return false;
693
708
  }
694
- toString() {
695
- return this.params.toString();
709
+ return obj instanceof Date || obj instanceof RegExp || obj instanceof HttpParams;
710
+ };
711
+ /**
712
+ * Kiểm tra đối tượng có phải là Async object không
713
+ */
714
+ const isAsyncObject = (obj) => {
715
+ if (obj === null || typeof obj !== 'object') {
716
+ return false;
696
717
  }
697
- }
698
- // Demo su dung GET_PATH_VARIABLE
699
- // interface Person {
700
- // name: string;
701
- // age: number;
702
- // location: string;
703
- // }
704
- // type c = GET_PATH_VARIABLE<Person, unknown>;
705
- // const a: c = {
706
- // "pathVariable-age": 1,
707
- // "pathVariable-location": '12',
708
- // "pathVariable-name": '124',
709
- // };
718
+ return obj instanceof Promise || obj instanceof Observable;
719
+ };
720
+ /**
721
+ * Kiểm tra đối tượng có phải là Special object cần bỏ qua không
722
+ * Bao gồm: Framework objects, File objects, Built-in objects, Async objects
723
+ */
724
+ const isSpecialObject = (obj) => {
725
+ return isFrameworkObject(obj) || isFileObject(obj) || isBuiltInObject(obj) || isAsyncObject(obj);
726
+ };
727
+ /**
728
+ * Kiểm tra đối tượng có phải là dayjs object không
729
+ */
730
+ const isDayjsObject = (obj) => {
731
+ return dayjs.isDayjs(obj);
732
+ };
733
+ /**
734
+ * Kiểm tra đối tượng có phải là object cần bỏ qua trong quá trình convert không
735
+ */
736
+ const isSkippableObject = (obj) => {
737
+ return isDangerousObject(obj) || isSpecialObject(obj);
738
+ };
739
+ /**
740
+ * Kiểm tra đối tượng có phải là Map object không
741
+ */
742
+ const isMapObject = (obj) => {
743
+ return obj instanceof Map;
744
+ };
745
+ /**
746
+ * Kiểm tra đối tượng có phải là Set object không
747
+ */
748
+ const isSetObject = (obj) => {
749
+ return obj instanceof Set;
750
+ };
751
+ /**
752
+ * Kiểm tra đối tượng có phải là Array object không
753
+ */
754
+ const isArrayObject = (obj) => {
755
+ return Array.isArray(obj);
756
+ };
757
+ /**
758
+ * Kiểm tra đối tượng có phải là object cần trả về nguyên trạng không
759
+ * Bao gồm: dangerous objects, special objects, dayjs objects
760
+ */
761
+ const isReturnAsIsObject = (obj) => {
762
+ return isSkippableObject(obj) || isDayjsObject(obj);
763
+ };
764
+ /**
765
+ * Kiểm tra xem đối tượng có an toàn để clone/convert không
766
+ */
767
+ const isSafeToProcess = (obj) => {
768
+ return !isDangerousObject(obj);
769
+ };
710
770
 
711
771
  let key = '12~@#loqwsxacva(3rdhaq12';
712
772
  /**
@@ -1538,6 +1598,207 @@ const getFormatData = (type, lang) => {
1538
1598
  }
1539
1599
  };
1540
1600
 
1601
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1602
+ const UtilsHttpParamsRequestInstance = (options, instance) => {
1603
+ return new UtilsHttpParamsRequest(options, instance);
1604
+ };
1605
+ class UtilsHttpParamsRequest extends HttpParams {
1606
+ params = new HttpParams();
1607
+ constructor(options, instance) {
1608
+ super(options);
1609
+ if (!instance) {
1610
+ this.params = new HttpParams(options);
1611
+ return;
1612
+ }
1613
+ if (instance instanceof UtilsHttpParamsRequest) {
1614
+ this.params = instance.getInstance();
1615
+ return;
1616
+ }
1617
+ if (instance instanceof HttpParams) {
1618
+ this.params = instance;
1619
+ return;
1620
+ }
1621
+ }
1622
+ getInstance() {
1623
+ return this.params;
1624
+ }
1625
+ setInstance(instance) {
1626
+ if (instance instanceof UtilsHttpParamsRequest) {
1627
+ this.params = instance.getInstance();
1628
+ return;
1629
+ }
1630
+ if (instance instanceof HttpParams) {
1631
+ this.params = instance;
1632
+ return;
1633
+ }
1634
+ }
1635
+ set(param, value) {
1636
+ this.params = this.params.set(param, value);
1637
+ return this;
1638
+ }
1639
+ has(param) {
1640
+ return this.params.has(param);
1641
+ }
1642
+ get(param) {
1643
+ return this.params.get(param);
1644
+ }
1645
+ getAll(param) {
1646
+ return this.params.getAll(param);
1647
+ }
1648
+ keys() {
1649
+ return this.params.keys();
1650
+ }
1651
+ append(param, value) {
1652
+ this.params = this.params.append(param, value);
1653
+ return this;
1654
+ }
1655
+ appendAll(params) {
1656
+ this.params = this.params.appendAll(params);
1657
+ return this;
1658
+ }
1659
+ delete(param, value) {
1660
+ this.params = this.params.delete(param, value);
1661
+ return this;
1662
+ }
1663
+ toString() {
1664
+ return this.params.toString();
1665
+ }
1666
+ }
1667
+ // Demo su dung GET_PATH_VARIABLE
1668
+ // interface Person {
1669
+ // name: string;
1670
+ // age: number;
1671
+ // location: string;
1672
+ // }
1673
+ // type c = GET_PATH_VARIABLE<Person, unknown>;
1674
+ // const a: c = {
1675
+ // "pathVariable-age": 1,
1676
+ // "pathVariable-location": '12',
1677
+ // "pathVariable-name": '124',
1678
+ // };
1679
+
1680
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1681
+ /**
1682
+ * Chuyển đổi một đối tượng hoặc giá trị thành signal
1683
+ * @param data Dữ liệu cần chuyển đổi thành signal
1684
+ * @param cloneDeepIfNotSignal Có thực hiện sao chép sâu dữ liệu trước khi chuyển đổi hay không nếu data không phải signal. Mặc định là true.
1685
+ * Đặt false nếu muốn giữ nguyên tham chiếu đến dữ liệu gốc.
1686
+ * Nếu muốn sao chép sâu đối tượng signal thì đặt cloneDeepIfNotSignal là true và acceptConvertObjectInnerWritableSignal là true.
1687
+ * @param isSignalPrimitiveType Có chuyển đổi các giá trị nguyên thủy (string, number, boolean) thành signal hay không. Mặc định là false.
1688
+ * Đặt true nếu muốn bọc các giá trị nguyên thủy trong signal.
1689
+ * @param acceptConvertObjectInnerWritableSignal Có tiếp tục tìm kiếm và chuyển đổi các đối tượng bên trong signal hay không. Mặc định là false.
1690
+ * Đặt true nếu muốn tìm và chuyển đổi các đối tượng bên trong signal hoặc chính nó thành signal mới.
1691
+ * @returns Dữ liệu đã được chuyển đổi theo kiểu T
1692
+ */
1693
+ const convertObjectToSignal = (data, cloneDeepIfNotSignal = true, isSignalPrimitiveType = false, acceptConvertObjectInnerWritableSignal = false, seen = new WeakMap()) => {
1694
+ if ((data === null || typeof data !== 'object') && !isSignal(data)) {
1695
+ return (isSignalPrimitiveType ? signal(data) : data);
1696
+ }
1697
+ if (seen.has(data)) {
1698
+ return seen.get(data);
1699
+ }
1700
+ if (isSignal(data)) {
1701
+ if (!acceptConvertObjectInnerWritableSignal) {
1702
+ return data;
1703
+ }
1704
+ seen.set(data, convertObjectToSignal(data(), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen));
1705
+ return seen.get(data);
1706
+ }
1707
+ if (isArrayObject(data)) {
1708
+ seen.set(data, signal(data.map((item) => convertObjectToSignal(item, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen))));
1709
+ return seen.get(data);
1710
+ }
1711
+ if (isMapObject(data)) {
1712
+ const mapCopy = new Map();
1713
+ Array.from(data.keys()).forEach((key) => {
1714
+ mapCopy.set(key, convertObjectToSignal(data.get(key), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal));
1715
+ });
1716
+ seen.set(data, signal(mapCopy));
1717
+ return seen.get(data);
1718
+ }
1719
+ // Bỏ qua các đối tượng async
1720
+ if (isAsyncObject(data)) {
1721
+ return data;
1722
+ }
1723
+ data = signal(cloneDeepIfNotSignal ? { ...data } : data);
1724
+ seen.set(data, data);
1725
+ for (const key in data()) {
1726
+ const value = data()[key];
1727
+ // Bỏ qua các đối tượng nguy hiểm và đặc biệt
1728
+ if (isReturnAsIsObject(value)) {
1729
+ continue;
1730
+ }
1731
+ if (Object.prototype.hasOwnProperty.call(data(), key)) {
1732
+ data()[key] = convertObjectToSignal(value, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal);
1733
+ }
1734
+ }
1735
+ return data;
1736
+ };
1737
+ const convertSignalToObject = (data, isCloneDeep = true, seen = new WeakMap()) => {
1738
+ let ignoreCheckSeenHasDataAfterWhile = false;
1739
+ while (isSignal(data) && !seen.has(data)) {
1740
+ const dataConvert = data();
1741
+ if (typeof dataConvert === 'object') {
1742
+ if (dataConvert === null || isReturnAsIsObject(dataConvert)) {
1743
+ return dataConvert;
1744
+ }
1745
+ seen.set(dataConvert, dataConvert);
1746
+ data = dataConvert;
1747
+ ignoreCheckSeenHasDataAfterWhile = true;
1748
+ break;
1749
+ }
1750
+ seen.set(data, dataConvert);
1751
+ data = dataConvert;
1752
+ }
1753
+ if (data === null || typeof data === 'function' || typeof data !== 'object' || isReturnAsIsObject(data)) {
1754
+ return data;
1755
+ }
1756
+ if (!ignoreCheckSeenHasDataAfterWhile && seen.has(data)) {
1757
+ return seen.get(data);
1758
+ }
1759
+ if (isArrayObject(data)) {
1760
+ if (!isSignal(data[0])) {
1761
+ return data;
1762
+ }
1763
+ seen.set(data, data.map((item) => convertSignalToObject(isCloneDeep ? cloneDeep(item) : item, isCloneDeep, seen)));
1764
+ return seen.get(data);
1765
+ }
1766
+ if (isMapObject(data)) {
1767
+ const mapCopy = new Map();
1768
+ Array.from(data.keys()).forEach((key) => {
1769
+ mapCopy.set(key, convertSignalToObject(isCloneDeep ? cloneDeep(data.get(key)) : data.get(key), isCloneDeep));
1770
+ });
1771
+ seen.set(data, mapCopy);
1772
+ return seen.get(data);
1773
+ }
1774
+ if (isSetObject(data)) {
1775
+ const setCopy = new Set();
1776
+ Array.from(data.values()).forEach((value) => {
1777
+ setCopy.add(convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep));
1778
+ });
1779
+ seen.set(data, setCopy);
1780
+ return seen.get(data);
1781
+ }
1782
+ // Bỏ qua các đối tượng nguy hiểm và đặc biệt
1783
+ if (isReturnAsIsObject(data)) {
1784
+ return data;
1785
+ }
1786
+ const result = isCloneDeep ? {} : data;
1787
+ seen.set(data, result);
1788
+ for (const key in data) {
1789
+ const value = data[key];
1790
+ if (Object.prototype.hasOwnProperty.call(data, key)) {
1791
+ // Bỏ qua các đối tượng nguy hiểm để tránh maximum call stack
1792
+ if (isReturnAsIsObject(value)) {
1793
+ result[key] = value;
1794
+ continue;
1795
+ }
1796
+ result[key] = convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep);
1797
+ }
1798
+ }
1799
+ return result;
1800
+ };
1801
+
1541
1802
  /* eslint-disable @typescript-eslint/no-explicit-any */
1542
1803
  /**Các hàm tương tự thư viện lodash */
1543
1804
  /**
@@ -1550,7 +1811,10 @@ const getFormatData = (type, lang) => {
1550
1811
  * isNil(0); // false
1551
1812
  * isNil('hello'); // false
1552
1813
  */
1553
- const isNil = (value) => {
1814
+ const isNil = (value, options) => {
1815
+ if (!options?.ignoreUnWrapSignal) {
1816
+ value = convertSignalToObject(value);
1817
+ }
1554
1818
  return value === null || value === undefined;
1555
1819
  };
1556
1820
  /**
@@ -1566,11 +1830,75 @@ const isNil = (value) => {
1566
1830
  * isEmpty([1, 2, 3]); // false
1567
1831
  * isEmpty({ a: 1 }); // false
1568
1832
  */
1569
- const isEmpty = (value) => {
1570
- while (isSignal(value)) {
1571
- value = value();
1833
+ const isEmpty = (value, options) => {
1834
+ if (!options?.ignoreUnWrapSignal) {
1835
+ value = convertSignalToObject(value);
1836
+ }
1837
+ if (options?.ignoreCheckFalsy) {
1838
+ return isEmptyTypeObject(value);
1839
+ }
1840
+ const valueIsFalsy = isFalsy(value, { ignoreUnWrapSignal: options?.ignoreUnWrapSignal, ignoreZero: true, ignoreCheckString: options?.ignoreCheckString });
1841
+ if (options?.ignoreCheckTypeObj) {
1842
+ return valueIsFalsy;
1843
+ }
1844
+ return valueIsFalsy || isEmptyTypeObject(value);
1845
+ };
1846
+ /**
1847
+ * Kiểm tra xem một giá trị có phải là object rỗng hay không
1848
+ * @param value Giá trị cần kiểm tra
1849
+ * @returns true nếu giá trị là object rỗng, false nếu không
1850
+ * @example
1851
+ * isEmptyTypeObject({}); // true
1852
+ * isEmptyTypeObject({ a: 1 }); // false
1853
+ */
1854
+ const isEmptyTypeObject = (value) => {
1855
+ return typeof value === 'object' && (JSON.stringify(value) === '{}' || JSON.stringify(value) === '[]');
1856
+ };
1857
+ /**
1858
+ * Kiểm tra xem một giá trị có phải là null, rỗng, undefined hoặc 0 hay không
1859
+ * @param value Giá trị cần kiểm tra
1860
+ * @param options Cấu hình tùy chọn
1861
+ * @param options.ignoreZero Nếu true, sẽ không kiểm tra giá trị 0
1862
+ * @returns true nếu giá trị là null, rỗng, undefined hoặc 0, false nếu không
1863
+ * @example
1864
+ * isTruthy(null); // false
1865
+ * isTruthy(''); // false
1866
+ * isTruthy(undefined); // false
1867
+ * isTruthy(0); // false
1868
+ * isTruthy({}); // false
1869
+ * isTruthy(0, { ignoreZero: true }); // true
1870
+ */
1871
+ const isTruthy = (value, options) => {
1872
+ return !isFalsy(value, options);
1873
+ };
1874
+ /**
1875
+ * Kiểm tra xem một giá trị có phải là null, rỗng, undefined hoặc 0 hay không
1876
+ * @param value Giá trị cần kiểm tra
1877
+ * @param options Cấu hình tùy chọn
1878
+ * @param options.ignoreZero Nếu true, sẽ không kiểm tra giá trị 0
1879
+ * @returns true nếu giá trị là null, rỗng, undefined hoặc 0, false nếu không
1880
+ * @example
1881
+ * isFalsy(null); // true
1882
+ * isFalsy(''); // true
1883
+ * isFalsy(undefined); // true
1884
+ * isFalsy(0); // true
1885
+ * isFalsy({}); // false
1886
+ * isFalsy(0, { ignoreZero: true }); // false
1887
+ */
1888
+ const isFalsy = (value, options) => {
1889
+ if (!options?.ignoreUnWrapSignal) {
1890
+ value = convertSignalToObject(value);
1891
+ }
1892
+ if (isNil(value, { ignoreUnWrapSignal: options?.ignoreUnWrapSignal })) {
1893
+ return true;
1894
+ }
1895
+ if (options?.ignoreZero) {
1896
+ return value === '';
1572
1897
  }
1573
- return value === null || value === '' || value === undefined || (typeof value === 'object' && (JSON.stringify(value) === '{}' || JSON.stringify(value) === '[]'));
1898
+ if (options?.ignoreCheckString) {
1899
+ return value === 0;
1900
+ }
1901
+ return value === '' || value === 0;
1574
1902
  };
1575
1903
  /**
1576
1904
  * Loại bỏ các thuộc tính của đối tượng dựa trên một hàm điều kiện
@@ -1708,7 +2036,7 @@ const get = (obj, path, defaultValue = undefined, keepLastValueIfSignal) => {
1708
2036
  * const obj = { a: { b: 1 } };
1709
2037
  * set(obj, 'a.b', 2); // { a: { b: 2 } }
1710
2038
  */
1711
- const set = (obj, path, value) => {
2039
+ const set = (obj, path, value, options) => {
1712
2040
  if (!obj || (typeof obj !== 'object' && !isSignal(obj)) || (isSignal(obj) && typeof obj() !== 'object')) {
1713
2041
  throw new Error('The first argument must be an object');
1714
2042
  }
@@ -1728,7 +2056,9 @@ const set = (obj, path, value) => {
1728
2056
  if (!(key in currentObjectByKey) || (typeof currentObjectByKey[key] !== 'object' && !isSignal(currentObjectByKey[key]))) {
1729
2057
  const nextKey = pathArray[index + 1];
1730
2058
  key = key.replace(/\[(\d+)]/g, '$1');
1731
- currentObjectByKey[key] = /\[(\d+)]/g.test(nextKey) ? [] : {};
2059
+ if (isNil(currentObjectByKey[key])) {
2060
+ currentObjectByKey[key] = /\[(\d+)]/g.test(nextKey) ? (options?.valueDefaultPathArrayUndefined ?? []) : (options?.valueDefaultPathObjectUndefined ?? {});
2061
+ }
1732
2062
  }
1733
2063
  currentObjectByKey = key ? currentObjectByKey[key] : currentObjectByKey;
1734
2064
  preObjectByKey = currentObjectByKey;
@@ -1787,7 +2117,7 @@ const set = (obj, path, value) => {
1787
2117
  * // clone là một bản sao hoàn toàn độc lập của obj
1788
2118
  */
1789
2119
  const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()) => {
1790
- if (data === null || (typeof data !== 'object' && !isSignal(data))) {
2120
+ if (data === null || (typeof data !== 'object' && !isSignal(data)) || isDangerousObject(data)) {
1791
2121
  return data;
1792
2122
  }
1793
2123
  if (seen.has(data)) {
@@ -1825,10 +2155,7 @@ const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()
1825
2155
  seen.set(data, data.map((item) => cloneDeep(item, options, seen)));
1826
2156
  return seen.get(data);
1827
2157
  }
1828
- if (data instanceof File || data instanceof Blob || Object.prototype.toString.call(data) === '[object File]') {
1829
- return data;
1830
- }
1831
- if (data instanceof TemplateRef || data instanceof ElementRef || data instanceof Element || data instanceof Promise || data instanceof Observable) {
2158
+ if (isReturnAsIsObject(data)) {
1832
2159
  return data;
1833
2160
  }
1834
2161
  if (isSignal(data)) {
@@ -1846,11 +2173,19 @@ const cloneDeep = (data, options = { ignoreSignal: false }, seen = new WeakMap()
1846
2173
  result[key] = new UtilsHttpParamsRequest(undefined, value);
1847
2174
  continue;
1848
2175
  }
2176
+ if (value instanceof Date) {
2177
+ result[key] = new Date(value.getTime());
2178
+ continue;
2179
+ }
1849
2180
  if (dayjs.isDayjs(value)) {
1850
2181
  result[key] = getDayjs({ date: value.valueOf() });
1851
2182
  continue;
1852
2183
  }
1853
- if (value instanceof TemplateRef || value instanceof ElementRef || value instanceof Element || value instanceof Promise || value instanceof Observable) {
2184
+ if (value instanceof RegExp) {
2185
+ result[key] = new RegExp(value.source, value.flags);
2186
+ continue;
2187
+ }
2188
+ if (isReturnAsIsObject(data)) {
1854
2189
  result[key] = value;
1855
2190
  continue;
1856
2191
  }
@@ -1982,6 +2317,11 @@ const range = (start, end, step) => {
1982
2317
  * isEqual({a:1}, {a:1}); // true
1983
2318
  */
1984
2319
  const isEqual = (value1, value2, options) => {
2320
+ // Handle signals
2321
+ if (!options?.ignoreUnWrapSignal) {
2322
+ value1 = convertSignalToObject(value1);
2323
+ value2 = convertSignalToObject(value2);
2324
+ }
1985
2325
  const { exactlyPosition = false, ignoreExactlyDataType = false } = options || {};
1986
2326
  if (value1 === value2 || (value1 === null && value2 === null) || (value1 === undefined && value2 === undefined)) {
1987
2327
  return true;
@@ -1989,13 +2329,6 @@ const isEqual = (value1, value2, options) => {
1989
2329
  if (ignoreExactlyDataType) {
1990
2330
  return isEqual(isNil(value1) ? undefined : `${value1}`, isNil(value2) ? undefined : `${value2}`);
1991
2331
  }
1992
- // Handle signals
1993
- while (isSignal(value1)) {
1994
- value1 = value1();
1995
- }
1996
- while (isSignal(value2)) {
1997
- value2 = value2();
1998
- }
1999
2332
  if (typeof value1 !== 'object' || typeof value2 !== 'object' || (Array.isArray(value1) && !Array.isArray(value2)) || (!Array.isArray(value1) && Array.isArray(value2))) {
2000
2333
  return false;
2001
2334
  }
@@ -2455,127 +2788,6 @@ const xssFilter = async (data) => {
2455
2788
  return await functionXssFilter(data);
2456
2789
  };
2457
2790
 
2458
- /* eslint-disable @typescript-eslint/no-explicit-any */
2459
- /**
2460
- * Chuyển đổi một đối tượng hoặc giá trị thành signal
2461
- * @param data Dữ liệu cần chuyển đổi thành signal
2462
- * @param cloneDeepIfNotSignal Có thực hiện sao chép sâu dữ liệu trước khi chuyển đổi hay không nếu data không phải signal. Mặc định là true.
2463
- * Đặt false nếu muốn giữ nguyên tham chiếu đến dữ liệu gốc.
2464
- * Nếu muốn sao chép sâu đối tượng signal thì đặt cloneDeepIfNotSignal là true và acceptConvertObjectInnerWritableSignal là true.
2465
- * @param isSignalPrimitiveType Có chuyển đổi các giá trị nguyên thủy (string, number, boolean) thành signal hay không. Mặc định là false.
2466
- * Đặt true nếu muốn bọc các giá trị nguyên thủy trong signal.
2467
- * @param acceptConvertObjectInnerWritableSignal Có tiếp tục tìm kiếm và chuyển đổi các đối tượng bên trong signal hay không. Mặc định là false.
2468
- * Đặt true nếu muốn tìm và chuyển đổi các đối tượng bên trong signal hoặc chính nó thành signal mới.
2469
- * @returns Dữ liệu đã được chuyển đổi theo kiểu T
2470
- */
2471
- const convertObjectToSignal = (data, cloneDeepIfNotSignal = true, isSignalPrimitiveType = false, acceptConvertObjectInnerWritableSignal = false, seen = new WeakMap()) => {
2472
- if ((data === null || typeof data !== 'object') && !isSignal(data)) {
2473
- return (isSignalPrimitiveType ? signal(data) : data);
2474
- }
2475
- if (seen.has(data)) {
2476
- return seen.get(data);
2477
- }
2478
- if (isSignal(data)) {
2479
- if (!acceptConvertObjectInnerWritableSignal) {
2480
- return data;
2481
- }
2482
- seen.set(data, convertObjectToSignal(data(), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen));
2483
- return seen.get(data);
2484
- }
2485
- if (Array.isArray(data)) {
2486
- seen.set(data, signal(data.map((item) => convertObjectToSignal(item, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal, seen))));
2487
- return seen.get(data);
2488
- }
2489
- if (data instanceof Map) {
2490
- const mapCopy = new Map();
2491
- Array.from(data.keys()).forEach((key) => {
2492
- mapCopy.set(key, convertObjectToSignal(data.get(key), cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal));
2493
- });
2494
- seen.set(data, signal(mapCopy));
2495
- return seen.get(data);
2496
- }
2497
- if (data instanceof Promise || data instanceof Observable) {
2498
- return data;
2499
- }
2500
- data = signal(cloneDeepIfNotSignal ? { ...data } : data);
2501
- seen.set(data, data);
2502
- for (const key in data()) {
2503
- const value = data()[key];
2504
- if (value instanceof TemplateRef ||
2505
- value instanceof File ||
2506
- value instanceof Blob ||
2507
- Object.prototype.toString.call(value) === '[object File]' ||
2508
- value instanceof ElementRef ||
2509
- value instanceof Element ||
2510
- value instanceof Date ||
2511
- value instanceof RegExp ||
2512
- value instanceof Set ||
2513
- value instanceof Map ||
2514
- value instanceof Promise ||
2515
- value instanceof Observable ||
2516
- value instanceof HttpParams) {
2517
- continue;
2518
- }
2519
- if (Object.prototype.hasOwnProperty.call(data(), key)) {
2520
- data()[key] = convertObjectToSignal(value, cloneDeepIfNotSignal, isSignalPrimitiveType, acceptConvertObjectInnerWritableSignal);
2521
- }
2522
- }
2523
- return data;
2524
- };
2525
- const convertSignalToObject = (data, isCloneDeep = true, seen = new WeakMap()) => {
2526
- let ignoreCheckSeenHasDataAfterWhile = false;
2527
- while (isSignal(data) && !seen.has(data)) {
2528
- const dataConvert = data();
2529
- if (typeof dataConvert === 'object') {
2530
- if (dataConvert === null) {
2531
- return dataConvert;
2532
- }
2533
- seen.set(dataConvert, dataConvert);
2534
- data = dataConvert;
2535
- ignoreCheckSeenHasDataAfterWhile = true;
2536
- break;
2537
- }
2538
- seen.set(data, dataConvert);
2539
- data = dataConvert;
2540
- }
2541
- if (data === null || typeof data === 'function' || typeof data !== 'object') {
2542
- return data;
2543
- }
2544
- if (!ignoreCheckSeenHasDataAfterWhile && seen.has(data)) {
2545
- return seen.get(data);
2546
- }
2547
- if (Array.isArray(data)) {
2548
- if (!isSignal(data[0])) {
2549
- return data;
2550
- }
2551
- seen.set(data, data.map((item) => convertSignalToObject(isCloneDeep ? cloneDeep(item) : item, isCloneDeep, seen)));
2552
- return seen.get(data);
2553
- }
2554
- if (data instanceof Map) {
2555
- const mapCopy = new Map();
2556
- Array.from(data.keys()).forEach((key) => {
2557
- mapCopy.set(key, convertSignalToObject(isCloneDeep ? cloneDeep(data.get(key)) : data.get(key), isCloneDeep));
2558
- });
2559
- seen.set(data, mapCopy);
2560
- return seen.get(data);
2561
- }
2562
- if (data instanceof File || data instanceof Blob || Object.prototype.toString.call(data) === '[object File]') {
2563
- return data;
2564
- }
2565
- if (data instanceof TemplateRef || data instanceof ElementRef || data instanceof Element || data instanceof Promise || data instanceof Observable || data instanceof HttpParams) {
2566
- return data;
2567
- }
2568
- const result = isCloneDeep ? {} : data;
2569
- seen.set(data, result);
2570
- for (const key in data) {
2571
- const value = data[key];
2572
- if (Object.prototype.hasOwnProperty.call(data, key)) {
2573
- result[key] = convertSignalToObject(isCloneDeep ? cloneDeep(value) : value, isCloneDeep);
2574
- }
2575
- }
2576
- return result;
2577
- };
2578
-
2579
2791
  const ENCODE_URI_PATTERN = /%([0-9A-F]{2})/g;
2580
2792
  const decodeURI = (value) => {
2581
2793
  return decodeURIComponent(value
@@ -2986,5 +3198,5 @@ const createUniqueRandomIntGenerator = (min, max) => {
2986
3198
  * Generated bundle index. Do not edit.
2987
3199
  */
2988
3200
 
2989
- export { AudioExtList, CHARACTER_DATA_EMPTY, COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE, COMMUNICATE_MICRO_PREFIX_TYPE, DEFAULT_START_PAGE_0, DocumentExtList, ENCODE_URI_PATTERN, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_LENGTH, ERROR_MESSAGE_MAX_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MIN_VALID, ERROR_MESSAGE_PATTEN_VALID, ExcelExtList, ImageExtList, LINK_IMAGE_ERROR_TOKEN_INJECT, PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT, PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT, UtilsCache, UtilsCommunicateMicro, UtilsCommunicateMicroKeyGlobal, UtilsHttpParamsRequest, UtilsHttpParamsRequestInstance, UtilsKeyCodeConstant, UtilsLanguageConstants, UtilsUrlSearchParams, VideoExtList, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertHtmlToDivBlocks, convertObjectToSignal, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, downloadFileByUrl, downloadFileByUrlUseXmlRequest, downloadImageFromELement, encodeURI, encrypt, encrypt3rd, endCodeUrl, escapeHtml, firstLetterToUpperCase, formatDate, formatNumber, formatTextCompare, fullNameFormat, generateInterface, get, getColorById, getDayjs, getDeltaFromHTML, getDeviceInfo, getDocumentByString, getDragEventByElement, getEventNameHandleClick, getFileExtension, getHTMLFromQuill, getKeyCacheByArrayObject, getLabelBySizeFile, getPlatFromBrowser, getSmartAxisScale, getViewport, groupBy, highlightByKeyword, insertContentWithRange, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isNil, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternPhoneNormal, patternRuleFieldReplace, patternTax, patternUrl, processPasteData, protectString, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setStylesElement, uniqBy, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
3201
+ export { AudioExtList, CHARACTER_DATA_EMPTY, COMMUNICATE_MICRO_KEY_GET_ALL_MESSAGE, COMMUNICATE_MICRO_PREFIX_TYPE, DEFAULT_START_PAGE_0, DocumentExtList, ENCODE_URI_PATTERN, ERROR_MESSAGE_EMPTY_VALID, ERROR_MESSAGE_MAX_LENGTH, ERROR_MESSAGE_MAX_VALID, ERROR_MESSAGE_MIN_LENGTH, ERROR_MESSAGE_MIN_VALID, ERROR_MESSAGE_PATTEN_VALID, ExcelExtList, ImageExtList, LINK_IMAGE_ERROR_TOKEN_INJECT, PROCESS_BAR_STANDARD_CONFIG_DEFAULT_TOKEN_INJECT, PROCESS_BAR_STEPS_CONFIG_DEFAULT_TOKEN_INJECT, UtilsCache, UtilsCommunicateMicro, UtilsCommunicateMicroKeyGlobal, UtilsHttpParamsRequest, UtilsHttpParamsRequestInstance, UtilsKeyCodeConstant, UtilsLanguageConstants, UtilsUrlSearchParams, VideoExtList, base64Decode, base64Encode, capitalize, checkMouseOverInContainer, checkViewInScreen, cloneDeep, cloneIBoundingClientRect, colorContrastFromOrigin, colorStepContrastFromOrigin, convertBase64ToBlob, convertBlobToFile, convertFileToBase64, convertFileToBase64_ObjectUrl, convertHtmlToDivBlocks, convertObjectToSignal, convertSignalToObject, convertUrlToFile, createUniqueRandomIntGenerator, decodeEscapeHtml, decodeURI, decrypt, decrypt3rd, deleteUnicode, downloadFileByUrl, downloadFileByUrlUseXmlRequest, downloadImageFromELement, encodeURI, encrypt, encrypt3rd, endCodeUrl, escapeHtml, firstLetterToUpperCase, formatDate, formatNumber, formatTextCompare, fullNameFormat, generateInterface, get, getColorById, getDayjs, getDeltaFromHTML, getDeviceInfo, getDocumentByString, getDragEventByElement, getEventNameHandleClick, getFileExtension, getHTMLFromQuill, getKeyCacheByArrayObject, getLabelBySizeFile, getPlatFromBrowser, getSmartAxisScale, getViewport, groupBy, hasDangerousConstructorName, highlightByKeyword, insertContentWithRange, isArrayObject, isAsyncObject, isBrowserAPIObject, isBrowserGlobalObject, isBuiltInObject, isDOMObject, isDangerousObject, isDayjsObject, isDifferenceDay, isDifferenceMonth, isDifferenceYear, isEmbedFrame, isEmpty, isEqual, isFalsy, isFileObject, isFrameworkObject, isIncludeAudioExtList, isIncludeDocumentExtList, isIncludeImageExtList, isIncludeVideoExtList, isMapObject, isNil, isReturnAsIsObject, isSafeToProcess, isSetObject, isSkippableObject, isSpecialObject, isTruthy, isTypeAudio, isTypeFile, isTypeImage, isTypeVideo, keyBy, listColorDefine, md5, omitBy, patternAccount, patternDomain, patternEmail, patternEmoji, patternEncodeUri, patternGetFieldByRuleFieldReplace, patternHostUrl, patternKey, patternMobilePhone, patternName, patternNameProfile, patternNameSpecial, patternNameUtf8, patternNumber, patternPem, patternPhone, patternPhoneNormal, patternRuleFieldReplace, patternTax, patternUrl, processPasteData, protectString, range, removeEmoji, revealString, rgbToHex, set, setCaretPosition, setDefaultTimeZone, setKeyCrypto, setKeyCrypto3rd, setStylesElement, uniqBy, updateFunctionCheckEmbedFrame, updateFunctionFormatDate, updateFunctionXssFilter, uppercaseByPosition, uuid, viewDataNumberByLanguage, xssFilter };
2990
3202
  //# sourceMappingURL=libs-ui-utils.mjs.map