@rzl-zone/utils-js 3.13.1-beta.0 → 3.14.0-beta.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/README.md +7 -6
- package/dist/.references/index.d.cts +2 -1
- package/dist/.references/index.d.ts +2 -1
- package/dist/AbortError-DK6kpzbu.cjs +26 -0
- package/dist/AbortError-DK6kpzbu.cjs.map +1 -0
- package/dist/AbortError-DVT8lAKn.js +20 -0
- package/dist/AbortError-DVT8lAKn.js.map +1 -0
- package/dist/{assertIsArray-DrLORH0Y.js → assertIsArray-CG7L7vlt.js} +3 -3
- package/dist/assertIsArray-CG7L7vlt.js.map +1 -0
- package/dist/{assertIsArray-CqIFmlgj.cjs → assertIsArray-CtCRD-_G.cjs} +5 -5
- package/dist/assertIsArray-CtCRD-_G.cjs.map +1 -0
- package/dist/assertIsPlainObject-DPZLj-Ho.cjs +26 -0
- package/dist/assertIsPlainObject-DPZLj-Ho.cjs.map +1 -0
- package/dist/assertIsPlainObject-j9bDqNLo.js +20 -0
- package/dist/assertIsPlainObject-j9bDqNLo.js.map +1 -0
- package/dist/{assertIsString-1iLqxrN0.js → assertIsString-CHIwE12y.js} +4 -4
- package/dist/assertIsString-CHIwE12y.js.map +1 -0
- package/dist/{assertIsString-DGDLC-XD.cjs → assertIsString-CjE9kbQ_.cjs} +6 -6
- package/dist/assertIsString-CjE9kbQ_.cjs.map +1 -0
- package/dist/assertions/index.cjs +14 -12
- package/dist/assertions/index.cjs.map +1 -1
- package/dist/assertions/index.d.cts +2 -2
- package/dist/assertions/index.d.ts +2 -2
- package/dist/assertions/index.js +10 -8
- package/dist/assertions/index.js.map +1 -1
- package/dist/conversions/index.cjs +6 -6
- package/dist/conversions/index.d.cts +2 -2
- package/dist/conversions/index.d.ts +2 -2
- package/dist/conversions/index.js +6 -6
- package/dist/conversions-BFz6MKaV.cjs +449 -0
- package/dist/conversions-BFz6MKaV.cjs.map +1 -0
- package/dist/{conversions-CA_3PTAH.js → conversions-Ben5p5Ts.js} +43 -40
- package/dist/conversions-Ben5p5Ts.js.map +1 -0
- package/dist/errors/index.cjs +13 -0
- package/dist/errors/index.d.cts +180 -0
- package/dist/errors/index.d.ts +180 -0
- package/dist/errors/index.js +11 -0
- package/dist/events/index.cjs +10 -9
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +185 -100
- package/dist/events/index.d.ts +185 -100
- package/dist/events/index.js +9 -8
- package/dist/events/index.js.map +1 -1
- package/dist/formatter-ekJQF_bA-BepnCBkQ.cjs +67 -0
- package/dist/formatter-ekJQF_bA-BepnCBkQ.cjs.map +1 -0
- package/dist/formatter-ekJQF_bA-xLD9mGk4.js +55 -0
- package/dist/formatter-ekJQF_bA-xLD9mGk4.js.map +1 -0
- package/dist/formatters/index.cjs +2 -2
- package/dist/formatters/index.d.cts +2 -2
- package/dist/formatters/index.d.ts +2 -2
- package/dist/formatters/index.js +2 -2
- package/dist/{formatters-Bm3a_akj.js → formatters-BAbGsnYA.js} +78 -71
- package/dist/formatters-BAbGsnYA.js.map +1 -0
- package/dist/formatters-zd0Gs4Cs.cjs +436 -0
- package/dist/formatters-zd0Gs4Cs.cjs.map +1 -0
- package/dist/generators/index.cjs +37 -31
- package/dist/generators/index.cjs.map +1 -1
- package/dist/generators/index.d.cts +2 -2
- package/dist/generators/index.d.ts +2 -2
- package/dist/generators/index.js +29 -23
- package/dist/generators/index.js.map +1 -1
- package/dist/hasOwnProp-CVIhlD1i.js +47 -0
- package/dist/hasOwnProp-CVIhlD1i.js.map +1 -0
- package/dist/hasOwnProp-D9Tpgokd.cjs +53 -0
- package/dist/hasOwnProp-D9Tpgokd.cjs.map +1 -0
- package/dist/{index-CakviK5E.d.cts → index-9JsU_wMu.d.ts} +1375 -937
- package/dist/{index-BqkYm8qT.d.ts → index-BP3sUrAx.d.ts} +242 -133
- package/dist/{index-CJx0EFQ4.d.cts → index-BVovC-yK.d.cts} +229 -200
- package/dist/index-C1X6ha9s.d.cts +1041 -0
- package/dist/index-CcPQZ41G.d.cts +1103 -0
- package/dist/index-CjpbuJF4.d.ts +2424 -0
- package/dist/index-CssrQyHh.d.cts +2424 -0
- package/dist/index-DZHiYYR7.d.cts +2179 -0
- package/dist/index-DZHiYYR7.d.ts +2179 -0
- package/dist/index-DlyDmXUo.d.ts +1103 -0
- package/dist/index-Dm4a___O.d.ts +1041 -0
- package/dist/{index-D5nTp1kV.d.ts → index-Dwduk7ez.d.cts} +1375 -937
- package/dist/{index-uaHl0X-r.d.cts → index-I5V6RbZM.d.cts} +1592 -790
- package/dist/{index-Bm5odgLW.d.ts → index-hOqBIL7F.d.ts} +1592 -790
- package/dist/{index-hOCUw-B9.d.ts → index-jyuOZMX7.d.ts} +229 -200
- package/dist/{index-BqkYm8qT.d.cts → index-lI0b7iUz.d.cts} +242 -133
- package/dist/{isBigInt-f6yY2fAV.js → isBigInt-Cez32M69.js} +2 -2
- package/dist/isBigInt-Cez32M69.js.map +1 -0
- package/dist/{isBigInt-CqZNWVtI.cjs → isBigInt-YgpNKTbA.cjs} +2 -2
- package/dist/isBigInt-YgpNKTbA.cjs.map +1 -0
- package/dist/{isEmptyString-Ga77_3Q1.js → isEmptyString-C9QLWjx2.js} +4 -4
- package/dist/isEmptyString-C9QLWjx2.js.map +1 -0
- package/dist/{isEmptyString-DNMPmS-H.cjs → isEmptyString-O4TFe1Ao.cjs} +5 -5
- package/dist/isEmptyString-O4TFe1Ao.cjs.map +1 -0
- package/dist/isEmptyValue-CFExALXZ.cjs +54 -0
- package/dist/isEmptyValue-CFExALXZ.cjs.map +1 -0
- package/dist/isEmptyValue-kCjnLjbN.js +36 -0
- package/dist/isEmptyValue-kCjnLjbN.js.map +1 -0
- package/dist/{isFinite-Crw95XV8.cjs → isFinite-B_hHbDpa.cjs} +6 -6
- package/dist/isFinite-B_hHbDpa.cjs.map +1 -0
- package/dist/{isFinite-BJO7Dt6B.js → isFinite-ZvNhyHlF.js} +5 -5
- package/dist/isFinite-ZvNhyHlF.js.map +1 -0
- package/dist/{isInteger-B75voxys.js → isInteger-aZgzTTZG.js} +4 -4
- package/dist/isInteger-aZgzTTZG.js.map +1 -0
- package/dist/{isInteger-CSMNm--9.cjs → isInteger-dnc6W63Z.cjs} +4 -4
- package/dist/isInteger-dnc6W63Z.cjs.map +1 -0
- package/dist/isNumber-BCWD4dW0.js +20 -0
- package/dist/isNumber-BCWD4dW0.js.map +1 -0
- package/dist/isNumber-BkzwAe50.cjs +26 -0
- package/dist/isNumber-BkzwAe50.cjs.map +1 -0
- package/dist/isPlainObject-CAe_ElKO.d.cts +331 -0
- package/dist/isPlainObject-CJvRG4Je.d.ts +331 -0
- package/dist/{isServer-BHOSvBhV.js → isServer-CQzrX5e0.js} +2 -2
- package/dist/isServer-CQzrX5e0.js.map +1 -0
- package/dist/{isServer-HA13Dzo2.cjs → isServer-DhFaedeT.cjs} +2 -2
- package/dist/isServer-DhFaedeT.cjs.map +1 -0
- package/dist/{isEqual-D8W3Wizi.cjs → isTypedArray-DjADSu8q.cjs} +45 -13
- package/dist/isTypedArray-DjADSu8q.cjs.map +1 -0
- package/dist/{isEqual-ekId-j5b.js → isTypedArray-DxsPKrLh.js} +29 -9
- package/dist/isTypedArray-DxsPKrLh.js.map +1 -0
- package/dist/{isValidDomain-BqyLVi7S.js → isValidDomain-CDtNOhMc.js} +13 -54
- package/dist/isValidDomain-CDtNOhMc.js.map +1 -0
- package/dist/{isValidDomain-ByrOfQsh.cjs → isValidDomain-D_x7uNIu.cjs} +16 -69
- package/dist/isValidDomain-D_x7uNIu.cjs.map +1 -0
- package/dist/{assertIsBoolean-DDhQ2D-k.js → logger-CLWnKRKE.js} +657 -587
- package/dist/logger-CLWnKRKE.js.map +1 -0
- package/dist/{assertIsBoolean-CEx4KbHg.cjs → logger-CUacYy3D.cjs} +658 -612
- package/dist/logger-CUacYy3D.cjs.map +1 -0
- package/dist/{noop-CkwxErJ2.cjs → noop-CjEbNsJL.cjs} +2 -2
- package/dist/noop-CjEbNsJL.cjs.map +1 -0
- package/dist/{noop-D_Ots__Z.js → noop-qxrcogt5.js} +2 -2
- package/dist/noop-qxrcogt5.js.map +1 -0
- package/dist/{normalizeSpaces-88yaixiu.cjs → normalizeSpaces-D0_Z4qnO.cjs} +6 -9
- package/dist/normalizeSpaces-D0_Z4qnO.cjs.map +1 -0
- package/dist/{normalizeSpaces-Cat8CHtt.js → normalizeSpaces-DAsxzBEQ.js} +4 -7
- package/dist/normalizeSpaces-DAsxzBEQ.js.map +1 -0
- package/dist/operations/index.cjs +152 -22
- package/dist/operations/index.cjs.map +1 -1
- package/dist/operations/index.d.cts +257 -35
- package/dist/operations/index.d.ts +257 -35
- package/dist/operations/index.js +142 -13
- package/dist/operations/index.js.map +1 -1
- package/dist/parsers/index.cjs +2 -2
- package/dist/parsers/index.d.cts +238 -180
- package/dist/parsers/index.d.ts +238 -180
- package/dist/parsers/index.js +2 -2
- package/dist/{parsers-BLHzVoh-.js → parsers-BBAE_xVM.js} +9 -8
- package/dist/parsers-BBAE_xVM.js.map +1 -0
- package/dist/{parsers-xAQmKCgS.cjs → parsers-i8WEeMJl.cjs} +10 -9
- package/dist/parsers-i8WEeMJl.cjs.map +1 -0
- package/dist/{parsing-BYo6U0EG.js → parsing-D9tbKQ0v.js} +3 -3
- package/dist/parsing-D9tbKQ0v.js.map +1 -0
- package/dist/{parsing-CuezVd0e.cjs → parsing-DGjB8cwr.cjs} +4 -4
- package/dist/parsing-DGjB8cwr.cjs.map +1 -0
- package/dist/predicates/index.cjs +43 -43
- package/dist/predicates/index.d.cts +3 -3
- package/dist/predicates/index.d.ts +3 -3
- package/dist/predicates/index.js +14 -14
- package/dist/{predicates-BMTIIYx8.js → predicates-C0dova7l.js} +45 -40
- package/dist/predicates-C0dova7l.js.map +1 -0
- package/dist/{predicates-ZmZpelMh.cjs → predicates-Dd7To7B4.cjs} +89 -84
- package/dist/predicates-Dd7To7B4.cjs.map +1 -0
- package/dist/promises/index.cjs +27 -26
- package/dist/promises/index.cjs.map +1 -1
- package/dist/promises/index.d.cts +227 -75
- package/dist/promises/index.d.ts +227 -75
- package/dist/promises/index.js +27 -26
- package/dist/promises/index.js.map +1 -1
- package/dist/{punyCode-WZ6-GaTM.cjs → punyCode-DHTLhGdD.cjs} +12 -12
- package/dist/punyCode-DHTLhGdD.cjs.map +1 -0
- package/dist/{punyCode-COTqgXMJ.js → punyCode-Deb1Mrkc.js} +12 -12
- package/dist/punyCode-Deb1Mrkc.js.map +1 -0
- package/dist/{removeSpaces-CQJvw1yU.js → removeSpaces-BPnsdRN0.js} +4 -4
- package/dist/removeSpaces-BPnsdRN0.js.map +1 -0
- package/dist/{removeSpaces-BeGkktUl.cjs → removeSpaces-CN3pxBz_.cjs} +7 -7
- package/dist/removeSpaces-CN3pxBz_.cjs.map +1 -0
- package/dist/rzl-utils.global.js +13 -13
- package/dist/safeJsonParse-D1FLVTEM.cjs +209 -0
- package/dist/safeJsonParse-D1FLVTEM.cjs.map +1 -0
- package/dist/{safeJsonParse-D8H3wCv7.js → safeJsonParse-DEVKNDSn.js} +29 -28
- package/dist/safeJsonParse-DEVKNDSn.js.map +1 -0
- package/dist/safeStableStringify-C5HHKUdn.cjs +125 -0
- package/dist/safeStableStringify-C5HHKUdn.cjs.map +1 -0
- package/dist/{safeStableStringify-BLwA1VC-.js → safeStableStringify-DfwxmiWn.js} +20 -13
- package/dist/safeStableStringify-DfwxmiWn.js.map +1 -0
- package/dist/strings/index.cjs +26 -30
- package/dist/strings/index.cjs.map +1 -1
- package/dist/strings/index.d.cts +2 -2
- package/dist/strings/index.d.ts +2 -2
- package/dist/strings/index.js +13 -17
- package/dist/strings/index.js.map +1 -1
- package/dist/tailwind/index.cjs +3 -3
- package/dist/tailwind/index.d.cts +3 -3
- package/dist/tailwind/index.d.ts +3 -3
- package/dist/tailwind/index.js +3 -3
- package/dist/{tailwind-CjxdO7aL.cjs → tailwind-BG7B0cDs.cjs} +59 -53
- package/dist/tailwind-BG7B0cDs.cjs.map +1 -0
- package/dist/{tailwind-RSE3obLb.js → tailwind-tJNnFPsF.js} +38 -32
- package/dist/tailwind-tJNnFPsF.js.map +1 -0
- package/dist/{toStringArrayUnRecursive-NreW1dyV.js → toStringArrayUnRecursive-D0WbLIRz.js} +9 -9
- package/dist/toStringArrayUnRecursive-D0WbLIRz.js.map +1 -0
- package/dist/toStringArrayUnRecursive-QLoaNX_-.cjs +51 -0
- package/dist/toStringArrayUnRecursive-QLoaNX_-.cjs.map +1 -0
- package/dist/urls/index.cjs +3 -3
- package/dist/urls/index.d.cts +635 -443
- package/dist/urls/index.d.ts +635 -443
- package/dist/urls/index.js +3 -3
- package/dist/{urls-CLVfEB7O.js → urls-EoWslGgg.js} +50 -41
- package/dist/urls-EoWslGgg.js.map +1 -0
- package/dist/urls-NCzPepe2.cjs +308 -0
- package/dist/urls-NCzPepe2.cjs.map +1 -0
- package/package.json +6 -6
- package/dist/assertIsArray-CqIFmlgj.cjs.map +0 -1
- package/dist/assertIsArray-DrLORH0Y.js.map +0 -1
- package/dist/assertIsBoolean-CEx4KbHg.cjs.map +0 -1
- package/dist/assertIsBoolean-DDhQ2D-k.js.map +0 -1
- package/dist/assertIsString-1iLqxrN0.js.map +0 -1
- package/dist/assertIsString-DGDLC-XD.cjs.map +0 -1
- package/dist/conversions-Bxa01uIl.cjs +0 -446
- package/dist/conversions-Bxa01uIl.cjs.map +0 -1
- package/dist/conversions-CA_3PTAH.js.map +0 -1
- package/dist/formatters-Bm3a_akj.js.map +0 -1
- package/dist/formatters-Bt6QuhxK.cjs +0 -429
- package/dist/formatters-Bt6QuhxK.cjs.map +0 -1
- package/dist/index--h04HuBE.d.cts +0 -765
- package/dist/index--h04HuBE.d.ts +0 -765
- package/dist/index-Ap8U-8Qx.d.cts +0 -947
- package/dist/index-BAeeggeh.d.cts +0 -1716
- package/dist/index-BAeeggeh.d.ts +0 -1716
- package/dist/index-CMglhpFG.d.ts +0 -947
- package/dist/isBigInt-CqZNWVtI.cjs.map +0 -1
- package/dist/isBigInt-f6yY2fAV.js.map +0 -1
- package/dist/isEmptyObject-BYNnSKzw.js +0 -25
- package/dist/isEmptyObject-BYNnSKzw.js.map +0 -1
- package/dist/isEmptyObject-C2lQyFZS.cjs +0 -37
- package/dist/isEmptyObject-C2lQyFZS.cjs.map +0 -1
- package/dist/isEmptyString-DNMPmS-H.cjs.map +0 -1
- package/dist/isEmptyString-Ga77_3Q1.js.map +0 -1
- package/dist/isEmptyValue-D7-6WWS9.js +0 -24
- package/dist/isEmptyValue-D7-6WWS9.js.map +0 -1
- package/dist/isEmptyValue-DZaDHEIw.cjs +0 -30
- package/dist/isEmptyValue-DZaDHEIw.cjs.map +0 -1
- package/dist/isEqual-D8W3Wizi.cjs.map +0 -1
- package/dist/isEqual-ekId-j5b.js.map +0 -1
- package/dist/isFinite-BJO7Dt6B.js.map +0 -1
- package/dist/isFinite-Crw95XV8.cjs.map +0 -1
- package/dist/isInteger-B75voxys.js.map +0 -1
- package/dist/isInteger-CSMNm--9.cjs.map +0 -1
- package/dist/isPlainObject-ByfuseCf.d.cts +0 -339
- package/dist/isPlainObject-ByfuseCf.d.ts +0 -339
- package/dist/isServer-BHOSvBhV.js.map +0 -1
- package/dist/isServer-HA13Dzo2.cjs.map +0 -1
- package/dist/isTypedArray-CWlHRz_O.cjs +0 -43
- package/dist/isTypedArray-CWlHRz_O.cjs.map +0 -1
- package/dist/isTypedArray-CmnQ7Yx9.js +0 -31
- package/dist/isTypedArray-CmnQ7Yx9.js.map +0 -1
- package/dist/isValidDomain-BqyLVi7S.js.map +0 -1
- package/dist/isValidDomain-ByrOfQsh.cjs.map +0 -1
- package/dist/noop-CkwxErJ2.cjs.map +0 -1
- package/dist/noop-D_Ots__Z.js.map +0 -1
- package/dist/normalizeSpaces-88yaixiu.cjs.map +0 -1
- package/dist/normalizeSpaces-Cat8CHtt.js.map +0 -1
- package/dist/parsers-BLHzVoh-.js.map +0 -1
- package/dist/parsers-xAQmKCgS.cjs.map +0 -1
- package/dist/parsing-BYo6U0EG.js.map +0 -1
- package/dist/parsing-CuezVd0e.cjs.map +0 -1
- package/dist/predicates-BMTIIYx8.js.map +0 -1
- package/dist/predicates-ZmZpelMh.cjs.map +0 -1
- package/dist/punyCode-COTqgXMJ.js.map +0 -1
- package/dist/punyCode-WZ6-GaTM.cjs.map +0 -1
- package/dist/removeSpaces-BeGkktUl.cjs.map +0 -1
- package/dist/removeSpaces-CQJvw1yU.js.map +0 -1
- package/dist/safeJsonParse-BznDD3fi.cjs +0 -208
- package/dist/safeJsonParse-BznDD3fi.cjs.map +0 -1
- package/dist/safeJsonParse-D8H3wCv7.js.map +0 -1
- package/dist/safeStableStringify-4b-E_UHM.cjs +0 -106
- package/dist/safeStableStringify-4b-E_UHM.cjs.map +0 -1
- package/dist/safeStableStringify-BLwA1VC-.js.map +0 -1
- package/dist/tailwind-CjxdO7aL.cjs.map +0 -1
- package/dist/tailwind-RSE3obLb.js.map +0 -1
- package/dist/toStringArrayUnRecursive-D-jHROts.cjs +0 -51
- package/dist/toStringArrayUnRecursive-D-jHROts.cjs.map +0 -1
- package/dist/toStringArrayUnRecursive-NreW1dyV.js.map +0 -1
- package/dist/urls-C6BvhrrV.cjs +0 -299
- package/dist/urls-C6BvhrrV.cjs.map +0 -1
- package/dist/urls-CLVfEB7O.js.map +0 -1
package/dist/urls/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ========================================================================
|
|
3
3
|
* @rzl-zone/utils-js
|
|
4
4
|
* ------------------------------------------------------------------------
|
|
5
|
-
* Version: `3.
|
|
5
|
+
* Version: `3.14.0-beta.0`
|
|
6
6
|
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
7
|
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
8
|
* ========================================================================
|
|
@@ -11,95 +11,138 @@
|
|
|
11
11
|
* * ***Type-Utility: `QueryParamPairs`.***
|
|
12
12
|
* ----------------------------------------------------------
|
|
13
13
|
* **Represents a non-empty array of key–value pairs.**
|
|
14
|
+
*
|
|
15
|
+
* ---
|
|
14
16
|
* @description
|
|
15
17
|
* Type for `queryParams` parameter, the second parameter of ***`constructURL` utility function***.
|
|
18
|
+
*
|
|
19
|
+
* ---
|
|
16
20
|
* - **Behavior:**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
21
|
+
* - Each inner tuple strictly follows the `[string, string | number]` shape.
|
|
22
|
+
* - Ensures the outer array contains **at least one pair** (non-empty).
|
|
23
|
+
* - Commonly used for URL construction parameters,
|
|
20
24
|
* query string segments, or other key–value structured data.
|
|
25
|
+
*
|
|
26
|
+
* ---
|
|
21
27
|
* @example
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* ]
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
28
|
+
* 1. #### Valid usage:
|
|
29
|
+
* ```ts
|
|
30
|
+
* const params: QueryParamPairs = [
|
|
31
|
+
* ["foo", 1],
|
|
32
|
+
* ["bar", "baz"]
|
|
33
|
+
* ];
|
|
34
|
+
* constructURL("https://example.com", params);
|
|
35
|
+
* ```
|
|
36
|
+
* ---
|
|
37
|
+
* 2. #### Invalid: must contain at least one item:
|
|
38
|
+
* ```ts
|
|
39
|
+
* const empty: QueryParamPairs = [];
|
|
40
|
+
* ```
|
|
41
|
+
* ---
|
|
42
|
+
* 3. #### Invalid: key without value pairs:
|
|
43
|
+
* ```ts
|
|
44
|
+
* const empty2: QueryParamPairs = [["key"]];
|
|
45
|
+
* ```
|
|
34
46
|
*/
|
|
35
47
|
type QueryParamPairs = [[string, string | number], ...[string, string | number][]];
|
|
36
|
-
/**
|
|
48
|
+
/** ---------------------------------------------------------------------------------------------------
|
|
37
49
|
* * ***Utility: `constructURL`.***
|
|
38
|
-
*
|
|
39
|
-
* **Constructs a valid URL with optional query parameters and allows selective removal
|
|
40
|
-
*
|
|
50
|
+
* ----------------------------------------------------------------------------------------------------
|
|
51
|
+
* **Constructs a valid URL with optional query parameters and allows selective removal
|
|
52
|
+
* of duplicate parameters.**
|
|
53
|
+
*
|
|
54
|
+
* ---
|
|
55
|
+
* @param {string | URL} baseUrl
|
|
56
|
+
* The base URL to build upon. Must include protocol (e.g., `"https://"`), `domain`, and may include port and existing query parameters.
|
|
41
57
|
* @param {Iterable<[string, string]> | URLSearchParamsIterator<[string, string]> | QueryParamPairs} [queryParams]
|
|
42
58
|
* Additional query parameters to append or overwrite on the URL.
|
|
43
59
|
* - Accepts any iterable of key-value pairs (like `new URLSearchParams().entries()` and `[[string, string | number]...]`).
|
|
44
60
|
* @param {string[]} [removeParams]
|
|
45
61
|
* A list of query parameter keys to remove from the final URL, whether they were in the base URL or provided queryParams.
|
|
62
|
+
*
|
|
63
|
+
* ---
|
|
64
|
+
* @throws **{@link TypeError | `TypeError`}** if `baseUrl` is not a valid non-empty string or URL object, or if `queryParams` is not iterable, or
|
|
65
|
+
* if `removeParams` is not an array of strings.
|
|
66
|
+
*
|
|
67
|
+
* ---
|
|
46
68
|
* @returns {URL} A new URL object representing the constructed URL with merged and cleaned query parameters.
|
|
47
|
-
*
|
|
69
|
+
*
|
|
70
|
+
* ---
|
|
48
71
|
* @example
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
72
|
+
* 1. #### Basic Usage:
|
|
73
|
+
* ```ts
|
|
74
|
+
* constructURL(
|
|
75
|
+
* "https://example.com/path",
|
|
76
|
+
* new URLSearchParams({ a: "1", b: "2" }).entries()
|
|
77
|
+
* );
|
|
78
|
+
* ```
|
|
79
|
+
* #### Result ➔ `URL { href: "https://example.com/path?a=1&b=2", ... }`
|
|
80
|
+
* ---
|
|
81
|
+
* 2. #### Remove parameters from Base and Added:
|
|
82
|
+
* - #### With `new URLSearchParams({ ... }).entries();`:
|
|
83
|
+
* ```ts
|
|
84
|
+
* constructURL(
|
|
85
|
+
* "https://example.com/path?foo=1&bar=2",
|
|
86
|
+
* new URLSearchParams({ bar: "ignored", baz: "3" }).entries(),
|
|
87
|
+
* ["bar"]
|
|
88
|
+
* );
|
|
89
|
+
* ```
|
|
90
|
+
* #### Result ➔ `URL { href: "https://example.com/path?foo=1&baz=3", ... }`
|
|
91
|
+
* ---
|
|
92
|
+
*
|
|
93
|
+
* - #### With `[[string, string | number]...]`:
|
|
94
|
+
* ```ts
|
|
95
|
+
* constructURL(
|
|
96
|
+
* "https://example.com/path?foo=1&bar=2",
|
|
97
|
+
* [["bar", "ignored"],["baz", 3]],
|
|
98
|
+
* ["bar"]
|
|
99
|
+
* );
|
|
100
|
+
* ```
|
|
101
|
+
* #### Result ➔ `URL { href: "https://example.com/path?foo=1&baz=3", ... }`
|
|
102
|
+
* ---
|
|
103
|
+
*
|
|
104
|
+
* - #### With separated variable and `[[string, number]...]` :
|
|
105
|
+
* ```ts
|
|
106
|
+
* const params: QueryParamPairs = [
|
|
107
|
+
* ["foo", 1],
|
|
108
|
+
* ["bar", 2],
|
|
109
|
+
* ["baz", 3]
|
|
110
|
+
* ];
|
|
111
|
+
*
|
|
112
|
+
* constructURL("https://example.com", params, ["bar"]);
|
|
113
|
+
* ```
|
|
114
|
+
* #### Result ➔ `URL { href: "https://example.com/?foo=1&baz=3", ... }`
|
|
84
115
|
*/
|
|
85
116
|
declare const constructURL: (baseUrl: string | URL, queryParams?: URLSearchParamsIterator<[string, string | number]> | QueryParamPairs, removeParams?: string[]) => URL;
|
|
86
117
|
/** ---------------------------------
|
|
87
118
|
* * ***Utility: `extractURLs`.***
|
|
88
119
|
* ---------------------------------
|
|
89
120
|
* **Extracts all valid URLs from a given string.**
|
|
121
|
+
*
|
|
122
|
+
* ---
|
|
90
123
|
* @description
|
|
91
124
|
* This function scans the input url and returns an array of URLs
|
|
92
125
|
* that match a valid `http` or `https` format.
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
126
|
+
*
|
|
127
|
+
* ---
|
|
128
|
+
* - #### *Behavior:*
|
|
129
|
+
* - #### Supports:
|
|
130
|
+
* - Internationalized domain names (IDN), e.g. `https://münich.de`.
|
|
131
|
+
* - Unicode & emoji paths, e.g. `https://example.com/🎉/page`.
|
|
132
|
+
* - Long URLs with multiple queries & fragments, e.g. `https://example.com/path?foo=1#hash`.
|
|
133
|
+
* ---
|
|
134
|
+
* - #### Ignores:
|
|
135
|
+
* - Non-string inputs.
|
|
136
|
+
* - Empty or whitespace-only strings.
|
|
137
|
+
* - Non-HTTP(S) protocols (ftp, mailto, etc).
|
|
138
|
+
*
|
|
139
|
+
* ---
|
|
101
140
|
* @param {string | null | undefined} url - The input string containing potential URLs.
|
|
141
|
+
*
|
|
142
|
+
* ---
|
|
102
143
|
* @returns {string[] | null} An array of extracted URLs or `null` if no URLs are found.
|
|
144
|
+
*
|
|
145
|
+
* ---
|
|
103
146
|
* @example
|
|
104
147
|
* extractURLs("Visit https://example.com and https://例子.公司");
|
|
105
148
|
* // ➔ ["https://example.com", "https://例子.公司"]
|
|
@@ -113,17 +156,23 @@ declare const extractURLs: (url: string | null | undefined) => string[] | null;
|
|
|
113
156
|
* * ***Utility: `getFirstPrefixPathname`.***
|
|
114
157
|
* --------------------------------------------------------
|
|
115
158
|
* **Extract First Valid Prefix from Path Array or String.**
|
|
159
|
+
*
|
|
160
|
+
* ---
|
|
116
161
|
* - **Main Purpose:**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
162
|
+
* - This function helps extract the first valid URL prefix from various possible inputs.
|
|
163
|
+
* - It is especially useful in routing systems, middleware, or frontend apps that need to
|
|
164
|
+
* decide layout, active navigation, or permissions based on the first segment (or prefix) of a pathname.
|
|
165
|
+
*
|
|
166
|
+
* ---
|
|
120
167
|
* - **Typical uses include:**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
168
|
+
* - Determining which layout to render (e.g., `/admin` vs `/dashboard` vs `/`).
|
|
169
|
+
* - Highlighting the active menu item in a sidebar based on the current URL.
|
|
170
|
+
* - Enforcing route guards or access controls depending on the URL prefix.
|
|
171
|
+
* - Parsing multi-level route prefixes and selecting the most relevant one.
|
|
172
|
+
*
|
|
173
|
+
* ---
|
|
125
174
|
* - **Behavior:**
|
|
126
|
-
*
|
|
175
|
+
* - It works as follows:
|
|
127
176
|
* - If `result` is an array of strings, it normalizes each element and returns
|
|
128
177
|
* the first non-root path (i.e., not just `"/"`).
|
|
129
178
|
* - If all items normalize to `"/"`,
|
|
@@ -131,66 +180,15 @@ declare const extractURLs: (url: string | null | undefined) => string[] | null;
|
|
|
131
180
|
* - If `result` is a single string, it normalizes it and returns it if valid,
|
|
132
181
|
* otherwise falls back to the normalized `defaultValue`.
|
|
133
182
|
* - If `result` is `null` or `undefined`, it returns the normalized `defaultValue`.
|
|
134
|
-
* - **Validation & Errors:**
|
|
135
|
-
* - Throws a `TypeError` if:
|
|
136
|
-
* - `defaultValue` is not a string or empty-string.
|
|
137
|
-
* - `result` is an array that contains non-string elements.
|
|
138
|
-
* - `result` is a value that is neither `string`, `string[]`, nor `null`.
|
|
139
|
-
* @example
|
|
140
|
-
* 1. #### For React (*Determining layout*):
|
|
141
|
-
* ```ts
|
|
142
|
-
* const prefix = getFirstPrefixPathname(
|
|
143
|
-
* getPrefixPathname(
|
|
144
|
-
* "/admin/settings",
|
|
145
|
-
* ["/admin", "/dashboard"]
|
|
146
|
-
* )
|
|
147
|
-
* );
|
|
148
|
-
*
|
|
149
|
-
* if (prefix === "/admin") {
|
|
150
|
-
* renderAdminLayout();
|
|
151
|
-
* }
|
|
152
|
-
* ```
|
|
153
183
|
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
184
|
+
* ---
|
|
185
|
+
* - **Validation & Errors:**
|
|
186
|
+
* - Throws a `TypeError` if:
|
|
187
|
+
* - `defaultValue` is not a string or empty-string.
|
|
188
|
+
* - `result` is an array that contains non-string elements.
|
|
189
|
+
* - `result` is a value that is neither `string`, `string[]`, nor `null`.
|
|
159
190
|
*
|
|
160
|
-
*
|
|
161
|
-
* ```ts
|
|
162
|
-
* const section = getFirstPrefixPathname([], "/home");
|
|
163
|
-
* // ➔ "/home"
|
|
164
|
-
* ```
|
|
165
|
-
* 4. #### ✅ Using with an Array of Pathnames:
|
|
166
|
-
* ```ts
|
|
167
|
-
* const result = getPrefixPathname([" ", "/dashboard", "/settings"]);
|
|
168
|
-
* console.log(getFirstPrefixPathname(result));
|
|
169
|
-
* // ➔ "/dashboard"
|
|
170
|
-
* ```
|
|
171
|
-
*
|
|
172
|
-
* 5. #### ✅ Using with Single String:
|
|
173
|
-
* ```ts
|
|
174
|
-
* console.log(getFirstPrefixPathname("/profile/settings"));
|
|
175
|
-
* // ➔ "/profile/settings"
|
|
176
|
-
* console.log(getFirstPrefixPathname(" "));
|
|
177
|
-
* // ➔ "/"
|
|
178
|
-
* ```
|
|
179
|
-
*
|
|
180
|
-
* 6. #### ✅ Fallback to Custom Default:
|
|
181
|
-
* ```ts
|
|
182
|
-
* console.log(getFirstPrefixPathname([" ", ""], "/home"));
|
|
183
|
-
* // ➔ "/home"
|
|
184
|
-
* console.log(getFirstPrefixPathname(null, "/dashboard"));
|
|
185
|
-
* // ➔ "/dashboard"
|
|
186
|
-
* ```
|
|
187
|
-
*
|
|
188
|
-
* 7. #### ✅ Throws on Invalid Input:
|
|
189
|
-
* ```ts
|
|
190
|
-
* getFirstPrefixPathname([1, 2] as any); // ➔ ❌ throws TypeError
|
|
191
|
-
* getFirstPrefixPathname({} as any); // ➔ ❌ throws TypeError
|
|
192
|
-
* getFirstPrefixPathname(null, " "); // ➔ ❌ throws TypeError
|
|
193
|
-
* ```
|
|
191
|
+
* ---
|
|
194
192
|
* @param {string | string[] | null | undefined} result
|
|
195
193
|
* ***The pathname(s) to process, can be:***
|
|
196
194
|
* - A string path (e.g. `"/profile"`),
|
|
@@ -200,191 +198,309 @@ declare const extractURLs: (url: string | null | undefined) => string[] | null;
|
|
|
200
198
|
* ***A custom default path to use if `result` is null or no valid prefix is found, behavior:***
|
|
201
199
|
* - Must be a string and non-empty string.
|
|
202
200
|
* - Defaults to `"/"`.
|
|
203
|
-
*
|
|
204
|
-
*
|
|
201
|
+
*
|
|
202
|
+
* ---
|
|
205
203
|
* @throws **{@link TypeError | `TypeError`}** ***if `result` is not a valid type, or `defaultValue` is not a string or empty-string.***
|
|
204
|
+
*
|
|
205
|
+
* ---
|
|
206
|
+
* @returns {string} ***The first valid normalized pathname, or the normalized default.***
|
|
207
|
+
*
|
|
208
|
+
* ---
|
|
209
|
+
* @example
|
|
210
|
+
* 1. #### For React (*Determining layout*):
|
|
211
|
+
* ```ts
|
|
212
|
+
* const prefix = getFirstPrefixPathname(
|
|
213
|
+
* getPrefixPathname(
|
|
214
|
+
* "/admin/settings",
|
|
215
|
+
* ["/admin", "/dashboard"]
|
|
216
|
+
* )
|
|
217
|
+
* );
|
|
218
|
+
*
|
|
219
|
+
* if (prefix === "/admin") {
|
|
220
|
+
* renderAdminLayout();
|
|
221
|
+
* }
|
|
222
|
+
* ```
|
|
223
|
+
* ---
|
|
224
|
+
* 2. #### Setting active menu state:
|
|
225
|
+
* ```ts
|
|
226
|
+
* const activeSection = getFirstPrefixPathname(["", "/dashboard", "/profile"]);
|
|
227
|
+
* // ➔ "/dashboard"
|
|
228
|
+
* ```
|
|
229
|
+
* ---
|
|
230
|
+
* 3. #### Providing graceful fallback:
|
|
231
|
+
* ```ts
|
|
232
|
+
* const section = getFirstPrefixPathname([], "/home");
|
|
233
|
+
* // ➔ "/home"
|
|
234
|
+
* ```
|
|
235
|
+
* ---
|
|
236
|
+
* 4. #### Using with an Array of Pathnames:
|
|
237
|
+
* ```ts
|
|
238
|
+
* const result = getPrefixPathname([" ", "/dashboard", "/settings"]);
|
|
239
|
+
* console.log(getFirstPrefixPathname(result));
|
|
240
|
+
* // ➔ "/dashboard"
|
|
241
|
+
* ```
|
|
242
|
+
* ---
|
|
243
|
+
* 5. #### Using with Single String:
|
|
244
|
+
* ```ts
|
|
245
|
+
* console.log(getFirstPrefixPathname("/profile/settings"));
|
|
246
|
+
* // ➔ "/profile/settings"
|
|
247
|
+
* console.log(getFirstPrefixPathname(" "));
|
|
248
|
+
* // ➔ "/"
|
|
249
|
+
* ```
|
|
250
|
+
* ---
|
|
251
|
+
* 6. #### Fallback to Custom Default:
|
|
252
|
+
* ```ts
|
|
253
|
+
* console.log(getFirstPrefixPathname([" ", ""], "/home"));
|
|
254
|
+
* // ➔ "/home"
|
|
255
|
+
* console.log(getFirstPrefixPathname(null, "/dashboard"));
|
|
256
|
+
* // ➔ "/dashboard"
|
|
257
|
+
* ```
|
|
258
|
+
* ---
|
|
259
|
+
* 7. #### Throws on Invalid Input:
|
|
260
|
+
* ```ts
|
|
261
|
+
* getFirstPrefixPathname([1, 2] as any);
|
|
262
|
+
* // ➔ ❌ throws TypeError
|
|
263
|
+
* getFirstPrefixPathname({} as any);
|
|
264
|
+
* // ➔ ❌ throws TypeError
|
|
265
|
+
* getFirstPrefixPathname(null, " ");
|
|
266
|
+
* // ➔ ❌ throws TypeError
|
|
267
|
+
* ```
|
|
206
268
|
*/
|
|
207
269
|
declare const getFirstPrefixPathname: (result: string | string[] | null | undefined, defaultValue?: string) => string;
|
|
208
270
|
type GetPrefixPathnameOptions = {
|
|
209
|
-
/**
|
|
271
|
+
/** --------------------------------------------------------
|
|
272
|
+
* * ***The number of levels to include in the prefix (default is `1`).***
|
|
273
|
+
* ---------------------------------------------------------
|
|
210
274
|
*
|
|
211
275
|
* - For example, with `levels = 2`, the function will return the first two parts of the URL.
|
|
212
|
-
*
|
|
276
|
+
* ---
|
|
213
277
|
* @default 1
|
|
214
278
|
*/
|
|
215
279
|
levels?: number;
|
|
216
|
-
/**
|
|
280
|
+
/** --------------------------------------------------------
|
|
281
|
+
* * ***Whether to remove duplicates from the result if multiple URLs are passed (default is `true`).***
|
|
282
|
+
* ---------------------------------------------------------
|
|
217
283
|
*
|
|
284
|
+
* - ***⚠️ Warning:***
|
|
285
|
+
* - Non-boolean values will throw `TypeError`.
|
|
286
|
+
* ---
|
|
218
287
|
* @default true
|
|
219
288
|
*/
|
|
220
289
|
removeDuplicates?: boolean;
|
|
221
290
|
};
|
|
222
291
|
/** --------------------------------------------------------
|
|
223
292
|
* * ***Utility: `getPrefixPathname`.***
|
|
224
|
-
*
|
|
293
|
+
* ---------------------------------------------------------
|
|
225
294
|
* **Get Prefix from URL with Optional Base or Auto-detection (Supports String or Array of URLs).**
|
|
295
|
+
*
|
|
296
|
+
* ---
|
|
226
297
|
* - **This function extracts the prefix from one or more URLs. It can either:**
|
|
227
|
-
*
|
|
228
|
-
*
|
|
298
|
+
* - Use a provided `base` string or an array of strings to check and return the matching prefix.
|
|
299
|
+
* - Automatically detect the prefix if no `base` is provided by analyzing the first part of the URL.
|
|
300
|
+
* ---
|
|
301
|
+
*
|
|
229
302
|
* - **The function is flexible and can handle both scenarios:**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
303
|
+
* 1. **When the base is provided as a single string or an array of strings**:
|
|
304
|
+
* - The function will check if the URL starts with one of the provided base(s) and return the matching base.
|
|
305
|
+
* 2. **When the base is not provided**:
|
|
306
|
+
* - The function will automatically detect the prefix by splitting the URL or using a regex.
|
|
307
|
+
* ---
|
|
234
308
|
* - **Important Notes**:
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
309
|
+
* - If a base (or an array of bases) is provided, the URL must start with one of the given base(s).
|
|
310
|
+
* - If no base is provided, the function will attempt to detect the prefix automatically.
|
|
311
|
+
* - The `url` parameter can be either a string or an array of strings.
|
|
312
|
+
* - Supports deduplication of results (enabled by default).
|
|
313
|
+
* - Automatically returns a single string if only one unique result exists after processing.
|
|
314
|
+
* ---
|
|
315
|
+
*
|
|
240
316
|
* @param {string|string[]} url
|
|
241
317
|
* ***The full URL(s) from which the prefix should be extracted, can be a `string` or an `array of strings`.***
|
|
242
318
|
* @param {string|string[]|null} [base=null]
|
|
243
319
|
* ***The base URL(s) (e.g., `"/settings"`), behavior:***
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
320
|
+
* - It can be a `string`, an `array of strings`, or `null`.
|
|
321
|
+
* - If `provided`, it will be used to check the URL(s).
|
|
322
|
+
* - If `not provided`, the prefix will be auto-detected.
|
|
247
323
|
* @param {GetPrefixPathnameOptions} [options]
|
|
248
324
|
* ***Additional options object:***
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* - A single string if only one unique prefix/base is found.
|
|
254
|
-
* - An array of strings if multiple different prefixes/bases are found.
|
|
255
|
-
* - `null` if no matching base is found when using `base`.
|
|
325
|
+
* - `levels` (default `1`): The number of segments to include when auto-detecting the prefix (e.g. `/foo/bar` for `levels: 2`).
|
|
326
|
+
* - `removeDuplicates` (default `true`): Whether to remove duplicate prefixes from the final array result.
|
|
327
|
+
*
|
|
328
|
+
* ---
|
|
256
329
|
* @throws **{@link TypeError | `TypeError`}**
|
|
257
330
|
* ***if:***
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
* @example
|
|
264
|
-
* - #### ✅ **Correct Usage (With an Array of URLs and Base):**
|
|
265
|
-
* ```ts
|
|
266
|
-
* const routes = [
|
|
267
|
-
* "/settings/profile",
|
|
268
|
-
* "/settings/password",
|
|
269
|
-
* "/settings/other-path",
|
|
270
|
-
* "/other-path/xyz",
|
|
271
|
-
* ];
|
|
331
|
+
* - `url` is `not a string` or `not an array of strings`.
|
|
332
|
+
* - `base` is `not a string`, `array of strings`, or `null`.
|
|
333
|
+
* - `options` is `not an object`.
|
|
334
|
+
* - `levels` is `not a number`.
|
|
335
|
+
* - `removeDuplicates` is `not a boolean`.
|
|
272
336
|
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
337
|
+
* ---
|
|
338
|
+
* @returns {string|string[]|null}
|
|
339
|
+
* ***Returns one of:***
|
|
340
|
+
* - A single string if only one unique prefix/base is found.
|
|
341
|
+
* - An array of strings if multiple different prefixes/bases are found.
|
|
342
|
+
* - `null` if no matching base is found when using `base`.
|
|
343
|
+
*
|
|
344
|
+
* ---
|
|
345
|
+
* @example
|
|
346
|
+
* 1. #### Correct Usage (With an Array of URLs and Base):
|
|
347
|
+
* ```ts
|
|
348
|
+
* const routes = [
|
|
349
|
+
* "/settings/profile",
|
|
350
|
+
* "/settings/password",
|
|
351
|
+
* "/settings/other-path",
|
|
352
|
+
* "/other-path/xyz",
|
|
353
|
+
* ];
|
|
354
|
+
*
|
|
355
|
+
* // With base provided as a string
|
|
356
|
+
* routes.forEach(route => {
|
|
357
|
+
* console.log(getPrefixPathname(route, '/settings'));
|
|
358
|
+
* // ➔ "/settings"
|
|
359
|
+
* });
|
|
360
|
+
*
|
|
361
|
+
* // With base provided as an array
|
|
362
|
+
* routes.forEach(route => {
|
|
363
|
+
* console.log(getPrefixPathname(route, ['/settings', '/admin']));
|
|
364
|
+
* // ➔ "/settings" or "/admin" depending on the current URL.
|
|
365
|
+
* });
|
|
366
|
+
* ```
|
|
367
|
+
* ---
|
|
368
|
+
* 2. #### Correct Usage (With Single URL and Single Base):
|
|
369
|
+
* ```ts
|
|
370
|
+
* const result = getPrefixPathname("/settings/profile", "/settings");
|
|
371
|
+
* console.log(result);
|
|
372
|
+
* // ➔ "/settings"
|
|
373
|
+
* ```
|
|
374
|
+
* ---
|
|
375
|
+
* 3. #### Correct Usage (With Multiple URLs and Single Base):
|
|
376
|
+
* ```ts
|
|
377
|
+
* const result = getPrefixPathname(
|
|
378
|
+
* ["/settings/profile", "/settings/password"],
|
|
379
|
+
* "/settings"
|
|
380
|
+
* );
|
|
381
|
+
* console.log(result);
|
|
276
382
|
* // ➔ "/settings"
|
|
277
|
-
* });
|
|
278
|
-
*
|
|
279
|
-
* // With base provided as an array
|
|
280
|
-
* routes.forEach(route => {
|
|
281
|
-
* console.log(getPrefixPathname(route, ['/settings', '/admin']));
|
|
282
|
-
* // ➔ "/settings" or "/admin" depending on the current URL.
|
|
283
|
-
* });
|
|
284
|
-
* ```
|
|
285
|
-
* - #### ✅ **Correct Usage (With Single URL and Single Base):**
|
|
286
|
-
* ```ts
|
|
287
|
-
* const result = getPrefixPathname("/settings/profile", "/settings");
|
|
288
|
-
* console.log(result); // ➔ "/settings"
|
|
289
|
-
* ```
|
|
290
|
-
* - #### ✅ **Correct Usage (With Multiple URLs and Single Base):**
|
|
291
|
-
* ```ts
|
|
292
|
-
* const result = getPrefixPathname(
|
|
293
|
-
* ["/settings/profile", "/settings/password"],
|
|
294
|
-
* "/settings"
|
|
295
|
-
* );
|
|
296
|
-
* console.log(result); // ➔ "/settings"
|
|
297
383
|
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* "/settings/profile
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
* );
|
|
322
|
-
* console.log(result2); // ➔ "/settings/profile"
|
|
323
|
-
* ```
|
|
324
|
-
* - #### ✅ **Multiple URLs with Auto-detection**
|
|
325
|
-
* ```ts
|
|
326
|
-
* const result = getPrefixPathname(["/admin/profile", "/settings/password"]);
|
|
327
|
-
* console.log(result); // ➔ ["/admin", "/settings"]
|
|
328
|
-
* ```
|
|
329
|
-
* - #### ✅ **Handling Duplicates**
|
|
330
|
-
* ```ts
|
|
331
|
-
* const result = getPrefixPathname(
|
|
332
|
-
* ["/settings/profile", "/settings/password"],
|
|
333
|
-
* "/settings"
|
|
334
|
-
* );
|
|
335
|
-
* console.log(result); // ➔ "/settings" (deduped to single string)
|
|
384
|
+
* const result2 = getPrefixPathname(
|
|
385
|
+
* ["/settings/profile", "/other/password"],
|
|
386
|
+
* "/other"
|
|
387
|
+
* );
|
|
388
|
+
* console.log(result2);
|
|
389
|
+
* // ➔ "/other"
|
|
390
|
+
* ```
|
|
391
|
+
* ---
|
|
392
|
+
* 4. #### Correct Usage (With Multiple URLs and Multiple Bases):
|
|
393
|
+
* ```ts
|
|
394
|
+
* const result = getPrefixPathname(
|
|
395
|
+
* ["/settings/profile", "/admin/password"],
|
|
396
|
+
* ["/settings", "/admin"]
|
|
397
|
+
* );
|
|
398
|
+
* console.log(result);
|
|
399
|
+
* // ➔ ["/settings", "/admin"]
|
|
400
|
+
* ```
|
|
401
|
+
* ---
|
|
402
|
+
* 5. #### Auto-detection of Prefix:
|
|
403
|
+
* ```ts
|
|
404
|
+
* const result = getPrefixPathname("/settings/profile");
|
|
405
|
+
* console.log(result);
|
|
406
|
+
* // ➔ "/settings"
|
|
336
407
|
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
408
|
+
* const result2 = getPrefixPathname(
|
|
409
|
+
* "/settings/profile/info",
|
|
410
|
+
* null,
|
|
411
|
+
* { levels: 2 }
|
|
412
|
+
* );
|
|
413
|
+
* console.log(result2);
|
|
414
|
+
* // ➔ "/settings/profile"
|
|
415
|
+
* ```
|
|
416
|
+
* ---
|
|
417
|
+
* 6. #### Multiple URLs with Auto-detection:
|
|
418
|
+
* ```ts
|
|
419
|
+
* const result = getPrefixPathname(["/admin/profile", "/settings/password"]);
|
|
420
|
+
* console.log(result);
|
|
421
|
+
* // ➔ ["/admin", "/settings"]
|
|
422
|
+
* ```
|
|
423
|
+
* ---
|
|
424
|
+
* 7. #### Handling Duplicates:
|
|
425
|
+
* ```ts
|
|
426
|
+
* const result = getPrefixPathname(
|
|
427
|
+
* ["/settings/profile", "/settings/password"],
|
|
428
|
+
* "/settings"
|
|
429
|
+
* );
|
|
430
|
+
* console.log(result);
|
|
431
|
+
* // ➔ "/settings" (deduped to single string)
|
|
432
|
+
*
|
|
433
|
+
* const result2 = getPrefixPathname(
|
|
434
|
+
* ["/settings/profile", "/settings/profile"],
|
|
435
|
+
* "/settings",
|
|
436
|
+
* { removeDuplicates: false }
|
|
437
|
+
* );
|
|
438
|
+
* console.log(result2);
|
|
439
|
+
* // ➔ ["/settings", "/settings"]
|
|
440
|
+
* ```
|
|
441
|
+
* ---
|
|
442
|
+
* 8. #### Incorrect Usage (URL Does Not Match Base):
|
|
443
|
+
* ```ts
|
|
444
|
+
* const result = getPrefixPathname("/other-path/profile", "/settings");
|
|
445
|
+
* console.log(result);
|
|
446
|
+
* // ➔ null
|
|
447
|
+
* ```
|
|
349
448
|
*/
|
|
350
449
|
declare const getPrefixPathname: (url: string | string[], base?: string | string[] | null, options?: GetPrefixPathnameOptions) => string | string[] | null;
|
|
351
|
-
/**
|
|
352
|
-
*
|
|
450
|
+
/** --------------------------------------------------------
|
|
451
|
+
* * ***Options when `keepNullable` is false (default).***
|
|
452
|
+
* ---------------------------------------------------------
|
|
353
453
|
* Returns `defaultPath` if `pathname` is empty or invalid.
|
|
354
454
|
*/
|
|
355
455
|
type UnKeepNullableOptions = {
|
|
356
|
-
/**
|
|
357
|
-
*
|
|
456
|
+
/** --------------------------------------------------------
|
|
457
|
+
* * ***Fallback value returned if `pathname` is empty-string or invalid.***
|
|
458
|
+
* ---------------------------------------------------------
|
|
358
459
|
* Must be a **`non-empty string`**, defaultValue: `"/"`.
|
|
359
460
|
*
|
|
461
|
+
* ---
|
|
360
462
|
* @default "/"
|
|
361
463
|
*/
|
|
362
464
|
defaultPath?: string;
|
|
363
|
-
/**
|
|
465
|
+
/** --------------------------------------------------------
|
|
466
|
+
* * ***Whether to preserve `null` or `undefined`, defaultValue: `false`.***
|
|
467
|
+
* ---------------------------------------------------------
|
|
364
468
|
*
|
|
469
|
+
* - ***⚠️ Warning:***
|
|
470
|
+
* - Non-boolean values will throw `TypeError`.
|
|
471
|
+
* ---
|
|
365
472
|
* @default false
|
|
366
473
|
*/
|
|
367
474
|
keepNullable?: false;
|
|
368
475
|
};
|
|
369
|
-
/**
|
|
476
|
+
/** --------------------------------------------------------
|
|
477
|
+
* * ***Options when `keepNullable` is true.***
|
|
478
|
+
* ---------------------------------------------------------
|
|
370
479
|
*
|
|
371
480
|
* Preserves `null` or `undefined` instead of returning `defaultPath`.
|
|
372
481
|
*/
|
|
373
482
|
type KeepNullableOptions = {
|
|
374
|
-
/**
|
|
483
|
+
/** --------------------------------------------------------
|
|
484
|
+
* * ***Fallback path is ignored when `keepNullable` is true **(except if
|
|
375
485
|
* `pathname` is empty-string or invalid, even this `true`)**,
|
|
376
486
|
* defaultValue: `"/"`.***
|
|
487
|
+
* --------------------------------------------------------
|
|
377
488
|
*
|
|
378
489
|
* @default "/"
|
|
379
490
|
*/
|
|
380
491
|
defaultPath?: string;
|
|
381
|
-
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* - Keep returning `defaultPath` if `pathname` is empty-string, even this `true`.
|
|
492
|
+
/** --------------------------------------------------------
|
|
493
|
+
* * ***Preserve `null` or `undefined` as-is if `true` (defaultValue: `false`).***
|
|
494
|
+
* --------------------------------------------------------
|
|
385
495
|
*
|
|
496
|
+
* - ***⚠️ Warning:***
|
|
497
|
+
* - Keeps returning `defaultPath` when `pathname` is an empty string, even if enabled.
|
|
498
|
+
* - Non-boolean values will throw `TypeError`.
|
|
499
|
+
* ---
|
|
386
500
|
* **Must be `true` in this type.**
|
|
387
501
|
*
|
|
502
|
+
* ---
|
|
503
|
+
*
|
|
388
504
|
* @default false
|
|
389
505
|
*/
|
|
390
506
|
keepNullable?: true;
|
|
@@ -392,96 +508,107 @@ type KeepNullableOptions = {
|
|
|
392
508
|
type MainNormalizePathnameOptions = {
|
|
393
509
|
/** --------------------------------------------------------
|
|
394
510
|
* * ***Preserve trailing slash at the end of the normalized pathname, defaultValue: `false`.***
|
|
395
|
-
*
|
|
511
|
+
* ---------------------------------------------------------
|
|
512
|
+
*
|
|
513
|
+
* - ***⚠️ Warning:***
|
|
514
|
+
* - Non-boolean values will throw `TypeError`.
|
|
515
|
+
* ---
|
|
516
|
+
*
|
|
517
|
+
* @default false
|
|
396
518
|
*
|
|
397
|
-
* @default `false`
|
|
398
519
|
*/
|
|
399
520
|
keepTrailingSlash?: boolean;
|
|
400
521
|
/** --------------------------------------------------------
|
|
401
522
|
* * ***Allow special localhost domain at the beginning of the pathname.***
|
|
402
|
-
*
|
|
523
|
+
* ---------------------------------------------------------
|
|
403
524
|
* @description
|
|
404
525
|
* If `true`, the first segment of the pathname that is `/localhost` or `localhost`
|
|
405
526
|
* (with or without a port, e.g., `localhost:3000`) will be treated as a special domain
|
|
406
527
|
* and **removed** from the normalized pathname.
|
|
407
528
|
*
|
|
529
|
+
* ---
|
|
408
530
|
* - **Examples (`localhostDomain: true`)**:
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
531
|
+
* - `"/localhost/path"` ➔ `"/path"`.
|
|
532
|
+
* - `"localhost:3000/path"` ➔ `"/path"`.
|
|
533
|
+
* - `"localhost"` ➔ `"/"` (**entire path removed**).
|
|
534
|
+
* ---
|
|
413
535
|
* - Only the **first path segment** is affected. Any subsequent occurrences of `"localhost"`
|
|
414
536
|
* will remain intact.
|
|
537
|
+
* ---
|
|
538
|
+
* - ***⚠️ Warning:***
|
|
539
|
+
* - Non-boolean values will throw `TypeError`.
|
|
415
540
|
*
|
|
416
541
|
* @default false
|
|
417
542
|
*/
|
|
418
543
|
localhostDomain?: boolean;
|
|
419
|
-
/**
|
|
420
|
-
* --------------------------------------------------------
|
|
544
|
+
/** --------------------------------------------------------
|
|
421
545
|
* * ***Custom list of file extensions that prevent the first path segment from being treated as a domain.***
|
|
422
546
|
* --------------------------------------------------------
|
|
423
547
|
*
|
|
424
|
-
* **
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
* **Type & Validation:**
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
* **Usage Notes:**
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
548
|
+
* - **Behavior:**
|
|
549
|
+
* - The first segment of a pathname is often interpreted as a domain (e.g., `example.com`).
|
|
550
|
+
* - If this first segment ends with any of the extensions listed here, it will **not** be considered a domain,
|
|
551
|
+
* and will instead be preserved as part of the relative path.
|
|
552
|
+
* - This is useful for cases where filenames appear at the start of a path and you want them treated as relative paths,
|
|
553
|
+
* such as `"image.png?version=2"` or `"archive.tar.gz#download"`.
|
|
554
|
+
* - Only the **first path segment** is affected; all other segments are processed normally.
|
|
555
|
+
* - **Ignored** if:
|
|
556
|
+
* 1. The pathname starts with a full URL protocol (`http://` or `https://`), e.g., `"https://example.com/file.png"`.
|
|
557
|
+
* 2. The first path segment is already a valid domain, e.g., `"example.com/image.png"`.
|
|
558
|
+
* ---
|
|
559
|
+
* - **Type & Validation:**
|
|
560
|
+
* - Must be a `Set<string>` or `string[]`.
|
|
561
|
+
* - Each string **must include the leading dot**, e.g., `.png`, `.tar.gz`.
|
|
562
|
+
* - Multi-part extensions (like `.tar.gz`, `.tar.bz`) are supported.
|
|
563
|
+
* - Throws a **TypeError** if:
|
|
564
|
+
* 1. The type is not a `Set<string>` or `string[]`.
|
|
565
|
+
* 2. Any string in the array/set is empty.
|
|
566
|
+
* 3. Any string does not start with a dot (`.`).
|
|
567
|
+
* ---
|
|
568
|
+
* - **Usage Notes:**
|
|
569
|
+
* - Only applied when the first segment is otherwise domain-like **and** pathname is relative or domain-like without protocol.
|
|
570
|
+
* - Query strings (`?x=1`) and hash fragments (`#section`) are preserved.
|
|
571
|
+
*
|
|
572
|
+
* ---
|
|
573
|
+
* @example
|
|
574
|
+
*
|
|
575
|
+
* 1. #### Examples (relative paths, option active):
|
|
576
|
+
* ```ts
|
|
577
|
+
* normalizePathname("image.png?version=2", {
|
|
578
|
+
* ignoreDomainExtensions: [".png", ".jpg"]
|
|
579
|
+
* });
|
|
580
|
+
* // ➔ "/image.png?version=2"
|
|
581
|
+
*
|
|
582
|
+
* normalizePathname("archive.tar.gz#download", {
|
|
583
|
+
* ignoreDomainExtensions: new Set([".tar.gz"])
|
|
584
|
+
* });
|
|
585
|
+
* // ➔ "/archive.tar.gz#download"
|
|
586
|
+
*
|
|
587
|
+
* normalizePathname("script.js?module=true#top", {
|
|
588
|
+
* ignoreDomainExtensions: [".js"]
|
|
589
|
+
* });
|
|
590
|
+
* // ➔ "/script.js?module=true#top"
|
|
591
|
+
* ```
|
|
592
|
+
* ---
|
|
593
|
+
* 2. #### Examples (full URL or explicit domain - option ignored):
|
|
594
|
+
* ```ts
|
|
595
|
+
* normalizePathname("https://example.com/image.png?version=2", {
|
|
596
|
+
* ignoreDomainExtensions: [".png"]
|
|
597
|
+
* });
|
|
598
|
+
* // ➔ "/image.png?version=2" // URL is parsed normally; ignoreDomainExtensions has no effect
|
|
599
|
+
*
|
|
600
|
+
* normalizePathname("example.com/script.js?module=true#top", {
|
|
601
|
+
* ignoreDomainExtensions: [".js"]
|
|
602
|
+
* });
|
|
603
|
+
* // ➔ "/script.js?module=true#top" // domain recognized; option ignored
|
|
604
|
+
* ```
|
|
605
|
+
* ---
|
|
606
|
+
* @notes
|
|
480
607
|
* - Only the **first path segment** is checked.
|
|
481
608
|
* - Prevents false-positive domain stripping for filenames that look like domains.
|
|
482
609
|
* - Throws **TypeError** if invalid type or invalid string is provided.
|
|
483
610
|
*
|
|
484
|
-
* @default undefined (feature inactive if not provided)
|
|
611
|
+
* @default undefined // (feature inactive if not provided)
|
|
485
612
|
*/
|
|
486
613
|
ignoreDomainExtensions?: Set<string> | string[];
|
|
487
614
|
};
|
|
@@ -493,146 +620,188 @@ type ResKeepNullable<T> = T extends string ? string : T extends undefined ? unde
|
|
|
493
620
|
* * ***Utility: `normalizePathname`.***
|
|
494
621
|
* --------------------------------------------------------
|
|
495
622
|
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
623
|
+
* **Normalizes any pathname or URL string to a clean, predictable format, useful for routing, file paths, and URL handling.**
|
|
624
|
+
*
|
|
625
|
+
* ---
|
|
626
|
+
* - **Handles:**
|
|
627
|
+
* - Leading/trailing spaces.
|
|
628
|
+
* - Internal spaces in path segments.
|
|
629
|
+
* - Redundant slashes (`//`).
|
|
630
|
+
* - Full URLs vs relative paths.
|
|
631
|
+
* - Query (`?`) and hash (`#`) preservation.
|
|
632
|
+
* - Unicode & emoji characters.
|
|
633
|
+
* - Optional nullable preservation (`keepNullable`).
|
|
634
|
+
* - Optional trailing slash preservation (`keepTrailingSlash`).
|
|
635
|
+
* - Optional removal of localhost first segment (`localhostDomain`).
|
|
636
|
+
* - Prevention of false-positive domain stripping (`ignoreDomainExtensions`).
|
|
637
|
+
* ---
|
|
511
638
|
* - **Key Steps Internally:**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
639
|
+
* 1. Validate `options` (plain object, correct types).
|
|
640
|
+
* 2. Validate `defaultPath` (non-empty string if `keepNullable` is false).
|
|
641
|
+
* 3. Validate `ignoreDomainExtensions` (Set<string> | string[], each starts with `.`).
|
|
642
|
+
* 4. Handle nullable:
|
|
643
|
+
* - Returns `null` / `undefined` if `keepNullable: true`.
|
|
644
|
+
* - Otherwise uses `defaultPath`.
|
|
645
|
+
* 5. Trim spaces, remove internal spaces.
|
|
646
|
+
* 6. If full URL: parse using `URL` constructor.
|
|
647
|
+
* 7. If relative path or domain-like:
|
|
648
|
+
* - Remove `localhost`/`localhost:port` if `localhostDomain`.
|
|
649
|
+
* - Remove first segment if domain-like and **not** in `ignoreDomainExtensions`.
|
|
650
|
+
* 8. Normalize slashes.
|
|
651
|
+
* 9. Ensure leading slash.
|
|
652
|
+
* 10. Handle trailing slash.
|
|
653
|
+
* 11. Decode Unicode safely.
|
|
654
|
+
* 12. Return normalized pathname + search + hash.
|
|
655
|
+
* ---
|
|
529
656
|
* - **Error Handling:**
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
*
|
|
657
|
+
* - ***TypeError***:
|
|
658
|
+
* - `defaultPath` invalid (non-string or empty) when `keepNullable: false`.
|
|
659
|
+
* - `keepNullable`, `keepTrailingSlash`, `localhostDomain` not boolean.
|
|
660
|
+
* - `ignoreDomainExtensions` invalid.
|
|
661
|
+
* - ***NormalizePathnameError*** (extends ***Error***):
|
|
662
|
+
* - Invalid URL parsing.
|
|
663
|
+
* - Unexpected normalization errors.
|
|
664
|
+
* ---
|
|
538
665
|
* - **Options:**
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
666
|
+
* ```ts
|
|
667
|
+
* {
|
|
668
|
+
* // fallback if invalid path, default: "/"
|
|
669
|
+
* defaultPath?: string;
|
|
670
|
+
* // preserve null/undefined, default: false
|
|
671
|
+
* keepNullable?: boolean;
|
|
672
|
+
* // preserve trailing slash, default: false
|
|
673
|
+
* keepTrailingSlash?: boolean;
|
|
674
|
+
* // remove localhost:port first segment, default: false
|
|
675
|
+
* localhostDomain?: boolean;
|
|
676
|
+
* // prevent domain stripping, default: undefined
|
|
677
|
+
* ignoreDomainExtensions?: Set<string> | string[];
|
|
678
|
+
* }
|
|
679
|
+
* ```
|
|
680
|
+
*
|
|
681
|
+
* ---
|
|
553
682
|
*
|
|
554
683
|
* @example
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
684
|
+
* 1. #### Basic path cleaning:
|
|
685
|
+
* ```ts
|
|
686
|
+
* normalizePathname(" /foo//bar ");
|
|
687
|
+
* // ➔ "/foo/bar"
|
|
688
|
+
* ```
|
|
689
|
+
* ---
|
|
690
|
+
* 2. #### Trailing slash control:
|
|
691
|
+
* ```ts
|
|
692
|
+
* normalizePathname("/api//v1//user//", { keepTrailingSlash: true });
|
|
693
|
+
* // ➔ "/api/v1/user/"
|
|
694
|
+
* normalizePathname("/api//v1//user//", { keepTrailingSlash: false });
|
|
695
|
+
* // ➔ "/api/v1/user"
|
|
696
|
+
* ```
|
|
697
|
+
* ---
|
|
698
|
+
* 3. #### Full URL normalization:
|
|
699
|
+
* ```ts
|
|
700
|
+
* normalizePathname("https://example.com//path///to/resource?x=1#hash");
|
|
701
|
+
* // ➔ "/path/to/resource?x=1#hash"
|
|
702
|
+
* ```
|
|
703
|
+
* ---
|
|
704
|
+
* 4. #### Null/undefined preservation:
|
|
705
|
+
* ```ts
|
|
706
|
+
* normalizePathname(null, { keepNullable: true });
|
|
707
|
+
* // ➔ null
|
|
708
|
+
* normalizePathname(undefined, { keepNullable: true });
|
|
709
|
+
* // ➔ undefined
|
|
710
|
+
* ```
|
|
711
|
+
* ---
|
|
712
|
+
* 5. #### Default fallback:
|
|
713
|
+
* ```ts
|
|
714
|
+
* normalizePathname("", { defaultPath: "/home" });
|
|
715
|
+
* // ➔ "/home"
|
|
716
|
+
* ```
|
|
717
|
+
* ---
|
|
718
|
+
* 6. #### Localhost removal:
|
|
719
|
+
* ```ts
|
|
720
|
+
* normalizePathname("localhost:3000/path/to/resource", { localhostDomain: true });
|
|
721
|
+
* // ➔ "/path/to/resource"
|
|
722
|
+
* ```
|
|
723
|
+
* ---
|
|
724
|
+
* 7. #### Prevent false-positive domain stripping:
|
|
725
|
+
* ```ts
|
|
726
|
+
* normalizePathname("archive.tar.gz#download", { ignoreDomainExtensions: [".tar.gz"] });
|
|
727
|
+
* // ➔ "/archive.tar.gz#download"
|
|
728
|
+
* normalizePathname("image.png?version=2", { ignoreDomainExtensions: [".png"] });
|
|
729
|
+
* // ➔ "/image.png?version=2"
|
|
730
|
+
* ```
|
|
731
|
+
* ---
|
|
732
|
+
* 8. #### Emojis and Unicode:
|
|
733
|
+
* ```ts
|
|
734
|
+
* normalizePathname("🔥//deep//path///🚀");
|
|
735
|
+
* // ➔ "/🔥/deep/path/🚀"
|
|
736
|
+
* ```
|
|
737
|
+
* ---
|
|
738
|
+
* 9. #### Query-only or hash-only:
|
|
739
|
+
* ```ts
|
|
740
|
+
* normalizePathname("?page=2");
|
|
741
|
+
* // ➔ "/?page=2"
|
|
742
|
+
* normalizePathname("#section3");
|
|
743
|
+
* // ➔ "/#section3"
|
|
744
|
+
* ```
|
|
745
|
+
* ---
|
|
746
|
+
* 10. #### Complex nested paths:
|
|
747
|
+
* ```ts
|
|
748
|
+
* normalizePathname(" //nested///folder//file.txt ");
|
|
749
|
+
* // ➔ "/nested/folder/file.txt"
|
|
750
|
+
* ```
|
|
751
|
+
* ---
|
|
752
|
+
* 11. #### Invalid URL triggers error:
|
|
753
|
+
* ```ts
|
|
754
|
+
* try {
|
|
755
|
+
* normalizePathname("http://");
|
|
756
|
+
* } catch (e) {
|
|
757
|
+
* // console.log(e);
|
|
758
|
+
* }
|
|
759
|
+
* ```
|
|
760
|
+
* ---
|
|
761
|
+
* 12. #### First segment is domain but ignored due to extension:
|
|
762
|
+
* ```ts
|
|
763
|
+
* normalizePathname("example.tar.bz/file", { ignoreDomainExtensions: [".tar.bz"] });
|
|
764
|
+
* // ➔ "/example.tar.bz/file"
|
|
765
|
+
* ```
|
|
613
766
|
*/
|
|
614
767
|
declare function normalizePathname<T>(pathname: T, options?: NormalizePathnameOptionsKeepNullableFalse): ResUnKeepNullable<T>;
|
|
615
768
|
declare function normalizePathname<T>(pathname: T, options?: NormalizePathnameOptionsKeepNullableTrue): ResKeepNullable<T>;
|
|
616
769
|
type FormatEnvPortOptions = {
|
|
617
|
-
/**
|
|
770
|
+
/** -----------------------------------------------
|
|
771
|
+
* * ***Add prefix with a colon, defaultValue: `false`.***
|
|
772
|
+
* ------------------------------------------------
|
|
773
|
+
*
|
|
774
|
+
* - ***⚠️ Warning***:
|
|
775
|
+
* - Non-boolean values will throw `TypeError`.
|
|
618
776
|
*
|
|
777
|
+
* ---
|
|
619
778
|
* @default false
|
|
620
779
|
*/
|
|
621
780
|
prefixColon?: boolean;
|
|
622
781
|
};
|
|
623
782
|
/** -----------------------------------------------
|
|
624
783
|
* * ***Utility: `formatEnvPort`.***
|
|
625
|
-
*
|
|
784
|
+
* ------------------------------------------------
|
|
626
785
|
* **Retrieves and formats an environment port variable.**
|
|
786
|
+
*
|
|
787
|
+
* ---
|
|
627
788
|
* - **Behavior:**
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
789
|
+
* - Extracts only digits from the input.
|
|
790
|
+
* - If no digits found, returns an empty string.
|
|
791
|
+
* - By default does NOT prefix with a colon.
|
|
792
|
+
* - Use `{ prefixColon: true }` to prefix with a colon, invalid type `prefixColon` will throw **TypeError**.
|
|
793
|
+
*
|
|
794
|
+
* ---
|
|
632
795
|
* @param {string | null | undefined} envVar The environment variable string.
|
|
633
796
|
* @param {FormatEnvPortOptions} [options] Optional object: `{ prefixColon?: boolean }`.
|
|
634
|
-
*
|
|
797
|
+
*
|
|
798
|
+
* ---
|
|
635
799
|
* @throws **{@link TypeError | `TypeError`}** if `options` is not an object or `prefixColon` is not boolean.
|
|
800
|
+
*
|
|
801
|
+
* ---
|
|
802
|
+
* @returns {string} A string like `":8080"` or `"8080"`, or `""` if no digits.
|
|
803
|
+
*
|
|
804
|
+
* ---
|
|
636
805
|
* @example
|
|
637
806
|
* formatEnvPort("port:8080");
|
|
638
807
|
* // ➔ "8080"
|
|
@@ -659,7 +828,11 @@ type PunycodeUtilsJS = {
|
|
|
659
828
|
* ---------------------------------------------------------
|
|
660
829
|
*
|
|
661
830
|
* @param input - The UCS-2 string to decode.
|
|
831
|
+
*
|
|
832
|
+
* ---
|
|
662
833
|
* @returns Array of Unicode code points.
|
|
834
|
+
*
|
|
835
|
+
* ---
|
|
663
836
|
* @example
|
|
664
837
|
* punycodeUtilsJS.ucs2.decode("𐍈");
|
|
665
838
|
* // ➔ [66376]
|
|
@@ -670,7 +843,11 @@ type PunycodeUtilsJS = {
|
|
|
670
843
|
* ---------------------------------------------------------
|
|
671
844
|
*
|
|
672
845
|
* @param points - Array of Unicode code points.
|
|
846
|
+
*
|
|
847
|
+
* ---
|
|
673
848
|
* @returns Encoded string.
|
|
849
|
+
*
|
|
850
|
+
* ---
|
|
674
851
|
* @example
|
|
675
852
|
* punycodeUtilsJS.ucs2.encode([66376]);
|
|
676
853
|
* // ➔ "𐍈"
|
|
@@ -682,7 +859,11 @@ type PunycodeUtilsJS = {
|
|
|
682
859
|
* ---------------------------------------------------------
|
|
683
860
|
*
|
|
684
861
|
* @param input - The `Punycode-UtilsJS` string to decode.
|
|
862
|
+
*
|
|
863
|
+
* ---
|
|
685
864
|
* @returns Decoded Unicode string.
|
|
865
|
+
*
|
|
866
|
+
* ---
|
|
686
867
|
* @example
|
|
687
868
|
* punycodeUtilsJS.decode("xn--fsq");
|
|
688
869
|
* // ➔ "ü"
|
|
@@ -693,7 +874,11 @@ type PunycodeUtilsJS = {
|
|
|
693
874
|
* ---------------------------------------------------------
|
|
694
875
|
*
|
|
695
876
|
* @param input - Unicode string to encode.
|
|
877
|
+
*
|
|
878
|
+
* ---
|
|
696
879
|
* @returns `Punycode-UtilsJS` string.
|
|
880
|
+
*
|
|
881
|
+
* ---
|
|
697
882
|
* @example
|
|
698
883
|
* punycodeUtilsJS.encode("ü");
|
|
699
884
|
* // ➔ "xn--fsq"
|
|
@@ -704,7 +889,11 @@ type PunycodeUtilsJS = {
|
|
|
704
889
|
* ---------------------------------------------------------
|
|
705
890
|
*
|
|
706
891
|
* @param input - Domain or label string.
|
|
892
|
+
*
|
|
893
|
+
* ---
|
|
707
894
|
* @returns ASCII string suitable for DNS.
|
|
895
|
+
*
|
|
896
|
+
* ---
|
|
708
897
|
* @example
|
|
709
898
|
* punycodeUtilsJS.toASCII("пример.рф");
|
|
710
899
|
* // ➔ "xn--e1afmkfd.xn--p1ai"
|
|
@@ -715,7 +904,11 @@ type PunycodeUtilsJS = {
|
|
|
715
904
|
* ---------------------------------------------------------
|
|
716
905
|
*
|
|
717
906
|
* @param input - ASCII string (with xn-- prefix if needed).
|
|
907
|
+
*
|
|
908
|
+
* ---
|
|
718
909
|
* @returns Unicode string.
|
|
910
|
+
*
|
|
911
|
+
* ---
|
|
719
912
|
* @example
|
|
720
913
|
* punycodeUtilsJS.toUnicode("xn--e1afmkfd.xn--p1ai");
|
|
721
914
|
* // ➔ "пример.рф"
|
|
@@ -725,10 +918,9 @@ type PunycodeUtilsJS = {
|
|
|
725
918
|
/** ---------------------------------------------------------
|
|
726
919
|
* * ***`Punycode-UtilsJS` object exposing all API functions and version.***
|
|
727
920
|
* ---------------------------------------------------------
|
|
728
|
-
* Provides encoding and decoding of Unicode domain names to ASCII (`Punycode-UtilsJS`)
|
|
729
|
-
* and vice versa.
|
|
921
|
+
* **Provides encoding and decoding of Unicode domain names to ASCII (`Punycode-UtilsJS`) and vice versa.**
|
|
730
922
|
*
|
|
731
|
-
* - Useful for IDN (Internationalized Domain Names) support.
|
|
923
|
+
* - Useful for `IDN` (**Internationalized Domain Names**) support.
|
|
732
924
|
*/
|
|
733
925
|
declare const punycodeUtilsJS: PunycodeUtilsJS;
|
|
734
926
|
/**
|