@mohasinac/utils 0.1.0 → 1.1.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/dist/index.js CHANGED
@@ -1,3 +1,20 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+
1
18
  // src/date.formatter.ts
2
19
  function resolveDate(value) {
3
20
  if (!value) return null;
@@ -150,6 +167,17 @@ function currentYear() {
150
167
  function nowISO() {
151
168
  return new Date(nowMs()).toISOString();
152
169
  }
170
+ function formatCustomDate(date, format = "medium") {
171
+ const dateObj = typeof date === "string" ? new Date(date) : date;
172
+ const formatOptions = {
173
+ short: { month: "numeric", day: "numeric", year: "2-digit" },
174
+ medium: { month: "short", day: "numeric", year: "numeric" },
175
+ long: { month: "long", day: "numeric", year: "numeric" },
176
+ full: { weekday: "long", month: "long", day: "numeric", year: "numeric" }
177
+ };
178
+ const options = formatOptions[format] || formatOptions.medium;
179
+ return dateObj.toLocaleDateString("en-US", options);
180
+ }
153
181
 
154
182
  // src/number.formatter.ts
155
183
  function formatCurrency(amount, currency = "USD", locale = "en-US") {
@@ -525,18 +553,370 @@ function generatePayoutId(input) {
525
553
  const d = String(date.getDate()).padStart(2, "0");
526
554
  return `payout-${sellerSlug}-${y}${m}${d}-${generateRandomString(6)}`;
527
555
  }
556
+
557
+ // src/array.helper.ts
558
+ function groupBy(array, key) {
559
+ return array.reduce(
560
+ (result, item) => {
561
+ const groupKey = String(item[key]);
562
+ if (!result[groupKey]) {
563
+ result[groupKey] = [];
564
+ }
565
+ result[groupKey].push(item);
566
+ return result;
567
+ },
568
+ {}
569
+ );
570
+ }
571
+ function unique(array) {
572
+ return Array.from(new Set(array));
573
+ }
574
+ function uniqueBy(array, key) {
575
+ const seen = /* @__PURE__ */ new Set();
576
+ return array.filter((item) => {
577
+ const value = item[key];
578
+ if (seen.has(value)) return false;
579
+ seen.add(value);
580
+ return true;
581
+ });
582
+ }
583
+ function sortBy(array, key, order = "asc") {
584
+ return [...array].sort((a, b) => {
585
+ const aVal = a[key];
586
+ const bVal = b[key];
587
+ if (aVal < bVal) return order === "asc" ? -1 : 1;
588
+ if (aVal > bVal) return order === "asc" ? 1 : -1;
589
+ return 0;
590
+ });
591
+ }
592
+ function chunk(array, size) {
593
+ const chunks = [];
594
+ for (let i = 0; i < array.length; i += size) {
595
+ chunks.push(array.slice(i, i + size));
596
+ }
597
+ return chunks;
598
+ }
599
+ function paginate(array, page, perPage) {
600
+ const total = array.length;
601
+ const totalPages = Math.ceil(total / perPage);
602
+ const start = (page - 1) * perPage;
603
+ const end = start + perPage;
604
+ return { data: array.slice(start, end), total, page, perPage, totalPages };
605
+ }
606
+
607
+ // src/object.helper.ts
608
+ function deepMerge(target, source) {
609
+ const output = __spreadValues({}, target);
610
+ Object.keys(source).forEach((key) => {
611
+ const sourceValue = source[key];
612
+ const targetValue = target[key];
613
+ if (sourceValue && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue && typeof targetValue === "object" && !Array.isArray(targetValue)) {
614
+ output[key] = deepMerge(targetValue, sourceValue);
615
+ } else {
616
+ output[key] = sourceValue;
617
+ }
618
+ });
619
+ return output;
620
+ }
621
+ function pick(obj, keys) {
622
+ const result = {};
623
+ keys.forEach((key) => {
624
+ if (key in obj) result[key] = obj[key];
625
+ });
626
+ return result;
627
+ }
628
+ function omit(obj, keys) {
629
+ const result = __spreadValues({}, obj);
630
+ keys.forEach((key) => {
631
+ delete result[key];
632
+ });
633
+ return result;
634
+ }
635
+ function isEmptyObject(obj) {
636
+ return Object.keys(obj).length === 0;
637
+ }
638
+ function deepClone(obj) {
639
+ if (obj === null || typeof obj !== "object") return obj;
640
+ if (Array.isArray(obj))
641
+ return obj.map((item) => deepClone(item));
642
+ const cloned = {};
643
+ Object.keys(obj).forEach((key) => {
644
+ cloned[key] = deepClone(obj[key]);
645
+ });
646
+ return cloned;
647
+ }
648
+ function isEqual(obj1, obj2) {
649
+ if (obj1 === obj2) return true;
650
+ if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) {
651
+ return false;
652
+ }
653
+ const keys1 = Object.keys(obj1);
654
+ const keys2 = Object.keys(obj2);
655
+ if (keys1.length !== keys2.length) return false;
656
+ return keys1.every((key) => isEqual(obj1[key], obj2[key]));
657
+ }
658
+ function cleanObject(obj, options = {}) {
659
+ const {
660
+ removeEmpty = true,
661
+ removeNull = true,
662
+ removeUndefined = true
663
+ } = options;
664
+ return Object.entries(obj).reduce((acc, [key, value]) => {
665
+ const shouldRemove = removeUndefined && value === void 0 || removeNull && value === null || removeEmpty && value === "";
666
+ if (!shouldRemove) acc[key] = value;
667
+ return acc;
668
+ }, {});
669
+ }
670
+
671
+ // src/pagination.helper.ts
672
+ function calculatePagination(options) {
673
+ const { page, perPage, total } = options;
674
+ const totalPages = Math.ceil(total / perPage);
675
+ const currentPage = Math.max(1, Math.min(page, totalPages));
676
+ const startIndex = (currentPage - 1) * perPage;
677
+ const endIndex = Math.min(startIndex + perPage, total);
678
+ return {
679
+ currentPage,
680
+ perPage,
681
+ total,
682
+ totalPages,
683
+ hasNextPage: currentPage < totalPages,
684
+ hasPrevPage: currentPage > 1,
685
+ nextPage: currentPage < totalPages ? currentPage + 1 : null,
686
+ prevPage: currentPage > 1 ? currentPage - 1 : null,
687
+ startIndex,
688
+ endIndex
689
+ };
690
+ }
691
+
692
+ // src/sorting.helper.ts
693
+ function sort(array, key, order = "asc") {
694
+ return [...array].sort((a, b) => {
695
+ const aVal = a[key];
696
+ const bVal = b[key];
697
+ if (aVal < bVal) return order === "asc" ? -1 : 1;
698
+ if (aVal > bVal) return order === "asc" ? 1 : -1;
699
+ return 0;
700
+ });
701
+ }
702
+
703
+ // src/filter.helper.ts
704
+ function buildSieveFilters(...entries) {
705
+ return entries.filter((entry) => !!entry[1]).map(([expr, value]) => `${expr}${value}`).join(",");
706
+ }
707
+
708
+ // src/animation.helper.ts
709
+ var easings = {
710
+ linear: (t) => t,
711
+ easeInQuad: (t) => t * t,
712
+ easeOutQuad: (t) => t * (2 - t),
713
+ easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
714
+ easeInCubic: (t) => t * t * t,
715
+ easeOutCubic: (t) => --t * t * t + 1,
716
+ easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
717
+ easeInQuart: (t) => t * t * t * t,
718
+ easeOutQuart: (t) => 1 - --t * t * t * t,
719
+ easeInOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t
720
+ };
721
+
722
+ // src/color.helper.ts
723
+ function hexToRgb(hex) {
724
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
725
+ return result ? {
726
+ r: parseInt(result[1], 16),
727
+ g: parseInt(result[2], 16),
728
+ b: parseInt(result[3], 16)
729
+ } : null;
730
+ }
731
+ function rgbToHex(r, g, b) {
732
+ return "#" + [r, g, b].map((x) => {
733
+ const hex = x.toString(16);
734
+ return hex.length === 1 ? "0" + hex : hex;
735
+ }).join("");
736
+ }
737
+ function getContrastColor(hex) {
738
+ const rgb = hexToRgb(hex);
739
+ if (!rgb) return "#000000";
740
+ const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
741
+ return luminance > 0.5 ? "#000000" : "#ffffff";
742
+ }
743
+
744
+ // src/event-manager.ts
745
+ var GlobalEventManager = class {
746
+ constructor() {
747
+ this.handlers = /* @__PURE__ */ new Map();
748
+ this.handlerIds = /* @__PURE__ */ new Map();
749
+ }
750
+ generateId(type, target) {
751
+ var _a;
752
+ const targetId = this.getTargetId(target);
753
+ const key = `${type}-${targetId}`;
754
+ const count = ((_a = this.handlerIds.get(key)) != null ? _a : 0) + 1;
755
+ this.handlerIds.set(key, count);
756
+ return `${key}-${count}`;
757
+ }
758
+ getTargetId(target) {
759
+ if (target === window) return "window";
760
+ if (target === document) return "document";
761
+ if (target instanceof HTMLElement && target.id) return target.id;
762
+ return `element-${crypto.randomUUID()}`;
763
+ }
764
+ add(target, type, callback, options) {
765
+ const id = this.generateId(type, target);
766
+ if (!this.handlers.has(id)) this.handlers.set(id, []);
767
+ this.handlers.get(id).push({ type, target, callback, options });
768
+ target.addEventListener(type, callback, options);
769
+ return id;
770
+ }
771
+ remove(id) {
772
+ const handlers = this.handlers.get(id);
773
+ if (!handlers) return;
774
+ handlers.forEach(({ type, target, callback, options }) => target.removeEventListener(type, callback, options));
775
+ this.handlers.delete(id);
776
+ }
777
+ removeAllForTarget(target, type) {
778
+ const toRemove = [];
779
+ this.handlers.forEach((handlers, id) => {
780
+ const matchesTarget = handlers.some((h) => h.target === target);
781
+ const matchesType = !type || handlers.some((h) => h.type === type);
782
+ if (matchesTarget && matchesType) toRemove.push(id);
783
+ });
784
+ toRemove.forEach((id) => this.remove(id));
785
+ }
786
+ clear() {
787
+ this.handlers.forEach(
788
+ (handlers) => handlers.forEach(({ type, target, callback, options }) => target.removeEventListener(type, callback, options))
789
+ );
790
+ this.handlers.clear();
791
+ this.handlerIds.clear();
792
+ }
793
+ getHandlerCount() {
794
+ return this.handlers.size;
795
+ }
796
+ has(id) {
797
+ return this.handlers.has(id);
798
+ }
799
+ };
800
+ var globalEventManager = new GlobalEventManager();
801
+ function throttle(func, delay) {
802
+ let timeoutId = null;
803
+ let lastRun = 0;
804
+ return (...args) => {
805
+ const now = Date.now();
806
+ if (now - lastRun >= delay) {
807
+ func(...args);
808
+ lastRun = now;
809
+ } else {
810
+ if (timeoutId) clearTimeout(timeoutId);
811
+ timeoutId = setTimeout(() => {
812
+ func(...args);
813
+ lastRun = Date.now();
814
+ }, delay - (now - lastRun));
815
+ }
816
+ };
817
+ }
818
+ function debounce(func, delay) {
819
+ let timeoutId = null;
820
+ return (...args) => {
821
+ if (timeoutId) clearTimeout(timeoutId);
822
+ timeoutId = setTimeout(() => func(...args), delay);
823
+ };
824
+ }
825
+ function addGlobalScrollHandler(callback, options) {
826
+ const { throttle: throttleDelay = 100, target = window } = options != null ? options : {};
827
+ const handler = throttleDelay > 0 ? throttle(callback, throttleDelay) : callback;
828
+ return globalEventManager.add(target, "scroll", handler, { passive: true });
829
+ }
830
+ function addGlobalResizeHandler(callback, options) {
831
+ const { throttle: throttleDelay = 200 } = options != null ? options : {};
832
+ const handler = throttleDelay > 0 ? throttle(callback, throttleDelay) : callback;
833
+ return globalEventManager.add(window, "resize", handler);
834
+ }
835
+ function addGlobalClickHandler(selector, callback, options) {
836
+ const handler = (event) => {
837
+ const element = event.target.closest(selector);
838
+ if (element) {
839
+ if (options == null ? void 0 : options.preventDefault) event.preventDefault();
840
+ callback(event, element);
841
+ }
842
+ };
843
+ return globalEventManager.add(document, "click", handler);
844
+ }
845
+ function addGlobalKeyHandler(key, callback, options) {
846
+ const keys = Array.isArray(key) ? key : [key];
847
+ const { preventDefault = false, ctrl = false, shift = false, alt = false, meta = false } = options != null ? options : {};
848
+ const handler = (event) => {
849
+ const e = event;
850
+ if (!keys.some((k) => e.key === k || e.code === k)) return;
851
+ if (e.ctrlKey !== ctrl || e.shiftKey !== shift || e.altKey !== alt || e.metaKey !== meta) return;
852
+ if (preventDefault) event.preventDefault();
853
+ callback(e);
854
+ };
855
+ return globalEventManager.add(document, "keydown", handler);
856
+ }
857
+ function removeGlobalHandler(id) {
858
+ globalEventManager.remove(id);
859
+ }
860
+ function isMobileDevice() {
861
+ if (typeof window === "undefined") return false;
862
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
863
+ }
864
+ function hasTouchSupport() {
865
+ if (typeof window === "undefined") return false;
866
+ return "ontouchstart" in window || navigator.maxTouchPoints > 0;
867
+ }
868
+ function getViewportDimensions() {
869
+ if (typeof window === "undefined") return { width: 0, height: 0 };
870
+ return { width: window.innerWidth || document.documentElement.clientWidth, height: window.innerHeight || document.documentElement.clientHeight };
871
+ }
872
+ function isInViewport(element, offset = 0) {
873
+ if (typeof window === "undefined") return false;
874
+ const rect = element.getBoundingClientRect();
875
+ const { width, height } = getViewportDimensions();
876
+ return rect.top >= -offset && rect.left >= -offset && rect.bottom <= height + offset && rect.right <= width + offset;
877
+ }
878
+ function smoothScrollTo(element, options) {
879
+ const target = typeof element === "string" ? document.querySelector(element) : element;
880
+ if (!target) return;
881
+ const { offset = 0 } = options != null ? options : {};
882
+ window.scrollTo({ top: target.getBoundingClientRect().top + window.pageYOffset - offset, behavior: "smooth" });
883
+ }
884
+ function preventBodyScroll(prevent) {
885
+ if (typeof document === "undefined") return;
886
+ if (prevent) {
887
+ document.body.style.overflow = "hidden";
888
+ document.body.style.paddingRight = `${window.innerWidth - document.documentElement.clientWidth}px`;
889
+ } else {
890
+ document.body.style.overflow = "";
891
+ document.body.style.paddingRight = "";
892
+ }
893
+ }
528
894
  export {
895
+ GlobalEventManager,
896
+ addGlobalClickHandler,
897
+ addGlobalKeyHandler,
898
+ addGlobalResizeHandler,
899
+ addGlobalScrollHandler,
529
900
  arrayToObject,
530
901
  booleanToString,
902
+ buildSieveFilters,
903
+ calculatePagination,
531
904
  capitalize,
532
905
  capitalizeWords,
906
+ chunk,
907
+ cleanObject,
533
908
  currentYear,
534
909
  dateToISOString,
910
+ debounce,
911
+ deepClone,
912
+ deepMerge,
535
913
  deleteCookie,
914
+ easings,
536
915
  escapeHtml,
537
916
  firestoreTimestampToDate,
538
917
  formatCompactNumber,
539
918
  formatCurrency,
919
+ formatCustomDate,
540
920
  formatDate,
541
921
  formatDateRange,
542
922
  formatDateTime,
@@ -562,10 +942,20 @@ export {
562
942
  generateProductId,
563
943
  generateReviewId,
564
944
  generateUserId,
945
+ getContrastColor,
565
946
  getCookie,
947
+ getViewportDimensions,
948
+ globalEventManager,
949
+ groupBy,
566
950
  hasCookie,
951
+ hasTouchSupport,
952
+ hexToRgb,
953
+ isEmptyObject,
567
954
  isEmptyString,
955
+ isEqual,
568
956
  isFuture,
957
+ isInViewport,
958
+ isMobileDevice,
569
959
  isPast,
570
960
  isSameMonth,
571
961
  isToday,
@@ -574,15 +964,27 @@ export {
574
964
  nowMs,
575
965
  objectToArray,
576
966
  objectToQueryString,
967
+ omit,
968
+ paginate,
577
969
  parseCookies,
578
970
  parseFormattedNumber,
971
+ pick,
972
+ preventBodyScroll,
579
973
  proseMirrorToHtml,
580
974
  queryStringToObject,
581
975
  randomString,
976
+ removeGlobalHandler,
582
977
  resolveDate,
978
+ rgbToHex,
583
979
  slugify,
980
+ smoothScrollTo,
981
+ sort,
982
+ sortBy,
584
983
  stringToBoolean,
585
984
  stripHtml,
985
+ throttle,
586
986
  truncate,
587
- truncateWords
987
+ truncateWords,
988
+ unique,
989
+ uniqueBy
588
990
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/utils",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "publishConfig": {