@h3ravel/support 0.12.0 → 0.14.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
@@ -3,130 +3,36 @@ import { createHash, createHmac, randomBytes, randomUUID } from "crypto";
3
3
  import process from "process";
4
4
  import util from "util";
5
5
  import dayjs from "dayjs";
6
- import advancedFormat from "dayjs/plugin/advancedFormat";
7
- import customParseFormat from "dayjs/plugin/customParseFormat";
8
- import dayOfYear from "dayjs/plugin/dayOfYear";
9
- import isBetween from "dayjs/plugin/isBetween";
10
- import isLeapYear from "dayjs/plugin/isLeapYear";
11
- import relativeTime from "dayjs/plugin/relativeTime";
12
- import timezone from "dayjs/plugin/timezone";
13
- import utc from "dayjs/plugin/utc";
6
+ import advancedFormat from "dayjs/plugin/advancedFormat.js";
7
+ import customParseFormat from "dayjs/plugin/customParseFormat.js";
8
+ import dayOfYear from "dayjs/plugin/dayOfYear.js";
9
+ import isBetween from "dayjs/plugin/isBetween.js";
10
+ import isLeapYear from "dayjs/plugin/isLeapYear.js";
11
+ import relativeTime from "dayjs/plugin/relativeTime.js";
12
+ import timezone from "dayjs/plugin/timezone.js";
13
+ import utc from "dayjs/plugin/utc.js";
14
14
 
15
- //#region src/Helpers/Arr.ts
16
- var Arr_exports = /* @__PURE__ */ __export({
17
- alternate: () => alternate,
18
- chunk: () => chunk,
19
- collapse: () => collapse,
20
- combine: () => combine,
21
- find: () => find,
22
- first: () => first,
23
- flatten: () => flatten,
24
- forget: () => forget,
25
- isEmpty: () => isEmpty,
26
- isNotEmpty: () => isNotEmpty,
27
- last: () => last,
28
- pop: () => pop,
29
- prepend: () => prepend,
30
- range: () => range,
31
- reverse: () => reverse,
32
- shift: () => shift,
33
- take: () => take
34
- });
35
- /**
36
- * Splits an array into chunks of a specified size.
37
- *
38
- * @template T - Type of elements in the array
39
- * @param arr - The input array
40
- * @param size - Size of each chunk (default: 2)
41
- * @returns An array of chunks (arrays)
42
- */
43
- const chunk = (arr, size = 2) => {
44
- if (size <= 0) throw new Error("Chunk size must be greater than 0");
45
- const chunks = [];
46
- for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
47
- return chunks;
48
- };
49
- /**
50
- * Collapse an array of arrays into a single array.
51
- */
52
- const collapse = (arr) => {
53
- const result = [];
54
- for (const item of arr) if (Array.isArray(item)) result.push(...item);
55
- else result.push(item);
56
- return result;
57
- };
15
+ //#region src/Exceptions/InvalidArgumentException.ts
58
16
  /**
59
- * Alternates between two arrays, creating a zipped result.
17
+ * Custom error for invalid type coercion
60
18
  */
61
- const alternate = (a, b) => {
62
- const result = [];
63
- const max = Math.max(a.length, b.length);
64
- for (let i = 0; i < max; i++) {
65
- if (i < a.length) result.push(a[i]);
66
- if (i < b.length) result.push(b[i]);
19
+ var InvalidArgumentException = class extends Error {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = "InvalidArgumentException";
67
23
  }
68
- return result;
69
- };
70
- /**
71
- * Combine arrays and sum their values element by element.
72
- */
73
- const combine = (...arr) => {
74
- const maxLength = Math.max(...arr.map((a) => a.length));
75
- const result = new Array(maxLength).fill(0);
76
- for (let i = 0; i < maxLength; i++) for (const array of arr) result[i] += array[i] || 0;
77
- return result;
78
- };
79
- /** Find the value associated with a given key. */
80
- const find = (key, arr) => arr.find((item) => item === key) || null;
81
- /** Returns a new array without the given indices. */
82
- const forget = (arr, keys) => arr.filter((_, i) => !keys.includes(i));
83
- /** Remove the first element and return tuple [el, rest]. */
84
- const first = (arr) => {
85
- if (!arr.length) throw new Error("Cannot shift from empty array");
86
- return [arr[0], arr.slice(1)];
87
24
  };
88
- /** Remove the last element and return tuple [el, rest]. */
89
- const last = (arr) => {
90
- if (!arr.length) throw new Error("Cannot pop from empty array");
91
- return [arr[arr.length - 1], arr.slice(0, -1)];
92
- };
93
- /** Check if array is empty. */
94
- const isEmpty = (arr) => {
95
- if (arr.length === 0) return true;
96
- else return false;
97
- };
98
- /** Check if array is empty. */
99
- const isNotEmpty = (arr) => arr.length > 0;
100
- /** Pop the element off the end of array. */
101
- const pop = (arr) => arr.slice(0, -1);
102
- /** Add elements to the beginning of array. */
103
- const prepend = (arr, ...elements) => [...elements, ...arr];
104
- /** Take first n elements of array. */
105
- const take = (amount, arr) => arr.slice(0, Math.max(0, amount));
106
- /** Create a new array in reverse order. */
107
- const reverse = (arr) => [...arr].reverse();
108
- /** Alias for first element removal. */
109
- const shift = first;
25
+
26
+ //#endregion
27
+ //#region src/Exceptions/RuntimeException.ts
110
28
  /**
111
- * Generates an array of sequential numbers.
112
- *
113
- * @param size - Number of elements in the range
114
- * @param startAt - Starting number (default: 0)
115
- * @returns An array of numbers from startAt to startAt + size - 1
29
+ * Custom error for invalid type coercion
116
30
  */
117
- const range = (size, startAt = 0) => {
118
- if (size <= 0 || !Number.isFinite(size)) return [];
119
- return Array.from({ length: size }, (_, i) => startAt + i);
120
- };
121
- /** Flatten multi-dimensional arrays into single level. */
122
- const flatten = (arr) => {
123
- const result = [];
124
- const recurse = (input) => {
125
- for (const item of input) if (Array.isArray(item)) recurse(item);
126
- else result.push(item);
127
- };
128
- recurse(arr);
129
- return result;
31
+ var RuntimeException = class extends Error {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = "RuntimeException";
35
+ }
130
36
  };
131
37
 
132
38
  //#endregion
@@ -293,10 +199,10 @@ const verifyChecksum = (data, expectedChecksum, algorithm = "sha256") => {
293
199
  * @param shift - Number of positions to shift (default: 13)
294
200
  * @returns Encrypted/decrypted text
295
201
  */
296
- const caesarCipher = (text, shift$1 = 13) => {
202
+ const caesarCipher = (text, shift = 13) => {
297
203
  return text.replace(/[a-zA-Z]/g, (char) => {
298
204
  const baseCharCode = char === char.toUpperCase() ? "A" : "a";
299
- const shiftedCharCode = (char.charCodeAt(0) - baseCharCode.charCodeAt(0) + shift$1) % 26;
205
+ const shiftedCharCode = (char.charCodeAt(0) - baseCharCode.charCodeAt(0) + shift) % 26;
300
206
  const newCharCode = (shiftedCharCode < 0 ? 26 + shiftedCharCode : shiftedCharCode) + baseCharCode.charCodeAt(0);
301
207
  return String.fromCharCode(newCharCode);
302
208
  });
@@ -508,22 +414,27 @@ const toHumanTime = (seconds = 0, worded = false) => {
508
414
  if (secs || !hours && !minutes) parts.push(`${secs}sec`);
509
415
  return parts.join(" ");
510
416
  }
511
- const hh = hours > 0 ? `${hours}:` : "";
512
- const mm = (hours > 0 && minutes < 10 ? `0${minutes}` : minutes) + ":";
513
- const ss = secs < 10 ? `0${secs}` : secs;
514
- return `${hh}${mm}${ss}`;
417
+ return `${hours > 0 ? `${hours}:` : ""}${(hours > 0 && minutes < 10 ? `0${minutes}` : minutes) + ":"}${secs < 10 ? `0${secs}` : secs}`;
515
418
  };
516
419
 
517
420
  //#endregion
518
421
  //#region src/Helpers/Obj.ts
519
422
  var Obj_exports = /* @__PURE__ */ __export({
423
+ Obj: () => Obj,
424
+ data_fill: () => data_fill,
425
+ data_forget: () => data_forget,
426
+ data_get: () => data_get,
427
+ data_set: () => data_set,
520
428
  dot: () => dot,
521
429
  extractProperties: () => extractProperties,
522
430
  getValue: () => getValue,
523
431
  modObj: () => modObj,
524
432
  safeDot: () => safeDot,
525
433
  setNested: () => setNested,
526
- slugifyKeys: () => slugifyKeys
434
+ slugifyKeys: () => slugifyKeys,
435
+ toCssClasses: () => toCssClasses,
436
+ toCssStyles: () => toCssStyles,
437
+ undot: () => undot
527
438
  });
528
439
  /**
529
440
  * Flattens a nested object into a single-level object
@@ -597,74 +508,1119 @@ const getValue = (key, item) => {
597
508
  if (child !== void 0) return String(item?.[parent]?.[child] ?? item?.[parent] ?? `${String(parent)}.${String(child)}`);
598
509
  return String(item?.[parent] ?? parent);
599
510
  }
600
- return String(item?.[key] ?? key);
601
- };
602
- /**
603
- * Maps over an object's entries and returns a new object
604
- * with transformed keys and/or values.
605
- *
606
- * @template T - Type of the input object
607
- * @template R - Type of the new values
608
- * @param obj - The object to transform
609
- * @param callback - Function that receives [key, value] and returns [newKey, newValue]
610
- * @returns A new object with transformed entries
611
- */
612
- const modObj = (obj, callback) => {
613
- return Object.fromEntries(Object.entries(obj).map(([key, value]) => callback([key, value])));
614
- };
615
- function safeDot(data, key) {
616
- if (!key) return data;
617
- return key.split(".").reduce((acc, k) => acc?.[k], data);
618
- }
619
- /**
620
- * Sets a nested property on an object using dot notation.
621
- *
622
- * @example
623
- * const obj = {}
624
- * setNested(obj, 'app.user.name', 'Legacy')
625
- * console.log(obj)
626
- * // Output: { app: { user: { name: 'Legacy' } } }
627
- *
628
- * @param obj - The target object to modify.
629
- * @param key - The dot-separated key (e.g., 'app.user.name').
630
- * @param value - The value to set at the specified path.
631
- */
632
- const setNested = (obj, key, value) => {
633
- if (!key.includes(".")) {
634
- obj[key] = value;
635
- return;
511
+ return String(item?.[key] ?? key);
512
+ };
513
+ /**
514
+ * Maps over an object's entries and returns a new object
515
+ * with transformed keys and/or values.
516
+ *
517
+ * @template T - Type of the input object
518
+ * @template R - Type of the new values
519
+ * @param obj - The object to transform
520
+ * @param callback - Function that receives [key, value] and returns [newKey, newValue]
521
+ * @returns A new object with transformed entries
522
+ */
523
+ const modObj = (obj, callback) => {
524
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => callback([key, value])));
525
+ };
526
+ function safeDot(data, key) {
527
+ if (!key) return data;
528
+ return key.split(".").reduce((acc, k) => acc?.[k], data);
529
+ }
530
+ /**
531
+ * Sets a nested property on an object using dot notation.
532
+ *
533
+ * @example
534
+ * const obj = {}
535
+ * setNested(obj, 'app.user.name', 'Legacy')
536
+ * console.log(obj)
537
+ * // Output: { app: { user: { name: 'Legacy' } } }
538
+ *
539
+ * @param obj - The target object to modify.
540
+ * @param key - The dot-separated key (e.g., 'app.user.name').
541
+ * @param value - The value to set at the specified path.
542
+ */
543
+ const setNested = (obj, key, value) => {
544
+ if (!key.includes(".")) {
545
+ obj[key] = value;
546
+ return;
547
+ }
548
+ const parts = key.split(".");
549
+ let current = obj;
550
+ for (let i = 0; i < parts.length; i++) {
551
+ const part = parts[i];
552
+ /**
553
+ * If we're at the last key, assign the value
554
+ */
555
+ if (i === parts.length - 1) current[part] = value;
556
+ else {
557
+ /**
558
+ * If the key doesn't exist or isn't an object, create it
559
+ */
560
+ if (typeof current[part] !== "object" || current[part] === null) current[part] = {};
561
+ current = current[part];
562
+ }
563
+ }
564
+ };
565
+ /**
566
+ * Converts object keys to a slugified format (e.g., snake_case).
567
+ *
568
+ * @template T - Type of the input object
569
+ * @param obj - The object whose keys will be slugified
570
+ * @param only - Optional array of keys to slugify (others remain unchanged)
571
+ * @param separator - Separator for slugified keys (default: "_")
572
+ * @returns A new object with slugified keys
573
+ */
574
+ const slugifyKeys = (obj, only = [], separator = "_") => {
575
+ const slugify = (key) => key.replace(/([a-z])([A-Z])/g, `$1${separator}$2`).replace(/[\s\W]+/g, separator).replace(new RegExp(`${separator}{2,}`, "g"), separator).replace(new RegExp(`^${separator}|${separator}$`, "g"), "").toLowerCase();
576
+ let entries = Object.entries(obj);
577
+ if (only.length) entries = entries.filter(([key]) => only.includes(key));
578
+ return Object.fromEntries(entries.map(([key, value]) => [slugify(key), value]));
579
+ };
580
+ /**
581
+ * toCssClasses
582
+ *
583
+ * Convert array/object/string input into a CSS class string.
584
+ * - Arrays: included if truthy
585
+ * - Objects: keys included if value is truthy
586
+ * - Strings: included as-is
587
+ */
588
+ function toCssClasses(input) {
589
+ if (!input) return "";
590
+ const classes = [];
591
+ if (typeof input === "string") return input.trim();
592
+ if (Array.isArray(input)) input.forEach((item) => {
593
+ if (item) classes.push(String(item).trim());
594
+ });
595
+ else if (typeof input === "object") {
596
+ for (const [key, value] of Object.entries(input)) if (value) classes.push(key);
597
+ }
598
+ return classes.join(" ");
599
+ }
600
+ /**
601
+ * toCssStyles
602
+ *
603
+ * Convert object input into CSS style string.
604
+ * - Only includes truthy values (ignores null/undefined/false)
605
+ */
606
+ function toCssStyles(styles) {
607
+ const parts = [];
608
+ for (const [k, v] of Object.entries(styles)) {
609
+ if (v === null || v === void 0 || v === false) continue;
610
+ parts.push(`${k}:${v}`);
611
+ }
612
+ return parts.join(";");
613
+ }
614
+ /**
615
+ * undot
616
+ *
617
+ * Convert a dot-notated object back into nested structure.
618
+ *
619
+ * Example:
620
+ * undot({ 'a.b': 1, 'c.0': 2 }) -> { a: { b: 1 }, c: [2] }
621
+ */
622
+ function undot(obj) {
623
+ const result = {};
624
+ for (const [key, value] of Object.entries(obj)) {
625
+ const parts = key.split(".");
626
+ let node = result;
627
+ for (let i = 0; i < parts.length; i++) {
628
+ const part = parts[i];
629
+ const isLast = i === parts.length - 1;
630
+ const nextPart = parts[i + 1];
631
+ const isArrayIndex = !isNaN(Number(nextPart));
632
+ if (isLast) node[part] = value;
633
+ else {
634
+ if (!(part in node)) node[part] = isArrayIndex ? [] : {};
635
+ node = node[part];
636
+ }
637
+ }
638
+ }
639
+ return result;
640
+ }
641
+ /**
642
+ * data_get
643
+ *
644
+ * Get a value from an object using dot notation.
645
+ */
646
+ function data_get(obj, path, defaultValue) {
647
+ if (!obj) return defaultValue;
648
+ const parts = Array.isArray(path) ? path : path.split(".");
649
+ let current = obj;
650
+ for (const part of parts) {
651
+ if (!current || !(part in current)) return defaultValue;
652
+ current = current[part];
653
+ }
654
+ return current;
655
+ }
656
+ /**
657
+ * data_set
658
+ *
659
+ * Set a value in an object using dot notation. Mutates the object.
660
+ */
661
+ function data_set(obj, path, value) {
662
+ const parts = Array.isArray(path) ? path : path.split(".");
663
+ let current = obj;
664
+ for (let i = 0; i < parts.length; i++) {
665
+ const part = parts[i];
666
+ if (i === parts.length - 1) current[part] = value;
667
+ else {
668
+ if (!(part in current) || typeof current[part] !== "object" || current[part] === null) current[part] = {};
669
+ current = current[part];
670
+ }
671
+ }
672
+ }
673
+ /**
674
+ * data_fill
675
+ *
676
+ * Like data_set, but only sets the value if the key does NOT exist.
677
+ */
678
+ function data_fill(obj, path, value) {
679
+ if (data_get(obj, path) === void 0) data_set(obj, path, value);
680
+ }
681
+ /**
682
+ * data_forget
683
+ *
684
+ * Remove a key from an object using dot notation.
685
+ */
686
+ function data_forget(obj, path) {
687
+ const parts = Array.isArray(path) ? path : path.split(".");
688
+ let current = obj;
689
+ for (let i = 0; i < parts.length; i++) {
690
+ const part = parts[i];
691
+ if (i === parts.length - 1) delete current[part];
692
+ else {
693
+ if (!current[part] || typeof current[part] !== "object") break;
694
+ current = current[part];
695
+ }
696
+ }
697
+ }
698
+ var Obj = class Obj {
699
+ /**
700
+ * Check if the value is a non-null object (associative/accessible).
701
+ */
702
+ static accessible(value) {
703
+ return value !== null && typeof value === "object";
704
+ }
705
+ /**
706
+ * Add a key-value pair to an object only if the key does not already exist.
707
+ *
708
+ * Returns a new object (does not mutate original).
709
+ */
710
+ static add(obj, key, value) {
711
+ if (!(key in obj)) return {
712
+ ...obj,
713
+ [key]: value
714
+ };
715
+ return obj;
716
+ }
717
+ /**
718
+ * Split object into [keys, values]
719
+ */
720
+ static divide(obj) {
721
+ return [Object.keys(obj), Object.values(obj)];
722
+ }
723
+ /**
724
+ * Check if a key exists in the object.
725
+ */
726
+ static exists(obj, key) {
727
+ return Object.prototype.hasOwnProperty.call(obj, key);
728
+ }
729
+ /**
730
+ * Get a value from an object using dot notation.
731
+ *
732
+ * Example:
733
+ * Obj.get({a:{b:1}}, 'a.b') -> 1
734
+ */
735
+ static get(obj, path, defaultValue) {
736
+ if (!Obj.accessible(obj)) return defaultValue;
737
+ const parts = Array.isArray(path) ? path : path.split(".");
738
+ let current = obj;
739
+ for (const part of parts) {
740
+ if (!Obj.accessible(current) || !(part in current)) return defaultValue;
741
+ current = current[part];
742
+ }
743
+ return current;
744
+ }
745
+ /**
746
+ * Check if the object has a given key or keys (dot notation supported).
747
+ */
748
+ static has(obj, keys) {
749
+ if (!Obj.accessible(obj)) return false;
750
+ return (Array.isArray(keys) ? keys : [keys]).every((key) => {
751
+ const parts = key.split(".");
752
+ let current = obj;
753
+ for (const part of parts) {
754
+ if (!Obj.accessible(current) || !(part in current)) return false;
755
+ current = current[part];
756
+ }
757
+ return true;
758
+ });
759
+ }
760
+ /**
761
+ * Check if an object is associative (has at least one non-numeric key).
762
+ */
763
+ static isAssoc(obj) {
764
+ if (!Obj.accessible(obj)) return false;
765
+ return Object.keys(obj).some((k) => isNaN(Number(k)));
766
+ }
767
+ /**
768
+ * Add a prefix to all keys of the object.
769
+ */
770
+ static prependKeysWith(obj, prefix) {
771
+ if (!Obj.accessible(obj)) return {};
772
+ const result = {};
773
+ for (const [k, v] of Object.entries(obj)) result[`${prefix}${k}`] = v;
774
+ return result;
775
+ }
776
+ /**
777
+ * Convert an object into a URL query string.
778
+ *
779
+ * Nested objects/arrays are flattened using bracket notation.
780
+ */
781
+ static query(obj) {
782
+ const encode = encodeURIComponent;
783
+ const parts = [];
784
+ function build(key, value) {
785
+ if (Array.isArray(value)) value.forEach((v, i) => build(`${key}[${i}]`, v));
786
+ else if (Obj.accessible(value)) Object.entries(value).forEach(([k, v]) => build(`${key}[${k}]`, v));
787
+ else parts.push(`${encode(key)}=${encode(value)}`);
788
+ }
789
+ Object.entries(obj).forEach(([k, v]) => build(k, v));
790
+ return parts.join("&");
791
+ }
792
+ };
793
+
794
+ //#endregion
795
+ //#region src/Helpers/Arr.ts
796
+ /**
797
+ * Arr — Laravel-like array helpers for JavaScript.
798
+ *
799
+ * - Methods aim for clear, predictable JS behavior.
800
+ * - Inputs are validated where useful; functions try not to mutate arguments.
801
+ */
802
+ var Arr = class Arr {
803
+ /**
804
+ * Helper: is a value an object (but not null).
805
+ */
806
+ static _isObject(value) {
807
+ return value !== null && typeof value === "object" && !Array.isArray(value);
808
+ }
809
+ /**
810
+ * Helper: deep clone for safety (simple).
811
+ * Uses JSON methods — good for typical data shapes (no functions, Dates, Maps).
812
+ */
813
+ static _clone(value) {
814
+ try {
815
+ return JSON.parse(JSON.stringify(value));
816
+ } catch {
817
+ return value;
818
+ }
819
+ }
820
+ /**
821
+ * Retrieve a value using dot notation
822
+ * Throws if value is not an array
823
+ */
824
+ static array(obj, path, defaultValue) {
825
+ const val = data_get(obj, path, defaultValue);
826
+ if (!Array.isArray(val)) throw new InvalidArgumentException(`Value at "${path}" is not an array.`);
827
+ return val;
828
+ }
829
+ /**
830
+ * Retrieve a value using dot notation
831
+ * Throws if value is not a boolean
832
+ */
833
+ static boolean(obj, path, defaultValue) {
834
+ const val = data_get(obj, path, defaultValue);
835
+ if (typeof val !== "boolean") throw new InvalidArgumentException(`Value at "${path}" is not a boolean.`);
836
+ return val;
837
+ }
838
+ /**
839
+ * Flatten an array of arrays by one level.
840
+ *
841
+ * Example:
842
+ * Arr.collapse([[1,2], [3], 4]) -> [1,2,3,4]
843
+ */
844
+ static collapse(array) {
845
+ if (!Array.isArray(array)) return [];
846
+ const result = [];
847
+ for (const item of array) if (Array.isArray(item)) result.push(...item);
848
+ else result.push(item);
849
+ return result;
850
+ }
851
+ /**
852
+ * Cartesian product of arrays.
853
+ *
854
+ * Example:
855
+ * Arr.crossJoin([1,2], ['a','b']) -> [[1,'a'], [1,'b'], [2,'a'], [2,'b']]
856
+ *
857
+ * Accepts any number of array arguments (or single array-of-arrays).
858
+ */
859
+ static crossJoin(...arrays) {
860
+ let inputs = arrays;
861
+ if (arrays.length === 1 && Array.isArray(arrays[0]) && arrays[0].some(Array.isArray)) inputs = arrays[0];
862
+ inputs = inputs.map((a) => Array.isArray(a) ? a : [a]);
863
+ let product = [[]];
864
+ for (const arr of inputs) {
865
+ const next = [];
866
+ for (const prefix of product) for (const value of arr) next.push([...prefix, value]);
867
+ product = next;
868
+ }
869
+ return product;
870
+ }
871
+ /**
872
+ * Split an array (or object) into two arrays: [keys, values].
873
+ *
874
+ * For arrays, keys are numeric indices. For objects, keys are property names.
875
+ *
876
+ * Example:
877
+ * Arr.divide(['a','b']) -> [[0,1], ['a','b']]
878
+ * Arr.divide({x:1,y:2}) -> [['x','y'], [1,2]]
879
+ */
880
+ static divide(input) {
881
+ if (Array.isArray(input)) return [input.map((_, i) => i), input.slice()];
882
+ if (Arr._isObject(input)) {
883
+ const keys = Object.keys(input);
884
+ return [keys, keys.map((k) => input[k])];
885
+ }
886
+ return [[], []];
887
+ }
888
+ /**
889
+ * Flatten a nested array/object structure into a single-level object
890
+ * with dot-notated keys.
891
+ *
892
+ * Example:
893
+ * Arr.dot({ a: { b: 1 }, c: [2,3] }) -> { 'a.b': 1, 'c.0': 2, 'c.1': 3 }
894
+ *
895
+ * Works for arrays and plain objects.
896
+ */
897
+ static dot(input, prefix = "") {
898
+ const result = {};
899
+ const recurse = (val, path) => {
900
+ if (Array.isArray(val)) for (let i = 0; i < val.length; i++) recurse(val[i], path ? `${path}.${i}` : String(i));
901
+ else if (Arr._isObject(val)) for (const [k, v] of Object.entries(val)) recurse(v, path ? `${path}.${k}` : k);
902
+ else result[path] = val;
903
+ };
904
+ if (Array.isArray(input) || Arr._isObject(input)) recurse(input, prefix);
905
+ return result;
906
+ }
907
+ /**
908
+ * Checks if all elements satisfy the predicate
909
+ */
910
+ static every(array, predicate) {
911
+ return array.every(predicate);
912
+ }
913
+ /**
914
+ * Remove items by keys/indices from an array or properties from an object.
915
+ *
916
+ * For arrays: keys are numeric indices (single number or array of numbers).
917
+ *
918
+ * Returns a shallow-copied result (does not mutate input).
919
+ *
920
+ * Example:
921
+ * Arr.except([10,20,30], [1]) -> [10,30]
922
+ */
923
+ static except(input, keys) {
924
+ const keySet = new Set(Array.isArray(keys) ? keys : [keys]);
925
+ if (Array.isArray(input)) return input.filter((_, idx) => !keySet.has(idx));
926
+ if (Arr._isObject(input)) {
927
+ const out = {};
928
+ for (const [k, v] of Object.entries(input)) if (!keySet.has(k)) out[k] = v;
929
+ return out;
930
+ }
931
+ return input;
932
+ }
933
+ /**
934
+ * Return the first element of an array that satisfies the predicate,
935
+ * or the first element if no predicate is provided, otherwise the defaultValue.
936
+ *
937
+ * Predicate can be true (boolean), a function or a value to match (strict equality).
938
+ *
939
+ * When predicate is true (boolean), the first element will be removed and a tuple will be returned [el, rest].
940
+ *
941
+ * @param array
942
+ * @param predicate
943
+ * @param defaultValue
944
+ *
945
+ * @returns
946
+ */
947
+ static first(array, predicate, defaultValue) {
948
+ if (predicate === true) {
949
+ if (!array.length) throw new Error("Cannot shift from empty array");
950
+ return [array[0], array.slice(1)];
951
+ }
952
+ if (!Array.isArray(array) || array.length === 0) return defaultValue;
953
+ if (predicate === void 0) return array[0];
954
+ if (typeof predicate === "function") {
955
+ for (const item of array) if (predicate(item)) return item;
956
+ return defaultValue;
957
+ }
958
+ for (const item of array) if (typeof predicate !== "boolean" && item === predicate) return item;
959
+ return defaultValue;
960
+ }
961
+ /**
962
+ * Recursively flatten an array up to `depth` levels (default: Infinity).
963
+ *
964
+ * Example:
965
+ * Arr.flatten([1, [2, [3]]], 1) -> [1,2,[3]]
966
+ */
967
+ static flatten(array, depth = Infinity) {
968
+ if (!Array.isArray(array)) return [];
969
+ if (depth < 1) return array.slice();
970
+ const result = [];
971
+ for (const item of array) if (Array.isArray(item) && depth > 0) result.push(...Arr.flatten(item, depth - 1));
972
+ else result.push(item);
973
+ return result;
974
+ }
975
+ /**
976
+ * Retrieve a value from an array/object using dot notation
977
+ * Throws if value is not a float
978
+ */
979
+ static float(obj, path, defaultValue) {
980
+ const val = data_get(obj, path, defaultValue);
981
+ if (typeof val !== "number" || Number.isNaN(val)) throw new InvalidArgumentException(`Value at "${path}" is not a float.`);
982
+ return val;
983
+ }
984
+ /**
985
+ * Remove element(s) by index or dot-notated path from an array/object.
986
+ *
987
+ * For arrays: accepts numeric index or array of indices. Returns a new array.
988
+ *
989
+ * For objects: supports dot notation to remove nested keys.
990
+ *
991
+ * Example:
992
+ * Arr.forget([1,2,3], 1) -> [1,3]
993
+ * Arr.forget({a:{b:1}}, 'a.b') -> { a: {} }
994
+ */
995
+ static forget(input, keys) {
996
+ if (Array.isArray(input)) {
997
+ const removeSet = new Set(Array.isArray(keys) ? keys : [keys]);
998
+ return input.filter((_, i) => !removeSet.has(i));
999
+ }
1000
+ if (Arr._isObject(input)) {
1001
+ const out = Arr._clone(input);
1002
+ const keyList = Array.isArray(keys) ? keys : [keys];
1003
+ for (const key of keyList) {
1004
+ const parts = String(key).split(".");
1005
+ let node = out;
1006
+ for (let i = 0; i < parts.length; i++) {
1007
+ const part = parts[i];
1008
+ if (i === parts.length - 1) {
1009
+ if (node && Object.prototype.hasOwnProperty.call(node, part)) delete node[part];
1010
+ } else {
1011
+ if (!Arr._isObject(node[part])) break;
1012
+ node = node[part];
1013
+ }
1014
+ }
1015
+ }
1016
+ return out;
1017
+ }
1018
+ return input;
1019
+ }
1020
+ /**
1021
+ * Converts various input types into a plain array
1022
+ * Supports Arrays, Objects, Iterables, Map, WeakMap, and custom toArray/toJSON/jsonSerialize methods
1023
+ */
1024
+ static from(value) {
1025
+ if (value == null) return [];
1026
+ if (Array.isArray(value)) return value;
1027
+ if (Symbol.iterator in Object(value)) return [...value];
1028
+ if (value.toArray) return value.toArray();
1029
+ if (value.toJSON) return value.toJSON();
1030
+ if (value.jsonSerialize) return value.jsonSerialize();
1031
+ if (value instanceof Map) return Array.from(value.entries());
1032
+ if (value instanceof WeakMap) return [];
1033
+ if (typeof value === "object") return Object.values(value);
1034
+ return [value];
1035
+ }
1036
+ /**
1037
+ * Checks if an object has all the specified keys
1038
+ */
1039
+ static hasAll(obj, keys) {
1040
+ return keys.every((k) => k in obj);
1041
+ }
1042
+ /**
1043
+ * For arrays: check if the array contains any of the provided values.
1044
+ *
1045
+ * values can be single value or array of values.
1046
+ *
1047
+ * Example:
1048
+ * Arr.hasAny([1,2,3], [4,2]) -> true
1049
+ */
1050
+ static hasAny(array, values) {
1051
+ if (!Array.isArray(array)) return false;
1052
+ const vs = Array.isArray(values) ? values : [values];
1053
+ const set = new Set(array);
1054
+ for (const v of vs) if (set.has(v)) return true;
1055
+ return false;
1056
+ }
1057
+ /**
1058
+ * Retrieve a value using dot notation
1059
+ * Throws if value is not an integer
1060
+ */
1061
+ static integer(obj, path, defaultValue) {
1062
+ const val = data_get(obj, path, defaultValue);
1063
+ if (!Number.isInteger(val)) throw new InvalidArgumentException(`Value at "${path}" is not an integer.`);
1064
+ return val;
1065
+ }
1066
+ /**
1067
+ * Determine if the input is a "list-like" array: an Array with
1068
+ * contiguous numeric indices starting at 0 (no gaps).
1069
+ *
1070
+ * Example:
1071
+ * Arr.isList([1,2,3]) -> true
1072
+ * const a = []; a[2] = 5; Arr.isList(a) -> false
1073
+ */
1074
+ static isList(value) {
1075
+ if (!Array.isArray(value)) return false;
1076
+ for (let i = 0; i < value.length; i++) if (!(i in value)) return false;
1077
+ return true;
1078
+ }
1079
+ /**
1080
+ * Join array elements into a string using the given separator.
1081
+ *
1082
+ * Example:
1083
+ * Arr.join([1,2,3], '-') -> '1-2-3'
1084
+ */
1085
+ static join(array, separator = ",") {
1086
+ return Array.isArray(array) ? array.join(separator) : "";
1087
+ }
1088
+ /**
1089
+ * Create an object indexed by a key or callback function.
1090
+ *
1091
+ * Example:
1092
+ * Arr.keyBy([{id:1},{id:2}], 'id') -> { '1': {id:1}, '2': {id:2} }
1093
+ */
1094
+ static keyBy(array, key) {
1095
+ const result = {};
1096
+ if (!Array.isArray(array)) return result;
1097
+ for (const item of array) {
1098
+ let k;
1099
+ if (typeof key === "function") k = key(item);
1100
+ else k = String(item[key]);
1101
+ result[k] = item;
1102
+ }
1103
+ return result;
1104
+ }
1105
+ /**
1106
+ * Get the last element of an array, optionally matching a predicate,
1107
+ * or the last element if no predicate is provided, otherwise the defaultValue.
1108
+ *
1109
+ * Predicate can be a true (boolean), a function or a value to match (strict equality).
1110
+ *
1111
+ * When predicate is true (boolean), the last element will be removed and a tuple will be returned [el, rest].
1112
+ *
1113
+ * @param array
1114
+ * @param predicate
1115
+ * @param defaultValue
1116
+ *
1117
+ * @returns
1118
+ */
1119
+ static last(array, predicate, defaultValue) {
1120
+ if (predicate === true) {
1121
+ if (!array.length) throw new Error("Cannot pop from empty array");
1122
+ return [array[array.length - 1], array.slice(0, -1)];
1123
+ }
1124
+ if (!Array.isArray(array) || array.length === 0) return defaultValue;
1125
+ if (!predicate) return array[array.length - 1];
1126
+ if (typeof predicate === "function") {
1127
+ for (let i = array.length - 1; i >= 0; i--) if (predicate(array[i])) return array[i];
1128
+ } else for (let i = array.length - 1; i >= 0; i--) if (array[i] === predicate) return array[i];
1129
+ return defaultValue;
1130
+ }
1131
+ /**
1132
+ * Transform each element in an array using a callback.
1133
+ */
1134
+ static map(array, callback) {
1135
+ return Array.isArray(array) ? array.map(callback) : [];
1136
+ }
1137
+ /**
1138
+ * Maps a multi-dimensional array with a spread callback
1139
+ */
1140
+ static mapSpread(array, callback) {
1141
+ return array.map((item) => callback(...Array.isArray(item) ? item : [item]));
1142
+ }
1143
+ /**
1144
+ * Map each element to a key-value pair.
1145
+ *
1146
+ * Example:
1147
+ * Arr.mapWithKeys([{id:1, name:'A'}], x => [x.id, x.name])
1148
+ * -> { '1': 'A' }
1149
+ */
1150
+ static mapWithKeys(array, callback) {
1151
+ const result = {};
1152
+ if (!Array.isArray(array)) return result;
1153
+ array.forEach((item, idx) => {
1154
+ const [k, v] = callback(item, idx);
1155
+ result[String(k)] = v;
1156
+ });
1157
+ return result;
1158
+ }
1159
+ /**
1160
+ * Return only elements at the given indices.
1161
+ *
1162
+ * Example:
1163
+ * Arr.only([10,20,30], [0,2]) -> [10,30]
1164
+ */
1165
+ static only(array, keys) {
1166
+ if (!Array.isArray(array)) return [];
1167
+ const keyArray = Array.isArray(keys) ? keys : [keys];
1168
+ return array.filter((_, idx) => keyArray.includes(idx));
1169
+ }
1170
+ /**
1171
+ * Split an array into two arrays based on a predicate
1172
+ */
1173
+ static partition(array, predicate) {
1174
+ const truthy = [];
1175
+ const falsy = [];
1176
+ array.forEach((item) => (predicate(item) ? truthy : falsy).push(item));
1177
+ return [truthy, falsy];
1178
+ }
1179
+ /**
1180
+ * Extract a property from each element in an array of objects.
1181
+ *
1182
+ * Example:
1183
+ * Arr.pluck([{name:'A'},{name:'B'}], 'name') -> ['A','B']
1184
+ */
1185
+ static pluck(array, key) {
1186
+ if (!Array.isArray(array)) return [];
1187
+ return array.map((item) => item[key]);
1188
+ }
1189
+ /**
1190
+ * Add elements to the beginning of an array and return a new array.
1191
+ *
1192
+ * @param array
1193
+ * @param value
1194
+ * @returns
1195
+ */
1196
+ static prepend(array, ...value) {
1197
+ return [...value, ...Array.isArray(array) ? array : []];
1198
+ }
1199
+ /**
1200
+ * Remove a value from an array by index and return it.
1201
+ * Returns a tuple: [newArray, removedValue]
1202
+ */
1203
+ static pull(array, key) {
1204
+ if (!Array.isArray(array) || key < 0 || key >= array.length) return [array, void 0];
1205
+ const copy = array.slice();
1206
+ const [removed] = copy.splice(key, 1);
1207
+ return [copy, removed];
1208
+ }
1209
+ /**
1210
+ * Append values to an array (mutable)
1211
+ */
1212
+ static push(array, ...values) {
1213
+ array.push(...values);
1214
+ return array;
1215
+ }
1216
+ /**
1217
+ * Pick one or more random elements from an array.
1218
+ */
1219
+ static random(array, count = 1) {
1220
+ if (!Array.isArray(array) || array.length === 0) return void 0;
1221
+ const shuffled = Arr.shuffle(array);
1222
+ if (count === 1) return shuffled[0];
1223
+ return shuffled.slice(0, count);
1224
+ }
1225
+ /**
1226
+ * Returns array elements that do NOT satisfy the predicate
1227
+ */
1228
+ static reject(array, predicate) {
1229
+ return array.filter((item) => !predicate(item));
1230
+ }
1231
+ /**
1232
+ * Pick keys from an array of objects or an object
1233
+ */
1234
+ static select(obj, keys) {
1235
+ const result = {};
1236
+ keys.forEach((k) => {
1237
+ if (k in obj) result[k] = obj[k];
1238
+ });
1239
+ return result;
1240
+ }
1241
+ /**
1242
+ * Returns the only element that passes a callback, throws if none or multiple
1243
+ */
1244
+ static sole(array, predicate) {
1245
+ const filtered = array.filter(predicate);
1246
+ if (filtered.length === 0) throw new InvalidArgumentException("No element satisfies the condition.");
1247
+ if (filtered.length > 1) throw new InvalidArgumentException("Multiple elements satisfy the condition.");
1248
+ return filtered[0];
1249
+ }
1250
+ /**
1251
+ * Checks if at least one element satisfies the predicate
1252
+ */
1253
+ static some(array, predicate) {
1254
+ return array.some(predicate);
1255
+ }
1256
+ /**
1257
+ * Randomly shuffle an array and return a new array.
1258
+ */
1259
+ static shuffle(array) {
1260
+ if (!Array.isArray(array)) return [];
1261
+ const copy = array.slice();
1262
+ for (let i = copy.length - 1; i > 0; i--) {
1263
+ const j = Math.floor(Math.random() * (i + 1));
1264
+ [copy[i], copy[j]] = [copy[j], copy[i]];
1265
+ }
1266
+ return copy;
1267
+ }
1268
+ /**
1269
+ * Sort an array ascending using optional comparator.
1270
+ */
1271
+ static sort(array, comparator) {
1272
+ if (!Array.isArray(array)) return [];
1273
+ return array.slice().sort(comparator);
1274
+ }
1275
+ /**
1276
+ * Sort an array descending using optional comparator.
1277
+ */
1278
+ static sortDesc(array, comparator) {
1279
+ return Arr.sort(array, comparator ? (a, b) => comparator(b, a) : void 0);
1280
+ }
1281
+ /**
1282
+ * Recursively sort arrays inside an array.
1283
+ */
1284
+ static sortRecursive(array) {
1285
+ if (!Array.isArray(array)) return [];
1286
+ return array.map((item) => Array.isArray(item) ? Arr.sortRecursive(item) : item).sort();
1287
+ }
1288
+ /**
1289
+ * Recursively sort arrays inside an array descending.
1290
+ */
1291
+ static sortRecursiveDesc(array) {
1292
+ if (!Array.isArray(array)) return [];
1293
+ return array.map((item) => Array.isArray(item) ? Arr.sortRecursiveDesc(item) : item).sort().reverse();
1294
+ }
1295
+ /**
1296
+ * Retrieve a value using dot notation
1297
+ * Throws if value is not a string
1298
+ */
1299
+ static string(obj, path, defaultValue) {
1300
+ const val = data_get(obj, path, defaultValue);
1301
+ if (typeof val !== "string") throw new InvalidArgumentException(`Value at "${path}" is not a string.`);
1302
+ return val;
1303
+ }
1304
+ /**
1305
+ * Return the first N elements of an array.
1306
+ *
1307
+ * @param array
1308
+ * @param count
1309
+ * @returns
1310
+ */
1311
+ static take(array, count) {
1312
+ if (!Array.isArray(array)) return [];
1313
+ return array.slice(0, count);
1314
+ }
1315
+ /**
1316
+ * Filter an array based on a predicate function or key-value match.
1317
+ */
1318
+ static where(array, predicate) {
1319
+ if (!Array.isArray(array)) return [];
1320
+ if (typeof predicate === "function") return array.filter(predicate);
1321
+ return array.filter((item) => Object.entries(predicate).every(([k, v]) => item[k] === v));
1322
+ }
1323
+ /**
1324
+ * Filter an array of objects, keeping elements where the given key is not null/undefined.
1325
+ */
1326
+ static whereNotNull(array, key) {
1327
+ if (!Array.isArray(array)) return [];
1328
+ return array.filter((item) => item[key] !== null && item[key] !== void 0);
1329
+ }
1330
+ /**
1331
+ * If the given value is not an array and not null, wrap it in one.
1332
+ *
1333
+ * Non-array values become [value]; null/undefined becomes [].
1334
+ *
1335
+ * @param value
1336
+ * @returns
1337
+ */
1338
+ static wrap(value) {
1339
+ if (value === null || value === void 0) return [];
1340
+ return Array.isArray(value) ? value : [value];
1341
+ }
1342
+ /**
1343
+ * Return the first element of an array, undefined if empty.
1344
+ */
1345
+ static head(array) {
1346
+ return Array.isArray(array) && array.length ? array[0] : void 0;
1347
+ }
1348
+ /**
1349
+ * Splits an array into chunks of a specified size.
1350
+ *
1351
+ * @template T - Type of elements in the array
1352
+ * @param arr - The input array
1353
+ * @param size - Size of each chunk (default: 2)
1354
+ * @returns An array of chunks (arrays)
1355
+ */
1356
+ static chunk = (arr, size = 2) => {
1357
+ if (size <= 0) throw new Error("Chunk size must be greater than 0");
1358
+ const chunks = [];
1359
+ for (let i = 0; i < arr.length; i += size) chunks.push(arr.slice(i, i + size));
1360
+ return chunks;
1361
+ };
1362
+ /**
1363
+ * Alternates between two arrays, creating a zipped result.
1364
+ *
1365
+ * @param a
1366
+ * @param b
1367
+ * @returns
1368
+ */
1369
+ static alternate(a, b) {
1370
+ const result = [];
1371
+ const max = Math.max(a.length, b.length);
1372
+ for (let i = 0; i < max; i++) {
1373
+ if (i < a.length) result.push(a[i]);
1374
+ if (i < b.length) result.push(b[i]);
1375
+ }
1376
+ return result;
1377
+ }
1378
+ /**
1379
+ * Combine arrays and sum their values element by element.
1380
+ *
1381
+ * @param arr
1382
+ * @returns
1383
+ */
1384
+ static combine(...arr) {
1385
+ const maxLength = Math.max(...arr.map((a) => a.length));
1386
+ const result = new Array(maxLength).fill(0);
1387
+ for (let i = 0; i < maxLength; i++) for (const array of arr) result[i] += array[i] || 0;
1388
+ return result;
1389
+ }
1390
+ /**
1391
+ * Find the value associated with a given key.
1392
+ *
1393
+ * @param key
1394
+ * @param arr
1395
+ * @returns
1396
+ */
1397
+ static find(key, arr) {
1398
+ return arr.find((item) => item === key) || null;
1399
+ }
1400
+ /**
1401
+ * Check if array is empty.
1402
+ *
1403
+ * @param arr
1404
+ * @returns
1405
+ */
1406
+ static isEmpty(arr) {
1407
+ if (arr.length === 0) return true;
1408
+ else return false;
1409
+ }
1410
+ /**
1411
+ * Check if array is empty.
1412
+ *
1413
+ * @param arr
1414
+ * @returns
1415
+ */
1416
+ static isNotEmpty(arr) {
1417
+ return arr.length > 0;
1418
+ }
1419
+ /**
1420
+ * Pop the element off the end of array.
1421
+ *
1422
+ * @param arr
1423
+ * @returns
1424
+ */
1425
+ static pop(arr) {
1426
+ return arr.slice(0, -1);
1427
+ }
1428
+ /**
1429
+ * Create a new array in reverse order.
1430
+ *
1431
+ * @param arr
1432
+ * @returns
1433
+ */
1434
+ static reverse(arr) {
1435
+ return [...arr].reverse();
1436
+ }
1437
+ /**
1438
+ * Return the first element of an array that satisfies the predicate,
1439
+ * or the first element if no predicate is provided, otherwise the defaultValue.
1440
+ *
1441
+ * Predicate can be true (boolean), a function or a value to match (strict equality).
1442
+ *
1443
+ * When predicate is true (boolean), the first element will be removed and a tuple will be returned [el, rest].
1444
+ *
1445
+ * @param array
1446
+ * @param predicate
1447
+ * @param defaultValue
1448
+ *
1449
+ * @alias Arr.first()
1450
+ * @returns
1451
+ */
1452
+ static shift(array, predicate, defaultValue) {
1453
+ return Arr.first(array, predicate, defaultValue);
1454
+ }
1455
+ /**
1456
+ * Generates an array of sequential numbers.
1457
+ *
1458
+ * @param size - Number of elements in the range
1459
+ * @param startAt - Starting number (default: 0)
1460
+ * @returns An array of numbers from startAt to startAt + size - 1
1461
+ */
1462
+ static range(size, startAt = 0) {
1463
+ if (size <= 0 || !Number.isFinite(size)) return [];
1464
+ return Array.from({ length: size }, (_, i) => startAt + i);
1465
+ }
1466
+ };
1467
+
1468
+ //#endregion
1469
+ //#region src/Helpers/Time.ts
1470
+ dayjs.extend(utc);
1471
+ dayjs.extend(timezone);
1472
+ dayjs.extend(dayOfYear);
1473
+ dayjs.extend(isBetween);
1474
+ dayjs.extend(isLeapYear);
1475
+ dayjs.extend(relativeTime);
1476
+ dayjs.extend(advancedFormat);
1477
+ dayjs.extend(customParseFormat);
1478
+ const phpToDayjsTokens = (format$1) => format$1.replace(/Y/g, "YYYY").replace(/m/g, "MM").replace(/d/g, "DD").replace(/H/g, "HH").replace(/i/g, "mm").replace(/s/g, "ss");
1479
+ function format(date, fmt) {
1480
+ return dayjs(date).format(phpToDayjsTokens(fmt));
1481
+ }
1482
+ const TimeClass = class {};
1483
+ var DateTime = class DateTime extends TimeClass {
1484
+ instance;
1485
+ constructor(config) {
1486
+ super(config);
1487
+ this.instance = dayjs(config);
1488
+ return new Proxy(this, { get: (target, prop, receiver) => {
1489
+ if (prop in target) return Reflect.get(target, prop, receiver);
1490
+ const value = Reflect.get(this.instance, prop, receiver);
1491
+ if (typeof value === "function") return (...args) => {
1492
+ const result = value.apply(this.instance, args);
1493
+ return dayjs.isDayjs(result) ? new DateTime(result) : result;
1494
+ };
1495
+ return value;
1496
+ } });
1497
+ }
1498
+ /**
1499
+ * Start time of a specific unit.
1500
+ *
1501
+ * @returns
1502
+ */
1503
+ start(unit = "days") {
1504
+ return this.startOf(unit);
1505
+ }
1506
+ /**
1507
+ * End time of a specific unit.
1508
+ *
1509
+ * @returns
1510
+ */
1511
+ end(unit = "days") {
1512
+ return this.endOf(unit);
1513
+ }
1514
+ /**
1515
+ * Get the first day of the month of the given date
1516
+ *
1517
+ * @returns
1518
+ */
1519
+ firstDayOfMonth() {
1520
+ return new DateTime(new Date(Date.UTC(this.year(), this.month(), 1)));
1521
+ }
1522
+ carbonFormat(template) {
1523
+ return template ? this.format(phpToDayjsTokens(template)) : this.format();
1524
+ }
1525
+ /**
1526
+ * Get the last day of the month of the given date
1527
+ *
1528
+ * @returns
1529
+ */
1530
+ lastDayOfMonth() {
1531
+ return new DateTime(new Date(Date.UTC(this.year(), this.month() + 1, 0)));
1532
+ }
1533
+ /**
1534
+ * Get a random time between the specified hour and minute.
1535
+ *
1536
+ * @param startHour
1537
+ * @param startMinute
1538
+ * @param endHour
1539
+ * @param endMinute
1540
+ * @returns
1541
+ */
1542
+ randomTime(startHour = 9, startMinute = 0, endHour = 17, endMinute = 0) {
1543
+ const today = /* @__PURE__ */ new Date();
1544
+ const startMinutes = startHour * 60 + startMinute;
1545
+ const endMinutes = endHour * 60 + endMinute;
1546
+ const randomMinutes = Math.floor(Math.random() * (endMinutes - startMinutes)) + startMinutes;
1547
+ const hour = Math.floor(randomMinutes / 60);
1548
+ const minute = randomMinutes % 60;
1549
+ const date = new Date(today);
1550
+ date.setHours(hour, minute, 0, 0);
1551
+ return new DateTime(date);
1552
+ }
1553
+ /**
1554
+ * Create a date for a given timestamp.
1555
+ *
1556
+ * @param timestamp - Unix timestamp
1557
+ *
1558
+ * @return {Date} object
1559
+ */
1560
+ static fromTimestamp(timestamp) {
1561
+ return /* @__PURE__ */ new Date(timestamp * 1e3);
1562
+ }
1563
+ /**
1564
+ * Get current time instance.
1565
+ *
1566
+ * @returns Current time
1567
+ */
1568
+ static now() {
1569
+ return new DateTime();
1570
+ }
1571
+ /**
1572
+ * Parse the time
1573
+ *
1574
+ * @param date
1575
+ * @returns
1576
+ */
1577
+ static parse(date) {
1578
+ return new DateTime(date);
1579
+ }
1580
+ /**
1581
+ * Get the formatted date according to the string of tokens passed in.
1582
+ *
1583
+ * To escape characters, wrap them in square brackets (e.g. [MM]).
1584
+ *
1585
+ * @param time - current time
1586
+ * @param template - time format
1587
+ */
1588
+ static format(time, template) {
1589
+ return new DateTime(time).format(template);
636
1590
  }
637
- const parts = key.split(".");
638
- let current = obj;
639
- for (let i = 0; i < parts.length; i++) {
640
- const part = parts[i];
641
- /**
642
- * If we're at the last key, assign the value
643
- */
644
- if (i === parts.length - 1) current[part] = value;
645
- else {
646
- /**
647
- * If the key doesn't exist or isn't an object, create it
648
- */
649
- if (typeof current[part] !== "object" || current[part] === null) current[part] = {};
650
- current = current[part];
651
- }
1591
+ /**
1592
+ * Get the difference in days from today.
1593
+ *
1594
+ * @param time
1595
+ * @param startHour
1596
+ * @param startMinute
1597
+ * @param endHour
1598
+ * @param endMinute
1599
+ * @returns
1600
+ */
1601
+ static randomTime(time, startHour, startMinute, endHour, endMinute) {
1602
+ return new DateTime(time).randomTime(startHour, startMinute, endHour, endMinute);
1603
+ }
1604
+ /**
1605
+ * Get the first day of the month of the given date
1606
+ *
1607
+ * @param time
1608
+ *
1609
+ * @returns
1610
+ */
1611
+ static firstDayOfMonth(time) {
1612
+ return new DateTime(time).firstDayOfMonth();
1613
+ }
1614
+ /**
1615
+ * Get the last day of the month of the given date
1616
+ *
1617
+ * @param time
1618
+ *
1619
+ * @returns
1620
+ */
1621
+ static lastDayOfMonth(time) {
1622
+ return new DateTime(time).lastDayOfMonth();
652
1623
  }
653
- };
654
- /**
655
- * Converts object keys to a slugified format (e.g., snake_case).
656
- *
657
- * @template T - Type of the input object
658
- * @param obj - The object whose keys will be slugified
659
- * @param only - Optional array of keys to slugify (others remain unchanged)
660
- * @param separator - Separator for slugified keys (default: "_")
661
- * @returns A new object with slugified keys
662
- */
663
- const slugifyKeys = (obj, only = [], separator = "_") => {
664
- const slugify = (key) => key.replace(/([a-z])([A-Z])/g, `$1${separator}$2`).replace(/[\s\W]+/g, separator).replace(new RegExp(`${separator}{2,}`, "g"), separator).replace(new RegExp(`^${separator}|${separator}$`, "g"), "").toLowerCase();
665
- let entries = Object.entries(obj);
666
- if (only.length) entries = entries.filter(([key]) => only.includes(key));
667
- return Object.fromEntries(entries.map(([key, value]) => [slugify(key), value]));
668
1624
  };
669
1625
 
670
1626
  //#endregion
@@ -5006,164 +5962,6 @@ function matchCase(value, comparison) {
5006
5962
  return value;
5007
5963
  }
5008
5964
 
5009
- //#endregion
5010
- //#region src/Helpers/Time.ts
5011
- dayjs.extend(utc);
5012
- dayjs.extend(timezone);
5013
- dayjs.extend(dayOfYear);
5014
- dayjs.extend(isBetween);
5015
- dayjs.extend(isLeapYear);
5016
- dayjs.extend(relativeTime);
5017
- dayjs.extend(advancedFormat);
5018
- dayjs.extend(customParseFormat);
5019
- const phpToDayjsTokens = (format$1) => format$1.replace(/Y/g, "YYYY").replace(/m/g, "MM").replace(/d/g, "DD").replace(/H/g, "HH").replace(/i/g, "mm").replace(/s/g, "ss");
5020
- function format(date, fmt) {
5021
- return dayjs(date).format(phpToDayjsTokens(fmt));
5022
- }
5023
- const TimeClass = class {};
5024
- var Time = class Time extends TimeClass {
5025
- instance;
5026
- constructor(config) {
5027
- super(config);
5028
- this.instance = dayjs(config);
5029
- return new Proxy(this, { get: (target, prop, receiver) => {
5030
- if (prop in target) return Reflect.get(target, prop, receiver);
5031
- const value = Reflect.get(this.instance, prop, receiver);
5032
- if (typeof value === "function") return (...args) => {
5033
- const result = value.apply(this.instance, args);
5034
- return dayjs.isDayjs(result) ? new Time(result) : result;
5035
- };
5036
- return value;
5037
- } });
5038
- }
5039
- /**
5040
- * Start time of a specific unit.
5041
- *
5042
- * @returns
5043
- */
5044
- start(unit = "days") {
5045
- return this.startOf(unit);
5046
- }
5047
- /**
5048
- * End time of a specific unit.
5049
- *
5050
- * @returns
5051
- */
5052
- end(unit = "days") {
5053
- return this.endOf(unit);
5054
- }
5055
- /**
5056
- * Get the first day of the month of the given date
5057
- *
5058
- * @returns
5059
- */
5060
- firstDayOfMonth() {
5061
- return new Time(new Date(Date.UTC(this.year(), this.month(), 1)));
5062
- }
5063
- carbonFormat(template) {
5064
- return template ? this.format(phpToDayjsTokens(template)) : this.format();
5065
- }
5066
- /**
5067
- * Get the last day of the month of the given date
5068
- *
5069
- * @returns
5070
- */
5071
- lastDayOfMonth() {
5072
- return new Time(new Date(Date.UTC(this.year(), this.month() + 1, 0)));
5073
- }
5074
- /**
5075
- * Get a random time between the specified hour and minute.
5076
- *
5077
- * @param startHour
5078
- * @param startMinute
5079
- * @param endHour
5080
- * @param endMinute
5081
- * @returns
5082
- */
5083
- randomTime(startHour = 9, startMinute = 0, endHour = 17, endMinute = 0) {
5084
- const today = /* @__PURE__ */ new Date();
5085
- const startMinutes = startHour * 60 + startMinute;
5086
- const endMinutes = endHour * 60 + endMinute;
5087
- const randomMinutes = Math.floor(Math.random() * (endMinutes - startMinutes)) + startMinutes;
5088
- const hour = Math.floor(randomMinutes / 60);
5089
- const minute = randomMinutes % 60;
5090
- const date = new Date(today);
5091
- date.setHours(hour, minute, 0, 0);
5092
- return new Time(date);
5093
- }
5094
- /**
5095
- * Create a date for a given timestamp.
5096
- *
5097
- * @param timestamp - Unix timestamp
5098
- *
5099
- * @return {Date} object
5100
- */
5101
- static fromTimestamp(timestamp) {
5102
- return /* @__PURE__ */ new Date(timestamp * 1e3);
5103
- }
5104
- /**
5105
- * Get current time instance.
5106
- *
5107
- * @returns Current time
5108
- */
5109
- static now() {
5110
- return new Time();
5111
- }
5112
- /**
5113
- * Parse the time
5114
- *
5115
- * @param date
5116
- * @returns
5117
- */
5118
- static parse(date) {
5119
- return new Time(date);
5120
- }
5121
- /**
5122
- * Get the formatted date according to the string of tokens passed in.
5123
- *
5124
- * To escape characters, wrap them in square brackets (e.g. [MM]).
5125
- *
5126
- * @param time - current time
5127
- * @param template - time format
5128
- */
5129
- static format(time, template) {
5130
- return new Time(time).format(template);
5131
- }
5132
- /**
5133
- * Get the difference in days from today.
5134
- *
5135
- * @param time
5136
- * @param startHour
5137
- * @param startMinute
5138
- * @param endHour
5139
- * @param endMinute
5140
- * @returns
5141
- */
5142
- static randomTime(time, startHour, startMinute, endHour, endMinute) {
5143
- return new Time(time).randomTime(startHour, startMinute, endHour, endMinute);
5144
- }
5145
- /**
5146
- * Get the first day of the month of the given date
5147
- *
5148
- * @param time
5149
- *
5150
- * @returns
5151
- */
5152
- static firstDayOfMonth(time) {
5153
- return new Time(time).firstDayOfMonth();
5154
- }
5155
- /**
5156
- * Get the last day of the month of the given date
5157
- *
5158
- * @param time
5159
- *
5160
- * @returns
5161
- */
5162
- static lastDayOfMonth(time) {
5163
- return new Time(time).lastDayOfMonth();
5164
- }
5165
- };
5166
-
5167
5965
  //#endregion
5168
5966
  //#region src/GlobalBootstrap.ts
5169
5967
  /**
@@ -5190,12 +5988,12 @@ var Time = class Time extends TimeClass {
5190
5988
  */
5191
5989
  function loadHelpers(target = globalThis) {
5192
5990
  const globalHelpers = {
5193
- Arr: Arr_exports,
5991
+ Arr,
5194
5992
  Crypto: Crypto_exports,
5195
5993
  Number: Number_exports,
5196
- Obj: Obj_exports,
5994
+ Obj,
5197
5995
  Str,
5198
- Time,
5996
+ DateTime,
5199
5997
  DumpDie: DumpDie_exports,
5200
5998
  apa: Str.apa,
5201
5999
  title: Str.title,
@@ -5209,24 +6007,26 @@ function loadHelpers(target = globalThis) {
5209
6007
  plural: Str.plural,
5210
6008
  singular: Str.singular,
5211
6009
  capitalize: Str.capitalize,
5212
- collapse,
5213
- alternate,
5214
- combine,
5215
- forget,
5216
- first,
5217
- last,
5218
- isEmpty,
5219
- isNotEmpty,
5220
- prepend,
5221
- range,
5222
- flatten,
6010
+ collapse: Arr.collapse,
6011
+ forget: Arr.forget,
6012
+ first: Arr.first,
6013
+ last: Arr.last,
6014
+ prepend: Arr.prepend,
6015
+ flatten: Arr.flatten,
5223
6016
  dot,
6017
+ undot,
5224
6018
  extractProperties,
5225
6019
  getValue,
5226
6020
  modObj,
5227
6021
  safeDot,
5228
6022
  setNested,
6023
+ toCssClasses,
5229
6024
  slugifyKeys,
6025
+ toCssStyles,
6026
+ data_get,
6027
+ data_set,
6028
+ data_fill,
6029
+ data_forget,
5230
6030
  uuid,
5231
6031
  random,
5232
6032
  randomSecure,
@@ -5241,13 +6041,13 @@ function loadHelpers(target = globalThis) {
5241
6041
  checksum,
5242
6042
  verifyChecksum,
5243
6043
  caesarCipher,
5244
- now: Time.now,
5245
- format: Time.format,
5246
- fromTimestamp: Time.fromTimestamp,
5247
- parse: Time.parse,
5248
- randomTime: Time.randomTime,
5249
- firstDayOfMonth: Time.firstDayOfMonth,
5250
- lastDayOfMonth: Time.lastDayOfMonth,
6044
+ now: DateTime.now,
6045
+ format: DateTime.format,
6046
+ fromTimestamp: DateTime.fromTimestamp,
6047
+ parse: DateTime.parse,
6048
+ randomTime: DateTime.randomTime,
6049
+ firstDayOfMonth: DateTime.firstDayOfMonth,
6050
+ lastDayOfMonth: DateTime.lastDayOfMonth,
5251
6051
  abbreviate,
5252
6052
  humanize,
5253
6053
  toBytes,
@@ -5308,6 +6108,13 @@ function cleanHelpers(target = globalThis) {
5308
6108
  "safeDot",
5309
6109
  "setNested",
5310
6110
  "slugifyKeys",
6111
+ "toCssClasses",
6112
+ "undot",
6113
+ "toCssStyles",
6114
+ "data_get",
6115
+ "data_set",
6116
+ "data_fill",
6117
+ "data_forget",
5311
6118
  "Crypto",
5312
6119
  "uuid",
5313
6120
  "random",
@@ -5345,5 +6152,5 @@ function cleanHelpers(target = globalThis) {
5345
6152
  }
5346
6153
 
5347
6154
  //#endregion
5348
- export { Arr_exports as Arr, Crypto_exports as Crypto, DumpDie_exports as DumpDie, HtmlString, Mode, Number_exports as Number, Obj_exports as Obj, Str, Stringable, Time, abbreviate, alternate, base64Decode, base64Encode, caesarCipher, checksum, chunk, cleanHelpers, collapse, combine, dd, dot, dump, extractProperties, find, first, flatten, forget, format, getValue, hash, hmac, humanize, isEmpty, isNotEmpty, last, loadHelpers, modObj, pop, prepend, random, randomColor, randomPassword, randomSecure, range, reverse, safeDot, secureToken, setNested, shift, slugifyKeys, str, take, toBytes, toHumanTime, uuid, verifyChecksum, xor };
6155
+ export { Arr, Crypto_exports as Crypto, DateTime, DumpDie_exports as DumpDie, HtmlString, InvalidArgumentException, Mode, Number_exports as Number, Obj_exports as Obj, RuntimeException, Str, Stringable, abbreviate, base64Decode, base64Encode, caesarCipher, checksum, cleanHelpers, data_fill, data_forget, data_get, data_set, dd, dot, dump, extractProperties, format, getValue, hash, hmac, humanize, loadHelpers, modObj, random, randomColor, randomPassword, randomSecure, safeDot, secureToken, setNested, slugifyKeys, str, toBytes, toCssClasses, toCssStyles, toHumanTime, undot, uuid, verifyChecksum, xor };
5349
6156
  //# sourceMappingURL=index.js.map