@h3ravel/support 0.15.5 → 0.16.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/RuntimeException-CmsL83ow.cjs +19 -0
- package/dist/RuntimeException-CrNX0B-p.js +13 -0
- package/dist/chunk-NmTyJVUt.js +20 -0
- package/dist/facades.cjs +111 -0
- package/dist/facades.d.ts +70 -0
- package/dist/facades.js +109 -0
- package/dist/index.cjs +898 -61
- package/dist/index.d.ts +470 -36
- package/dist/index.js +856 -45
- package/package.json +10 -4
- package/dist/chunk-Bop6jNiL.js +0 -15
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { t as __export } from "./chunk-
|
|
1
|
+
import { t as __export } from "./chunk-NmTyJVUt.js";
|
|
2
|
+
import { t as RuntimeException } from "./RuntimeException-CrNX0B-p.js";
|
|
3
|
+
import { Collection as Collection$1 } from "@h3ravel/collect.js";
|
|
2
4
|
import { createHash, createHmac, randomBytes, randomUUID } from "crypto";
|
|
3
5
|
import process from "process";
|
|
4
6
|
import util from "util";
|
|
@@ -11,27 +13,48 @@ import isLeapYear from "dayjs/plugin/isLeapYear.js";
|
|
|
11
13
|
import relativeTime from "dayjs/plugin/relativeTime.js";
|
|
12
14
|
import timezone from "dayjs/plugin/timezone.js";
|
|
13
15
|
import utc from "dayjs/plugin/utc.js";
|
|
16
|
+
import { isIP } from "node:net";
|
|
17
|
+
import { Logger, trait } from "@h3ravel/shared";
|
|
18
|
+
import { readFile, stat } from "node:fs/promises";
|
|
19
|
+
import { IRouter, IServiceProvider } from "@h3ravel/contracts";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { statSync } from "node:fs";
|
|
14
22
|
|
|
15
|
-
//#region src/
|
|
23
|
+
//#region src/Collection.ts
|
|
24
|
+
var Collection = class extends Collection$1 {
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param collection
|
|
28
|
+
*/
|
|
29
|
+
constructor(collection) {
|
|
30
|
+
super(collection);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
16
33
|
/**
|
|
17
|
-
*
|
|
34
|
+
*
|
|
35
|
+
* @param collection
|
|
36
|
+
* @returns
|
|
18
37
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
super(message);
|
|
22
|
-
this.name = "InvalidArgumentException";
|
|
23
|
-
}
|
|
38
|
+
const collect = (collection) => {
|
|
39
|
+
return new Collection(collection);
|
|
24
40
|
};
|
|
25
41
|
|
|
26
42
|
//#endregion
|
|
27
|
-
//#region src/Exceptions/
|
|
43
|
+
//#region src/Exceptions/BadMethodCallException.ts
|
|
44
|
+
/**
|
|
45
|
+
* Exception thrown if an error with a method call occurs.
|
|
46
|
+
*/
|
|
47
|
+
var BadMethodCallException = class extends Error {};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/Exceptions/InvalidArgumentException.ts
|
|
28
51
|
/**
|
|
29
52
|
* Custom error for invalid type coercion
|
|
30
53
|
*/
|
|
31
|
-
var
|
|
54
|
+
var InvalidArgumentException = class extends Error {
|
|
32
55
|
constructor(message) {
|
|
33
56
|
super(message);
|
|
34
|
-
this.name = "
|
|
57
|
+
this.name = "InvalidArgumentException";
|
|
35
58
|
}
|
|
36
59
|
};
|
|
37
60
|
|
|
@@ -424,7 +447,7 @@ const toHumanTime = (seconds = 0, worded = false) => {
|
|
|
424
447
|
* with dot-separated keys.
|
|
425
448
|
*
|
|
426
449
|
* Example:
|
|
427
|
-
*
|
|
450
|
+
* dot({
|
|
428
451
|
* user: { name: "John", address: { city: "NY" } },
|
|
429
452
|
* active: true
|
|
430
453
|
* })
|
|
@@ -567,6 +590,9 @@ const slugifyKeys = (obj, only = [], separator = "_") => {
|
|
|
567
590
|
* - Arrays: included if truthy
|
|
568
591
|
* - Objects: keys included if value is truthy
|
|
569
592
|
* - Strings: included as-is
|
|
593
|
+
*
|
|
594
|
+
* @param input
|
|
595
|
+
* @returns
|
|
570
596
|
*/
|
|
571
597
|
function toCssClasses(input) {
|
|
572
598
|
if (!input) return "";
|
|
@@ -585,6 +611,9 @@ function toCssClasses(input) {
|
|
|
585
611
|
*
|
|
586
612
|
* Convert object input into CSS style string.
|
|
587
613
|
* - Only includes truthy values (ignores null/undefined/false)
|
|
614
|
+
*
|
|
615
|
+
* @param styles
|
|
616
|
+
* @returns
|
|
588
617
|
*/
|
|
589
618
|
function toCssStyles(styles) {
|
|
590
619
|
const parts = [];
|
|
@@ -601,6 +630,9 @@ function toCssStyles(styles) {
|
|
|
601
630
|
*
|
|
602
631
|
* Example:
|
|
603
632
|
* undot({ 'a.b': 1, 'c.0': 2 }) -> { a: { b: 1 }, c: [2] }
|
|
633
|
+
*
|
|
634
|
+
* @param obj
|
|
635
|
+
* @returns
|
|
604
636
|
*/
|
|
605
637
|
function undot(obj) {
|
|
606
638
|
const result = {};
|
|
@@ -625,6 +657,11 @@ function undot(obj) {
|
|
|
625
657
|
* data_get
|
|
626
658
|
*
|
|
627
659
|
* Get a value from an object using dot notation.
|
|
660
|
+
*
|
|
661
|
+
* @param obj
|
|
662
|
+
* @param path
|
|
663
|
+
* @param defaultValue
|
|
664
|
+
* @returns
|
|
628
665
|
*/
|
|
629
666
|
function data_get(obj, path, defaultValue) {
|
|
630
667
|
if (!obj) return defaultValue;
|
|
@@ -640,6 +677,10 @@ function data_get(obj, path, defaultValue) {
|
|
|
640
677
|
* data_set
|
|
641
678
|
*
|
|
642
679
|
* Set a value in an object using dot notation. Mutates the object.
|
|
680
|
+
*
|
|
681
|
+
* @param obj
|
|
682
|
+
* @param path
|
|
683
|
+
* @param value
|
|
643
684
|
*/
|
|
644
685
|
function data_set(obj, path, value) {
|
|
645
686
|
const parts = Array.isArray(path) ? path : path.split(".");
|
|
@@ -657,6 +698,10 @@ function data_set(obj, path, value) {
|
|
|
657
698
|
* data_fill
|
|
658
699
|
*
|
|
659
700
|
* Like data_set, but only sets the value if the key does NOT exist.
|
|
701
|
+
*
|
|
702
|
+
* @param obj
|
|
703
|
+
* @param path
|
|
704
|
+
* @param value
|
|
660
705
|
*/
|
|
661
706
|
function data_fill(obj, path, value) {
|
|
662
707
|
if (data_get(obj, path) === void 0) data_set(obj, path, value);
|
|
@@ -665,6 +710,9 @@ function data_fill(obj, path, value) {
|
|
|
665
710
|
* data_forget
|
|
666
711
|
*
|
|
667
712
|
* Remove a key from an object using dot notation.
|
|
713
|
+
*
|
|
714
|
+
* @param obj
|
|
715
|
+
* @param path
|
|
668
716
|
*/
|
|
669
717
|
function data_forget(obj, path) {
|
|
670
718
|
const parts = Array.isArray(path) ? path : path.split(".");
|
|
@@ -682,14 +730,18 @@ function data_forget(obj, path) {
|
|
|
682
730
|
* Checks if a value is a plain object (not array, function, etc.)
|
|
683
731
|
*
|
|
684
732
|
* @param value
|
|
733
|
+
* @param allowArray
|
|
685
734
|
* @returns
|
|
686
735
|
*/
|
|
687
|
-
function isPlainObject(value) {
|
|
688
|
-
return value !== null && typeof value === "object" &&
|
|
736
|
+
function isPlainObject(value, allowArray) {
|
|
737
|
+
return value !== null && typeof value === "object" && (Array.isArray(value) === false || allowArray === true) && Object.prototype.toString.call(value) === "[object Object]";
|
|
689
738
|
}
|
|
690
739
|
var Obj = class Obj {
|
|
691
740
|
/**
|
|
692
741
|
* Check if the value is a non-null object (associative/accessible).
|
|
742
|
+
*
|
|
743
|
+
* @param value
|
|
744
|
+
* @returns
|
|
693
745
|
*/
|
|
694
746
|
static accessible(value) {
|
|
695
747
|
return value !== null && typeof value === "object";
|
|
@@ -698,6 +750,11 @@ var Obj = class Obj {
|
|
|
698
750
|
* Add a key-value pair to an object only if the key does not already exist.
|
|
699
751
|
*
|
|
700
752
|
* Returns a new object (does not mutate original).
|
|
753
|
+
*
|
|
754
|
+
* @param obj
|
|
755
|
+
* @param key
|
|
756
|
+
* @param value
|
|
757
|
+
* @returns
|
|
701
758
|
*/
|
|
702
759
|
static add(obj, key, value) {
|
|
703
760
|
if (!(key in obj)) return {
|
|
@@ -729,12 +786,43 @@ var Obj = class Obj {
|
|
|
729
786
|
}
|
|
730
787
|
/**
|
|
731
788
|
* Split object into [keys, values]
|
|
789
|
+
*
|
|
790
|
+
* @param obj
|
|
791
|
+
* @returns
|
|
732
792
|
*/
|
|
733
793
|
static divide(obj) {
|
|
734
794
|
return [Object.keys(obj), Object.values(obj)];
|
|
735
795
|
}
|
|
736
796
|
/**
|
|
797
|
+
* Flattens a nested object into a single-level object
|
|
798
|
+
* with dot-separated keys.
|
|
799
|
+
*
|
|
800
|
+
* Example:
|
|
801
|
+
* dot({
|
|
802
|
+
* user: { name: "John", address: { city: "NY" } },
|
|
803
|
+
* active: true
|
|
804
|
+
* })
|
|
805
|
+
*
|
|
806
|
+
* Output:
|
|
807
|
+
* {
|
|
808
|
+
* "user.name": "John",
|
|
809
|
+
* "user.address.city": "NY",
|
|
810
|
+
* "active": true
|
|
811
|
+
* }
|
|
812
|
+
*
|
|
813
|
+
* @template T - The type of the input object
|
|
814
|
+
* @param obj - The nested object to flatten
|
|
815
|
+
* @returns A flattened object with dotted keys and inferred types
|
|
816
|
+
*/
|
|
817
|
+
static dot(obj) {
|
|
818
|
+
return dot(obj);
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
737
821
|
* Check if a key exists in the object.
|
|
822
|
+
*
|
|
823
|
+
* @param obj
|
|
824
|
+
* @param key
|
|
825
|
+
* @returns
|
|
738
826
|
*/
|
|
739
827
|
static exists(obj, key) {
|
|
740
828
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
@@ -744,6 +832,11 @@ var Obj = class Obj {
|
|
|
744
832
|
*
|
|
745
833
|
* Example:
|
|
746
834
|
* Obj.get({a:{b:1}}, 'a.b') -> 1
|
|
835
|
+
*
|
|
836
|
+
* @param obj
|
|
837
|
+
* @param path
|
|
838
|
+
* @param defaultValue
|
|
839
|
+
* @returns
|
|
747
840
|
*/
|
|
748
841
|
static get(obj, path, defaultValue) {
|
|
749
842
|
if (!Obj.accessible(obj)) return defaultValue;
|
|
@@ -757,6 +850,10 @@ var Obj = class Obj {
|
|
|
757
850
|
}
|
|
758
851
|
/**
|
|
759
852
|
* Check if the object has a given key or keys (dot notation supported).
|
|
853
|
+
*
|
|
854
|
+
* @param obj
|
|
855
|
+
* @param keys
|
|
856
|
+
* @returns
|
|
760
857
|
*/
|
|
761
858
|
static has(obj, keys) {
|
|
762
859
|
if (!Obj.accessible(obj)) return false;
|
|
@@ -772,13 +869,30 @@ var Obj = class Obj {
|
|
|
772
869
|
}
|
|
773
870
|
/**
|
|
774
871
|
* Check if an object is associative (has at least one non-numeric key).
|
|
872
|
+
*
|
|
873
|
+
* @param obj
|
|
874
|
+
* @returns
|
|
775
875
|
*/
|
|
776
876
|
static isAssoc(obj) {
|
|
777
877
|
if (!Obj.accessible(obj)) return false;
|
|
778
878
|
return Object.keys(obj).some((k) => isNaN(Number(k)));
|
|
779
879
|
}
|
|
780
880
|
/**
|
|
881
|
+
* Checks if a value is a plain object (not array, function, etc.)
|
|
882
|
+
*
|
|
883
|
+
* @param value
|
|
884
|
+
* @param allowArray
|
|
885
|
+
* @returns
|
|
886
|
+
*/
|
|
887
|
+
static isPlainObject(value, allowArray) {
|
|
888
|
+
return isPlainObject(value, allowArray);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
781
891
|
* Add a prefix to all keys of the object.
|
|
892
|
+
*
|
|
893
|
+
* @param obj
|
|
894
|
+
* @param prefix
|
|
895
|
+
* @returns
|
|
782
896
|
*/
|
|
783
897
|
static prependKeysWith(obj, prefix) {
|
|
784
898
|
if (!Obj.accessible(obj)) return {};
|
|
@@ -790,6 +904,9 @@ var Obj = class Obj {
|
|
|
790
904
|
* Convert an object into a URL query string.
|
|
791
905
|
*
|
|
792
906
|
* Nested objects/arrays are flattened using bracket notation.
|
|
907
|
+
*
|
|
908
|
+
* @param obj
|
|
909
|
+
* @returns
|
|
793
910
|
*/
|
|
794
911
|
static query(obj) {
|
|
795
912
|
const encode = encodeURIComponent;
|
|
@@ -802,6 +919,20 @@ var Obj = class Obj {
|
|
|
802
919
|
Object.entries(obj).forEach(([k, v]) => build(k, v));
|
|
803
920
|
return parts.join("&");
|
|
804
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* undot
|
|
924
|
+
*
|
|
925
|
+
* Convert a dot-notated object back into nested structure.
|
|
926
|
+
*
|
|
927
|
+
* Example:
|
|
928
|
+
* undot({ 'a.b': 1, 'c.0': 2 }) -> { a: { b: 1 }, c: [2] }
|
|
929
|
+
*
|
|
930
|
+
* @param obj
|
|
931
|
+
* @returns
|
|
932
|
+
*/
|
|
933
|
+
undot(obj) {
|
|
934
|
+
return undot(obj);
|
|
935
|
+
}
|
|
805
936
|
};
|
|
806
937
|
|
|
807
938
|
//#endregion
|
|
@@ -1338,6 +1469,7 @@ var Arr = class Arr {
|
|
|
1338
1469
|
*/
|
|
1339
1470
|
static whereNotNull(array, key) {
|
|
1340
1471
|
if (!Array.isArray(array)) return [];
|
|
1472
|
+
if (!key) return array.filter((item) => item !== null && item !== void 0);
|
|
1341
1473
|
return array.filter((item) => item[key] !== null && item[key] !== void 0);
|
|
1342
1474
|
}
|
|
1343
1475
|
/**
|
|
@@ -1476,6 +1608,15 @@ var Arr = class Arr {
|
|
|
1476
1608
|
if (size <= 0 || !Number.isFinite(size)) return [];
|
|
1477
1609
|
return Array.from({ length: size }, (_, i) => startAt + i);
|
|
1478
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Filters an array and returns only unique values
|
|
1613
|
+
*
|
|
1614
|
+
* @param items
|
|
1615
|
+
* @returns
|
|
1616
|
+
*/
|
|
1617
|
+
static unique(items) {
|
|
1618
|
+
return items.filter((value, index, self) => self.indexOf(value) === index);
|
|
1619
|
+
}
|
|
1479
1620
|
};
|
|
1480
1621
|
|
|
1481
1622
|
//#endregion
|
|
@@ -1495,9 +1636,9 @@ function format(date, fmt) {
|
|
|
1495
1636
|
const TimeClass = class {};
|
|
1496
1637
|
var DateTime = class DateTime extends TimeClass {
|
|
1497
1638
|
instance;
|
|
1498
|
-
constructor(config) {
|
|
1639
|
+
constructor(config, format$1, locale, strict) {
|
|
1499
1640
|
super(config);
|
|
1500
|
-
this.instance = dayjs(config);
|
|
1641
|
+
this.instance = dayjs(config, format$1, locale, strict);
|
|
1501
1642
|
return new Proxy(this, { get: (target, prop, receiver) => {
|
|
1502
1643
|
if (prop in target) return Reflect.get(target, prop, receiver);
|
|
1503
1644
|
const value = Reflect.get(this.instance, prop, receiver);
|
|
@@ -1865,18 +2006,6 @@ var Str = class Str {
|
|
|
1865
2006
|
return result;
|
|
1866
2007
|
}
|
|
1867
2008
|
/**
|
|
1868
|
-
* Determine if a given string doesn't contain a given substring.
|
|
1869
|
-
*
|
|
1870
|
-
* @param { string } haystack
|
|
1871
|
-
* @param { string | string[] } needles
|
|
1872
|
-
* @param { boolean } ignoreCase
|
|
1873
|
-
*
|
|
1874
|
-
* @return { boolean }
|
|
1875
|
-
*/
|
|
1876
|
-
static doesntContain(haystack, needles, ignoreCase = false) {
|
|
1877
|
-
return !this.contains(haystack, needles, ignoreCase);
|
|
1878
|
-
}
|
|
1879
|
-
/**
|
|
1880
2009
|
* Convert the case of a string.
|
|
1881
2010
|
*
|
|
1882
2011
|
* @param { string } string
|
|
@@ -1914,6 +2043,46 @@ var Str = class Str {
|
|
|
1914
2043
|
return string;
|
|
1915
2044
|
}
|
|
1916
2045
|
/**
|
|
2046
|
+
* Detect content type
|
|
2047
|
+
*
|
|
2048
|
+
* @param content
|
|
2049
|
+
* @returns
|
|
2050
|
+
*/
|
|
2051
|
+
static detectContentType(content) {
|
|
2052
|
+
if (typeof content !== "string") return "json";
|
|
2053
|
+
const trimmed = content.trim();
|
|
2054
|
+
/**
|
|
2055
|
+
* JSON check
|
|
2056
|
+
*/
|
|
2057
|
+
if (/^[[{]/.test(trimmed)) try {
|
|
2058
|
+
JSON.parse(trimmed);
|
|
2059
|
+
return "json";
|
|
2060
|
+
} catch {}
|
|
2061
|
+
/**
|
|
2062
|
+
* XML check
|
|
2063
|
+
*/
|
|
2064
|
+
if (/^<\?xml/i.test(trimmed) || /^<[A-Za-z]+[^>]*>/.test(trimmed)) {
|
|
2065
|
+
if (!/^<!DOCTYPE html>/i.test(trimmed) && !/<html[\s>]/i.test(trimmed)) return "xml";
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* HTML check
|
|
2069
|
+
*/
|
|
2070
|
+
if (/<(html|head|body|div|span|p|!DOCTYPE)/i.test(trimmed)) return "html";
|
|
2071
|
+
return "text";
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* Determine if a given string doesn't contain a given substring.
|
|
2075
|
+
*
|
|
2076
|
+
* @param { string } haystack
|
|
2077
|
+
* @param { string | string[] } needles
|
|
2078
|
+
* @param { boolean } ignoreCase
|
|
2079
|
+
*
|
|
2080
|
+
* @return { boolean }
|
|
2081
|
+
*/
|
|
2082
|
+
static doesntContain(haystack, needles, ignoreCase = false) {
|
|
2083
|
+
return !this.contains(haystack, needles, ignoreCase);
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
1917
2086
|
* Replace consecutive instances of a given character with a single character in the given string.
|
|
1918
2087
|
*
|
|
1919
2088
|
* @param { string } string
|
|
@@ -2058,7 +2227,7 @@ var Str = class Str {
|
|
|
2058
2227
|
for (let pattern$1 of patterns) {
|
|
2059
2228
|
if (pattern$1 === value) return true;
|
|
2060
2229
|
if (ignoreCase && pattern$1.toLowerCase() === value.toLowerCase()) return true;
|
|
2061
|
-
pattern$1 = pattern$1.replace(/[
|
|
2230
|
+
pattern$1 = pattern$1.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&").replace(/\\\*/g, ".*");
|
|
2062
2231
|
if (new RegExp("^" + pattern$1 + "$", ignoreCase ? "iu" : "u").test(value)) return true;
|
|
2063
2232
|
}
|
|
2064
2233
|
return false;
|
|
@@ -2186,6 +2355,19 @@ var Str = class Str {
|
|
|
2186
2355
|
return value.toLowerCase();
|
|
2187
2356
|
}
|
|
2188
2357
|
/**
|
|
2358
|
+
* Parse a Class[@]method style callback into class and method.
|
|
2359
|
+
*
|
|
2360
|
+
* @param callback
|
|
2361
|
+
* @param defaultValue
|
|
2362
|
+
*/
|
|
2363
|
+
static parseCallback(callback, defaultValue) {
|
|
2364
|
+
if (this.contains(callback, "anonymous")) {
|
|
2365
|
+
if (this.substrCount(callback, "@") > 1) return [this.beforeLast(callback, "@"), this.afterLast(callback, "@")];
|
|
2366
|
+
return [callback, defaultValue];
|
|
2367
|
+
}
|
|
2368
|
+
return this.contains(callback, "@") ? callback.split("@", 2) : [callback, defaultValue];
|
|
2369
|
+
}
|
|
2370
|
+
/**
|
|
2189
2371
|
* Get substring by start/stop indexes.
|
|
2190
2372
|
*
|
|
2191
2373
|
* @param string
|
|
@@ -3635,10 +3817,9 @@ var Str = class Str {
|
|
|
3635
3817
|
static trim(value, characters = null) {
|
|
3636
3818
|
if (characters === null) return value.trim();
|
|
3637
3819
|
if (characters === "") return value;
|
|
3638
|
-
|
|
3639
|
-
characters
|
|
3640
|
-
|
|
3641
|
-
return value.replace(regex, "") ?? value;
|
|
3820
|
+
for (const char of characters) while (value.startsWith(char)) value = value.substring(char.length);
|
|
3821
|
+
for (const char of characters) while (value.endsWith(char)) value = value.substring(0, value.length - char.length);
|
|
3822
|
+
return value;
|
|
3642
3823
|
}
|
|
3643
3824
|
/**
|
|
3644
3825
|
* Remove all whitespace from the beginning of a string.
|
|
@@ -3651,8 +3832,7 @@ var Str = class Str {
|
|
|
3651
3832
|
static ltrim(value, characters = null) {
|
|
3652
3833
|
if (characters === null) return value.trimStart();
|
|
3653
3834
|
if (characters === "") return value;
|
|
3654
|
-
|
|
3655
|
-
characters.split("").forEach((character) => value = this.replaceStart(character, "", value));
|
|
3835
|
+
for (const char of characters) while (value.startsWith(char)) value = value.substring(char.length);
|
|
3656
3836
|
return value;
|
|
3657
3837
|
}
|
|
3658
3838
|
/**
|
|
@@ -3666,8 +3846,7 @@ var Str = class Str {
|
|
|
3666
3846
|
static rtrim(value, characters = null) {
|
|
3667
3847
|
if (characters === null) return value.trimEnd();
|
|
3668
3848
|
if (characters === "") return value;
|
|
3669
|
-
|
|
3670
|
-
characters.split("").forEach((character) => value = this.replaceEnd(character, "", value));
|
|
3849
|
+
for (const char of characters) while (value.endsWith(char)) value = value.substring(0, value.length - char.length);
|
|
3671
3850
|
return value;
|
|
3672
3851
|
}
|
|
3673
3852
|
/**
|
|
@@ -4018,6 +4197,23 @@ var Str = class Str {
|
|
|
4018
4197
|
return result;
|
|
4019
4198
|
}
|
|
4020
4199
|
/**
|
|
4200
|
+
* Validate an IP address
|
|
4201
|
+
*
|
|
4202
|
+
* @param host
|
|
4203
|
+
* @param type
|
|
4204
|
+
*
|
|
4205
|
+
* @return { boolean }
|
|
4206
|
+
*/
|
|
4207
|
+
static validateIp(host, type) {
|
|
4208
|
+
const code = {
|
|
4209
|
+
ipv4: 4,
|
|
4210
|
+
ipv6: 6
|
|
4211
|
+
};
|
|
4212
|
+
const result = isIP(host);
|
|
4213
|
+
if (type) return result === code[type];
|
|
4214
|
+
return result > 0;
|
|
4215
|
+
}
|
|
4216
|
+
/**
|
|
4021
4217
|
* Generate a time-ordered UUID (version 4).
|
|
4022
4218
|
*
|
|
4023
4219
|
* @return { string }
|
|
@@ -4390,6 +4586,16 @@ var Stringable = class Stringable {
|
|
|
4390
4586
|
return Str.containsAll(this.#value, needles, ignoreCase);
|
|
4391
4587
|
}
|
|
4392
4588
|
/**
|
|
4589
|
+
* Convert the case of a string.
|
|
4590
|
+
*
|
|
4591
|
+
* @param { Mode | number } mode
|
|
4592
|
+
*
|
|
4593
|
+
* @return { Stringable }
|
|
4594
|
+
*/
|
|
4595
|
+
convertCase(mode = Mode.MB_CASE_FOLD) {
|
|
4596
|
+
return new Stringable(Str.convertCase(this.#value, mode));
|
|
4597
|
+
}
|
|
4598
|
+
/**
|
|
4393
4599
|
* Determine if a given string doesn't contain a given substring.
|
|
4394
4600
|
*
|
|
4395
4601
|
* @param { string | string[] } needles
|
|
@@ -4401,14 +4607,13 @@ var Stringable = class Stringable {
|
|
|
4401
4607
|
return !this.contains(needles, ignoreCase);
|
|
4402
4608
|
}
|
|
4403
4609
|
/**
|
|
4404
|
-
*
|
|
4405
|
-
*
|
|
4406
|
-
* @param
|
|
4407
|
-
*
|
|
4408
|
-
* @return { Stringable }
|
|
4610
|
+
* Detect content type
|
|
4611
|
+
*
|
|
4612
|
+
* @param content
|
|
4613
|
+
* @returns
|
|
4409
4614
|
*/
|
|
4410
|
-
|
|
4411
|
-
return
|
|
4615
|
+
static detectContentType(content) {
|
|
4616
|
+
return Str.detectContentType(content);
|
|
4412
4617
|
}
|
|
4413
4618
|
/**
|
|
4414
4619
|
* Replace consecutive instances of a given character with a single character in the given string.
|
|
@@ -5221,6 +5426,16 @@ var Stringable = class Stringable {
|
|
|
5221
5426
|
return this;
|
|
5222
5427
|
}
|
|
5223
5428
|
/**
|
|
5429
|
+
* Validate an IP address
|
|
5430
|
+
*
|
|
5431
|
+
* @param host
|
|
5432
|
+
* @param type
|
|
5433
|
+
* @returns
|
|
5434
|
+
*/
|
|
5435
|
+
validateIp(type = "ipv4") {
|
|
5436
|
+
return Str.validateIp(this.#value, type);
|
|
5437
|
+
}
|
|
5438
|
+
/**
|
|
5224
5439
|
* Execute the given callback if the string contains a given substring.
|
|
5225
5440
|
*
|
|
5226
5441
|
* @param { string | string[] } needles
|
|
@@ -6035,6 +6250,7 @@ function loadHelpers(target = globalThis) {
|
|
|
6035
6250
|
last: Arr.last,
|
|
6036
6251
|
prepend: Arr.prepend,
|
|
6037
6252
|
flatten: Arr.flatten,
|
|
6253
|
+
unique: Arr.unique,
|
|
6038
6254
|
dot,
|
|
6039
6255
|
undot,
|
|
6040
6256
|
extractProperties,
|
|
@@ -6049,6 +6265,7 @@ function loadHelpers(target = globalThis) {
|
|
|
6049
6265
|
data_set,
|
|
6050
6266
|
data_fill,
|
|
6051
6267
|
data_forget,
|
|
6268
|
+
isPlainObject,
|
|
6052
6269
|
uuid,
|
|
6053
6270
|
random,
|
|
6054
6271
|
randomSecure,
|
|
@@ -6174,4 +6391,598 @@ function cleanHelpers(target = globalThis) {
|
|
|
6174
6391
|
}
|
|
6175
6392
|
|
|
6176
6393
|
//#endregion
|
|
6177
|
-
|
|
6394
|
+
//#region src/HigherOrderTapProxy.ts
|
|
6395
|
+
var HigherOrderTapProxy = class {
|
|
6396
|
+
/**
|
|
6397
|
+
* The target being tapped.
|
|
6398
|
+
*/
|
|
6399
|
+
target;
|
|
6400
|
+
/**
|
|
6401
|
+
* Create a new tap proxy instance.
|
|
6402
|
+
*/
|
|
6403
|
+
constructor(target) {
|
|
6404
|
+
this.target = target;
|
|
6405
|
+
}
|
|
6406
|
+
/**
|
|
6407
|
+
* Dynamically pass method calls to the target.
|
|
6408
|
+
*
|
|
6409
|
+
* @param method
|
|
6410
|
+
* @param parameters
|
|
6411
|
+
*/
|
|
6412
|
+
__call(method, parameters) {
|
|
6413
|
+
this.target[method](...parameters);
|
|
6414
|
+
return this.target;
|
|
6415
|
+
}
|
|
6416
|
+
};
|
|
6417
|
+
|
|
6418
|
+
//#endregion
|
|
6419
|
+
//#region src/Helpers.ts
|
|
6420
|
+
/**
|
|
6421
|
+
* Call the given Closure with the given value then return the value.
|
|
6422
|
+
*
|
|
6423
|
+
* @param value
|
|
6424
|
+
* @param callback
|
|
6425
|
+
*/
|
|
6426
|
+
const tap = (value, callback) => {
|
|
6427
|
+
if (!callback) return new HigherOrderTapProxy(value);
|
|
6428
|
+
callback(value);
|
|
6429
|
+
return value;
|
|
6430
|
+
};
|
|
6431
|
+
/**
|
|
6432
|
+
* Optional Proxy factory
|
|
6433
|
+
*
|
|
6434
|
+
* @param value
|
|
6435
|
+
* @returns
|
|
6436
|
+
*/
|
|
6437
|
+
const createOptionalProxy = (value) => {
|
|
6438
|
+
return new Proxy({}, { get(_, prop) {
|
|
6439
|
+
if (prop === "value") return () => value ?? void 0;
|
|
6440
|
+
if (value == null) return createOptionalProxy(void 0);
|
|
6441
|
+
const result = value[prop];
|
|
6442
|
+
if (typeof result === "function") return (...args) => {
|
|
6443
|
+
try {
|
|
6444
|
+
return createOptionalProxy(result.apply(value, args));
|
|
6445
|
+
} catch {
|
|
6446
|
+
return createOptionalProxy(void 0);
|
|
6447
|
+
}
|
|
6448
|
+
};
|
|
6449
|
+
return createOptionalProxy(result);
|
|
6450
|
+
} });
|
|
6451
|
+
};
|
|
6452
|
+
/**
|
|
6453
|
+
* Provide access to optional objects.
|
|
6454
|
+
*
|
|
6455
|
+
* @param value
|
|
6456
|
+
* @param callback
|
|
6457
|
+
*/
|
|
6458
|
+
const optional = (value, callback) => {
|
|
6459
|
+
if (callback) return value != null ? callback(value) : void 0;
|
|
6460
|
+
return createOptionalProxy(value);
|
|
6461
|
+
};
|
|
6462
|
+
/**
|
|
6463
|
+
* Checks if the givevn value is a class
|
|
6464
|
+
*
|
|
6465
|
+
* @param C
|
|
6466
|
+
*/
|
|
6467
|
+
const isClass = (C) => {
|
|
6468
|
+
return typeof C === "function" && C.prototype !== void 0 && Object.toString.call(C).substring(0, 5) === "class";
|
|
6469
|
+
};
|
|
6470
|
+
/**
|
|
6471
|
+
* Checks if the givevn value is an abstract class
|
|
6472
|
+
*
|
|
6473
|
+
* @param C
|
|
6474
|
+
*/
|
|
6475
|
+
const isAbstract = (C) => {
|
|
6476
|
+
return isClass(C) && C.name.startsWith("I");
|
|
6477
|
+
};
|
|
6478
|
+
/**
|
|
6479
|
+
* Checks if the givevn value is callable
|
|
6480
|
+
*
|
|
6481
|
+
* @param C
|
|
6482
|
+
*/
|
|
6483
|
+
const isCallable = (C) => {
|
|
6484
|
+
return typeof C === "function" && !isClass(C);
|
|
6485
|
+
};
|
|
6486
|
+
|
|
6487
|
+
//#endregion
|
|
6488
|
+
//#region src/Macroable.ts
|
|
6489
|
+
const Macroable = () => trait((Base) => {
|
|
6490
|
+
return class Macroable$1 extends Base {
|
|
6491
|
+
static macros = {};
|
|
6492
|
+
constructor(...args) {
|
|
6493
|
+
super(...args);
|
|
6494
|
+
return new Proxy(this, { get(target, prop, receiver) {
|
|
6495
|
+
if (typeof prop === "string") {
|
|
6496
|
+
const ctor = target.constructor;
|
|
6497
|
+
if (ctor.hasMacro(prop)) return (...args$1) => ctor.macros[prop].apply(receiver, args$1);
|
|
6498
|
+
}
|
|
6499
|
+
return Reflect.get(target, prop, receiver);
|
|
6500
|
+
} });
|
|
6501
|
+
}
|
|
6502
|
+
static macro(name, macro) {
|
|
6503
|
+
this.macros[name] = macro;
|
|
6504
|
+
}
|
|
6505
|
+
static hasMacro(name) {
|
|
6506
|
+
return Object.prototype.hasOwnProperty.call(this.macros, name);
|
|
6507
|
+
}
|
|
6508
|
+
static flushMacros() {
|
|
6509
|
+
this.macros = {};
|
|
6510
|
+
}
|
|
6511
|
+
static mixin(mixin, replace = true) {
|
|
6512
|
+
const proto = Object.getPrototypeOf(mixin);
|
|
6513
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
6514
|
+
if (key === "constructor") continue;
|
|
6515
|
+
const desc = Object.getOwnPropertyDescriptor(proto, key);
|
|
6516
|
+
if (!desc || typeof desc.value !== "function") continue;
|
|
6517
|
+
if (replace || !this.hasMacro(key)) this.macro(key, desc.value.bind(mixin));
|
|
6518
|
+
}
|
|
6519
|
+
}
|
|
6520
|
+
static createProxy() {
|
|
6521
|
+
return new Proxy(this, { get(target, prop, receiver) {
|
|
6522
|
+
if (typeof prop === "string" && target.hasMacro(prop)) return (...args) => target.macros[prop](...args);
|
|
6523
|
+
return Reflect.get(target, prop, receiver);
|
|
6524
|
+
} });
|
|
6525
|
+
}
|
|
6526
|
+
/**
|
|
6527
|
+
* Dynamically handle calls to the class.
|
|
6528
|
+
*
|
|
6529
|
+
* @param method
|
|
6530
|
+
* @param parameters
|
|
6531
|
+
*
|
|
6532
|
+
* @throws {BadMethodCallException}
|
|
6533
|
+
*/
|
|
6534
|
+
static macroCallStatic(method, parameters = []) {
|
|
6535
|
+
if (!Macroable$1.hasMacro(method)) throw new BadMethodCallException(`Method ${Macroable$1.constructor.name}.${method} does not exist.`);
|
|
6536
|
+
let macro = Macroable$1.macros[method];
|
|
6537
|
+
if (typeof macro === "function") macro = macro.bind(this);
|
|
6538
|
+
if (typeof macro === "function") macro = macro.bind(this);
|
|
6539
|
+
return macro(...parameters);
|
|
6540
|
+
}
|
|
6541
|
+
/**
|
|
6542
|
+
* Dynamically handle calls to the class.
|
|
6543
|
+
*
|
|
6544
|
+
* @param method
|
|
6545
|
+
* @param parameters
|
|
6546
|
+
*
|
|
6547
|
+
* @throws {BadMethodCallException}
|
|
6548
|
+
*/
|
|
6549
|
+
macroCall(method, parameters = []) {
|
|
6550
|
+
if (!Macroable$1.hasMacro(method)) throw new BadMethodCallException(`Method ${Macroable$1.constructor.name}.${method} does not exist.`);
|
|
6551
|
+
let macro = Macroable$1.macros[method];
|
|
6552
|
+
if (typeof macro === "function") macro = macro.bind(this);
|
|
6553
|
+
return macro(...parameters);
|
|
6554
|
+
}
|
|
6555
|
+
};
|
|
6556
|
+
});
|
|
6557
|
+
const MacroableClass = Macroable().factory(class {});
|
|
6558
|
+
|
|
6559
|
+
//#endregion
|
|
6560
|
+
//#region src/Providers/ServiceProvider.ts
|
|
6561
|
+
var ServiceProvider = class extends IServiceProvider {
|
|
6562
|
+
/**
|
|
6563
|
+
* The current app instance
|
|
6564
|
+
*/
|
|
6565
|
+
app;
|
|
6566
|
+
/**
|
|
6567
|
+
* Unique Identifier for the service providers
|
|
6568
|
+
*/
|
|
6569
|
+
static uid;
|
|
6570
|
+
/**
|
|
6571
|
+
* Sort order
|
|
6572
|
+
*/
|
|
6573
|
+
static order;
|
|
6574
|
+
/**
|
|
6575
|
+
* Sort priority
|
|
6576
|
+
*/
|
|
6577
|
+
static priority = 0;
|
|
6578
|
+
/**
|
|
6579
|
+
* Indicate that this service provider only runs in console
|
|
6580
|
+
*/
|
|
6581
|
+
static console = false;
|
|
6582
|
+
/**
|
|
6583
|
+
* Indicate that this service provider only runs in console
|
|
6584
|
+
*/
|
|
6585
|
+
console = false;
|
|
6586
|
+
/**
|
|
6587
|
+
* Indicate that this service provider only runs in console
|
|
6588
|
+
*/
|
|
6589
|
+
runsInConsole = false;
|
|
6590
|
+
/**
|
|
6591
|
+
* List of registered console commands
|
|
6592
|
+
*/
|
|
6593
|
+
registeredCommands = [];
|
|
6594
|
+
/**
|
|
6595
|
+
* All of the registered booted callbacks.
|
|
6596
|
+
*/
|
|
6597
|
+
bootedCallbacks = [];
|
|
6598
|
+
constructor(app) {
|
|
6599
|
+
super();
|
|
6600
|
+
this.app = app;
|
|
6601
|
+
}
|
|
6602
|
+
/**
|
|
6603
|
+
* Register a booted callback to be run after the "boot" method is called.
|
|
6604
|
+
*
|
|
6605
|
+
* @param callback
|
|
6606
|
+
*/
|
|
6607
|
+
booted(callback) {
|
|
6608
|
+
this.bootedCallbacks.push(callback);
|
|
6609
|
+
}
|
|
6610
|
+
/**
|
|
6611
|
+
* Call the registered booted callbacks.
|
|
6612
|
+
*/
|
|
6613
|
+
async callBootedCallbacks() {
|
|
6614
|
+
let index = 0;
|
|
6615
|
+
while (index < this.bootedCallbacks.length) {
|
|
6616
|
+
await this.app.call(this.bootedCallbacks[index]);
|
|
6617
|
+
index++;
|
|
6618
|
+
}
|
|
6619
|
+
}
|
|
6620
|
+
/**
|
|
6621
|
+
* Register the listed service providers.
|
|
6622
|
+
*
|
|
6623
|
+
* @param commands An array of console commands to register.
|
|
6624
|
+
*
|
|
6625
|
+
* @deprecated since version 1.16.0. Will be removed in future versions, use `registerCommands` instead
|
|
6626
|
+
*/
|
|
6627
|
+
commands(commands) {
|
|
6628
|
+
this.registerCommands(commands);
|
|
6629
|
+
}
|
|
6630
|
+
/**
|
|
6631
|
+
* Register the listed service providers.
|
|
6632
|
+
*
|
|
6633
|
+
* @param commands An array of console commands to register.
|
|
6634
|
+
*/
|
|
6635
|
+
registerCommands(commands) {
|
|
6636
|
+
this.registeredCommands = commands;
|
|
6637
|
+
}
|
|
6638
|
+
};
|
|
6639
|
+
|
|
6640
|
+
//#endregion
|
|
6641
|
+
//#region ../../node_modules/.pnpm/h3@2.0.1-rc.5/node_modules/h3/dist/h3.mjs
|
|
6642
|
+
const kEventNS = "h3.internal.event.";
|
|
6643
|
+
const kEventRes = /* @__PURE__ */ Symbol.for(`${kEventNS}res`);
|
|
6644
|
+
const kEventResHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.headers`);
|
|
6645
|
+
const DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
|
|
6646
|
+
function sanitizeStatusMessage(statusMessage = "") {
|
|
6647
|
+
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
|
|
6648
|
+
}
|
|
6649
|
+
function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
|
|
6650
|
+
if (!statusCode) return defaultStatusCode;
|
|
6651
|
+
if (typeof statusCode === "string") statusCode = +statusCode;
|
|
6652
|
+
if (statusCode < 100 || statusCode > 599) return defaultStatusCode;
|
|
6653
|
+
return statusCode;
|
|
6654
|
+
}
|
|
6655
|
+
var HTTPError = class HTTPError$1 extends Error {
|
|
6656
|
+
get name() {
|
|
6657
|
+
return "HTTPError";
|
|
6658
|
+
}
|
|
6659
|
+
status;
|
|
6660
|
+
statusText;
|
|
6661
|
+
headers;
|
|
6662
|
+
cause;
|
|
6663
|
+
data;
|
|
6664
|
+
body;
|
|
6665
|
+
unhandled;
|
|
6666
|
+
static isError(input) {
|
|
6667
|
+
return input instanceof Error && input?.name === "HTTPError";
|
|
6668
|
+
}
|
|
6669
|
+
static status(status, statusText, details) {
|
|
6670
|
+
return new HTTPError$1({
|
|
6671
|
+
...details,
|
|
6672
|
+
statusText,
|
|
6673
|
+
status
|
|
6674
|
+
});
|
|
6675
|
+
}
|
|
6676
|
+
constructor(arg1, arg2) {
|
|
6677
|
+
let messageInput;
|
|
6678
|
+
let details;
|
|
6679
|
+
if (typeof arg1 === "string") {
|
|
6680
|
+
messageInput = arg1;
|
|
6681
|
+
details = arg2;
|
|
6682
|
+
} else details = arg1;
|
|
6683
|
+
const status = sanitizeStatusCode(details?.status || (details?.cause)?.status || details?.status || details?.statusCode, 500);
|
|
6684
|
+
const statusText = sanitizeStatusMessage(details?.statusText || (details?.cause)?.statusText || details?.statusText || details?.statusMessage);
|
|
6685
|
+
const message = messageInput || details?.message || (details?.cause)?.message || details?.statusText || details?.statusMessage || [
|
|
6686
|
+
"HTTPError",
|
|
6687
|
+
status,
|
|
6688
|
+
statusText
|
|
6689
|
+
].filter(Boolean).join(" ");
|
|
6690
|
+
super(message, { cause: details });
|
|
6691
|
+
this.cause = details;
|
|
6692
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
6693
|
+
this.status = status;
|
|
6694
|
+
this.statusText = statusText || void 0;
|
|
6695
|
+
const rawHeaders = details?.headers || (details?.cause)?.headers;
|
|
6696
|
+
this.headers = rawHeaders ? new Headers(rawHeaders) : void 0;
|
|
6697
|
+
this.unhandled = details?.unhandled ?? (details?.cause)?.unhandled ?? void 0;
|
|
6698
|
+
this.data = details?.data;
|
|
6699
|
+
this.body = details?.body;
|
|
6700
|
+
}
|
|
6701
|
+
get statusCode() {
|
|
6702
|
+
return this.status;
|
|
6703
|
+
}
|
|
6704
|
+
get statusMessage() {
|
|
6705
|
+
return this.statusText;
|
|
6706
|
+
}
|
|
6707
|
+
toJSON() {
|
|
6708
|
+
const unhandled = this.unhandled;
|
|
6709
|
+
return {
|
|
6710
|
+
status: this.status,
|
|
6711
|
+
statusText: this.statusText,
|
|
6712
|
+
unhandled,
|
|
6713
|
+
message: unhandled ? "HTTPError" : this.message,
|
|
6714
|
+
data: unhandled ? void 0 : this.data,
|
|
6715
|
+
...unhandled ? void 0 : this.body
|
|
6716
|
+
};
|
|
6717
|
+
}
|
|
6718
|
+
};
|
|
6719
|
+
var HTTPResponse = class {
|
|
6720
|
+
#headers;
|
|
6721
|
+
#init;
|
|
6722
|
+
body;
|
|
6723
|
+
constructor(body, init) {
|
|
6724
|
+
this.body = body;
|
|
6725
|
+
this.#init = init;
|
|
6726
|
+
}
|
|
6727
|
+
get status() {
|
|
6728
|
+
return this.#init?.status || 200;
|
|
6729
|
+
}
|
|
6730
|
+
get statusText() {
|
|
6731
|
+
return this.#init?.statusText || "OK";
|
|
6732
|
+
}
|
|
6733
|
+
get headers() {
|
|
6734
|
+
return this.#headers ||= new Headers(this.#init?.headers);
|
|
6735
|
+
}
|
|
6736
|
+
};
|
|
6737
|
+
function withLeadingSlash(path) {
|
|
6738
|
+
if (!path || path === "/") return "/";
|
|
6739
|
+
return path[0] === "/" ? path : `/${path}`;
|
|
6740
|
+
}
|
|
6741
|
+
function withoutTrailingSlash(path) {
|
|
6742
|
+
if (!path || path === "/") return "/";
|
|
6743
|
+
return path[path.length - 1] === "/" ? path.slice(0, -1) : path;
|
|
6744
|
+
}
|
|
6745
|
+
const COMMON_MIME_TYPES = {
|
|
6746
|
+
".html": "text/html",
|
|
6747
|
+
".htm": "text/html",
|
|
6748
|
+
".css": "text/css",
|
|
6749
|
+
".js": "text/javascript",
|
|
6750
|
+
".json": "application/json",
|
|
6751
|
+
".txt": "text/plain",
|
|
6752
|
+
".xml": "application/xml",
|
|
6753
|
+
".gif": "image/gif",
|
|
6754
|
+
".ico": "image/vnd.microsoft.icon",
|
|
6755
|
+
".jpeg": "image/jpeg",
|
|
6756
|
+
".jpg": "image/jpeg",
|
|
6757
|
+
".png": "image/png",
|
|
6758
|
+
".svg": "image/svg+xml",
|
|
6759
|
+
".webp": "image/webp",
|
|
6760
|
+
".woff": "font/woff",
|
|
6761
|
+
".woff2": "font/woff2",
|
|
6762
|
+
".mp4": "video/mp4",
|
|
6763
|
+
".webm": "video/webm",
|
|
6764
|
+
".zip": "application/zip",
|
|
6765
|
+
".pdf": "application/pdf"
|
|
6766
|
+
};
|
|
6767
|
+
function getExtension(path) {
|
|
6768
|
+
const filename = path.split("/").pop();
|
|
6769
|
+
if (!filename) return;
|
|
6770
|
+
const separatorIndex = filename.lastIndexOf(".");
|
|
6771
|
+
if (separatorIndex !== -1) return filename.slice(separatorIndex);
|
|
6772
|
+
}
|
|
6773
|
+
function getType(ext) {
|
|
6774
|
+
return ext ? COMMON_MIME_TYPES[ext] : void 0;
|
|
6775
|
+
}
|
|
6776
|
+
async function serveStatic(event, options) {
|
|
6777
|
+
if (options.headers) {
|
|
6778
|
+
const entries = Array.isArray(options.headers) ? options.headers : typeof options.headers.entries === "function" ? options.headers.entries() : Object.entries(options.headers);
|
|
6779
|
+
for (const [key, value] of entries) event.res.headers.set(key, value);
|
|
6780
|
+
}
|
|
6781
|
+
if (event.req.method !== "GET" && event.req.method !== "HEAD") {
|
|
6782
|
+
if (options.fallthrough) return;
|
|
6783
|
+
event.res.headers.set("allow", "GET, HEAD");
|
|
6784
|
+
throw new HTTPError({ status: 405 });
|
|
6785
|
+
}
|
|
6786
|
+
const originalId = decodeURI(withLeadingSlash(withoutTrailingSlash(event.url.pathname)));
|
|
6787
|
+
const acceptEncodings = parseAcceptEncoding(event.req.headers.get("accept-encoding") || "", options.encodings);
|
|
6788
|
+
if (acceptEncodings.length > 1) event.res.headers.set("vary", "accept-encoding");
|
|
6789
|
+
let id = originalId;
|
|
6790
|
+
let meta;
|
|
6791
|
+
const _ids = idSearchPaths(originalId, acceptEncodings, options.indexNames || ["/index.html"]);
|
|
6792
|
+
for (const _id of _ids) {
|
|
6793
|
+
const _meta = await options.getMeta(_id);
|
|
6794
|
+
if (_meta) {
|
|
6795
|
+
meta = _meta;
|
|
6796
|
+
id = _id;
|
|
6797
|
+
break;
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
if (!meta) {
|
|
6801
|
+
if (options.fallthrough) return;
|
|
6802
|
+
throw new HTTPError({ statusCode: 404 });
|
|
6803
|
+
}
|
|
6804
|
+
if (meta.mtime) {
|
|
6805
|
+
const mtimeDate = new Date(meta.mtime);
|
|
6806
|
+
const ifModifiedSinceH = event.req.headers.get("if-modified-since");
|
|
6807
|
+
if (ifModifiedSinceH && new Date(ifModifiedSinceH) >= mtimeDate) return new HTTPResponse(null, {
|
|
6808
|
+
status: 304,
|
|
6809
|
+
statusText: "Not Modified"
|
|
6810
|
+
});
|
|
6811
|
+
if (!event.res.headers.get("last-modified")) event.res.headers.set("last-modified", mtimeDate.toUTCString());
|
|
6812
|
+
}
|
|
6813
|
+
if (meta.etag && !event.res.headers.has("etag")) event.res.headers.set("etag", meta.etag);
|
|
6814
|
+
if (meta.etag && event.req.headers.get("if-none-match") === meta.etag) return new HTTPResponse(null, {
|
|
6815
|
+
status: 304,
|
|
6816
|
+
statusText: "Not Modified"
|
|
6817
|
+
});
|
|
6818
|
+
if (!event.res.headers.get("content-type")) if (meta.type) event.res.headers.set("content-type", meta.type);
|
|
6819
|
+
else {
|
|
6820
|
+
const ext = getExtension(id);
|
|
6821
|
+
const type = ext ? options.getType?.(ext) ?? getType(ext) : void 0;
|
|
6822
|
+
if (type) event.res.headers.set("content-type", type);
|
|
6823
|
+
}
|
|
6824
|
+
if (meta.encoding && !event.res.headers.get("content-encoding")) event.res.headers.set("content-encoding", meta.encoding);
|
|
6825
|
+
if (meta.size !== void 0 && meta.size > 0 && !event.req.headers.get("content-length")) event.res.headers.set("content-length", meta.size + "");
|
|
6826
|
+
if (event.req.method === "HEAD") return new HTTPResponse(null, { status: 200 });
|
|
6827
|
+
return new HTTPResponse(await options.getContents(id) || null, { status: 200 });
|
|
6828
|
+
}
|
|
6829
|
+
function parseAcceptEncoding(header, encodingMap) {
|
|
6830
|
+
if (!encodingMap || !header) return [];
|
|
6831
|
+
return String(header || "").split(",").map((e) => encodingMap[e.trim()]).filter(Boolean);
|
|
6832
|
+
}
|
|
6833
|
+
function idSearchPaths(id, encodings, indexNames) {
|
|
6834
|
+
const ids = [];
|
|
6835
|
+
for (const suffix of ["", ...indexNames]) for (const encoding of [...encodings, ""]) ids.push(`${id}${suffix}${encoding}`);
|
|
6836
|
+
return ids;
|
|
6837
|
+
}
|
|
6838
|
+
|
|
6839
|
+
//#endregion
|
|
6840
|
+
//#region src/Providers/AssetsServiceProvider.ts
|
|
6841
|
+
/**
|
|
6842
|
+
* Handles public assets loading
|
|
6843
|
+
*
|
|
6844
|
+
* Auto-Registered
|
|
6845
|
+
*/
|
|
6846
|
+
var AssetsServiceProvider = class extends ServiceProvider {
|
|
6847
|
+
static priority = 996;
|
|
6848
|
+
register() {
|
|
6849
|
+
const app = this.app.make("router");
|
|
6850
|
+
const publicPath = this.app.getPath("public");
|
|
6851
|
+
/**
|
|
6852
|
+
* Use a middleware to check if this request for for a file
|
|
6853
|
+
*/
|
|
6854
|
+
app.h3middleware((event) => {
|
|
6855
|
+
const { pathname } = new URL(event.req.url);
|
|
6856
|
+
/**
|
|
6857
|
+
* Only serve if it looks like a static asset (has an extension)
|
|
6858
|
+
* but skip dotfiles or sensitive files
|
|
6859
|
+
*/
|
|
6860
|
+
if (!/\.[a-zA-Z0-9]+$/.test(pathname)) return;
|
|
6861
|
+
if (pathname.startsWith("/.") || pathname.includes("..")) return;
|
|
6862
|
+
/**
|
|
6863
|
+
* Serve the asset
|
|
6864
|
+
*/
|
|
6865
|
+
return serveStatic(event, {
|
|
6866
|
+
indexNames: ["/index.html"],
|
|
6867
|
+
getContents: (id) => {
|
|
6868
|
+
return readFile(join(Str.before(publicPath, id), id));
|
|
6869
|
+
},
|
|
6870
|
+
getMeta: async (id) => {
|
|
6871
|
+
const stats = await stat(join(Str.before(publicPath, id), id)).catch(() => {});
|
|
6872
|
+
if (stats?.isFile()) return {
|
|
6873
|
+
size: stats.size,
|
|
6874
|
+
mtime: stats.mtimeMs
|
|
6875
|
+
};
|
|
6876
|
+
}
|
|
6877
|
+
});
|
|
6878
|
+
});
|
|
6879
|
+
this.app.singleton("asset", () => {
|
|
6880
|
+
return (key, def) => {
|
|
6881
|
+
if (def) try {
|
|
6882
|
+
statSync(join(Str.before(publicPath, key), key));
|
|
6883
|
+
} catch {
|
|
6884
|
+
key = def;
|
|
6885
|
+
}
|
|
6886
|
+
return key;
|
|
6887
|
+
};
|
|
6888
|
+
});
|
|
6889
|
+
}
|
|
6890
|
+
};
|
|
6891
|
+
|
|
6892
|
+
//#endregion
|
|
6893
|
+
//#region src/Providers/RouteServiceProvider.ts
|
|
6894
|
+
/**
|
|
6895
|
+
* Handles routing registration
|
|
6896
|
+
*
|
|
6897
|
+
* Load route files (web.ts, api.ts).
|
|
6898
|
+
* Map controllers to routes.
|
|
6899
|
+
* Register route-related middleware.
|
|
6900
|
+
*/
|
|
6901
|
+
var RouteServiceProvider = class RouteServiceProvider extends ServiceProvider {
|
|
6902
|
+
static priority = 997;
|
|
6903
|
+
/**
|
|
6904
|
+
* The callback that should be used to load the application's routes.
|
|
6905
|
+
*/
|
|
6906
|
+
loadRoutesUsing;
|
|
6907
|
+
/**
|
|
6908
|
+
* The global callback that should be used to load the application's routes.
|
|
6909
|
+
*/
|
|
6910
|
+
static alwaysLoadRoutesUsing;
|
|
6911
|
+
async register() {
|
|
6912
|
+
const { RouteListCommand, Router, SubstituteBindings } = await import("@h3ravel/router");
|
|
6913
|
+
this.app.bindMiddleware("SubstituteBindings", SubstituteBindings);
|
|
6914
|
+
this.booted(() => {
|
|
6915
|
+
const router$1 = this.app.make(IRouter);
|
|
6916
|
+
if (typeof router$1.getRoutes === "function") {
|
|
6917
|
+
router$1.getRoutes().refreshActionLookups();
|
|
6918
|
+
router$1.getRoutes().refreshNameLookups();
|
|
6919
|
+
}
|
|
6920
|
+
});
|
|
6921
|
+
const router = () => {
|
|
6922
|
+
try {
|
|
6923
|
+
return new Router(this.app.make("http.app"), this.app);
|
|
6924
|
+
} catch (error) {
|
|
6925
|
+
if (String(error.message).includes("http.app")) Logger.log([
|
|
6926
|
+
["The", "white"],
|
|
6927
|
+
["@h3ravel/http", ["italic", "gray"]],
|
|
6928
|
+
["package is required to use the routing system.", "white"]
|
|
6929
|
+
], " ");
|
|
6930
|
+
else Logger.log(error, "white");
|
|
6931
|
+
}
|
|
6932
|
+
return {};
|
|
6933
|
+
};
|
|
6934
|
+
this.app.singleton("router", router);
|
|
6935
|
+
this.app.alias(Router, "router");
|
|
6936
|
+
this.app.alias(IRouter, "router");
|
|
6937
|
+
this.registerCommands([RouteListCommand]);
|
|
6938
|
+
}
|
|
6939
|
+
/**
|
|
6940
|
+
* Load routes from src/routes
|
|
6941
|
+
*/
|
|
6942
|
+
async boot() {
|
|
6943
|
+
await this.loadRoutes();
|
|
6944
|
+
}
|
|
6945
|
+
/**
|
|
6946
|
+
* Register the callback that will be used to load the application's routes.
|
|
6947
|
+
*
|
|
6948
|
+
* @param routesCallback
|
|
6949
|
+
*/
|
|
6950
|
+
routes(routesCallback) {
|
|
6951
|
+
this.loadRoutesUsing = routesCallback;
|
|
6952
|
+
return this;
|
|
6953
|
+
}
|
|
6954
|
+
/**
|
|
6955
|
+
* Register the callback that will be used to load the application's routes.
|
|
6956
|
+
*
|
|
6957
|
+
* @param routesCallback
|
|
6958
|
+
*/
|
|
6959
|
+
static loadRoutesUsing(routesCallback) {
|
|
6960
|
+
this.alwaysLoadRoutesUsing = routesCallback;
|
|
6961
|
+
}
|
|
6962
|
+
/**
|
|
6963
|
+
* Load the application routes.
|
|
6964
|
+
*/
|
|
6965
|
+
async loadRoutes() {
|
|
6966
|
+
if (RouteServiceProvider.alwaysLoadRoutesUsing != null) this.app.call(RouteServiceProvider.alwaysLoadRoutesUsing);
|
|
6967
|
+
if (this.loadRoutesUsing != null) this.app.call(this.loadRoutesUsing);
|
|
6968
|
+
else if (typeof this["map"] === "function") this.app.call(this["map"]);
|
|
6969
|
+
}
|
|
6970
|
+
};
|
|
6971
|
+
|
|
6972
|
+
//#endregion
|
|
6973
|
+
//#region src/Tappable.ts
|
|
6974
|
+
const Tappable = (Base) => {
|
|
6975
|
+
return class extends Base {
|
|
6976
|
+
/**
|
|
6977
|
+
* Call the given Closure with this instance then return the instance.
|
|
6978
|
+
*
|
|
6979
|
+
* @param callback
|
|
6980
|
+
*/
|
|
6981
|
+
tap(callback) {
|
|
6982
|
+
return tap(this, callback);
|
|
6983
|
+
}
|
|
6984
|
+
};
|
|
6985
|
+
};
|
|
6986
|
+
|
|
6987
|
+
//#endregion
|
|
6988
|
+
export { Arr, AssetsServiceProvider, BadMethodCallException, Collection, Crypto_exports as Crypto, DateTime, HigherOrderTapProxy, HtmlString, InvalidArgumentException, Macroable, MacroableClass, Mode, Number_exports as Number, Obj, RouteServiceProvider, RuntimeException, ServiceProvider, Str, Stringable, Tappable, abbreviate, base64Decode, base64Encode, caesarCipher, checksum, cleanHelpers, collect, createOptionalProxy, data_fill, data_forget, data_get, data_set, dd, dot, dump, extractProperties, format, getValue, hash, hmac, humanize, isAbstract, isCallable, isClass, isPlainObject, loadHelpers, modObj, optional, random, randomColor, randomPassword, randomSecure, safeDot, secureToken, setNested, slugifyKeys, str, tap, toBytes, toCssClasses, toCssStyles, toHumanTime, undot, uuid, verifyChecksum, xor };
|