@rzl-zone/utils-js 3.13.0-beta.3 → 3.13.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/.references/index.d.cts +1 -1
- package/dist/.references/index.d.ts +1 -1
- package/dist/{assertIsArray-DWsgvahU.cjs → assertIsArray-BgdgVjDu.cjs} +3 -3
- package/dist/{assertIsArray-DWsgvahU.cjs.map → assertIsArray-BgdgVjDu.cjs.map} +1 -1
- package/dist/{assertIsArray-C2rkhR9M.js → assertIsArray-hZyYKvLb.js} +3 -3
- package/dist/{assertIsArray-C2rkhR9M.js.map → assertIsArray-hZyYKvLb.js.map} +1 -1
- package/dist/{assertIsBoolean-Clc7Vw4v.js → assertIsBoolean-9-huIcIR.js} +2 -2
- package/dist/{assertIsBoolean-Clc7Vw4v.js.map → assertIsBoolean-9-huIcIR.js.map} +1 -1
- package/dist/{assertIsBoolean-BKcvET7Z.cjs → assertIsBoolean-JGpkg5ju.cjs} +2 -2
- package/dist/{assertIsBoolean-BKcvET7Z.cjs.map → assertIsBoolean-JGpkg5ju.cjs.map} +1 -1
- package/dist/{assertIsString-Ddz4y81W.js → assertIsString-CcOpQqcv.js} +3 -3
- package/dist/{assertIsString-Ddz4y81W.js.map → assertIsString-CcOpQqcv.js.map} +1 -1
- package/dist/{assertIsString-DxIqUfF1.cjs → assertIsString-UR6QjqyZ.cjs} +3 -3
- package/dist/{assertIsString-DxIqUfF1.cjs.map → assertIsString-UR6QjqyZ.cjs.map} +1 -1
- package/dist/assertions/index.cjs +5 -5
- package/dist/assertions/index.d.cts +2 -2
- package/dist/assertions/index.d.ts +2 -2
- package/dist/assertions/index.js +5 -5
- 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-Bu5c_RZ9.cjs → conversions-DLt2zlyu.cjs} +12 -12
- package/dist/{conversions-Bu5c_RZ9.cjs.map → conversions-DLt2zlyu.cjs.map} +1 -1
- package/dist/{conversions-DjfhrQE9.js → conversions-Du6GC5JA.js} +12 -12
- package/dist/{conversions-DjfhrQE9.js.map → conversions-Du6GC5JA.js.map} +1 -1
- package/dist/events/index.cjs +4 -4
- package/dist/events/index.d.cts +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +4 -4
- 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-DF4887ia.cjs → formatters-C0t5CdX-.cjs} +10 -10
- package/dist/{formatters-DF4887ia.cjs.map → formatters-C0t5CdX-.cjs.map} +1 -1
- package/dist/{formatters-CidRTj87.js → formatters-RomzqDp_.js} +10 -10
- package/dist/{formatters-CidRTj87.js.map → formatters-RomzqDp_.js.map} +1 -1
- package/dist/generators/index.cjs +5 -5
- package/dist/generators/index.d.cts +2 -2
- package/dist/generators/index.d.ts +2 -2
- package/dist/generators/index.js +5 -5
- package/dist/{index-C02XatNH.d.ts → index-50G4edI1.d.ts} +2 -2
- package/dist/{index-DC7eXTo_.d.cts → index-5DpyzfpU.d.ts} +1 -1
- package/dist/{index-Dq5vUFfH.d.ts → index-B6Xg9Z8l.d.ts} +1 -1
- package/dist/{index-CHwf6vUh.d.ts → index-BFI4R7Pn.d.ts} +1 -1
- package/dist/{index-BK86Fnvd.d.ts → index-BcKPWWfh.d.ts} +2 -2
- package/dist/{index-YeyLvCAr.d.cts → index-CMcxcN7w.d.cts} +1 -1
- package/dist/{index-DPBypj6v.d.ts → index-CPc-TTMc.d.cts} +1 -1
- package/dist/{index-CIBhF2hQ.d.cts → index-D-5AsV9K.d.cts} +1 -1
- package/dist/{index-BZMwAuLf.d.ts → index-DM_0q4CY.d.cts} +1 -1
- package/dist/{index-CX8gCrW8.d.ts → index-DoteSYTy.d.cts} +3 -3
- package/dist/{index-Cyu3Mh3N.d.cts → index-bGRsmkyA.d.ts} +3 -3
- package/dist/{index-CyZz4BHD.d.cts → index-hsSSKuvW.d.ts} +1 -1
- package/dist/{index-BbCX319b.d.cts → index-s7h0w-8H.d.cts} +2 -2
- package/dist/{index-CWgiyaU3.d.cts → index-tYmZ3X4Y.d.cts} +2 -2
- package/dist/{isBigInt-BePsmNsm.cjs → isBigInt-C0gHDkh4.cjs} +2 -2
- package/dist/{isBigInt-BePsmNsm.cjs.map → isBigInt-C0gHDkh4.cjs.map} +1 -1
- package/dist/{isBigInt-Cx4j_cju.js → isBigInt-bbW78ITJ.js} +2 -2
- package/dist/{isBigInt-Cx4j_cju.js.map → isBigInt-bbW78ITJ.js.map} +1 -1
- package/dist/{isEmptyObject-Dp4pCGTa.js → isEmptyObject-CZsFdN7x.js} +3 -3
- package/dist/{isEmptyObject-Dp4pCGTa.js.map → isEmptyObject-CZsFdN7x.js.map} +1 -1
- package/dist/{isEmptyObject-DYypq92-.cjs → isEmptyObject-D-fETD_f.cjs} +3 -3
- package/dist/{isEmptyObject-DYypq92-.cjs.map → isEmptyObject-D-fETD_f.cjs.map} +1 -1
- package/dist/{isEmptyString-CzY-9G-x.cjs → isEmptyString-Dx6OM5PL.cjs} +3 -3
- package/dist/{isEmptyString-CzY-9G-x.cjs.map → isEmptyString-Dx6OM5PL.cjs.map} +1 -1
- package/dist/{isEmptyString-BXgKFQxw.js → isEmptyString-pmcf-orv.js} +3 -3
- package/dist/{isEmptyString-BXgKFQxw.js.map → isEmptyString-pmcf-orv.js.map} +1 -1
- package/dist/{isEmptyValue-B7Zd9DI3.js → isEmptyValue-CkiXENcT.js} +5 -5
- package/dist/{isEmptyValue-B7Zd9DI3.js.map → isEmptyValue-CkiXENcT.js.map} +1 -1
- package/dist/{isEmptyValue-Ci3kVU4E.cjs → isEmptyValue-v6BsHBiu.cjs} +5 -5
- package/dist/{isEmptyValue-Ci3kVU4E.cjs.map → isEmptyValue-v6BsHBiu.cjs.map} +1 -1
- package/dist/{isEqual-Bd7mClU4.cjs → isEqual-CZxetLzm.cjs} +4 -4
- package/dist/{isEqual-Bd7mClU4.cjs.map → isEqual-CZxetLzm.cjs.map} +1 -1
- package/dist/{isEqual-CylDBGUr.js → isEqual-Dc8fNB2J.js} +4 -4
- package/dist/{isEqual-CylDBGUr.js.map → isEqual-Dc8fNB2J.js.map} +1 -1
- package/dist/{isFinite-D8jhlqPf.cjs → isFinite-0z31xOa2.cjs} +3 -3
- package/dist/{isFinite-D8jhlqPf.cjs.map → isFinite-0z31xOa2.cjs.map} +1 -1
- package/dist/{isFinite-CZ-Aiy4T.js → isFinite-CI59vUHt.js} +3 -3
- package/dist/{isFinite-CZ-Aiy4T.js.map → isFinite-CI59vUHt.js.map} +1 -1
- package/dist/{isInteger-CCJhQ1Mx.cjs → isInteger-DUhd-dyt.cjs} +2 -2
- package/dist/{isInteger-CCJhQ1Mx.cjs.map → isInteger-DUhd-dyt.cjs.map} +1 -1
- package/dist/{isInteger-DK_0nvNU.js → isInteger-DeN5FIAr.js} +2 -2
- package/dist/{isInteger-DK_0nvNU.js.map → isInteger-DeN5FIAr.js.map} +1 -1
- package/dist/{isPlainObject-DtduwtUp.d.ts → isPlainObject-CjoJH9yk.d.ts} +1 -1
- package/dist/{isPlainObject-BGg8uHeL.d.cts → isPlainObject-DvxdHoAf.d.cts} +1 -1
- package/dist/{isServer-C2YtJlD1.js → isServer-BM5GzRpI.js} +2 -2
- package/dist/{isServer-C2YtJlD1.js.map → isServer-BM5GzRpI.js.map} +1 -1
- package/dist/{isServer-CT9EkFKG.cjs → isServer-TOmhgOtP.cjs} +2 -2
- package/dist/{isServer-CT9EkFKG.cjs.map → isServer-TOmhgOtP.cjs.map} +1 -1
- package/dist/{isTypedArray-hcngU0pK.js → isTypedArray-BPerK072.js} +3 -3
- package/dist/{isTypedArray-hcngU0pK.js.map → isTypedArray-BPerK072.js.map} +1 -1
- package/dist/{isTypedArray-BT7YP1S9.cjs → isTypedArray-pAdBFUDl.cjs} +3 -3
- package/dist/{isTypedArray-BT7YP1S9.cjs.map → isTypedArray-pAdBFUDl.cjs.map} +1 -1
- package/dist/{isValidDomain-CXWNcRo6.cjs → isValidDomain-BMcr9vTp.cjs} +6 -6
- package/dist/isValidDomain-BMcr9vTp.cjs.map +1 -0
- package/dist/{isValidDomain-BCN5-tj9.js → isValidDomain-CHKOn79-.js} +6 -6
- package/dist/isValidDomain-CHKOn79-.js.map +1 -0
- package/dist/{noop-BDfC9Zq4.js → noop-BaNz9ls5.js} +2 -2
- package/dist/{noop-BDfC9Zq4.js.map → noop-BaNz9ls5.js.map} +1 -1
- package/dist/{noop-D4tT7tWN.cjs → noop-D4g9yTAW.cjs} +2 -2
- package/dist/{noop-D4tT7tWN.cjs.map → noop-D4g9yTAW.cjs.map} +1 -1
- package/dist/{normalizeSpaces-B289eKyK.js → normalizeSpaces-DupusmF5.js} +3 -3
- package/dist/{normalizeSpaces-B289eKyK.js.map → normalizeSpaces-DupusmF5.js.map} +1 -1
- package/dist/{normalizeSpaces-BTXDP8vZ.cjs → normalizeSpaces-MWiYtSyS.cjs} +3 -3
- package/dist/{normalizeSpaces-BTXDP8vZ.cjs.map → normalizeSpaces-MWiYtSyS.cjs.map} +1 -1
- package/dist/operations/index.cjs +7 -7
- package/dist/operations/index.d.cts +1 -1
- package/dist/operations/index.d.ts +1 -1
- package/dist/operations/index.js +7 -7
- package/dist/parsers/index.cjs +2 -2
- package/dist/parsers/index.d.cts +1 -1
- package/dist/parsers/index.d.ts +1 -1
- package/dist/parsers/index.js +2 -2
- package/dist/{parsers-5G1Lface.cjs → parsers-Bd-YRt6j.cjs} +4 -4
- package/dist/{parsers-5G1Lface.cjs.map → parsers-Bd-YRt6j.cjs.map} +1 -1
- package/dist/{parsers-CNag9LsX.js → parsers-Dl9fFra4.js} +4 -4
- package/dist/{parsers-CNag9LsX.js.map → parsers-Dl9fFra4.js.map} +1 -1
- package/dist/{parsing-CobzHooQ.js → parsing-BG73HUrI.js} +3 -3
- package/dist/{parsing-CobzHooQ.js.map → parsing-BG73HUrI.js.map} +1 -1
- package/dist/{parsing-B6vxp2h8.cjs → parsing-CU_Mc7CF.cjs} +3 -3
- package/dist/{parsing-B6vxp2h8.cjs.map → parsing-CU_Mc7CF.cjs.map} +1 -1
- package/dist/predicates/index.cjs +14 -14
- 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-DlID4Pks.cjs → predicates-Bd4AnXr0.cjs} +11 -11
- package/dist/{predicates-DlID4Pks.cjs.map → predicates-Bd4AnXr0.cjs.map} +1 -1
- package/dist/{predicates-DvLryz_b.js → predicates-VJN-VDha.js} +11 -11
- package/dist/{predicates-DvLryz_b.js.map → predicates-VJN-VDha.js.map} +1 -1
- package/dist/promises/index.cjs +4 -4
- package/dist/promises/index.d.cts +1 -1
- package/dist/promises/index.d.ts +1 -1
- package/dist/promises/index.js +4 -4
- package/dist/{punyCode-DaBFrfga.cjs → punyCode-5wmummgP.cjs} +4 -4
- package/dist/{punyCode-DaBFrfga.cjs.map → punyCode-5wmummgP.cjs.map} +1 -1
- package/dist/{punyCode-GakZYPCT.js → punyCode-C0ft9dER.js} +4 -4
- package/dist/{punyCode-GakZYPCT.js.map → punyCode-C0ft9dER.js.map} +1 -1
- package/dist/{removeSpaces-DhJ1haaH.cjs → removeSpaces-CPj1ABLa.cjs} +3 -3
- package/dist/{removeSpaces-DhJ1haaH.cjs.map → removeSpaces-CPj1ABLa.cjs.map} +1 -1
- package/dist/{removeSpaces-BJ-zNnJq.js → removeSpaces-DpiJ1H1P.js} +3 -3
- package/dist/{removeSpaces-BJ-zNnJq.js.map → removeSpaces-DpiJ1H1P.js.map} +1 -1
- package/dist/rzl-utils.global.js +1 -1
- package/dist/{safeJsonParse-bcBYPjeb.js → safeJsonParse-BxOZgGy7.js} +6 -6
- package/dist/{safeJsonParse-bcBYPjeb.js.map → safeJsonParse-BxOZgGy7.js.map} +1 -1
- package/dist/{safeJsonParse-DiWBPfaE.cjs → safeJsonParse-v7ll9iFG.cjs} +6 -6
- package/dist/{safeJsonParse-DiWBPfaE.cjs.map → safeJsonParse-v7ll9iFG.cjs.map} +1 -1
- package/dist/{safeStableStringify-DSwcrPll.cjs → safeStableStringify-BiUOLBYo.cjs} +4 -4
- package/dist/{safeStableStringify-DSwcrPll.cjs.map → safeStableStringify-BiUOLBYo.cjs.map} +1 -1
- package/dist/{safeStableStringify-C1SA52w7.js → safeStableStringify-C5Gc3ZED.js} +4 -4
- package/dist/{safeStableStringify-C1SA52w7.js.map → safeStableStringify-C5Gc3ZED.js.map} +1 -1
- package/dist/strings/index.cjs +5 -5
- package/dist/strings/index.d.cts +2 -2
- package/dist/strings/index.d.ts +2 -2
- package/dist/strings/index.js +5 -5
- package/dist/tailwind/index.cjs +2 -2
- package/dist/tailwind/index.d.cts +2 -2
- package/dist/tailwind/index.d.ts +2 -2
- package/dist/tailwind/index.js +2 -2
- package/dist/{tailwind-D62asDBR.js → tailwind-CxI2DXpR.js} +5 -5
- package/dist/{tailwind-D62asDBR.js.map → tailwind-CxI2DXpR.js.map} +1 -1
- package/dist/{tailwind-DMPTwJ0X.cjs → tailwind-DhKiKZAc.cjs} +5 -5
- package/dist/{tailwind-DMPTwJ0X.cjs.map → tailwind-DhKiKZAc.cjs.map} +1 -1
- package/dist/{toStringArrayUnRecursive-DBicbWv8.js → toStringArrayUnRecursive-BaZrCGaR.js} +6 -6
- package/dist/{toStringArrayUnRecursive-DBicbWv8.js.map → toStringArrayUnRecursive-BaZrCGaR.js.map} +1 -1
- package/dist/{toStringArrayUnRecursive-DJ8JBO3N.cjs → toStringArrayUnRecursive-BuRBWRcB.cjs} +6 -6
- package/dist/{toStringArrayUnRecursive-DJ8JBO3N.cjs.map → toStringArrayUnRecursive-BuRBWRcB.cjs.map} +1 -1
- package/dist/urls/index.cjs +3 -3
- package/dist/urls/index.d.cts +1 -1
- package/dist/urls/index.d.ts +1 -1
- package/dist/urls/index.js +3 -3
- package/dist/{urls-DCjjZNTH.cjs → urls-CyhKg1Cn.cjs} +11 -11
- package/dist/{urls-DCjjZNTH.cjs.map → urls-CyhKg1Cn.cjs.map} +1 -1
- package/dist/{urls-DTndjYDD.js → urls-nr2hUK75.js} +11 -11
- package/dist/{urls-DTndjYDD.js.map → urls-nr2hUK75.js.map} +1 -1
- package/package.json +5 -5
- package/dist/isValidDomain-BCN5-tj9.js.map +0 -1
- package/dist/isValidDomain-CXWNcRo6.cjs.map +0 -1
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
* ========================================================================
|
|
3
3
|
* @rzl-zone/utils-js
|
|
4
4
|
* ------------------------------------------------------------------------
|
|
5
|
-
* Version: `3.13.0
|
|
5
|
+
* Version: `3.13.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
|
* ========================================================================
|
|
9
9
|
*/
|
|
10
|
-
import { A as isPlainObject, E as isNull, F as isBoolean, M as isArray, N as isNil, P as isFunction, S as isUndefined, T as assertIsPlainObject, b as hasOwnProp, f as isSet, k as isString, p as isNonEmptyArray, r as getPreciseType, t as assertIsBoolean, v as isError, w as isNumber, y as isNonEmptyString } from "./assertIsBoolean-
|
|
11
|
-
import { t as assertIsArray } from "./assertIsArray-
|
|
12
|
-
import { t as toStringArrayUnRecursive } from "./toStringArrayUnRecursive-
|
|
13
|
-
import { t as safeStableStringify } from "./safeStableStringify-
|
|
14
|
-
import { t as isEmptyString } from "./isEmptyString-
|
|
15
|
-
import { t as isEmptyValue } from "./isEmptyValue-
|
|
16
|
-
import { t as isInteger } from "./isInteger-
|
|
17
|
-
import { i as isURL, n as EOL, r as joinLines, t as isValidDomain } from "./isValidDomain-
|
|
18
|
-
import { n as normalizeString, t as removeSpaces } from "./removeSpaces-
|
|
10
|
+
import { A as isPlainObject, E as isNull, F as isBoolean, M as isArray, N as isNil, P as isFunction, S as isUndefined, T as assertIsPlainObject, b as hasOwnProp, f as isSet, k as isString, p as isNonEmptyArray, r as getPreciseType, t as assertIsBoolean, v as isError, w as isNumber, y as isNonEmptyString } from "./assertIsBoolean-9-huIcIR.js";
|
|
11
|
+
import { t as assertIsArray } from "./assertIsArray-hZyYKvLb.js";
|
|
12
|
+
import { t as toStringArrayUnRecursive } from "./toStringArrayUnRecursive-BaZrCGaR.js";
|
|
13
|
+
import { t as safeStableStringify } from "./safeStableStringify-C5Gc3ZED.js";
|
|
14
|
+
import { t as isEmptyString } from "./isEmptyString-pmcf-orv.js";
|
|
15
|
+
import { t as isEmptyValue } from "./isEmptyValue-CkiXENcT.js";
|
|
16
|
+
import { t as isInteger } from "./isInteger-DeN5FIAr.js";
|
|
17
|
+
import { i as isURL, n as EOL, r as joinLines, t as isValidDomain } from "./isValidDomain-CHKOn79-.js";
|
|
18
|
+
import { n as normalizeString, t as removeSpaces } from "./removeSpaces-DpiJ1H1P.js";
|
|
19
19
|
const constructURL = (baseUrl, queryParams, removeParams) => {
|
|
20
20
|
if (isString(baseUrl)) {
|
|
21
21
|
if (isEmptyString(baseUrl)) throw new TypeError("First parameter (`baseUrl`) cannot be an empty-string.");
|
|
@@ -260,4 +260,4 @@ const formatEnvPort = (envVar, options = {}) => {
|
|
|
260
260
|
return prefixColon ? `:${digitsOnly}` : digitsOnly;
|
|
261
261
|
};
|
|
262
262
|
export { extractURLs as a, normalizePathname as i, getPrefixPathname as n, constructURL as o, getFirstPrefixPathname as r, formatEnvPort as t };
|
|
263
|
-
//# sourceMappingURL=urls-
|
|
263
|
+
//# sourceMappingURL=urls-nr2hUK75.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"urls-DTndjYDD.js","names":[],"sources":["../src/urls/builders/constructURL.ts","../src/urls/extractors/extractURLs.ts","../src/urls/_private/NormalizePathnameError.ts","../src/urls/pathname/normalizePathname.ts","../src/urls/pathname/getFirstPrefixPathname.ts","../src/urls/pathname/getPrefixPathname.ts","../src/urls/utils/formatEnvPort.ts"],"sourcesContent":["import { isURL } from \"@/predicates/is/isURL\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isNumber } from \"@/predicates/is/isNumber\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isFunction } from \"@/predicates/is/isFunction\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isEmptyValue } from \"@/predicates/is/isEmptyValue\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { normalizeString } from \"@/strings/sanitizations/normalizeString\";\n\nimport { assertIsArray } from \"@/assertions/objects/assertIsArray\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\nimport { toStringArrayUnRecursive } from \"@/conversions/arrays/casts/toStringArrayUnRecursive\";\n\n/** ----------------------------------------------------------\n * * ***Type-Utility: `QueryParamPairs`.***\n * ----------------------------------------------------------\n * **Represents a non-empty array of key–value pairs.**\n * @description\n * Type for `queryParams` parameter, the second parameter of ***`constructURL` utility function***.\n * - **Behavior:**\n * - Each inner tuple strictly follows the `[string, string | number]` shape.\n * - Ensures the outer array contains **at least one pair** (non-empty).\n * - Commonly used for URL construction parameters,\n * query string segments, or other key–value structured data.\n * @example\n * // ✅ valid usage\n * const params: QueryParamPairs = [\n * [\"foo\", 1],\n * [\"bar\", \"baz\"]\n * ];\n * constructURL(\"https://example.com\", params);\n *\n * // ❌ invalid: must contain at least one item\n * const empty: QueryParamPairs = [];\n *\n * // ❌ invalid: key without value pairs.\n * const empty2: QueryParamPairs = [[\"key\"]];\n */\nexport type QueryParamPairs = [\n [string, string | number],\n ...[string, string | number][]\n];\n\n/** ---------------------------------\n * * ***Utility: `constructURL`.***\n * ---------------------------------\n * **Constructs a valid URL with optional query parameters and allows selective removal of duplicate parameters.**\n * @param {string | URL} baseUrl The base URL to build upon. Must include protocol (e.g., `\"https://\"`), `domain`, and may include port and existing query parameters.\n * @param {Iterable<[string, string]> | URLSearchParamsIterator<[string, string]> | QueryParamPairs} [queryParams]\n * Additional query parameters to append or overwrite on the URL.\n * - Accepts any iterable of key-value pairs (like `new URLSearchParams().entries()` and `[[string, string | number]...]`).\n * @param {string[]} [removeParams]\n * A list of query parameter keys to remove from the final URL, whether they were in the base URL or provided queryParams.\n * @returns {URL} A new URL object representing the constructed URL with merged and cleaned query parameters.\n * @throws **{@link TypeError | `TypeError`}** if `baseUrl` is not a valid non-empty string or URL object, or if `queryParams` is not iterable, or if `removeParams` is not an array of strings.\n * @example\n * 1. #### Basic Usage:\n * ```ts\n * constructURL(\n * \"https://example.com/path\",\n * new URLSearchParams({ a: \"1\", b: \"2\" }).entries()\n * );\n * // ➔ URL { href: \"https://example.com/path?a=1&b=2\", ... }\n * ```\n * 2. #### Remove parameters from Base and Added:\n * ```ts\n * // with new URLSearchParams({ ... }).entries();\n * constructURL(\n * \"https://example.com/path?foo=1&bar=2\",\n * new URLSearchParams({ bar: \"ignored\", baz: \"3\" }).entries(),\n * [\"bar\"]\n * );\n * // ➔ URL { href: \"https://example.com/path?foo=1&baz=3\", ... }\n *\n * // with [[string, string | number]...]\n * constructURL(\n * \"https://example.com/path?foo=1&bar=2\",\n * [[\"bar\", \"ignored\"],[\"baz\", 3]],\n * [\"bar\"]\n * );\n * // ➔ URL { href: \"https://example.com/path?foo=1&baz=3\", ... }\n *\n * const params: QueryParamPairs = [\n * [\"foo\", 1],\n * [\"bar\", 2],\n * [\"baz\", 3]\n * ];\n *\n * constructURL(\"https://example.com\", params, [\"bar\"]);\n * // ➔ URL { href: \"https://example.com/?foo=1&baz=3\", ... }\n * ```\n */\nexport const constructURL = (\n baseUrl: string | URL,\n queryParams?:\n | URLSearchParamsIterator<[string, string | number]>\n | QueryParamPairs,\n removeParams?: string[]\n): URL => {\n if (isString(baseUrl)) {\n if (isEmptyString(baseUrl)) {\n throw new TypeError(\n \"First parameter (`baseUrl`) cannot be an empty-string.\"\n );\n }\n baseUrl = normalizeString(baseUrl);\n } else if (!isURL(baseUrl)) {\n throw new TypeError(\n `First parameter (\\`baseUrl\\`) must be of type an URL instance or a \\`string\\` and a non empty-string, but received: \\`${getPreciseType(\n baseUrl\n )}\\`, with current value: \\`${safeStableStringify(baseUrl, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n // Check removeParams\n if (!isUndefined(removeParams)) {\n assertIsArray(removeParams, {\n message: ({ currentType, validType }) =>\n `Third parameter (\\`removeParams\\`) must be of type \\`${validType} of strings\\`, but received: \\`${currentType}\\`.`\n });\n\n if (!removeParams.every((param) => isNonEmptyString(param))) {\n throw new TypeError(\n \"Third parameter (`removeParams`) must be of type `array` and contains `string` only and non empty-string.\"\n );\n }\n }\n\n try {\n // Check queryParams\n if (\n !isUndefined(queryParams) &&\n !isFunction(queryParams[Symbol.iterator])\n ) {\n throw new TypeError(\n `Second parameter (\\`queryParams\\`) must be iterable (like URLSearchParams.entries() or an array of [[string, string | number]...]), but received: \\`${getPreciseType(\n queryParams\n )}\\`, with value: \\`${safeStableStringify(queryParams, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n const urlInstance = new URL(baseUrl);\n\n // Add query parameters if provided\n if (!isUndefined(queryParams)) {\n const paramObject = Object.fromEntries(queryParams);\n\n if (!isEmptyValue(paramObject)) {\n // existing params\n const mergedParams = new URLSearchParams(urlInstance.search);\n\n // add / overwrite from queryParams\n for (const [key, value] of Object.entries(paramObject)) {\n if (\n !isNonEmptyString(value) &&\n !isNumber(value, { includeNaN: true })\n ) {\n throw new TypeError(\n `Second parameter (\\`queryParams\\`) must be iterable (like URLSearchParams.entries() or an array of [[string, string | number]...]), but received: \\`${getPreciseType(\n queryParams\n )}\\`, with value: \\`${safeStableStringify(queryParams, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n mergedParams.set(key, String(value));\n }\n\n // Remove specific query parameters if needed\n if (removeParams?.length) {\n toStringArrayUnRecursive(removeParams).map((paramKey) => {\n mergedParams.delete(paramKey);\n });\n }\n\n urlInstance.search = mergedParams.toString();\n }\n }\n\n // Remove query parameters directly from URL if needed\n removeParams?.forEach((param) => urlInstance.searchParams.delete(param));\n\n return urlInstance;\n } catch (error) {\n if (isError(error)) throw error;\n\n throw new Error(\n \"Failed to construct a valid URL in `constructURL()`, Error:\" + error,\n { cause: error }\n );\n }\n};\n","import { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\n/** ---------------------------------\n * * ***Utility: `extractURLs`.***\n * ---------------------------------\n * **Extracts all valid URLs from a given string.**\n * @description\n * This function scans the input url and returns an array of URLs\n * that match a valid `http` or `https` format.\n * - **Supports:**\n * - Internationalized domain names (IDN), e.g. `https://münich.de`\n * - Unicode & emoji paths, e.g. `https://example.com/🎉/page`\n * - Long URLs with multiple queries & fragments, e.g. `https://example.com/path?foo=1#hash`\n * - **Ignores:**\n * - Non-string inputs\n * - Empty or whitespace-only strings\n * - Non-HTTP(S) protocols (ftp, mailto, etc)\n * @param {string | null | undefined} url - The input string containing potential URLs.\n * @returns {string[] | null} An array of extracted URLs or `null` if no URLs are found.\n * @example\n * extractURLs(\"Visit https://example.com and https://例子.公司\");\n * // ➔ [\"https://example.com\", \"https://例子.公司\"]\n * extractURLs(\"Here: https://example.com/🎉/page\");\n * // ➔ [\"https://example.com/🎉/page\"]\n * extractURLs(\"ftp://example.com http://example.com\");\n * // ➔ [\"http://example.com\"]\n */\nexport const extractURLs = (\n url: string | null | undefined\n): string[] | null => {\n if (!isNonEmptyString(url)) return null;\n\n let decoded;\n try {\n decoded = decodeURIComponent(url);\n } catch {\n return null;\n }\n\n // Core regex with lookahead\n const urlPattern = /https?:\\/\\/.*?(?=https?:\\/\\/|\\s|$)/g;\n const matches = decoded.match(urlPattern);\n if (!matches) return null;\n\n // Cleanup trailing punctuation and validation protocol\n const cleaned = matches\n .map((url) => url.replace(/[.,;:!?)]*$/, \"\"))\n .filter((url) => {\n try {\n const u = new URL(url);\n return u.protocol === \"http:\" || u.protocol === \"https:\";\n } catch {\n return false;\n }\n });\n\n return cleaned.length ? cleaned : null;\n};\n","import { isFunction } from \"@/predicates/is/isFunction\";\n\n/** ---------------------------------\n * * ***Custom Error for Pathname Normalization Failures***\n * ---------------------------------\n */\nexport class NormalizePathnameError extends Error {\n /** ---------------------------------\n * * ***The original error that triggered this normalization failure.***\n * ---------------------------------\n *\n * **Always available for backward compatibility.**\n */\n public readonly originalError: Error;\n\n constructor(message: string, originalError: Error) {\n // Pass a `cause` option if the runtime supports it (ignored by older engines).\n super(message, isFunction(Error) ? { cause: originalError } : undefined);\n\n this.name = \"NormalizePathnameError\";\n this.originalError = originalError;\n\n // Preserve stack trace when available (Node.js & modern browsers).\n if (isFunction(Error.captureStackTrace)) {\n Error.captureStackTrace(this, NormalizePathnameError);\n } else {\n // Fallback for very old environments.\n this.stack = new Error(message).stack;\n }\n }\n\n /** ---------------------------------\n * * ***Safe JSON representation for logging or IPC.***\n * ---------------------------------\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n stack: this.stack,\n originalError: {\n name: this.originalError.name,\n message: this.originalError.message,\n stack: this.originalError.stack\n }\n };\n }\n}\n","import type { OverrideTypes, Prettify } from \"@rzl-zone/ts-types-plus\";\n\nimport { isSet } from \"@/predicates/is/isSet\";\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isNull } from \"@/predicates/is/isNull\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isValidDomain } from \"@/predicates/is/isValidDomain\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\n\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { NormalizePathnameError } from \"../_private/NormalizePathnameError\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\n\n/** Options when `keepNullable` is false (default).\n *\n * Returns `defaultPath` if `pathname` is empty or invalid.\n */\ntype UnKeepNullableOptions = {\n /** * ***Fallback value returned if `pathname` is empty-string or invalid.***\n *\n * Must be a **`non-empty string`**, defaultValue: `\"/\"`.\n *\n * @default \"/\"\n */\n defaultPath?: string;\n\n /** * ***Whether to preserve `null` or `undefined`, defaultValue: `false`.***\n *\n * @default false\n */\n keepNullable?: false;\n};\n\n/** Options when `keepNullable` is true.\n *\n * Preserves `null` or `undefined` instead of returning `defaultPath`.\n */\ntype KeepNullableOptions = {\n /** * ***Fallback path is ignored when `keepNullable` is true **(except if\n * `pathname` is empty-string or invalid, even this `true`)**,\n * defaultValue: `\"/\"`.***\n *\n * @default \"/\"\n */\n defaultPath?: string;\n\n /** * ***Preserve `null` or `undefined` as-is if `true` (defaultValue: `false`).***\n *\n * - ***⚠️ Notes:***\n * - Keep returning `defaultPath` if `pathname` is empty-string, even this `true`.\n *\n * **Must be `true` in this type.**\n *\n * @default false\n */\n keepNullable?: true;\n};\n\ntype MainNormalizePathnameOptions = {\n /** --------------------------------------------------------\n * * ***Preserve trailing slash at the end of the normalized pathname, defaultValue: `false`.***\n * --------------------------------------------------------\n *\n * @default `false`\n */\n keepTrailingSlash?: boolean;\n\n /** --------------------------------------------------------\n * * ***Allow special localhost domain at the beginning of the pathname.***\n * --------------------------------------------------------\n * @description\n * If `true`, the first segment of the pathname that is `/localhost` or `localhost`\n * (with or without a port, e.g., `localhost:3000`) will be treated as a special domain\n * and **removed** from the normalized pathname.\n *\n * - **Examples (`localhostDomain: true`)**:\n * - `\"/localhost/path\"` ➔ `\"/path\"`\n * - `\"localhost:3000/path\"` ➔ `\"/path\"`\n * - `\"localhost\"` ➔ `\"/\"` (entire path removed)\n *\n * - Only the **first path segment** is affected. Any subsequent occurrences of `\"localhost\"`\n * will remain intact.\n *\n * @default false\n */\n localhostDomain?: boolean;\n\n /**\n * --------------------------------------------------------\n * * ***Custom list of file extensions that prevent the first path segment from being treated as a domain.***\n * --------------------------------------------------------\n *\n * **Description:**\n * - The first segment of a pathname is often interpreted as a domain (e.g., `example.com`).\n * - If this first segment ends with any of the extensions listed here, it will **not** be considered a domain,\n * and will instead be preserved as part of the relative path.\n * - This is useful for cases where filenames appear at the start of a path and you want them treated as relative paths,\n * such as `\"image.png?version=2\"` or `\"archive.tar.gz#download\"`.\n * - Only the **first path segment** is affected; all other segments are processed normally.\n * - **Ignored** if:\n * 1. The pathname starts with a full URL protocol (`http://` or `https://`), e.g., `\"https://example.com/file.png\"`.\n * 2. The first path segment is already a valid domain, e.g., `\"example.com/image.png\"`.\n *\n * **Type & Validation:**\n * - Must be a `Set<string>` or `string[]`.\n * - Each string **must include the leading dot**, e.g., `.png`, `.tar.gz`.\n * - Multi-part extensions (like `.tar.gz`, `.tar.bz`) are supported.\n * - Throws a **TypeError** if:\n * 1. The type is not a `Set<string>` or `string[]`.\n * 2. Any string in the array/set is empty.\n * 3. Any string does not start with a dot (`.`).\n *\n * **Usage Notes:**\n * - Only applied when the first segment is otherwise domain-like **and** pathname is relative or domain-like without protocol.\n * - Query strings (`?x=1`) and hash fragments (`#section`) are preserved.\n *\n * **Examples (relative paths, option active):**\n * ```ts\n * normalizePathname(\"image.png?version=2\", {\n * ignoreDomainExtensions: [\".png\", \".jpg\"]\n * });\n * // ➔ \"/image.png?version=2\"\n *\n * normalizePathname(\"archive.tar.gz#download\", {\n * ignoreDomainExtensions: new Set([\".tar.gz\"])\n * });\n * // ➔ \"/archive.tar.gz#download\"\n *\n * normalizePathname(\"script.js?module=true#top\", {\n * ignoreDomainExtensions: [\".js\"]\n * });\n * // ➔ \"/script.js?module=true#top\"\n * ```\n *\n * **Examples (full URL or explicit domain - option ignored):**\n * ```ts\n * normalizePathname(\"https://example.com/image.png?version=2\", {\n * ignoreDomainExtensions: [\".png\"]\n * });\n * // ➔ \"/image.png?version=2\" // URL is parsed normally; ignoreDomainExtensions has no effect\n *\n * normalizePathname(\"example.com/script.js?module=true#top\", {\n * ignoreDomainExtensions: [\".js\"]\n * });\n * // ➔ \"/script.js?module=true#top\" // domain recognized; option ignored\n * ```\n *\n * **Notes:**\n * - Only the **first path segment** is checked.\n * - Prevents false-positive domain stripping for filenames that look like domains.\n * - Throws **TypeError** if invalid type or invalid string is provided.\n *\n * @default undefined (feature inactive if not provided)\n */\n ignoreDomainExtensions?: Set<string> | string[];\n};\n\n/** Options for main `normalizePathname`.\n *\n * Combines `UnKeepNullableOptions` or `KeepNullableOptions` with trailing slash control.\n */\ntype NormalizePathnameOptions = Prettify<\n MainNormalizePathnameOptions & (UnKeepNullableOptions | KeepNullableOptions)\n>;\n\ntype NormalizePathnameOptionsKeepNullableTrue = MainNormalizePathnameOptions &\n KeepNullableOptions;\ntype NormalizePathnameOptionsKeepNullableFalse = MainNormalizePathnameOptions &\n UnKeepNullableOptions;\n\ntype ResUnKeepNullable<T> = T extends undefined\n ? string\n : T extends null\n ? string\n : T extends null | undefined\n ? string\n : string;\n\ntype ResKeepNullable<T> = T extends string\n ? string\n : T extends undefined\n ? undefined\n : T extends null\n ? null\n : T extends null | undefined\n ? null | undefined\n : string | null | undefined;\n\n/** --------------------------------------------------------\n * * ***Utility: `normalizePathname`.***\n * --------------------------------------------------------\n *\n * - **Description:**\n * Normalizes any pathname or URL string to a clean, predictable format.\n * Useful for routing, file paths, and URL handling.\n * - Handles:\n * - Leading/trailing spaces\n * - Internal spaces in path segments\n * - Redundant slashes (`//`)\n * - Full URLs vs relative paths\n * - Query (`?`) and hash (`#`) preservation\n * - Unicode & emoji characters\n * - Optional nullable preservation (`keepNullable`)\n * - Optional trailing slash preservation (`keepTrailingSlash`)\n * - Optional removal of localhost first segment (`localhostDomain`)\n * - Prevention of false-positive domain stripping (`ignoreDomainExtensions`)\n *\n * - **Key Steps Internally:**\n * 1. Validate `options` (plain object, correct types)\n * 2. Validate `defaultPath` (non-empty string if `keepNullable` is false)\n * 3. Validate `ignoreDomainExtensions` (Set<string> | string[], each starts with `.`)\n * 4. Handle nullable:\n * - Returns `null` / `undefined` if `keepNullable: true`\n * - Otherwise uses `defaultPath`\n * 5. Trim spaces, remove internal spaces\n * 6. If full URL: parse using `URL` constructor\n * 7. If relative path or domain-like:\n * - Remove `localhost`/`localhost:port` if `localhostDomain`\n * - Remove first segment if domain-like and **not** in `ignoreDomainExtensions`\n * 8. Normalize slashes\n * 9. Ensure leading slash\n * 10. Handle trailing slash\n * 11. Decode Unicode safely\n * 12. Return normalized pathname + search + hash\n *\n * - **Error Handling:**\n * - **TypeError**:\n * - `defaultPath` invalid (non-string or empty) when `keepNullable: false`\n * - `keepNullable`, `keepTrailingSlash`, `localhostDomain` not boolean\n * - `ignoreDomainExtensions` invalid\n * - **NormalizePathnameError** (extends ***Error***):\n * - Invalid URL parsing\n * - Unexpected normalization errors\n *\n * - **Options:**\n * ```ts\n * {\n * // fallback if invalid path, default: \"/\"\n * defaultPath?: string;\n * // preserve null/undefined, default: false\n * keepNullable?: boolean;\n * // preserve trailing slash, default: false\n * keepTrailingSlash?: boolean;\n * // remove localhost:port first segment, default: false\n * localhostDomain?: boolean;\n * // prevent domain stripping, default: undefined\n * ignoreDomainExtensions?: Set<string> | string[];\n * }\n * ```\n *\n * @example\n * // Basic path cleaning\n * normalizePathname(\" /foo//bar \");\n * // ➔ \"/foo/bar\"\n *\n * // Trailing slash control\n * normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: true });\n * // ➔ \"/api/v1/user/\"\n * normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: false });\n * // ➔ \"/api/v1/user\"\n *\n * // Full URL normalization\n * normalizePathname(\"https://example.com//path///to/resource?x=1#hash\");\n * // ➔ \"/path/to/resource?x=1#hash\"\n *\n * // Null/undefined preservation\n * normalizePathname(null, { keepNullable: true });\n * // ➔ null\n * normalizePathname(undefined, { keepNullable: true });\n * // ➔ undefined\n *\n * // Default fallback\n * normalizePathname(\"\", { defaultPath: \"/home\" });\n * // ➔ \"/home\"\n *\n * // Localhost removal\n * normalizePathname(\"localhost:3000/path/to/resource\", { localhostDomain: true });\n * // ➔ \"/path/to/resource\"\n *\n * // Prevent false-positive domain stripping\n * normalizePathname(\"archive.tar.gz#download\", { ignoreDomainExtensions: [\".tar.gz\"] });\n * // ➔ \"/archive.tar.gz#download\"\n * normalizePathname(\"image.png?version=2\", { ignoreDomainExtensions: [\".png\"] });\n * // ➔ \"/image.png?version=2\"\n *\n * // Emojis and Unicode\n * normalizePathname(\"🔥//deep//path///🚀\");\n * // ➔ \"/🔥/deep/path/🚀\"\n *\n * // Query-only or hash-only\n * normalizePathname(\"?page=2\");\n * // ➔ \"/?page=2\"\n * normalizePathname(\"#section3\");\n * // ➔ \"/#section3\"\n *\n * // Complex nested paths\n * normalizePathname(\" //nested///folder//file.txt \");\n * // ➔ \"/nested/folder/file.txt\"\n *\n * // Invalid URL triggers error\n * try {\n * normalizePathname(\"http://\");\n * } catch (e) {\n * // console.log(e);\n * }\n *\n * // First segment is domain but ignored due to extension\n * normalizePathname(\"example.tar.bz/file\", { ignoreDomainExtensions: [\".tar.bz\"] });\n * // ➔ \"/example.tar.bz/file\"\n */\nexport function normalizePathname<T>(\n pathname: T,\n options?: NormalizePathnameOptionsKeepNullableFalse\n): ResUnKeepNullable<T>;\nexport function normalizePathname<T>(\n pathname: T,\n options?: NormalizePathnameOptionsKeepNullableTrue\n): ResKeepNullable<T>;\nexport function normalizePathname(\n pathname: unknown,\n options: NormalizePathnameOptions = {\n defaultPath: \"/\",\n keepNullable: false\n }\n): string | null | undefined {\n assertIsPlainObject(options, {\n message({ currentType, validType }) {\n return `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n const {\n defaultPath = \"/\",\n keepNullable = false,\n keepTrailingSlash = false,\n localhostDomain = false,\n ignoreDomainExtensions = undefined\n } = options;\n\n // Validate defaultPath\n if (!isNonEmptyString(defaultPath)) {\n throw new TypeError(\n `Parameter \\`defaultPath\\` property of the \\`options\\` (second parameter) must be of type \\`string\\` and not empty-string, but received: \\`${getPreciseType(\n defaultPath\n )}\\`, with value: \\`${safeStableStringify(defaultPath, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n assertIsBoolean(keepNullable, {\n message({ currentType, validType }) {\n return `Parameter \\`keepNullable\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n assertIsBoolean(keepTrailingSlash, {\n message({ currentType, validType }) {\n return `Parameter \\`keepTrailingSlash\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n assertIsBoolean(localhostDomain, {\n message({ currentType, validType }) {\n return `Parameter \\`localhostDomain\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n let ignoreDomainExtsSet: Set<string> | undefined;\n\n if (!isUndefined(ignoreDomainExtensions)) {\n if (!isSet(ignoreDomainExtensions) && !isArray(ignoreDomainExtensions)) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions\\` must be of type a \\`Set<string>\\` or \\`string[]\\`, but received: \\`${getPreciseType(\n ignoreDomainExtensions\n )}\\`.`\n );\n }\n\n ignoreDomainExtsSet = isSet(ignoreDomainExtensions)\n ? ignoreDomainExtensions\n : new Set(ignoreDomainExtensions);\n\n // validation every ext\n let idx = 0;\n for (const ext of ignoreDomainExtsSet) {\n if (!isNonEmptyString(ext)) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions[${idx}]\\` must be a \\`string\\` and \\`non-empty string\\`, but received: \\`${safeStableStringify(\n ext,\n { keepUndefined: true }\n )}\\`.`\n );\n }\n if (!ext.startsWith(\".\")) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions[${idx}]\\` must start with a dot (.), but received: ${safeStableStringify(\n ext,\n { keepUndefined: true }\n )}`\n );\n }\n idx++;\n }\n }\n\n try {\n if (keepNullable && (isNil(pathname) || !isString(pathname))) {\n if (isNull(pathname)) return null;\n return undefined;\n }\n\n // If the pathname is invalid (null, undefined, or an empty string), return the default value, only if `keepNullable` is false\n let currentPathName: string = isNonEmptyString(pathname)\n ? pathname\n : defaultPath;\n\n // Trim spaces from the string (only trim leading and trailing spaces)\n currentPathName = removeSpaces(currentPathName, { trimOnly: true }).replace(\n /\\s+/g,\n \"\"\n ); // remove all space\n\n currentPathName = stripLeadingDomain(currentPathName, {\n keepTrailingSlash,\n localhostDomain,\n ignoreDomainExtensions: ignoreDomainExtsSet\n });\n\n let _pathName: string = currentPathName;\n let search = \"\";\n let hash = \"\";\n\n // relative path: extract search/hash manually\n const searchIndex = currentPathName.indexOf(\"?\");\n const hashIndex = currentPathName.indexOf(\"#\");\n\n if (searchIndex !== -1) {\n search = currentPathName.slice(\n searchIndex,\n hashIndex !== -1 ? hashIndex : undefined\n );\n }\n if (hashIndex !== -1) {\n hash = currentPathName.slice(hashIndex);\n }\n\n const endIndex = Math.min(\n searchIndex !== -1 ? searchIndex : currentPathName.length,\n hashIndex !== -1 ? hashIndex : currentPathName.length\n );\n _pathName = currentPathName.slice(0, endIndex);\n\n // Normalize slashes\n _pathName = \"/\" + _pathName.replace(/^\\/+/, \"\").replace(/\\/{2,}/g, \"/\");\n\n // Trailing slash\n if (!keepTrailingSlash && _pathName !== \"/\") {\n _pathName = _pathName.replace(/\\/+$/, \"\");\n }\n\n // Decode Unicode safely\n _pathName = decodeUnicodeSequences(_pathName);\n search = decodeUnicodeSequences(search);\n hash = decodeUnicodeSequences(hash);\n\n return _pathName + search + hash;\n } catch (error) {\n // Handle any errors that occur during processing\n throwError(error);\n }\n}\n\n// --- Internal Helper Utils ----\n\n/**\n * @internal\n */\nconst decodeUnicodeSequences = (str: string): string => {\n return str.replace(/(?:%(?:[0-9A-F]{2})){2,}/gi, (match) => {\n try {\n const decoded = decodeURIComponent(match);\n // eslint-disable-next-line no-control-regex\n if (/^[\\u0000-\\u007F]+$/.test(decoded)) return match;\n // eslint-enable-next-line no-control-regex\n return decoded;\n } catch {\n return match;\n }\n });\n};\n\n/**\n * @internal\n */\nconst stripLeadingDomain = (\n path: string,\n options: OverrideTypes<\n MainNormalizePathnameOptions,\n { ignoreDomainExtensions?: Set<string> }\n >\n): string => {\n let currentPath = path;\n\n const { ignoreDomainExtensions, localhostDomain } = options;\n\n // Full URL (protocol) -> only normalize path, ignore ignoreDomainExtensions\n if (/^https?:\\/\\//i.test(currentPath)) {\n try {\n const url = new URL(currentPath);\n currentPath =\n url.pathname.replace(/^\\/+/, \"\").replace(/\\/{2,}/g, \"/\") +\n url.search +\n url.hash;\n\n return ensureLeadingSlash(currentPath);\n } catch (error) {\n // fallback: keep as-is\n // Handle any errors that occur during processing\n throwError(error);\n }\n }\n\n // relative path: remove leading slash\n if (currentPath.startsWith(\"/\")) {\n currentPath = currentPath.replace(/\\/{2,}/g, \"/\").slice(1);\n }\n\n // take first segment\n const segments = currentPath.split(\"/\");\n const firstPart = segments[0];\n const domainPart = firstPart?.split(\":\")[0];\n\n const isDomain = isValidDomain(domainPart, {\n subdomain: true,\n allowUnicode: true,\n wildcard: true,\n allowLocalhost: localhostDomain,\n allowPort: true,\n allowProtocol: true,\n topLevel: false\n });\n\n // ignoreDomainExtensions only applies for relative/non-protocol paths\n let hasIgnoredExtension = false;\n if (ignoreDomainExtensions) {\n for (const ext of ignoreDomainExtensions) {\n if (firstPart?.endsWith(ext)) {\n hasIgnoredExtension = true;\n break;\n }\n }\n }\n\n if (isDomain && !hasIgnoredExtension) {\n segments.shift(); // remove first segment\n }\n\n return ensureLeadingSlash(segments.join(\"/\"));\n};\n\n/**\n * @internal\n */\nconst ensureLeadingSlash = (path: string): string => {\n if (!path.startsWith(\"/\")) path = \"/\" + path;\n return path;\n};\n\n/**\n * @internal\n */\nconst throwError = (error: unknown): never => {\n // Handle any errors that occur during processing\n const err = isError(error)\n ? error\n : new Error(\"Unknown error from function `normalizePathname()`.\");\n throw new NormalizePathnameError(\n `Failed to normalize pathname in function \\`normalizePathname()\\`: ${err.message}`,\n err\n );\n};\n","import { isNil } from \"@/predicates/is/isNil\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\nimport { normalizePathname } from \"./normalizePathname\";\n\n/** --------------------------------------------------------\n * * ***Utility: `getFirstPrefixPathname`.***\n * --------------------------------------------------------\n * **Extract First Valid Prefix from Path Array or String.**\n * - **Main Purpose:**\n * - This function helps extract the first valid URL prefix from various possible inputs.\n * - It is especially useful in routing systems, middleware, or frontend apps that need to\n * decide layout, active navigation, or permissions based on the first segment (or prefix) of a pathname.\n * - **Typical uses include:**\n * - Determining which layout to render (e.g., `/admin` vs `/dashboard` vs `/`).\n * - Highlighting the active menu item in a sidebar based on the current URL.\n * - Enforcing route guards or access controls depending on the URL prefix.\n * - Parsing multi-level route prefixes and selecting the most relevant one.\n * - **Behavior:**\n * - It works as follows:\n * - If `result` is an array of strings, it normalizes each element and returns\n * the first non-root path (i.e., not just `\"/\"`).\n * - If all items normalize to `\"/\"`,\n * it returns the `defaultValue` (normalized).\n * - If `result` is a single string, it normalizes it and returns it if valid,\n * otherwise falls back to the normalized `defaultValue`.\n * - If `result` is `null` or `undefined`, it returns the normalized `defaultValue`.\n * - **Validation & Errors:**\n * - Throws a `TypeError` if:\n * - `defaultValue` is not a string or empty-string.\n * - `result` is an array that contains non-string elements.\n * - `result` is a value that is neither `string`, `string[]`, nor `null`.\n * @example\n * 1. #### For React (*Determining layout*):\n * ```ts\n * const prefix = getFirstPrefixPathname(\n * getPrefixPathname(\n * \"/admin/settings\",\n * [\"/admin\", \"/dashboard\"]\n * )\n * );\n *\n * if (prefix === \"/admin\") {\n * renderAdminLayout();\n * }\n * ```\n *\n * 2. #### Setting active menu state:\n * ```ts\n * const activeSection = getFirstPrefixPathname([\"\", \"/dashboard\", \"/profile\"]);\n * // ➔ \"/dashboard\"\n * ```\n *\n * 3. #### Providing graceful fallback:\n * ```ts\n * const section = getFirstPrefixPathname([], \"/home\");\n * // ➔ \"/home\"\n * ```\n * 4. #### ✅ Using with an Array of Pathnames:\n * ```ts\n * const result = getPrefixPathname([\" \", \"/dashboard\", \"/settings\"]);\n * console.log(getFirstPrefixPathname(result));\n * // ➔ \"/dashboard\"\n * ```\n *\n * 5. #### ✅ Using with Single String:\n * ```ts\n * console.log(getFirstPrefixPathname(\"/profile/settings\"));\n * // ➔ \"/profile/settings\"\n * console.log(getFirstPrefixPathname(\" \"));\n * // ➔ \"/\"\n * ```\n *\n * 6. #### ✅ Fallback to Custom Default:\n * ```ts\n * console.log(getFirstPrefixPathname([\" \", \"\"], \"/home\"));\n * // ➔ \"/home\"\n * console.log(getFirstPrefixPathname(null, \"/dashboard\"));\n * // ➔ \"/dashboard\"\n * ```\n *\n * 7. #### ✅ Throws on Invalid Input:\n * ```ts\n * getFirstPrefixPathname([1, 2] as any); // ➔ ❌ throws TypeError\n * getFirstPrefixPathname({} as any); // ➔ ❌ throws TypeError\n * getFirstPrefixPathname(null, \" \"); // ➔ ❌ throws TypeError\n * ```\n * @param {string | string[] | null | undefined} result\n * ***The pathname(s) to process, can be:***\n * - A string path (e.g. `\"/profile\"`),\n * - An array of string paths (e.g. `[\" \", \"/dashboard\"]`),\n * - Or `null`.\n * @param {string} [defaultValue=\"/\"]\n * ***A custom default path to use if `result` is null or no valid prefix is found, behavior:***\n * - Must be a string and non-empty string.\n * - Defaults to `\"/\"`.\n * @returns {string}\n * ***The first valid normalized pathname, or the normalized default.***\n * @throws **{@link TypeError | `TypeError`}** ***if `result` is not a valid type, or `defaultValue` is not a string or empty-string.***\n */\nexport const getFirstPrefixPathname = (\n result: string | string[] | null | undefined,\n defaultValue: string = \"/\"\n): string => {\n if (!isNonEmptyString(defaultValue)) {\n throw new TypeError(\n `Second parameter (\\`defaultValue\\`) must be of type \\`string\\` and not an \\`empty-string\\`, but received: \\`${getPreciseType(\n defaultValue\n )}\\`, with value: \\`${safeStableStringify(defaultValue, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n if (isArray(result)) {\n if (!result.every((item) => isString(item))) {\n throw new TypeError(\n `First parameter (\\`result\\`) must be of type \\`string\\` or \\`array of string\\`, but received: \\`${getPreciseType(\n result\n )}\\`, with value: \\`${safeStableStringify(result, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n for (const item of result) {\n const normalized = normalizePathname(item);\n if (normalized !== \"/\") {\n return normalized;\n }\n }\n return normalizePathname(defaultValue);\n }\n\n if (isString(result)) {\n const normalized = normalizePathname(result);\n return normalized !== \"/\" ? normalized : normalizePathname(defaultValue);\n }\n\n if (!isNil(result)) {\n throw new TypeError(\n `First parameter (\\`result\\`) must be of type \\`string\\`, \\`array-string\\`, \\`null\\` or \\`undefined\\`, but received: \\`${getPreciseType(\n result\n )}\\`.`\n );\n }\n\n return normalizePathname(defaultValue);\n};\n","import { joinLines, EOL } from \"@rzl-zone/build-tools/utils\";\n\nimport { isNull } from \"@/predicates/is/isNull\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isInteger } from \"@/predicates/is/isInteger\";\nimport { isBoolean } from \"@/predicates/is/isBoolean\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyArray } from \"@/predicates/is/isNonEmptyArray\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { normalizePathname } from \"./normalizePathname\";\n\ntype GetPrefixPathnameOptions = {\n /** The number of levels to include in the prefix (default is `1`).\n *\n * - For example, with `levels = 2`, the function will return the first two parts of the URL.\n *\n * @default 1\n */\n levels?: number;\n /** Whether to remove duplicates from the result if multiple URLs are passed (default is `true`).\n *\n * @default true\n */\n removeDuplicates?: boolean;\n};\n\n/** --------------------------------------------------------\n * * ***Utility: `getPrefixPathname`.***\n * --------------------------------------------------------\n * **Get Prefix from URL with Optional Base or Auto-detection (Supports String or Array of URLs).**\n * - **This function extracts the prefix from one or more URLs. It can either:**\n * - Use a provided `base` string or an array of strings to check and return the matching prefix.\n * - Automatically detect the prefix if no `base` is provided by analyzing the first part of the URL.\n * - **The function is flexible and can handle both scenarios:**\n * 1. **When the base is provided as a single string or an array of strings**:\n * - The function will check if the URL starts with one of the provided base(s) and return the matching base.\n * 2. **When the base is not provided**:\n * - The function will automatically detect the prefix by splitting the URL or using a regex.\n * - **Important Notes**:\n * - If a base (or an array of bases) is provided, the URL must start with one of the given base(s).\n * - If no base is provided, the function will attempt to detect the prefix automatically.\n * - The `url` parameter can be either a string or an array of strings.\n * - Supports deduplication of results (enabled by default).\n * - Automatically returns a single string if only one unique result exists after processing.\n * @param {string|string[]} url\n * ***The full URL(s) from which the prefix should be extracted, can be a `string` or an `array of strings`.***\n * @param {string|string[]|null} [base=null]\n * ***The base URL(s) (e.g., `\"/settings\"`), behavior:***\n * - It can be a `string`, an `array of strings`, or `null`.\n * - If `provided`, it will be used to check the URL(s).\n * - If `not provided`, the prefix will be auto-detected.\n * @param {GetPrefixPathnameOptions} [options]\n * ***Additional options object:***\n * - `levels` (default `1`): The number of segments to include when auto-detecting the prefix (e.g. `/foo/bar` for `levels: 2`).\n * - `removeDuplicates` (default `true`): Whether to remove duplicate prefixes from the final array result.\n * @returns {string|string[]|null}\n * ***Returns one of:***\n * - A single string if only one unique prefix/base is found.\n * - An array of strings if multiple different prefixes/bases are found.\n * - `null` if no matching base is found when using `base`.\n * @throws **{@link TypeError | `TypeError`}**\n * ***if:***\n * - `url` is `not a string` or `not an array of strings`.\n * - `base` is `not a string`, `array of strings`, or `null`.\n * - `options` is `not an object`.\n * - `levels` is `not a number`.\n * - `removeDuplicates` is `not a boolean`.\n * @example\n * - #### ✅ **Correct Usage (With an Array of URLs and Base):**\n * ```ts\n * const routes = [\n * \"/settings/profile\",\n * \"/settings/password\",\n * \"/settings/other-path\",\n * \"/other-path/xyz\",\n * ];\n *\n * // With base provided as a string\n * routes.forEach(route => {\n * console.log(getPrefixPathname(route, '/settings'));\n * // ➔ \"/settings\"\n * });\n *\n * // With base provided as an array\n * routes.forEach(route => {\n * console.log(getPrefixPathname(route, ['/settings', '/admin']));\n * // ➔ \"/settings\" or \"/admin\" depending on the current URL.\n * });\n * ```\n * - #### ✅ **Correct Usage (With Single URL and Single Base):**\n * ```ts\n * const result = getPrefixPathname(\"/settings/profile\", \"/settings\");\n * console.log(result); // ➔ \"/settings\"\n * ```\n * - #### ✅ **Correct Usage (With Multiple URLs and Single Base):**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/password\"],\n * \"/settings\"\n * );\n * console.log(result); // ➔ \"/settings\"\n *\n * const result2 = getPrefixPathname(\n * [\"/settings/profile\", \"/other/password\"],\n * \"/other\"\n * );\n * console.log(result2); // ➔ \"/other\"\n * ```\n * - #### ✅ **Correct Usage (With Multiple URLs and Multiple Bases)**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/admin/password\"],\n * [\"/settings\", \"/admin\"]\n * );\n * console.log(result); // ➔ [\"/settings\", \"/admin\"]\n * ```\n * - #### ✅ **Auto-detection of Prefix**\n * ```ts\n * const result = getPrefixPathname(\"/settings/profile\");\n * console.log(result); // ➔ \"/settings\"\n *\n * const result2 = getPrefixPathname(\n * \"/settings/profile/info\",\n * null,\n * { levels: 2 }\n * );\n * console.log(result2); // ➔ \"/settings/profile\"\n * ```\n * - #### ✅ **Multiple URLs with Auto-detection**\n * ```ts\n * const result = getPrefixPathname([\"/admin/profile\", \"/settings/password\"]);\n * console.log(result); // ➔ [\"/admin\", \"/settings\"]\n * ```\n * - #### ✅ **Handling Duplicates**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/password\"],\n * \"/settings\"\n * );\n * console.log(result); // ➔ \"/settings\" (deduped to single string)\n *\n * const result2 = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/profile\"],\n * \"/settings\",\n * { removeDuplicates: false }\n * );\n * console.log(result2); // ➔ [\"/settings\", \"/settings\"]\n * ```\n * - #### ❌ **Incorrect Usage (URL Does Not Match Base)**\n * ```ts\n * const result = getPrefixPathname(\"/other-path/profile\", \"/settings\");\n * console.log(result); // ➔ null\n * ```\n */\nexport const getPrefixPathname = (\n url: string | string[],\n base: string | string[] | null = null,\n options: GetPrefixPathnameOptions = {}\n): string | string[] | null => {\n const errors: string[] = [];\n\n if (!isString(url) && !isArray(url)) {\n errors.push(\n `First parameter (\\`url\\`) must be of type \\`string\\` or \\`array-string\\`, but received: \\`${getPreciseType(\n url\n )}\\`.`\n );\n }\n if (!isString(base) && !isArray(base) && !isNull(base)) {\n errors.push(\n `Second parameter (\\`base\\`) must be of type \\`string\\`, \\`array-string\\` or \\`null\\`, but received: \\`${getPreciseType(\n base\n )}\\`.`\n );\n }\n if (!isPlainObject(options)) {\n errors.push(\n `Second parameter (\\`options\\`) must be of type \\`plain-object\\`, but received: \\`${getPreciseType(\n options\n )}\\`.`\n );\n }\n\n const { levels = 1, removeDuplicates = true } = options;\n\n if (!isInteger(levels) || (isInteger(levels) && levels < 0)) {\n errors.push(\n `Parameter \\`levels\\` property of the \\`options\\` (second parameter) must be of type \\`integer-number\\` and minimum is \\`0\\`, but received: \\`${getPreciseType(\n levels\n )}\\`, with value: \\`${safeStableStringify(levels, {\n keepUndefined: true\n })}\\`.`\n );\n }\n if (!isBoolean(removeDuplicates)) {\n errors.push(\n `Parameter \\`removeDuplicates\\` property of the \\`options\\` (second parameter) must be of type \\`boolean\\`, but received: \\`${getPreciseType(\n removeDuplicates\n )}\\`.`\n );\n }\n if (isNonEmptyArray(errors)) {\n throw new TypeError(\n joinLines(\n \"Invalid parameter(s) in `getPrefixPathname` function:\",\n `- ${errors.join(`${EOL}- `)}`\n )\n );\n }\n\n // Helper function to process a single URL\n function getLevel(singleUrl: string) {\n // If no base is provided, detect the base automatically\n const parts = normalizePathname(singleUrl).split(\"/\").filter(Boolean); // Split URL into parts\n\n // Return the first `levels` parts as the prefix\n return `/${parts.slice(0, levels).join(\"/\")}`;\n }\n\n // Helper function to process a single URL\n function processUrl(singleUrl: string): string | null {\n // If a base is provided, check if URL starts with one of the bases\n if (base) {\n singleUrl = normalizePathname(singleUrl);\n\n if (isArray(base)) {\n // Check if the URL starts with any of the base values in the array\n for (const b of base) {\n if (singleUrl.startsWith(normalizePathname(b))) {\n // return normalizePathname(b); // Return the matching base if URL starts with it\n return getLevel(singleUrl);\n }\n }\n } else if (\n isNonEmptyString(base) &&\n singleUrl.startsWith(normalizePathname(base))\n ) {\n // If base is a single string, check if URL starts with it\n // return normalizePathname(base); // Return the base if URL starts with it\n return getLevel(singleUrl);\n }\n return null; // Return null if the URL does not match any base\n }\n\n return getLevel(singleUrl);\n }\n\n // If url is an array, process each URL and return an array of results\n if (isArray(url)) {\n const result = url.map(processUrl).filter((r): r is string => !isNull(r));\n\n // Remove duplicates if required\n const uniqueResult = removeDuplicates ? [...new Set(result)] : result;\n\n // If all results are the same, return just the first one\n if (uniqueResult.length === 1) {\n return uniqueResult[0] ?? null;\n }\n\n return uniqueResult;\n }\n\n // If url is a single string, process it and return the result\n return processUrl(url);\n};\n","import { isBoolean } from \"@/predicates/is/isBoolean\";\nimport { hasOwnProp } from \"@/predicates/has/hasOwnProp\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\n\ntype FormatEnvPortOptions = {\n /** Add prefix with a colon, defaultValue: `false`.\n *\n * @default false\n */\n prefixColon?: boolean;\n};\n\n/** -----------------------------------------------\n * * ***Utility: `formatEnvPort`.***\n * -----------------------------------------------\n * **Retrieves and formats an environment port variable.**\n * - **Behavior:**\n * - Extracts only digits from the input.\n * - If no digits found, returns an empty string.\n * - By default does NOT prefix with a colon.\n * - Use `{ prefixColon: true }` to prefix with a colon.\n * @param {string | null | undefined} envVar The environment variable string.\n * @param {FormatEnvPortOptions} [options] Optional object: `{ prefixColon?: boolean }`.\n * @returns {string} A string like `\":8080\"` or `\"8080\"`, or `\"\"` if no digits.\n * @throws **{@link TypeError | `TypeError`}** if `options` is not an object or `prefixColon` is not boolean.\n * @example\n * formatEnvPort(\"port:8080\");\n * // ➔ \"8080\"\n * formatEnvPort(\"port:8080\", { prefixColon: true });\n * // ➔ \":8080\"\n */\nexport const formatEnvPort = (\n envVar: string | null | undefined,\n options: FormatEnvPortOptions = {}\n): string => {\n if (!isNonEmptyString(envVar)) return \"\"; // Handle empty string case\n\n assertIsPlainObject(options, {\n message: ({ currentType, validType }) =>\n `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n const prefixColon = hasOwnProp(options, \"prefixColon\")\n ? options.prefixColon\n : false;\n\n if (!isBoolean(prefixColon)) {\n throw new TypeError(\n `Parameter \\`prefixColon\\` property of the \\`options\\` (second parameter) must be of type \\`boolean\\`, but received: \\`${getPreciseType(\n prefixColon\n )}\\`.`\n );\n }\n\n const digitsOnly = envVar.replace(/\\D+/g, \"\");\n if (isEmptyString(digitsOnly)) return \"\";\n\n return prefixColon ? `:${digitsOnly}` : digitsOnly;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"urls-nr2hUK75.js","names":[],"sources":["../src/urls/builders/constructURL.ts","../src/urls/extractors/extractURLs.ts","../src/urls/_private/NormalizePathnameError.ts","../src/urls/pathname/normalizePathname.ts","../src/urls/pathname/getFirstPrefixPathname.ts","../src/urls/pathname/getPrefixPathname.ts","../src/urls/utils/formatEnvPort.ts"],"sourcesContent":["import { isURL } from \"@/predicates/is/isURL\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isNumber } from \"@/predicates/is/isNumber\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isFunction } from \"@/predicates/is/isFunction\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isEmptyValue } from \"@/predicates/is/isEmptyValue\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { normalizeString } from \"@/strings/sanitizations/normalizeString\";\n\nimport { assertIsArray } from \"@/assertions/objects/assertIsArray\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\nimport { toStringArrayUnRecursive } from \"@/conversions/arrays/casts/toStringArrayUnRecursive\";\n\n/** ----------------------------------------------------------\n * * ***Type-Utility: `QueryParamPairs`.***\n * ----------------------------------------------------------\n * **Represents a non-empty array of key–value pairs.**\n * @description\n * Type for `queryParams` parameter, the second parameter of ***`constructURL` utility function***.\n * - **Behavior:**\n * - Each inner tuple strictly follows the `[string, string | number]` shape.\n * - Ensures the outer array contains **at least one pair** (non-empty).\n * - Commonly used for URL construction parameters,\n * query string segments, or other key–value structured data.\n * @example\n * // ✅ valid usage\n * const params: QueryParamPairs = [\n * [\"foo\", 1],\n * [\"bar\", \"baz\"]\n * ];\n * constructURL(\"https://example.com\", params);\n *\n * // ❌ invalid: must contain at least one item\n * const empty: QueryParamPairs = [];\n *\n * // ❌ invalid: key without value pairs.\n * const empty2: QueryParamPairs = [[\"key\"]];\n */\nexport type QueryParamPairs = [\n [string, string | number],\n ...[string, string | number][]\n];\n\n/** ---------------------------------\n * * ***Utility: `constructURL`.***\n * ---------------------------------\n * **Constructs a valid URL with optional query parameters and allows selective removal of duplicate parameters.**\n * @param {string | URL} baseUrl The base URL to build upon. Must include protocol (e.g., `\"https://\"`), `domain`, and may include port and existing query parameters.\n * @param {Iterable<[string, string]> | URLSearchParamsIterator<[string, string]> | QueryParamPairs} [queryParams]\n * Additional query parameters to append or overwrite on the URL.\n * - Accepts any iterable of key-value pairs (like `new URLSearchParams().entries()` and `[[string, string | number]...]`).\n * @param {string[]} [removeParams]\n * A list of query parameter keys to remove from the final URL, whether they were in the base URL or provided queryParams.\n * @returns {URL} A new URL object representing the constructed URL with merged and cleaned query parameters.\n * @throws **{@link TypeError | `TypeError`}** if `baseUrl` is not a valid non-empty string or URL object, or if `queryParams` is not iterable, or if `removeParams` is not an array of strings.\n * @example\n * 1. #### Basic Usage:\n * ```ts\n * constructURL(\n * \"https://example.com/path\",\n * new URLSearchParams({ a: \"1\", b: \"2\" }).entries()\n * );\n * // ➔ URL { href: \"https://example.com/path?a=1&b=2\", ... }\n * ```\n * 2. #### Remove parameters from Base and Added:\n * ```ts\n * // with new URLSearchParams({ ... }).entries();\n * constructURL(\n * \"https://example.com/path?foo=1&bar=2\",\n * new URLSearchParams({ bar: \"ignored\", baz: \"3\" }).entries(),\n * [\"bar\"]\n * );\n * // ➔ URL { href: \"https://example.com/path?foo=1&baz=3\", ... }\n *\n * // with [[string, string | number]...]\n * constructURL(\n * \"https://example.com/path?foo=1&bar=2\",\n * [[\"bar\", \"ignored\"],[\"baz\", 3]],\n * [\"bar\"]\n * );\n * // ➔ URL { href: \"https://example.com/path?foo=1&baz=3\", ... }\n *\n * const params: QueryParamPairs = [\n * [\"foo\", 1],\n * [\"bar\", 2],\n * [\"baz\", 3]\n * ];\n *\n * constructURL(\"https://example.com\", params, [\"bar\"]);\n * // ➔ URL { href: \"https://example.com/?foo=1&baz=3\", ... }\n * ```\n */\nexport const constructURL = (\n baseUrl: string | URL,\n queryParams?:\n | URLSearchParamsIterator<[string, string | number]>\n | QueryParamPairs,\n removeParams?: string[]\n): URL => {\n if (isString(baseUrl)) {\n if (isEmptyString(baseUrl)) {\n throw new TypeError(\n \"First parameter (`baseUrl`) cannot be an empty-string.\"\n );\n }\n baseUrl = normalizeString(baseUrl);\n } else if (!isURL(baseUrl)) {\n throw new TypeError(\n `First parameter (\\`baseUrl\\`) must be of type an URL instance or a \\`string\\` and a non empty-string, but received: \\`${getPreciseType(\n baseUrl\n )}\\`, with current value: \\`${safeStableStringify(baseUrl, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n // Check removeParams\n if (!isUndefined(removeParams)) {\n assertIsArray(removeParams, {\n message: ({ currentType, validType }) =>\n `Third parameter (\\`removeParams\\`) must be of type \\`${validType} of strings\\`, but received: \\`${currentType}\\`.`\n });\n\n if (!removeParams.every((param) => isNonEmptyString(param))) {\n throw new TypeError(\n \"Third parameter (`removeParams`) must be of type `array` and contains `string` only and non empty-string.\"\n );\n }\n }\n\n try {\n // Check queryParams\n if (\n !isUndefined(queryParams) &&\n !isFunction(queryParams[Symbol.iterator])\n ) {\n throw new TypeError(\n `Second parameter (\\`queryParams\\`) must be iterable (like URLSearchParams.entries() or an array of [[string, string | number]...]), but received: \\`${getPreciseType(\n queryParams\n )}\\`, with value: \\`${safeStableStringify(queryParams, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n const urlInstance = new URL(baseUrl);\n\n // Add query parameters if provided\n if (!isUndefined(queryParams)) {\n const paramObject = Object.fromEntries(queryParams);\n\n if (!isEmptyValue(paramObject)) {\n // existing params\n const mergedParams = new URLSearchParams(urlInstance.search);\n\n // add / overwrite from queryParams\n for (const [key, value] of Object.entries(paramObject)) {\n if (\n !isNonEmptyString(value) &&\n !isNumber(value, { includeNaN: true })\n ) {\n throw new TypeError(\n `Second parameter (\\`queryParams\\`) must be iterable (like URLSearchParams.entries() or an array of [[string, string | number]...]), but received: \\`${getPreciseType(\n queryParams\n )}\\`, with value: \\`${safeStableStringify(queryParams, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n mergedParams.set(key, String(value));\n }\n\n // Remove specific query parameters if needed\n if (removeParams?.length) {\n toStringArrayUnRecursive(removeParams).map((paramKey) => {\n mergedParams.delete(paramKey);\n });\n }\n\n urlInstance.search = mergedParams.toString();\n }\n }\n\n // Remove query parameters directly from URL if needed\n removeParams?.forEach((param) => urlInstance.searchParams.delete(param));\n\n return urlInstance;\n } catch (error) {\n if (isError(error)) throw error;\n\n throw new Error(\n \"Failed to construct a valid URL in `constructURL()`, Error:\" + error,\n { cause: error }\n );\n }\n};\n","import { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\n/** ---------------------------------\n * * ***Utility: `extractURLs`.***\n * ---------------------------------\n * **Extracts all valid URLs from a given string.**\n * @description\n * This function scans the input url and returns an array of URLs\n * that match a valid `http` or `https` format.\n * - **Supports:**\n * - Internationalized domain names (IDN), e.g. `https://münich.de`\n * - Unicode & emoji paths, e.g. `https://example.com/🎉/page`\n * - Long URLs with multiple queries & fragments, e.g. `https://example.com/path?foo=1#hash`\n * - **Ignores:**\n * - Non-string inputs\n * - Empty or whitespace-only strings\n * - Non-HTTP(S) protocols (ftp, mailto, etc)\n * @param {string | null | undefined} url - The input string containing potential URLs.\n * @returns {string[] | null} An array of extracted URLs or `null` if no URLs are found.\n * @example\n * extractURLs(\"Visit https://example.com and https://例子.公司\");\n * // ➔ [\"https://example.com\", \"https://例子.公司\"]\n * extractURLs(\"Here: https://example.com/🎉/page\");\n * // ➔ [\"https://example.com/🎉/page\"]\n * extractURLs(\"ftp://example.com http://example.com\");\n * // ➔ [\"http://example.com\"]\n */\nexport const extractURLs = (\n url: string | null | undefined\n): string[] | null => {\n if (!isNonEmptyString(url)) return null;\n\n let decoded;\n try {\n decoded = decodeURIComponent(url);\n } catch {\n return null;\n }\n\n // Core regex with lookahead\n const urlPattern = /https?:\\/\\/.*?(?=https?:\\/\\/|\\s|$)/g;\n const matches = decoded.match(urlPattern);\n if (!matches) return null;\n\n // Cleanup trailing punctuation and validation protocol\n const cleaned = matches\n .map((url) => url.replace(/[.,;:!?)]*$/, \"\"))\n .filter((url) => {\n try {\n const u = new URL(url);\n return u.protocol === \"http:\" || u.protocol === \"https:\";\n } catch {\n return false;\n }\n });\n\n return cleaned.length ? cleaned : null;\n};\n","import { isFunction } from \"@/predicates/is/isFunction\";\n\n/** ---------------------------------\n * * ***Custom Error for Pathname Normalization Failures***\n * ---------------------------------\n */\nexport class NormalizePathnameError extends Error {\n /** ---------------------------------\n * * ***The original error that triggered this normalization failure.***\n * ---------------------------------\n *\n * **Always available for backward compatibility.**\n */\n public readonly originalError: Error;\n\n constructor(message: string, originalError: Error) {\n // Pass a `cause` option if the runtime supports it (ignored by older engines).\n super(message, isFunction(Error) ? { cause: originalError } : undefined);\n\n this.name = \"NormalizePathnameError\";\n this.originalError = originalError;\n\n // Preserve stack trace when available (Node.js & modern browsers).\n if (isFunction(Error.captureStackTrace)) {\n Error.captureStackTrace(this, NormalizePathnameError);\n } else {\n // Fallback for very old environments.\n this.stack = new Error(message).stack;\n }\n }\n\n /** ---------------------------------\n * * ***Safe JSON representation for logging or IPC.***\n * ---------------------------------\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n stack: this.stack,\n originalError: {\n name: this.originalError.name,\n message: this.originalError.message,\n stack: this.originalError.stack\n }\n };\n }\n}\n","import type { OverrideTypes, Prettify } from \"@rzl-zone/ts-types-plus\";\n\nimport { isSet } from \"@/predicates/is/isSet\";\nimport { isNil } from \"@/predicates/is/isNil\";\nimport { isNull } from \"@/predicates/is/isNull\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isError } from \"@/predicates/is/isError\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isValidDomain } from \"@/predicates/is/isValidDomain\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\n\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { NormalizePathnameError } from \"../_private/NormalizePathnameError\";\nimport { isUndefined } from \"@/predicates/is/isUndefined\";\n\n/** Options when `keepNullable` is false (default).\n *\n * Returns `defaultPath` if `pathname` is empty or invalid.\n */\ntype UnKeepNullableOptions = {\n /** * ***Fallback value returned if `pathname` is empty-string or invalid.***\n *\n * Must be a **`non-empty string`**, defaultValue: `\"/\"`.\n *\n * @default \"/\"\n */\n defaultPath?: string;\n\n /** * ***Whether to preserve `null` or `undefined`, defaultValue: `false`.***\n *\n * @default false\n */\n keepNullable?: false;\n};\n\n/** Options when `keepNullable` is true.\n *\n * Preserves `null` or `undefined` instead of returning `defaultPath`.\n */\ntype KeepNullableOptions = {\n /** * ***Fallback path is ignored when `keepNullable` is true **(except if\n * `pathname` is empty-string or invalid, even this `true`)**,\n * defaultValue: `\"/\"`.***\n *\n * @default \"/\"\n */\n defaultPath?: string;\n\n /** * ***Preserve `null` or `undefined` as-is if `true` (defaultValue: `false`).***\n *\n * - ***⚠️ Notes:***\n * - Keep returning `defaultPath` if `pathname` is empty-string, even this `true`.\n *\n * **Must be `true` in this type.**\n *\n * @default false\n */\n keepNullable?: true;\n};\n\ntype MainNormalizePathnameOptions = {\n /** --------------------------------------------------------\n * * ***Preserve trailing slash at the end of the normalized pathname, defaultValue: `false`.***\n * --------------------------------------------------------\n *\n * @default `false`\n */\n keepTrailingSlash?: boolean;\n\n /** --------------------------------------------------------\n * * ***Allow special localhost domain at the beginning of the pathname.***\n * --------------------------------------------------------\n * @description\n * If `true`, the first segment of the pathname that is `/localhost` or `localhost`\n * (with or without a port, e.g., `localhost:3000`) will be treated as a special domain\n * and **removed** from the normalized pathname.\n *\n * - **Examples (`localhostDomain: true`)**:\n * - `\"/localhost/path\"` ➔ `\"/path\"`\n * - `\"localhost:3000/path\"` ➔ `\"/path\"`\n * - `\"localhost\"` ➔ `\"/\"` (entire path removed)\n *\n * - Only the **first path segment** is affected. Any subsequent occurrences of `\"localhost\"`\n * will remain intact.\n *\n * @default false\n */\n localhostDomain?: boolean;\n\n /**\n * --------------------------------------------------------\n * * ***Custom list of file extensions that prevent the first path segment from being treated as a domain.***\n * --------------------------------------------------------\n *\n * **Description:**\n * - The first segment of a pathname is often interpreted as a domain (e.g., `example.com`).\n * - If this first segment ends with any of the extensions listed here, it will **not** be considered a domain,\n * and will instead be preserved as part of the relative path.\n * - This is useful for cases where filenames appear at the start of a path and you want them treated as relative paths,\n * such as `\"image.png?version=2\"` or `\"archive.tar.gz#download\"`.\n * - Only the **first path segment** is affected; all other segments are processed normally.\n * - **Ignored** if:\n * 1. The pathname starts with a full URL protocol (`http://` or `https://`), e.g., `\"https://example.com/file.png\"`.\n * 2. The first path segment is already a valid domain, e.g., `\"example.com/image.png\"`.\n *\n * **Type & Validation:**\n * - Must be a `Set<string>` or `string[]`.\n * - Each string **must include the leading dot**, e.g., `.png`, `.tar.gz`.\n * - Multi-part extensions (like `.tar.gz`, `.tar.bz`) are supported.\n * - Throws a **TypeError** if:\n * 1. The type is not a `Set<string>` or `string[]`.\n * 2. Any string in the array/set is empty.\n * 3. Any string does not start with a dot (`.`).\n *\n * **Usage Notes:**\n * - Only applied when the first segment is otherwise domain-like **and** pathname is relative or domain-like without protocol.\n * - Query strings (`?x=1`) and hash fragments (`#section`) are preserved.\n *\n * **Examples (relative paths, option active):**\n * ```ts\n * normalizePathname(\"image.png?version=2\", {\n * ignoreDomainExtensions: [\".png\", \".jpg\"]\n * });\n * // ➔ \"/image.png?version=2\"\n *\n * normalizePathname(\"archive.tar.gz#download\", {\n * ignoreDomainExtensions: new Set([\".tar.gz\"])\n * });\n * // ➔ \"/archive.tar.gz#download\"\n *\n * normalizePathname(\"script.js?module=true#top\", {\n * ignoreDomainExtensions: [\".js\"]\n * });\n * // ➔ \"/script.js?module=true#top\"\n * ```\n *\n * **Examples (full URL or explicit domain - option ignored):**\n * ```ts\n * normalizePathname(\"https://example.com/image.png?version=2\", {\n * ignoreDomainExtensions: [\".png\"]\n * });\n * // ➔ \"/image.png?version=2\" // URL is parsed normally; ignoreDomainExtensions has no effect\n *\n * normalizePathname(\"example.com/script.js?module=true#top\", {\n * ignoreDomainExtensions: [\".js\"]\n * });\n * // ➔ \"/script.js?module=true#top\" // domain recognized; option ignored\n * ```\n *\n * **Notes:**\n * - Only the **first path segment** is checked.\n * - Prevents false-positive domain stripping for filenames that look like domains.\n * - Throws **TypeError** if invalid type or invalid string is provided.\n *\n * @default undefined (feature inactive if not provided)\n */\n ignoreDomainExtensions?: Set<string> | string[];\n};\n\n/** Options for main `normalizePathname`.\n *\n * Combines `UnKeepNullableOptions` or `KeepNullableOptions` with trailing slash control.\n */\ntype NormalizePathnameOptions = Prettify<\n MainNormalizePathnameOptions & (UnKeepNullableOptions | KeepNullableOptions)\n>;\n\ntype NormalizePathnameOptionsKeepNullableTrue = MainNormalizePathnameOptions &\n KeepNullableOptions;\ntype NormalizePathnameOptionsKeepNullableFalse = MainNormalizePathnameOptions &\n UnKeepNullableOptions;\n\ntype ResUnKeepNullable<T> = T extends undefined\n ? string\n : T extends null\n ? string\n : T extends null | undefined\n ? string\n : string;\n\ntype ResKeepNullable<T> = T extends string\n ? string\n : T extends undefined\n ? undefined\n : T extends null\n ? null\n : T extends null | undefined\n ? null | undefined\n : string | null | undefined;\n\n/** --------------------------------------------------------\n * * ***Utility: `normalizePathname`.***\n * --------------------------------------------------------\n *\n * - **Description:**\n * Normalizes any pathname or URL string to a clean, predictable format.\n * Useful for routing, file paths, and URL handling.\n * - Handles:\n * - Leading/trailing spaces\n * - Internal spaces in path segments\n * - Redundant slashes (`//`)\n * - Full URLs vs relative paths\n * - Query (`?`) and hash (`#`) preservation\n * - Unicode & emoji characters\n * - Optional nullable preservation (`keepNullable`)\n * - Optional trailing slash preservation (`keepTrailingSlash`)\n * - Optional removal of localhost first segment (`localhostDomain`)\n * - Prevention of false-positive domain stripping (`ignoreDomainExtensions`)\n *\n * - **Key Steps Internally:**\n * 1. Validate `options` (plain object, correct types)\n * 2. Validate `defaultPath` (non-empty string if `keepNullable` is false)\n * 3. Validate `ignoreDomainExtensions` (Set<string> | string[], each starts with `.`)\n * 4. Handle nullable:\n * - Returns `null` / `undefined` if `keepNullable: true`\n * - Otherwise uses `defaultPath`\n * 5. Trim spaces, remove internal spaces\n * 6. If full URL: parse using `URL` constructor\n * 7. If relative path or domain-like:\n * - Remove `localhost`/`localhost:port` if `localhostDomain`\n * - Remove first segment if domain-like and **not** in `ignoreDomainExtensions`\n * 8. Normalize slashes\n * 9. Ensure leading slash\n * 10. Handle trailing slash\n * 11. Decode Unicode safely\n * 12. Return normalized pathname + search + hash\n *\n * - **Error Handling:**\n * - **TypeError**:\n * - `defaultPath` invalid (non-string or empty) when `keepNullable: false`\n * - `keepNullable`, `keepTrailingSlash`, `localhostDomain` not boolean\n * - `ignoreDomainExtensions` invalid\n * - **NormalizePathnameError** (extends ***Error***):\n * - Invalid URL parsing\n * - Unexpected normalization errors\n *\n * - **Options:**\n * ```ts\n * {\n * // fallback if invalid path, default: \"/\"\n * defaultPath?: string;\n * // preserve null/undefined, default: false\n * keepNullable?: boolean;\n * // preserve trailing slash, default: false\n * keepTrailingSlash?: boolean;\n * // remove localhost:port first segment, default: false\n * localhostDomain?: boolean;\n * // prevent domain stripping, default: undefined\n * ignoreDomainExtensions?: Set<string> | string[];\n * }\n * ```\n *\n * @example\n * // Basic path cleaning\n * normalizePathname(\" /foo//bar \");\n * // ➔ \"/foo/bar\"\n *\n * // Trailing slash control\n * normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: true });\n * // ➔ \"/api/v1/user/\"\n * normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: false });\n * // ➔ \"/api/v1/user\"\n *\n * // Full URL normalization\n * normalizePathname(\"https://example.com//path///to/resource?x=1#hash\");\n * // ➔ \"/path/to/resource?x=1#hash\"\n *\n * // Null/undefined preservation\n * normalizePathname(null, { keepNullable: true });\n * // ➔ null\n * normalizePathname(undefined, { keepNullable: true });\n * // ➔ undefined\n *\n * // Default fallback\n * normalizePathname(\"\", { defaultPath: \"/home\" });\n * // ➔ \"/home\"\n *\n * // Localhost removal\n * normalizePathname(\"localhost:3000/path/to/resource\", { localhostDomain: true });\n * // ➔ \"/path/to/resource\"\n *\n * // Prevent false-positive domain stripping\n * normalizePathname(\"archive.tar.gz#download\", { ignoreDomainExtensions: [\".tar.gz\"] });\n * // ➔ \"/archive.tar.gz#download\"\n * normalizePathname(\"image.png?version=2\", { ignoreDomainExtensions: [\".png\"] });\n * // ➔ \"/image.png?version=2\"\n *\n * // Emojis and Unicode\n * normalizePathname(\"🔥//deep//path///🚀\");\n * // ➔ \"/🔥/deep/path/🚀\"\n *\n * // Query-only or hash-only\n * normalizePathname(\"?page=2\");\n * // ➔ \"/?page=2\"\n * normalizePathname(\"#section3\");\n * // ➔ \"/#section3\"\n *\n * // Complex nested paths\n * normalizePathname(\" //nested///folder//file.txt \");\n * // ➔ \"/nested/folder/file.txt\"\n *\n * // Invalid URL triggers error\n * try {\n * normalizePathname(\"http://\");\n * } catch (e) {\n * // console.log(e);\n * }\n *\n * // First segment is domain but ignored due to extension\n * normalizePathname(\"example.tar.bz/file\", { ignoreDomainExtensions: [\".tar.bz\"] });\n * // ➔ \"/example.tar.bz/file\"\n */\nexport function normalizePathname<T>(\n pathname: T,\n options?: NormalizePathnameOptionsKeepNullableFalse\n): ResUnKeepNullable<T>;\nexport function normalizePathname<T>(\n pathname: T,\n options?: NormalizePathnameOptionsKeepNullableTrue\n): ResKeepNullable<T>;\nexport function normalizePathname(\n pathname: unknown,\n options: NormalizePathnameOptions = {\n defaultPath: \"/\",\n keepNullable: false\n }\n): string | null | undefined {\n assertIsPlainObject(options, {\n message({ currentType, validType }) {\n return `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n const {\n defaultPath = \"/\",\n keepNullable = false,\n keepTrailingSlash = false,\n localhostDomain = false,\n ignoreDomainExtensions = undefined\n } = options;\n\n // Validate defaultPath\n if (!isNonEmptyString(defaultPath)) {\n throw new TypeError(\n `Parameter \\`defaultPath\\` property of the \\`options\\` (second parameter) must be of type \\`string\\` and not empty-string, but received: \\`${getPreciseType(\n defaultPath\n )}\\`, with value: \\`${safeStableStringify(defaultPath, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n assertIsBoolean(keepNullable, {\n message({ currentType, validType }) {\n return `Parameter \\`keepNullable\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n assertIsBoolean(keepTrailingSlash, {\n message({ currentType, validType }) {\n return `Parameter \\`keepTrailingSlash\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n assertIsBoolean(localhostDomain, {\n message({ currentType, validType }) {\n return `Parameter \\`localhostDomain\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`;\n }\n });\n\n let ignoreDomainExtsSet: Set<string> | undefined;\n\n if (!isUndefined(ignoreDomainExtensions)) {\n if (!isSet(ignoreDomainExtensions) && !isArray(ignoreDomainExtensions)) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions\\` must be of type a \\`Set<string>\\` or \\`string[]\\`, but received: \\`${getPreciseType(\n ignoreDomainExtensions\n )}\\`.`\n );\n }\n\n ignoreDomainExtsSet = isSet(ignoreDomainExtensions)\n ? ignoreDomainExtensions\n : new Set(ignoreDomainExtensions);\n\n // validation every ext\n let idx = 0;\n for (const ext of ignoreDomainExtsSet) {\n if (!isNonEmptyString(ext)) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions[${idx}]\\` must be a \\`string\\` and \\`non-empty string\\`, but received: \\`${safeStableStringify(\n ext,\n { keepUndefined: true }\n )}\\`.`\n );\n }\n if (!ext.startsWith(\".\")) {\n throw new TypeError(\n `Parameter \\`ignoreDomainExtensions[${idx}]\\` must start with a dot (.), but received: ${safeStableStringify(\n ext,\n { keepUndefined: true }\n )}`\n );\n }\n idx++;\n }\n }\n\n try {\n if (keepNullable && (isNil(pathname) || !isString(pathname))) {\n if (isNull(pathname)) return null;\n return undefined;\n }\n\n // If the pathname is invalid (null, undefined, or an empty string), return the default value, only if `keepNullable` is false\n let currentPathName: string = isNonEmptyString(pathname)\n ? pathname\n : defaultPath;\n\n // Trim spaces from the string (only trim leading and trailing spaces)\n currentPathName = removeSpaces(currentPathName, { trimOnly: true }).replace(\n /\\s+/g,\n \"\"\n ); // remove all space\n\n currentPathName = stripLeadingDomain(currentPathName, {\n keepTrailingSlash,\n localhostDomain,\n ignoreDomainExtensions: ignoreDomainExtsSet\n });\n\n let _pathName: string = currentPathName;\n let search = \"\";\n let hash = \"\";\n\n // relative path: extract search/hash manually\n const searchIndex = currentPathName.indexOf(\"?\");\n const hashIndex = currentPathName.indexOf(\"#\");\n\n if (searchIndex !== -1) {\n search = currentPathName.slice(\n searchIndex,\n hashIndex !== -1 ? hashIndex : undefined\n );\n }\n if (hashIndex !== -1) {\n hash = currentPathName.slice(hashIndex);\n }\n\n const endIndex = Math.min(\n searchIndex !== -1 ? searchIndex : currentPathName.length,\n hashIndex !== -1 ? hashIndex : currentPathName.length\n );\n _pathName = currentPathName.slice(0, endIndex);\n\n // Normalize slashes\n _pathName = \"/\" + _pathName.replace(/^\\/+/, \"\").replace(/\\/{2,}/g, \"/\");\n\n // Trailing slash\n if (!keepTrailingSlash && _pathName !== \"/\") {\n _pathName = _pathName.replace(/\\/+$/, \"\");\n }\n\n // Decode Unicode safely\n _pathName = decodeUnicodeSequences(_pathName);\n search = decodeUnicodeSequences(search);\n hash = decodeUnicodeSequences(hash);\n\n return _pathName + search + hash;\n } catch (error) {\n // Handle any errors that occur during processing\n throwError(error);\n }\n}\n\n// --- Internal Helper Utils ----\n\n/**\n * @internal\n */\nconst decodeUnicodeSequences = (str: string): string => {\n return str.replace(/(?:%(?:[0-9A-F]{2})){2,}/gi, (match) => {\n try {\n const decoded = decodeURIComponent(match);\n // eslint-disable-next-line no-control-regex\n if (/^[\\u0000-\\u007F]+$/.test(decoded)) return match;\n // eslint-enable-next-line no-control-regex\n return decoded;\n } catch {\n return match;\n }\n });\n};\n\n/**\n * @internal\n */\nconst stripLeadingDomain = (\n path: string,\n options: OverrideTypes<\n MainNormalizePathnameOptions,\n { ignoreDomainExtensions?: Set<string> }\n >\n): string => {\n let currentPath = path;\n\n const { ignoreDomainExtensions, localhostDomain } = options;\n\n // Full URL (protocol) -> only normalize path, ignore ignoreDomainExtensions\n if (/^https?:\\/\\//i.test(currentPath)) {\n try {\n const url = new URL(currentPath);\n currentPath =\n url.pathname.replace(/^\\/+/, \"\").replace(/\\/{2,}/g, \"/\") +\n url.search +\n url.hash;\n\n return ensureLeadingSlash(currentPath);\n } catch (error) {\n // fallback: keep as-is\n // Handle any errors that occur during processing\n throwError(error);\n }\n }\n\n // relative path: remove leading slash\n if (currentPath.startsWith(\"/\")) {\n currentPath = currentPath.replace(/\\/{2,}/g, \"/\").slice(1);\n }\n\n // take first segment\n const segments = currentPath.split(\"/\");\n const firstPart = segments[0];\n const domainPart = firstPart?.split(\":\")[0];\n\n const isDomain = isValidDomain(domainPart, {\n subdomain: true,\n allowUnicode: true,\n wildcard: true,\n allowLocalhost: localhostDomain,\n allowPort: true,\n allowProtocol: true,\n topLevel: false\n });\n\n // ignoreDomainExtensions only applies for relative/non-protocol paths\n let hasIgnoredExtension = false;\n if (ignoreDomainExtensions) {\n for (const ext of ignoreDomainExtensions) {\n if (firstPart?.endsWith(ext)) {\n hasIgnoredExtension = true;\n break;\n }\n }\n }\n\n if (isDomain && !hasIgnoredExtension) {\n segments.shift(); // remove first segment\n }\n\n return ensureLeadingSlash(segments.join(\"/\"));\n};\n\n/**\n * @internal\n */\nconst ensureLeadingSlash = (path: string): string => {\n if (!path.startsWith(\"/\")) path = \"/\" + path;\n return path;\n};\n\n/**\n * @internal\n */\nconst throwError = (error: unknown): never => {\n // Handle any errors that occur during processing\n const err = isError(error)\n ? error\n : new Error(\"Unknown error from function `normalizePathname()`.\");\n throw new NormalizePathnameError(\n `Failed to normalize pathname in function \\`normalizePathname()\\`: ${err.message}`,\n err\n );\n};\n","import { isNil } from \"@/predicates/is/isNil\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\nimport { normalizePathname } from \"./normalizePathname\";\n\n/** --------------------------------------------------------\n * * ***Utility: `getFirstPrefixPathname`.***\n * --------------------------------------------------------\n * **Extract First Valid Prefix from Path Array or String.**\n * - **Main Purpose:**\n * - This function helps extract the first valid URL prefix from various possible inputs.\n * - It is especially useful in routing systems, middleware, or frontend apps that need to\n * decide layout, active navigation, or permissions based on the first segment (or prefix) of a pathname.\n * - **Typical uses include:**\n * - Determining which layout to render (e.g., `/admin` vs `/dashboard` vs `/`).\n * - Highlighting the active menu item in a sidebar based on the current URL.\n * - Enforcing route guards or access controls depending on the URL prefix.\n * - Parsing multi-level route prefixes and selecting the most relevant one.\n * - **Behavior:**\n * - It works as follows:\n * - If `result` is an array of strings, it normalizes each element and returns\n * the first non-root path (i.e., not just `\"/\"`).\n * - If all items normalize to `\"/\"`,\n * it returns the `defaultValue` (normalized).\n * - If `result` is a single string, it normalizes it and returns it if valid,\n * otherwise falls back to the normalized `defaultValue`.\n * - If `result` is `null` or `undefined`, it returns the normalized `defaultValue`.\n * - **Validation & Errors:**\n * - Throws a `TypeError` if:\n * - `defaultValue` is not a string or empty-string.\n * - `result` is an array that contains non-string elements.\n * - `result` is a value that is neither `string`, `string[]`, nor `null`.\n * @example\n * 1. #### For React (*Determining layout*):\n * ```ts\n * const prefix = getFirstPrefixPathname(\n * getPrefixPathname(\n * \"/admin/settings\",\n * [\"/admin\", \"/dashboard\"]\n * )\n * );\n *\n * if (prefix === \"/admin\") {\n * renderAdminLayout();\n * }\n * ```\n *\n * 2. #### Setting active menu state:\n * ```ts\n * const activeSection = getFirstPrefixPathname([\"\", \"/dashboard\", \"/profile\"]);\n * // ➔ \"/dashboard\"\n * ```\n *\n * 3. #### Providing graceful fallback:\n * ```ts\n * const section = getFirstPrefixPathname([], \"/home\");\n * // ➔ \"/home\"\n * ```\n * 4. #### ✅ Using with an Array of Pathnames:\n * ```ts\n * const result = getPrefixPathname([\" \", \"/dashboard\", \"/settings\"]);\n * console.log(getFirstPrefixPathname(result));\n * // ➔ \"/dashboard\"\n * ```\n *\n * 5. #### ✅ Using with Single String:\n * ```ts\n * console.log(getFirstPrefixPathname(\"/profile/settings\"));\n * // ➔ \"/profile/settings\"\n * console.log(getFirstPrefixPathname(\" \"));\n * // ➔ \"/\"\n * ```\n *\n * 6. #### ✅ Fallback to Custom Default:\n * ```ts\n * console.log(getFirstPrefixPathname([\" \", \"\"], \"/home\"));\n * // ➔ \"/home\"\n * console.log(getFirstPrefixPathname(null, \"/dashboard\"));\n * // ➔ \"/dashboard\"\n * ```\n *\n * 7. #### ✅ Throws on Invalid Input:\n * ```ts\n * getFirstPrefixPathname([1, 2] as any); // ➔ ❌ throws TypeError\n * getFirstPrefixPathname({} as any); // ➔ ❌ throws TypeError\n * getFirstPrefixPathname(null, \" \"); // ➔ ❌ throws TypeError\n * ```\n * @param {string | string[] | null | undefined} result\n * ***The pathname(s) to process, can be:***\n * - A string path (e.g. `\"/profile\"`),\n * - An array of string paths (e.g. `[\" \", \"/dashboard\"]`),\n * - Or `null`.\n * @param {string} [defaultValue=\"/\"]\n * ***A custom default path to use if `result` is null or no valid prefix is found, behavior:***\n * - Must be a string and non-empty string.\n * - Defaults to `\"/\"`.\n * @returns {string}\n * ***The first valid normalized pathname, or the normalized default.***\n * @throws **{@link TypeError | `TypeError`}** ***if `result` is not a valid type, or `defaultValue` is not a string or empty-string.***\n */\nexport const getFirstPrefixPathname = (\n result: string | string[] | null | undefined,\n defaultValue: string = \"/\"\n): string => {\n if (!isNonEmptyString(defaultValue)) {\n throw new TypeError(\n `Second parameter (\\`defaultValue\\`) must be of type \\`string\\` and not an \\`empty-string\\`, but received: \\`${getPreciseType(\n defaultValue\n )}\\`, with value: \\`${safeStableStringify(defaultValue, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n if (isArray(result)) {\n if (!result.every((item) => isString(item))) {\n throw new TypeError(\n `First parameter (\\`result\\`) must be of type \\`string\\` or \\`array of string\\`, but received: \\`${getPreciseType(\n result\n )}\\`, with value: \\`${safeStableStringify(result, {\n keepUndefined: true\n })}\\`.`\n );\n }\n\n for (const item of result) {\n const normalized = normalizePathname(item);\n if (normalized !== \"/\") {\n return normalized;\n }\n }\n return normalizePathname(defaultValue);\n }\n\n if (isString(result)) {\n const normalized = normalizePathname(result);\n return normalized !== \"/\" ? normalized : normalizePathname(defaultValue);\n }\n\n if (!isNil(result)) {\n throw new TypeError(\n `First parameter (\\`result\\`) must be of type \\`string\\`, \\`array-string\\`, \\`null\\` or \\`undefined\\`, but received: \\`${getPreciseType(\n result\n )}\\`.`\n );\n }\n\n return normalizePathname(defaultValue);\n};\n","import { joinLines, EOL } from \"@rzl-zone/build-tools/utils\";\n\nimport { isNull } from \"@/predicates/is/isNull\";\nimport { isArray } from \"@/predicates/is/isArray\";\nimport { isString } from \"@/predicates/is/isString\";\nimport { isInteger } from \"@/predicates/is/isInteger\";\nimport { isBoolean } from \"@/predicates/is/isBoolean\";\nimport { isPlainObject } from \"@/predicates/is/isPlainObject\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyArray } from \"@/predicates/is/isNonEmptyArray\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { normalizePathname } from \"./normalizePathname\";\n\ntype GetPrefixPathnameOptions = {\n /** The number of levels to include in the prefix (default is `1`).\n *\n * - For example, with `levels = 2`, the function will return the first two parts of the URL.\n *\n * @default 1\n */\n levels?: number;\n /** Whether to remove duplicates from the result if multiple URLs are passed (default is `true`).\n *\n * @default true\n */\n removeDuplicates?: boolean;\n};\n\n/** --------------------------------------------------------\n * * ***Utility: `getPrefixPathname`.***\n * --------------------------------------------------------\n * **Get Prefix from URL with Optional Base or Auto-detection (Supports String or Array of URLs).**\n * - **This function extracts the prefix from one or more URLs. It can either:**\n * - Use a provided `base` string or an array of strings to check and return the matching prefix.\n * - Automatically detect the prefix if no `base` is provided by analyzing the first part of the URL.\n * - **The function is flexible and can handle both scenarios:**\n * 1. **When the base is provided as a single string or an array of strings**:\n * - The function will check if the URL starts with one of the provided base(s) and return the matching base.\n * 2. **When the base is not provided**:\n * - The function will automatically detect the prefix by splitting the URL or using a regex.\n * - **Important Notes**:\n * - If a base (or an array of bases) is provided, the URL must start with one of the given base(s).\n * - If no base is provided, the function will attempt to detect the prefix automatically.\n * - The `url` parameter can be either a string or an array of strings.\n * - Supports deduplication of results (enabled by default).\n * - Automatically returns a single string if only one unique result exists after processing.\n * @param {string|string[]} url\n * ***The full URL(s) from which the prefix should be extracted, can be a `string` or an `array of strings`.***\n * @param {string|string[]|null} [base=null]\n * ***The base URL(s) (e.g., `\"/settings\"`), behavior:***\n * - It can be a `string`, an `array of strings`, or `null`.\n * - If `provided`, it will be used to check the URL(s).\n * - If `not provided`, the prefix will be auto-detected.\n * @param {GetPrefixPathnameOptions} [options]\n * ***Additional options object:***\n * - `levels` (default `1`): The number of segments to include when auto-detecting the prefix (e.g. `/foo/bar` for `levels: 2`).\n * - `removeDuplicates` (default `true`): Whether to remove duplicate prefixes from the final array result.\n * @returns {string|string[]|null}\n * ***Returns one of:***\n * - A single string if only one unique prefix/base is found.\n * - An array of strings if multiple different prefixes/bases are found.\n * - `null` if no matching base is found when using `base`.\n * @throws **{@link TypeError | `TypeError`}**\n * ***if:***\n * - `url` is `not a string` or `not an array of strings`.\n * - `base` is `not a string`, `array of strings`, or `null`.\n * - `options` is `not an object`.\n * - `levels` is `not a number`.\n * - `removeDuplicates` is `not a boolean`.\n * @example\n * - #### ✅ **Correct Usage (With an Array of URLs and Base):**\n * ```ts\n * const routes = [\n * \"/settings/profile\",\n * \"/settings/password\",\n * \"/settings/other-path\",\n * \"/other-path/xyz\",\n * ];\n *\n * // With base provided as a string\n * routes.forEach(route => {\n * console.log(getPrefixPathname(route, '/settings'));\n * // ➔ \"/settings\"\n * });\n *\n * // With base provided as an array\n * routes.forEach(route => {\n * console.log(getPrefixPathname(route, ['/settings', '/admin']));\n * // ➔ \"/settings\" or \"/admin\" depending on the current URL.\n * });\n * ```\n * - #### ✅ **Correct Usage (With Single URL and Single Base):**\n * ```ts\n * const result = getPrefixPathname(\"/settings/profile\", \"/settings\");\n * console.log(result); // ➔ \"/settings\"\n * ```\n * - #### ✅ **Correct Usage (With Multiple URLs and Single Base):**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/password\"],\n * \"/settings\"\n * );\n * console.log(result); // ➔ \"/settings\"\n *\n * const result2 = getPrefixPathname(\n * [\"/settings/profile\", \"/other/password\"],\n * \"/other\"\n * );\n * console.log(result2); // ➔ \"/other\"\n * ```\n * - #### ✅ **Correct Usage (With Multiple URLs and Multiple Bases)**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/admin/password\"],\n * [\"/settings\", \"/admin\"]\n * );\n * console.log(result); // ➔ [\"/settings\", \"/admin\"]\n * ```\n * - #### ✅ **Auto-detection of Prefix**\n * ```ts\n * const result = getPrefixPathname(\"/settings/profile\");\n * console.log(result); // ➔ \"/settings\"\n *\n * const result2 = getPrefixPathname(\n * \"/settings/profile/info\",\n * null,\n * { levels: 2 }\n * );\n * console.log(result2); // ➔ \"/settings/profile\"\n * ```\n * - #### ✅ **Multiple URLs with Auto-detection**\n * ```ts\n * const result = getPrefixPathname([\"/admin/profile\", \"/settings/password\"]);\n * console.log(result); // ➔ [\"/admin\", \"/settings\"]\n * ```\n * - #### ✅ **Handling Duplicates**\n * ```ts\n * const result = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/password\"],\n * \"/settings\"\n * );\n * console.log(result); // ➔ \"/settings\" (deduped to single string)\n *\n * const result2 = getPrefixPathname(\n * [\"/settings/profile\", \"/settings/profile\"],\n * \"/settings\",\n * { removeDuplicates: false }\n * );\n * console.log(result2); // ➔ [\"/settings\", \"/settings\"]\n * ```\n * - #### ❌ **Incorrect Usage (URL Does Not Match Base)**\n * ```ts\n * const result = getPrefixPathname(\"/other-path/profile\", \"/settings\");\n * console.log(result); // ➔ null\n * ```\n */\nexport const getPrefixPathname = (\n url: string | string[],\n base: string | string[] | null = null,\n options: GetPrefixPathnameOptions = {}\n): string | string[] | null => {\n const errors: string[] = [];\n\n if (!isString(url) && !isArray(url)) {\n errors.push(\n `First parameter (\\`url\\`) must be of type \\`string\\` or \\`array-string\\`, but received: \\`${getPreciseType(\n url\n )}\\`.`\n );\n }\n if (!isString(base) && !isArray(base) && !isNull(base)) {\n errors.push(\n `Second parameter (\\`base\\`) must be of type \\`string\\`, \\`array-string\\` or \\`null\\`, but received: \\`${getPreciseType(\n base\n )}\\`.`\n );\n }\n if (!isPlainObject(options)) {\n errors.push(\n `Second parameter (\\`options\\`) must be of type \\`plain-object\\`, but received: \\`${getPreciseType(\n options\n )}\\`.`\n );\n }\n\n const { levels = 1, removeDuplicates = true } = options;\n\n if (!isInteger(levels) || (isInteger(levels) && levels < 0)) {\n errors.push(\n `Parameter \\`levels\\` property of the \\`options\\` (second parameter) must be of type \\`integer-number\\` and minimum is \\`0\\`, but received: \\`${getPreciseType(\n levels\n )}\\`, with value: \\`${safeStableStringify(levels, {\n keepUndefined: true\n })}\\`.`\n );\n }\n if (!isBoolean(removeDuplicates)) {\n errors.push(\n `Parameter \\`removeDuplicates\\` property of the \\`options\\` (second parameter) must be of type \\`boolean\\`, but received: \\`${getPreciseType(\n removeDuplicates\n )}\\`.`\n );\n }\n if (isNonEmptyArray(errors)) {\n throw new TypeError(\n joinLines(\n \"Invalid parameter(s) in `getPrefixPathname` function:\",\n `- ${errors.join(`${EOL}- `)}`\n )\n );\n }\n\n // Helper function to process a single URL\n function getLevel(singleUrl: string) {\n // If no base is provided, detect the base automatically\n const parts = normalizePathname(singleUrl).split(\"/\").filter(Boolean); // Split URL into parts\n\n // Return the first `levels` parts as the prefix\n return `/${parts.slice(0, levels).join(\"/\")}`;\n }\n\n // Helper function to process a single URL\n function processUrl(singleUrl: string): string | null {\n // If a base is provided, check if URL starts with one of the bases\n if (base) {\n singleUrl = normalizePathname(singleUrl);\n\n if (isArray(base)) {\n // Check if the URL starts with any of the base values in the array\n for (const b of base) {\n if (singleUrl.startsWith(normalizePathname(b))) {\n // return normalizePathname(b); // Return the matching base if URL starts with it\n return getLevel(singleUrl);\n }\n }\n } else if (\n isNonEmptyString(base) &&\n singleUrl.startsWith(normalizePathname(base))\n ) {\n // If base is a single string, check if URL starts with it\n // return normalizePathname(base); // Return the base if URL starts with it\n return getLevel(singleUrl);\n }\n return null; // Return null if the URL does not match any base\n }\n\n return getLevel(singleUrl);\n }\n\n // If url is an array, process each URL and return an array of results\n if (isArray(url)) {\n const result = url.map(processUrl).filter((r): r is string => !isNull(r));\n\n // Remove duplicates if required\n const uniqueResult = removeDuplicates ? [...new Set(result)] : result;\n\n // If all results are the same, return just the first one\n if (uniqueResult.length === 1) {\n return uniqueResult[0] ?? null;\n }\n\n return uniqueResult;\n }\n\n // If url is a single string, process it and return the result\n return processUrl(url);\n};\n","import { isBoolean } from \"@/predicates/is/isBoolean\";\nimport { hasOwnProp } from \"@/predicates/has/hasOwnProp\";\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\n\ntype FormatEnvPortOptions = {\n /** Add prefix with a colon, defaultValue: `false`.\n *\n * @default false\n */\n prefixColon?: boolean;\n};\n\n/** -----------------------------------------------\n * * ***Utility: `formatEnvPort`.***\n * -----------------------------------------------\n * **Retrieves and formats an environment port variable.**\n * - **Behavior:**\n * - Extracts only digits from the input.\n * - If no digits found, returns an empty string.\n * - By default does NOT prefix with a colon.\n * - Use `{ prefixColon: true }` to prefix with a colon.\n * @param {string | null | undefined} envVar The environment variable string.\n * @param {FormatEnvPortOptions} [options] Optional object: `{ prefixColon?: boolean }`.\n * @returns {string} A string like `\":8080\"` or `\"8080\"`, or `\"\"` if no digits.\n * @throws **{@link TypeError | `TypeError`}** if `options` is not an object or `prefixColon` is not boolean.\n * @example\n * formatEnvPort(\"port:8080\");\n * // ➔ \"8080\"\n * formatEnvPort(\"port:8080\", { prefixColon: true });\n * // ➔ \":8080\"\n */\nexport const formatEnvPort = (\n envVar: string | null | undefined,\n options: FormatEnvPortOptions = {}\n): string => {\n if (!isNonEmptyString(envVar)) return \"\"; // Handle empty string case\n\n assertIsPlainObject(options, {\n message: ({ currentType, validType }) =>\n `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n const prefixColon = hasOwnProp(options, \"prefixColon\")\n ? options.prefixColon\n : false;\n\n if (!isBoolean(prefixColon)) {\n throw new TypeError(\n `Parameter \\`prefixColon\\` property of the \\`options\\` (second parameter) must be of type \\`boolean\\`, but received: \\`${getPreciseType(\n prefixColon\n )}\\`.`\n );\n }\n\n const digitsOnly = envVar.replace(/\\D+/g, \"\");\n if (isEmptyString(digitsOnly)) return \"\";\n\n return prefixColon ? `:${digitsOnly}` : digitsOnly;\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rzl-zone/utils-js",
|
|
3
|
-
"version": "3.13.0
|
|
3
|
+
"version": "3.13.0",
|
|
4
4
|
"description": "A modern, lightweight set of JavaScript utility functions with TypeScript support for everyday development, crafted to enhance code readability and maintainability.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"unpkg": "./dist/rzl-utils.global.js",
|
|
@@ -190,8 +190,8 @@
|
|
|
190
190
|
"libphonenumber-js": "^1.13.1",
|
|
191
191
|
"tailwind-merge-v3": "npm:tailwind-merge@^2",
|
|
192
192
|
"tailwind-merge-v4": "npm:tailwind-merge@^3",
|
|
193
|
-
"@rzl-zone/node-only": "0.0.10
|
|
194
|
-
"@rzl-zone/ts-types-plus": "0.1.6
|
|
193
|
+
"@rzl-zone/node-only": "0.0.10",
|
|
194
|
+
"@rzl-zone/ts-types-plus": "0.1.6"
|
|
195
195
|
},
|
|
196
196
|
"devDependencies": {
|
|
197
197
|
"@eslint/js": "^10",
|
|
@@ -206,8 +206,8 @@
|
|
|
206
206
|
"tsx": "^4.21.0",
|
|
207
207
|
"typescript": "6.0.3",
|
|
208
208
|
"vitest": "^4.1.6",
|
|
209
|
-
"@rzl-zone/build-tools": "0.0.12
|
|
210
|
-
"@rzl-zone/eslint": "0.0.10
|
|
209
|
+
"@rzl-zone/build-tools": "0.0.12",
|
|
210
|
+
"@rzl-zone/eslint": "0.0.10",
|
|
211
211
|
"@workspace/eslint-config": "0.0.0",
|
|
212
212
|
"@workspace/typescript-config": "0.0.0"
|
|
213
213
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isValidDomain-BCN5-tj9.js","names":["ccTldMap","sldMap"],"sources":["../src/predicates/is/isURL.ts","../../build-tools/dist/formatter-BS3omf7k.js","../src/predicates/is/_private/data/domain/sldMap.json","../src/predicates/is/_private/data/domain/ccTldMap.json","../src/predicates/is/isValidDomain.ts"],"sourcesContent":["/** ---------------------------------------------------------\n * * ***Type guard: `isURL`.***\n * ----------------------------------------------------------\n * **Checks if a value is an instance of the\n * **[`URL`](https://developer.mozilla.org/docs/Web/API/URL)** class.**\n * - **Behavior:**\n * - Narrows type to `URL` when true.\n * - Excludes `strings`, `plain-objects`, and `other non-URL values`.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the value is an instance of `URL`, otherwise `false`.\n * @example\n * isURL(new URL(\"https://example.com\"));\n * // ➔ true\n * isURL(\"https://example.com\");\n * // ➔ false\n */\nexport const isURL = (value: unknown): value is URL => {\n return value instanceof URL;\n};\n","/*!\n* ========================================================================\n* @rzl-zone/build-tools\n* ------------------------------------------------------------------------\n* Version: `0.0.12-beta.0`\n* Author: `Rizalvin Dwiky <rizalvindwiky1998@gmail.com>`\n* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/build-tools`\n* ========================================================================\n*/\n\nimport pcr from \"picocolors\";\nfunction deepFreeze(value) {\n\tif (typeof value !== \"object\" || value === null) return value;\n\tconst seen = /* @__PURE__ */ new WeakSet();\n\tconst stack = [value];\n\twhile (stack.length) {\n\t\tconst obj = stack.pop();\n\t\tif (seen.has(obj) || Object.isFrozen(obj)) continue;\n\t\tseen.add(obj);\n\t\tif (isMap(obj)) for (const [k, v] of obj) {\n\t\t\tif (typeof k === \"object\" && k !== null) stack.push(k);\n\t\t\tif (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t}\n\t\telse if (isSet(obj)) {\n\t\t\tfor (const v of obj) if (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t} else if (isArray(obj)) {\n\t\t\tfor (const v of obj) if (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t} else {\n\t\t\tconst record = obj;\n\t\t\tfor (const key of Reflect.ownKeys(record)) {\n\t\t\t\tconst v = record[key];\n\t\t\t\tif (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t\t}\n\t\t}\n\t\tObject.freeze(obj);\n\t}\n\treturn value;\n}\nconst isRegExp = (value) => {\n\treturn value instanceof RegExp;\n};\nconst isString = (value) => {\n\treturn typeof value === \"string\";\n};\nfunction isSet(value) {\n\treturn Object.prototype.toString.call(value) === \"[object Set]\" || value instanceof Set;\n}\nfunction isMap(value) {\n\treturn Object.prototype.toString.call(value) === \"[object Map]\" || value instanceof Map;\n}\nfunction isArray(value) {\n\treturn Array.isArray(value);\n}\nconst isNull = (val) => val === null;\nfunction isPlainObject(value) {\n\tif (!isObject(value)) return false;\n\tconst proto = Object.getPrototypeOf(value);\n\treturn proto === Object.prototype || proto === null;\n}\nfunction isObject(value) {\n\treturn typeof value === \"object\" && !isNil(value) && !isArray(value);\n}\nfunction isObjectOrArray(value) {\n\treturn isArray(value) || isObject(value);\n}\nconst isNil = (value) => {\n\treturn value == null;\n};\nconst isBoolean = (value) => {\n\treturn typeof value === \"boolean\";\n};\nconst isUndefined = (value) => {\n\treturn typeof value === \"undefined\";\n};\nconst isFunction = (value) => {\n\treturn typeof value === \"function\";\n};\nconst isNumberObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object Number]\";\n};\nconst isStringObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object String]\";\n};\nconst isBooleanObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object Boolean]\";\n};\nconst isInfinityNumber = (value) => {\n\tif (typeof value === \"number\" || isNumberObject(value)) {\n\t\tconst num = Number(value);\n\t\treturn num === Infinity || num === -Infinity;\n\t}\n\treturn false;\n};\nconst isSymbol = (value) => {\n\treturn typeof value === \"symbol\";\n};\nconst isBigInt = (value) => {\n\treturn typeof value === \"bigint\";\n};\nconst isNaN = (value) => {\n\treturn typeof value === \"number\" ? Number.isNaN(value) : isNumberObject(value) && Number.isNaN(value.valueOf());\n};\nconst isNonEmptyString = (value, options = {}) => {\n\tif (!isString(value)) return false;\n\treturn (options.trim ?? true ? value.trim() : value).length > 0;\n};\nconst isNumber = (value, options = {}) => {\n\tconst includeNaN = isPlainObject(options) && isBoolean(options.includeNaN) ? options.includeNaN : false;\n\tconst aNumber = typeof value === \"number\";\n\treturn includeNaN ? aNumber : aNumber && !Number.isNaN(value);\n};\nconst isError = (error) => {\n\treturn Object.prototype.toString.call(error) === \"[object Error]\" || error instanceof Error;\n};\nconst isDate = (value, options = {}) => {\n\tconst skipInvalidDate = isPlainObject(options) && isBoolean(options.skipInvalidDate) ? options.skipInvalidDate : false;\n\tconst instanceDate = value instanceof Date;\n\tif (skipInvalidDate) return instanceDate;\n\treturn instanceDate && !isNaN(value.getTime());\n};\nconst safeStableStringify = (value, options = {}) => {\n\tconst pretty = options.pretty ?? false;\n\tconst sortKeys = options.sortKeys ?? true;\n\tconst sortArray = options.sortArray ?? false;\n\tconst keepUndefined = options.keepUndefined ?? false;\n\tif (isUndefined(value)) return keepUndefined ? \"undefined\" : \"null\";\n\tconst seen = /* @__PURE__ */ new WeakSet();\n\tconst isPrimitive = (val) => isNull(val) || !isObjectOrArray(val) && !isFunction(val);\n\tconst deepProcess = (val) => {\n\t\tif (isNumberObject(val)) {\n\t\t\tconst valOf = val.valueOf();\n\t\t\treturn isNaN(valOf) || isInfinityNumber(valOf) ? null : valOf;\n\t\t}\n\t\tif (isStringObject(val)) return val.valueOf();\n\t\tif (isBooleanObject(val)) return val.valueOf();\n\t\tif (isFunction(val) || isSymbol(val)) return void 0;\n\t\tif (isBigInt(val)) return val.toString();\n\t\tif (isNaN(val) || isInfinityNumber(val)) return null;\n\t\tif (isUndefined(val)) return keepUndefined ? void 0 : null;\n\t\tif (isObjectOrArray(val)) {\n\t\t\tif (seen.has(val)) return \"[Circular]\";\n\t\t\tseen.add(val);\n\t\t\tif (isDate(val)) return val.toISOString();\n\t\t\tif (isMap(val)) return { map: Array.from(val.entries()).map(([k, v]) => [k, deepProcess(v)]) };\n\t\t\tif (isSet(val)) return { set: Array.from(val.values()).map(deepProcess) };\n\t\t\tif (isArray(val)) {\n\t\t\t\tconst processedArr = val.map(deepProcess);\n\t\t\t\tif (sortArray) {\n\t\t\t\t\tconst primitives = [];\n\t\t\t\t\tconst nonPrimitives = [];\n\t\t\t\t\tfor (const item of processedArr) if (isPrimitive(item)) primitives.push(item);\n\t\t\t\t\telse nonPrimitives.push(item);\n\t\t\t\t\tprimitives.sort((a, b) => {\n\t\t\t\t\t\tif (isNumber(a) && isNumber(b)) return a - b;\n\t\t\t\t\t\treturn String(a).localeCompare(String(b));\n\t\t\t\t\t});\n\t\t\t\t\treturn [...primitives, ...nonPrimitives];\n\t\t\t\t}\n\t\t\t\treturn processedArr;\n\t\t\t}\n\t\t\tconst keys = Object.keys(val);\n\t\t\tif (sortKeys) keys.sort((a, b) => {\n\t\t\t\tconst na = Number(a);\n\t\t\t\tconst nb = Number(b);\n\t\t\t\tif (!isNaN(na) && !isNaN(nb)) return na - nb;\n\t\t\t\treturn a.localeCompare(b);\n\t\t\t});\n\t\t\tconst result = {};\n\t\t\tif (isObject(val)) for (const k of keys) {\n\t\t\t\tconst v = deepProcess(val[k]);\n\t\t\t\tif (!isUndefined(v)) result[k] = v;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\treturn val;\n\t};\n\ttry {\n\t\treturn JSON.stringify(deepProcess(value), null, pretty ? 2 : 0);\n\t} catch (err) {\n\t\tconsole.warn(\"Error in safeStableStringify:\", err);\n\t\treturn \"{}\";\n\t}\n};\nconst normalizeSpaces = (value, options = {\n\twithTrim: true,\n\ttrimOnly: false\n}) => {\n\tif (!isNonEmptyString(value)) return \"\";\n\tif (!isPlainObject(options)) options = {};\n\tconst { trimOnly = false, withTrim = true } = options;\n\tif (trimOnly) return value.trim();\n\tif (withTrim) value = value.trim();\n\treturn value.replace(/\\s+/g, \" \");\n};\nconst isStringArray = (v) => isArray(v) && v.every((i) => isString(i));\nconst isStringSet = (v) => isSet(v) && [...v].every((i) => isString(i));\nconst assertValidatePatternArgs = (v, parameterKey = \"pattern\") => {\n\tif (!isString(v) && !isStringArray(v) && !isStringSet(v)) throw new TypeError(`The \\`${parameterKey}\\` argument must be a string, string[] or Set<string>.`);\n};\nconst flattenStrings = (input) => {\n\treturn input.flat(Infinity).filter((v) => typeof v === \"string\");\n};\nconst toStringSet = (pattern, options = {}) => {\n\tconst { withValidationType = true, parameterKey = \"pattern\" } = options;\n\tif (withValidationType) assertValidatePatternArgs(pattern, parameterKey);\n\treturn toObjectSet(pattern);\n};\nconst toObjectSet = (value) => {\n\tif (isSet(value)) return value;\n\treturn new Set(isArray(value) ? value : [value]);\n};\nconst toArray = (value) => {\n\treturn isArray(value) ? value : [value];\n};\nconst hasGlobalRequire = (value) => isObject(value) && isFunction(value.require);\nconst getRuntimeRequire = () => {\n\tif (!hasGlobalRequire(globalThis)) return void 0;\n\treturn globalThis.require;\n};\nconst __runtimeRequire = ((x) => {\n\tconst r = getRuntimeRequire();\n\tif (r) return r;\n\tif (typeof Proxy !== \"undefined\") return new Proxy(x, { get(target, prop) {\n\t\tconst r2 = getRuntimeRequire();\n\t\treturn r2 ? r2[prop] : target[prop];\n\t} });\n\treturn x;\n})(function(id) {\n\tconst r = getRuntimeRequire();\n\tif (r) return r.call(this, id);\n\tthrow new Error(`Calling \\`require\\` for \"${id}\" in an environment that doesn't expose the \\`require\\` function.`);\n});\nconst picocolors = pcr;\nconst NEWLINE = atob(\"Cg==\");\nconst EOL = hasGlobalRequire(globalThis) ? __runtimeRequire(\"node:os\").EOL : NEWLINE;\nfunction plural(count, word, pluralWord) {\n\tif (count === 1) return word;\n\treturn pluralWord ?? `${word}s`;\n}\nfunction padText(value, options = {}) {\n\tconst { start = true, end = true, padOnInvalid = true } = options;\n\tif (!isNonEmptyString(value)) return padOnInvalid ? \" \" : \"\";\n\treturn `${start ? \" \" : \"\"}${value}${end ? \" \" : \"\"}`;\n}\nfunction joinInline(...text) {\n\treturn text.filter(Boolean).join(\" \");\n}\nfunction joinLines(...text) {\n\treturn text.filter(Boolean).join(EOL);\n}\nfunction joinLinesLoose(...text) {\n\treturn text.filter((v) => v !== false && v !== null && v !== void 0).join(EOL);\n}\nfunction formatOptionValue(value, options) {\n\tconst { pretty = false, indent = 2, sortKeys = false, sortArray = false } = options ?? {};\n\tconst indentUnit = \" \".repeat(indent);\n\tfunction formatRecursive(input, depth = 0) {\n\t\tconst currentIndent = indentUnit.repeat(depth);\n\t\tconst nextIndent = indentUnit.repeat(depth + 1);\n\t\tconst joinInline = picocolors.dim(\", \");\n\t\tconst joinPretty = `,${EOL}`;\n\t\tif (isSet(input)) return formatRecursive([...input], depth);\n\t\tif (isMap(input)) return formatRecursive(Object.fromEntries(input), depth);\n\t\tif (isArray(input)) {\n\t\t\tconst arr = sortArray ? [...input].sort() : input;\n\t\t\tif (arr.length === 0) return picocolors.gray(\"[]\");\n\t\t\tif (!pretty) {\n\t\t\t\tconst items = arr.map((v) => formatRecursive(v, depth)).join(joinInline);\n\t\t\t\treturn picocolors.gray(\"[\") + items + picocolors.gray(\"]\");\n\t\t\t}\n\t\t\tconst items = arr.map((v) => nextIndent + formatRecursive(v, depth + 1)).join(joinPretty);\n\t\t\treturn picocolors.gray(`[${EOL}`) + items + EOL + currentIndent + picocolors.gray(\"]\");\n\t\t}\n\t\tif (isPlainObject(input)) {\n\t\t\tlet entries = Object.entries(input);\n\t\t\tif (sortKeys) entries = entries.sort(([a], [b]) => a.localeCompare(b));\n\t\t\tif (entries.length === 0) return picocolors.gray(\"{}\");\n\t\t\tif (!pretty) {\n\t\t\t\tconst props = entries.map(([key, val]) => {\n\t\t\t\t\treturn picocolors.dim(key) + picocolors.gray(\": \") + formatRecursive(val, depth);\n\t\t\t\t}).join(joinInline);\n\t\t\t\treturn picocolors.gray(\"{ \") + props + picocolors.gray(\" }\");\n\t\t\t}\n\t\t\tconst props = entries.map(([key, val]) => {\n\t\t\t\treturn nextIndent + picocolors.dim(key) + picocolors.gray(\": \") + formatRecursive(val, depth + 1);\n\t\t\t}).join(joinPretty);\n\t\t\treturn picocolors.gray(`{${EOL}`) + props + EOL + currentIndent + picocolors.gray(\"}\");\n\t\t}\n\t\tif (isRegExp(input)) return picocolors.greenBright(\"/\") + picocolors.redBright(input.source) + picocolors.greenBright(\"/\") + picocolors.magentaBright(input.flags);\n\t\tif (isString(input)) return picocolors.gray(`\"${input}\"`);\n\t\tif (isNumber(input, { includeNaN: true })) return picocolors.redBright(String(input));\n\t\tif (isBoolean(input)) return picocolors.redBright(String(input));\n\t\tif (isNil(input)) return picocolors.redBright(String(input));\n\t\tif (isObject(input)) return picocolors.cyanBright(Object.prototype.toString.call(input));\n\t\treturn picocolors.cyanBright(String(input));\n\t}\n\treturn formatRecursive(value);\n}\nexport { isString as C, toArray as D, safeStableStringify as E, toObjectSet as O, isSet as S, normalizeSpaces as T, isNonEmptyString as _, joinLines as a, isPlainObject as b, picocolors as c, flattenStrings as d, isArray as f, isNil as g, isFunction as h, joinInline as i, toStringSet as k, plural as l, isError as m, NEWLINE as n, joinLinesLoose as o, isBoolean as p, formatOptionValue as r, padText as s, EOL as t, deepFreeze as u, isNull as v, isUndefined as w, isRegExp as x, isNumber as y };\n//# sourceMappingURL=formatter-BS3omf7k.js.map\n","","","import { joinLines, EOL } from \"@rzl-zone/build-tools/utils\";\n\nimport { punycodeUtilsJS } from \"@/urls/utils/punyCode\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport sldMap from \"./_private/data/domain/sldMap.json\";\nimport ccTldMap from \"./_private/data/domain/ccTldMap.json\";\n\nimport { isString } from \"./isString\";\nimport { isBoolean } from \"./isBoolean\";\n\nimport { getPreciseType } from \"../type/getPreciseType\";\n\n/** ---------------------------------------------------------\n * * ***Options for `isValidDomain` predicate.***\n * ---------------------------------------------------------\n * **Customize the behavior of domain validation.**\n */\ntype IsValidDomainOptions = {\n /** * ***Enable conversion of Unicode domains (IDN) to ASCII (punycode).***\n *\n * - Example: `\"пример.рф\"` ➔ `\"xn--e1afmkfd.xn--p1ai\"`\n * - Allows validating Unicode domains correctly.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowUnicode?: boolean;\n\n /** * ***If `true`, validates **only top-level domains (TLDs)** that are not part of any SLD/second-level domain.***\n *\n * - Accepts country-code TLDs like `\"ai\"` or `\"ai.\"` ✅\n * - Rejects common TLDs that are part of SLDs like `\"com\"` ❌\n * - Only the final label is checked; subdomains are ignored.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n topLevel?: boolean;\n\n /** * ***Allow or disallow subdomains.***\n *\n * - Example: `\"sub.example.com\"` ✅ if `subdomain` is `true`, ❌ if `false`\n * - Wildcards and SLDs are considered when evaluating subdomains.\n * - Default: `true`\n *\n * @defaultValue `true`.\n */\n subdomain?: boolean;\n\n /** * ***Allow a wildcard `*` in the left-most label.***\n *\n * - Example: `\"*.example.com\"` ✅ if `wildcard` is `true`, ❌ if `false`\n * - Wildcards are only valid in the first label and require at least one additional label.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n wildcard?: boolean;\n\n /** * ***Allow a port after the domain.***\n *\n * - Example: `\"localhost:3000\"` or `\"example.com:8080\"` ✅ if `allowPort` is `true`\n * - Validates that the port is a number between `1` and `65535`.\n * - Does not affect domain validation rules otherwise.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowPort?: boolean;\n\n /** * ***Allow special domains like `localhost`.***\n *\n * - Example: `\"localhost\"` ✅ if `allowLocalhost` is `true`\n * - Works with or without a port if `allowPort` is enabled.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowLocalhost?: boolean;\n\n /** * ***Allow URLs with protocol (`http`/`https`) and automatically extract the hostname.***\n *\n * - Example: `\"https://example.com/foo/bar\"` ➔ `\"example.com\"`\n * - The function will validate only the hostname part and ignore the path, query, and fragment.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowProtocol?: boolean;\n};\n\n/** ---------------------------------------------------------\n * * ***Predicate: `isValidDomain`.***\n * ---------------------------------------------------------\n * **Validates whether a given string is a properly formatted domain name.**\n *\n * - **Supports options for:**\n * - `allowUnicode` ➔ allows internationalized domain names (IDN) with Unicode characters.\n * - `topLevel` ➔ validates **only top-level domains (TLDs)**; ignores subdomains and SLDs.\n * - `subdomain` ➔ allows or disallows subdomains.\n * - `wildcard` ➔ allows wildcard (`*`) in the left-most label.\n * - `allowPort` ➔ allows a port number after the domain (e.g., `example.com:8080`).\n * - `allowLocalhost` ➔ allows the special domain `\"localhost\"`.\n * - `allowProtocol` ➔ allows a URL with protocol (`http`/`https`) and extracts the hostname.\n *\n * - **Behavior:**\n * - ✅ Converts Unicode to ASCII (punycode) if `allowUnicode` is `true`.\n * - ✅ Checks label lengths (≤63 chars), valid characters, and punycode consistency.\n * - ✅ Validates port if `allowPort` is `true` (must be 1–65535).\n * - ✅ Accepts `\"localhost\"` if `allowLocalhost` is `true`.\n * - ✅ Extracts hostname from URLs if `allowProtocol` is `true`.\n * - ❌ Rejects invalid domains, labels starting/ending with `-`, double dots, malformed TLDs, or invalid port numbers.\n * - ✅ Handles both standard domains (example.com), URLs with protocols (https://example.com/foo), and IDNs (пример.рф).\n *\n * @param {*} value - The value to validate; only strings are valid domains.\n * @param {IsValidDomainOptions} [options] - Optional configuration for domain validation.\n * @param {boolean} [options.allowUnicode=false] - Enable punycode conversion for Unicode domains.\n * @param {boolean} [options.topLevel=false] - Validate only TLDs (e.g., `ai`, `uk.`); ignores SLDs like `com`.\n * @param {boolean} [options.subdomain=true] - Allow subdomains; set `false` to reject any subdomain.\n * @param {boolean} [options.wildcard=false] - Allow wildcard `*` in the left-most label (e.g., `*.example.com`).\n * @param {boolean} [options.allowPort=false] - Allow port number after domain (e.g., `:3000`); must be 1–65535.\n * @param {boolean} [options.allowLocalhost=false] - Allow special domain `\"localhost\"`.\n * @param {boolean} [options.allowProtocol=false] - Allow URLs with protocol (`http`/`https`) and extract hostname only.\n * @returns {boolean} Returns `true` if the value is a valid domain according to the rules and options; otherwise `false`.\n *\n * @example\n * isValidDomain(\"google.com\");\n * // ➔ true\n * isValidDomain(\"пример.рф\", { allowUnicode: true });\n * // ➔ true\n * isValidDomain(\"sub.example.com\", { subdomain: false });\n * // ➔ false\n * isValidDomain(\"*.example.com\", { wildcard: true });\n * // ➔ true\n * isValidDomain(\"com\", { topLevel: true });\n * // ➔ false (common TLD rejected because it's part of SLD)\n * isValidDomain(\"ai.\", { topLevel: true });\n * // ➔ true (country-code TLD accepted)\n * isValidDomain(\"localhost\", { allowLocalhost: true });\n * // ➔ true\n * isValidDomain(\"localhost:3000\", { allowLocalhost: true, allowPort: true });\n * // ➔ true\n * isValidDomain(\"example.com:8080\", { allowPort: true });\n * // ➔ true\n * isValidDomain(\"https://example.com/foo/bar\", { allowProtocol: true });\n * // ➔ true (protocol stripped and hostname validated)\n * isValidDomain(\"invalid_domain.com\");\n * // ➔ false\n */\nexport function isValidDomain(\n value: unknown,\n options: IsValidDomainOptions = {}\n): boolean {\n if (!isString(value)) return false;\n\n assertIsPlainObject(options, {\n message: ({ currentType, validType }) =>\n `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n const {\n subdomain = true,\n topLevel = false,\n wildcard = false,\n allowUnicode = false,\n allowPort = false,\n allowLocalhost = false,\n allowProtocol = false\n } = options;\n\n // Validate Options:\n const invalid = Object.entries({\n subdomain,\n topLevel,\n wildcard,\n allowUnicode,\n allowProtocol,\n allowPort,\n allowLocalhost\n }).filter(([, value]) => !isBoolean(value));\n\n if (invalid.length) {\n const msg = invalid\n .map(([key, value], i) => {\n return joinLines(\n ` ${i + 1}. option: \"${key}\"`,\n \" expected: boolean\",\n ` received: ${getPreciseType(value)} (${safeStableStringify(\n value,\n {\n keepUndefined: true\n }\n )})`\n );\n })\n .join(EOL);\n\n throw new TypeError(\n joinLines(\n \"\",\n \"> Invalid options detected in second parameter of `isValidDomain`:\",\n msg\n )\n );\n }\n // -----------------\n\n let _value = value.toLowerCase();\n\n if (allowProtocol) {\n try {\n const url = new URL(value); // use original input\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return false; // reject non-http(s)\n if (!allowPort && url.port) return false; // reject port if allowPort=false\n _value = url.hostname.toLowerCase(); // extract only hostname\n\n // wildcard check\n const labels = _value.split(\".\");\n if (labels[0] === \"*\" && !wildcard) return false;\n } catch {\n // if parsing fails, leave _value unchanged\n }\n }\n\n if (value.endsWith(\".\")) {\n _value = _value.slice(0, _value.length - 1);\n }\n\n // Handle port\n let port: string;\n if (allowPort) {\n const portMatch = _value.match(/:(\\d{1,5})$/);\n if (portMatch) {\n port = portMatch[0];\n _value = _value.slice(0, -port.length);\n const portNum = Number(portMatch[1]);\n if (portNum < 1 || portNum > 65535) return false;\n }\n }\n\n // Allow localhost\n if (allowLocalhost && _value === \"localhost\") return true;\n\n if (allowUnicode) {\n try {\n _value = punycodeUtilsJS.toASCII(_value);\n } catch {\n return false;\n }\n }\n\n if (_value.length > 253) return false;\n\n const validChars = /^([\\u0E00-\\u0E7Fa-z0-9-._*]+)$/g;\n if (!validChars.test(_value)) return false;\n\n if (topLevel) {\n if (ccTldMap[_value.replace(/\\.$/, \"\") as keyof typeof ccTldMap]) {\n return true;\n }\n }\n\n const sldRegex = /(.*)\\.(([\\u0E00-\\u0E7Fa-z0-9]+)(\\.[a-z0-9]+))/;\n const matches = _value.match(sldRegex);\n // eslint-disable-next-line no-useless-assignment\n let tld: string | null = null;\n let labels: string[] | null = null;\n\n if (matches && matches.length > 2) {\n if (sldMap[matches[2] as keyof typeof sldMap]) {\n // eslint-disable-next-line no-useless-assignment\n tld = matches[2] || null;\n labels = matches[1]?.split(\".\") || null;\n }\n }\n\n if (!labels) {\n labels = _value.split(\".\");\n if (labels.length <= 1) return false;\n\n tld = labels.pop()!;\n const tldRegex = /^(?:xn--)?(?!^\\d+$)[\\u0E00-\\u0E7Fa-z0-9]+$/gi;\n if (!tldRegex.test(tld)) return false;\n }\n\n if (subdomain === false && labels.length > 1) return false;\n\n return labels.every((label, index) => {\n if (wildcard && index === 0 && label === \"*\" && labels.length > 1) {\n return true;\n }\n\n let validLabelChars = /^([\\u0E00-\\u0E7Fa-zA-Z0-9-_]+)$/g;\n if (index === labels.length - 1) {\n validLabelChars = /^([\\u0E00-\\u0E7Fa-zA-Z0-9-]+)$/g;\n }\n\n const doubleDashCount = (label.match(/--(--)?/g) || []).length;\n const xnDashCount = (label.match(/xn--/g) || []).length;\n if (index === labels.length - 1 && doubleDashCount !== xnDashCount) {\n return false;\n }\n\n return (\n validLabelChars.test(label) &&\n label.length < 64 &&\n !label.startsWith(\"-\") &&\n !label.endsWith(\"-\")\n );\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAa,SAAS,UAAiC;CACrD,OAAO,iBAAiB;;;;;;;;;;;;;;ACiC1B,SAAS,QAAQ,OAAO;CACvB,OAAO,MAAM,QAAQ,MAAM;;AAQ5B,SAAS,SAAS,OAAO;CACxB,OAAO,OAAO,UAAU,YAAY,CAAC,MAAM,MAAM,IAAI,CAAC,QAAQ,MAAM;;AAKrE,MAAM,SAAS,UAAU;CACxB,OAAO,SAAS;;AAQjB,MAAM,cAAc,UAAU;CAC7B,OAAO,OAAO,UAAU;;AA2IzB,MAAM,oBAAoB,UAAU,SAAS,MAAM,IAAI,WAAW,MAAM,QAAQ;AAChF,MAAM,0BAA0B;CAC/B,IAAI,CAAC,iBAAiB,WAAW,EAAE,OAAO,KAAK;CAC/C,OAAO,WAAW;;AAEnB,MAAM,qBAAqB,MAAM;CAChC,MAAM,IAAI,mBAAmB;CAC7B,IAAI,GAAG,OAAO;CACd,IAAI,OAAO,UAAU,aAAa,OAAO,IAAI,MAAM,GAAG,EAAE,IAAI,QAAQ,MAAM;EACzE,MAAM,KAAK,mBAAmB;EAC9B,OAAO,KAAK,GAAG,QAAQ,OAAO;IAC5B,CAAC;CACJ,OAAO;GACL,SAAS,IAAI;CACf,MAAM,IAAI,mBAAmB;CAC7B,IAAI,GAAG,OAAO,EAAE,KAAK,MAAM,GAAG;CAC9B,MAAM,IAAI,MAAM,4BAA4B,GAAG,mEAAmE;EACjH;AAEF,MAAM,UAAU,KAAK,OAAO;AAC5B,MAAM,MAAM,iBAAiB,WAAW,GAAG,iBAAiB,UAAU,CAAC,MAAM;AAa7E,SAAS,UAAU,GAAG,MAAM;CAC3B,OAAO,KAAK,OAAO,QAAQ,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isValidDomain-CXWNcRo6.cjs","names":["isString","isBoolean","getPreciseType","safeStableStringify","punycodeUtilsJS","ccTldMap","sldMap"],"sources":["../src/predicates/is/isURL.ts","../../build-tools/dist/formatter-BS3omf7k.js","../src/predicates/is/_private/data/domain/sldMap.json","../src/predicates/is/_private/data/domain/ccTldMap.json","../src/predicates/is/isValidDomain.ts"],"sourcesContent":["/** ---------------------------------------------------------\n * * ***Type guard: `isURL`.***\n * ----------------------------------------------------------\n * **Checks if a value is an instance of the\n * **[`URL`](https://developer.mozilla.org/docs/Web/API/URL)** class.**\n * - **Behavior:**\n * - Narrows type to `URL` when true.\n * - Excludes `strings`, `plain-objects`, and `other non-URL values`.\n * @param {*} value - The value to check.\n * @returns {boolean} Returns `true` if the value is an instance of `URL`, otherwise `false`.\n * @example\n * isURL(new URL(\"https://example.com\"));\n * // ➔ true\n * isURL(\"https://example.com\");\n * // ➔ false\n */\nexport const isURL = (value: unknown): value is URL => {\n return value instanceof URL;\n};\n","/*!\n* ========================================================================\n* @rzl-zone/build-tools\n* ------------------------------------------------------------------------\n* Version: `0.0.12-beta.0`\n* Author: `Rizalvin Dwiky <rizalvindwiky1998@gmail.com>`\n* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/build-tools`\n* ========================================================================\n*/\n\nimport pcr from \"picocolors\";\nfunction deepFreeze(value) {\n\tif (typeof value !== \"object\" || value === null) return value;\n\tconst seen = /* @__PURE__ */ new WeakSet();\n\tconst stack = [value];\n\twhile (stack.length) {\n\t\tconst obj = stack.pop();\n\t\tif (seen.has(obj) || Object.isFrozen(obj)) continue;\n\t\tseen.add(obj);\n\t\tif (isMap(obj)) for (const [k, v] of obj) {\n\t\t\tif (typeof k === \"object\" && k !== null) stack.push(k);\n\t\t\tif (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t}\n\t\telse if (isSet(obj)) {\n\t\t\tfor (const v of obj) if (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t} else if (isArray(obj)) {\n\t\t\tfor (const v of obj) if (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t} else {\n\t\t\tconst record = obj;\n\t\t\tfor (const key of Reflect.ownKeys(record)) {\n\t\t\t\tconst v = record[key];\n\t\t\t\tif (typeof v === \"object\" && v !== null) stack.push(v);\n\t\t\t}\n\t\t}\n\t\tObject.freeze(obj);\n\t}\n\treturn value;\n}\nconst isRegExp = (value) => {\n\treturn value instanceof RegExp;\n};\nconst isString = (value) => {\n\treturn typeof value === \"string\";\n};\nfunction isSet(value) {\n\treturn Object.prototype.toString.call(value) === \"[object Set]\" || value instanceof Set;\n}\nfunction isMap(value) {\n\treturn Object.prototype.toString.call(value) === \"[object Map]\" || value instanceof Map;\n}\nfunction isArray(value) {\n\treturn Array.isArray(value);\n}\nconst isNull = (val) => val === null;\nfunction isPlainObject(value) {\n\tif (!isObject(value)) return false;\n\tconst proto = Object.getPrototypeOf(value);\n\treturn proto === Object.prototype || proto === null;\n}\nfunction isObject(value) {\n\treturn typeof value === \"object\" && !isNil(value) && !isArray(value);\n}\nfunction isObjectOrArray(value) {\n\treturn isArray(value) || isObject(value);\n}\nconst isNil = (value) => {\n\treturn value == null;\n};\nconst isBoolean = (value) => {\n\treturn typeof value === \"boolean\";\n};\nconst isUndefined = (value) => {\n\treturn typeof value === \"undefined\";\n};\nconst isFunction = (value) => {\n\treturn typeof value === \"function\";\n};\nconst isNumberObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object Number]\";\n};\nconst isStringObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object String]\";\n};\nconst isBooleanObject = (value) => {\n\treturn isObject(value) && Object.prototype.toString.call(value) === \"[object Boolean]\";\n};\nconst isInfinityNumber = (value) => {\n\tif (typeof value === \"number\" || isNumberObject(value)) {\n\t\tconst num = Number(value);\n\t\treturn num === Infinity || num === -Infinity;\n\t}\n\treturn false;\n};\nconst isSymbol = (value) => {\n\treturn typeof value === \"symbol\";\n};\nconst isBigInt = (value) => {\n\treturn typeof value === \"bigint\";\n};\nconst isNaN = (value) => {\n\treturn typeof value === \"number\" ? Number.isNaN(value) : isNumberObject(value) && Number.isNaN(value.valueOf());\n};\nconst isNonEmptyString = (value, options = {}) => {\n\tif (!isString(value)) return false;\n\treturn (options.trim ?? true ? value.trim() : value).length > 0;\n};\nconst isNumber = (value, options = {}) => {\n\tconst includeNaN = isPlainObject(options) && isBoolean(options.includeNaN) ? options.includeNaN : false;\n\tconst aNumber = typeof value === \"number\";\n\treturn includeNaN ? aNumber : aNumber && !Number.isNaN(value);\n};\nconst isError = (error) => {\n\treturn Object.prototype.toString.call(error) === \"[object Error]\" || error instanceof Error;\n};\nconst isDate = (value, options = {}) => {\n\tconst skipInvalidDate = isPlainObject(options) && isBoolean(options.skipInvalidDate) ? options.skipInvalidDate : false;\n\tconst instanceDate = value instanceof Date;\n\tif (skipInvalidDate) return instanceDate;\n\treturn instanceDate && !isNaN(value.getTime());\n};\nconst safeStableStringify = (value, options = {}) => {\n\tconst pretty = options.pretty ?? false;\n\tconst sortKeys = options.sortKeys ?? true;\n\tconst sortArray = options.sortArray ?? false;\n\tconst keepUndefined = options.keepUndefined ?? false;\n\tif (isUndefined(value)) return keepUndefined ? \"undefined\" : \"null\";\n\tconst seen = /* @__PURE__ */ new WeakSet();\n\tconst isPrimitive = (val) => isNull(val) || !isObjectOrArray(val) && !isFunction(val);\n\tconst deepProcess = (val) => {\n\t\tif (isNumberObject(val)) {\n\t\t\tconst valOf = val.valueOf();\n\t\t\treturn isNaN(valOf) || isInfinityNumber(valOf) ? null : valOf;\n\t\t}\n\t\tif (isStringObject(val)) return val.valueOf();\n\t\tif (isBooleanObject(val)) return val.valueOf();\n\t\tif (isFunction(val) || isSymbol(val)) return void 0;\n\t\tif (isBigInt(val)) return val.toString();\n\t\tif (isNaN(val) || isInfinityNumber(val)) return null;\n\t\tif (isUndefined(val)) return keepUndefined ? void 0 : null;\n\t\tif (isObjectOrArray(val)) {\n\t\t\tif (seen.has(val)) return \"[Circular]\";\n\t\t\tseen.add(val);\n\t\t\tif (isDate(val)) return val.toISOString();\n\t\t\tif (isMap(val)) return { map: Array.from(val.entries()).map(([k, v]) => [k, deepProcess(v)]) };\n\t\t\tif (isSet(val)) return { set: Array.from(val.values()).map(deepProcess) };\n\t\t\tif (isArray(val)) {\n\t\t\t\tconst processedArr = val.map(deepProcess);\n\t\t\t\tif (sortArray) {\n\t\t\t\t\tconst primitives = [];\n\t\t\t\t\tconst nonPrimitives = [];\n\t\t\t\t\tfor (const item of processedArr) if (isPrimitive(item)) primitives.push(item);\n\t\t\t\t\telse nonPrimitives.push(item);\n\t\t\t\t\tprimitives.sort((a, b) => {\n\t\t\t\t\t\tif (isNumber(a) && isNumber(b)) return a - b;\n\t\t\t\t\t\treturn String(a).localeCompare(String(b));\n\t\t\t\t\t});\n\t\t\t\t\treturn [...primitives, ...nonPrimitives];\n\t\t\t\t}\n\t\t\t\treturn processedArr;\n\t\t\t}\n\t\t\tconst keys = Object.keys(val);\n\t\t\tif (sortKeys) keys.sort((a, b) => {\n\t\t\t\tconst na = Number(a);\n\t\t\t\tconst nb = Number(b);\n\t\t\t\tif (!isNaN(na) && !isNaN(nb)) return na - nb;\n\t\t\t\treturn a.localeCompare(b);\n\t\t\t});\n\t\t\tconst result = {};\n\t\t\tif (isObject(val)) for (const k of keys) {\n\t\t\t\tconst v = deepProcess(val[k]);\n\t\t\t\tif (!isUndefined(v)) result[k] = v;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\treturn val;\n\t};\n\ttry {\n\t\treturn JSON.stringify(deepProcess(value), null, pretty ? 2 : 0);\n\t} catch (err) {\n\t\tconsole.warn(\"Error in safeStableStringify:\", err);\n\t\treturn \"{}\";\n\t}\n};\nconst normalizeSpaces = (value, options = {\n\twithTrim: true,\n\ttrimOnly: false\n}) => {\n\tif (!isNonEmptyString(value)) return \"\";\n\tif (!isPlainObject(options)) options = {};\n\tconst { trimOnly = false, withTrim = true } = options;\n\tif (trimOnly) return value.trim();\n\tif (withTrim) value = value.trim();\n\treturn value.replace(/\\s+/g, \" \");\n};\nconst isStringArray = (v) => isArray(v) && v.every((i) => isString(i));\nconst isStringSet = (v) => isSet(v) && [...v].every((i) => isString(i));\nconst assertValidatePatternArgs = (v, parameterKey = \"pattern\") => {\n\tif (!isString(v) && !isStringArray(v) && !isStringSet(v)) throw new TypeError(`The \\`${parameterKey}\\` argument must be a string, string[] or Set<string>.`);\n};\nconst flattenStrings = (input) => {\n\treturn input.flat(Infinity).filter((v) => typeof v === \"string\");\n};\nconst toStringSet = (pattern, options = {}) => {\n\tconst { withValidationType = true, parameterKey = \"pattern\" } = options;\n\tif (withValidationType) assertValidatePatternArgs(pattern, parameterKey);\n\treturn toObjectSet(pattern);\n};\nconst toObjectSet = (value) => {\n\tif (isSet(value)) return value;\n\treturn new Set(isArray(value) ? value : [value]);\n};\nconst toArray = (value) => {\n\treturn isArray(value) ? value : [value];\n};\nconst hasGlobalRequire = (value) => isObject(value) && isFunction(value.require);\nconst getRuntimeRequire = () => {\n\tif (!hasGlobalRequire(globalThis)) return void 0;\n\treturn globalThis.require;\n};\nconst __runtimeRequire = ((x) => {\n\tconst r = getRuntimeRequire();\n\tif (r) return r;\n\tif (typeof Proxy !== \"undefined\") return new Proxy(x, { get(target, prop) {\n\t\tconst r2 = getRuntimeRequire();\n\t\treturn r2 ? r2[prop] : target[prop];\n\t} });\n\treturn x;\n})(function(id) {\n\tconst r = getRuntimeRequire();\n\tif (r) return r.call(this, id);\n\tthrow new Error(`Calling \\`require\\` for \"${id}\" in an environment that doesn't expose the \\`require\\` function.`);\n});\nconst picocolors = pcr;\nconst NEWLINE = atob(\"Cg==\");\nconst EOL = hasGlobalRequire(globalThis) ? __runtimeRequire(\"node:os\").EOL : NEWLINE;\nfunction plural(count, word, pluralWord) {\n\tif (count === 1) return word;\n\treturn pluralWord ?? `${word}s`;\n}\nfunction padText(value, options = {}) {\n\tconst { start = true, end = true, padOnInvalid = true } = options;\n\tif (!isNonEmptyString(value)) return padOnInvalid ? \" \" : \"\";\n\treturn `${start ? \" \" : \"\"}${value}${end ? \" \" : \"\"}`;\n}\nfunction joinInline(...text) {\n\treturn text.filter(Boolean).join(\" \");\n}\nfunction joinLines(...text) {\n\treturn text.filter(Boolean).join(EOL);\n}\nfunction joinLinesLoose(...text) {\n\treturn text.filter((v) => v !== false && v !== null && v !== void 0).join(EOL);\n}\nfunction formatOptionValue(value, options) {\n\tconst { pretty = false, indent = 2, sortKeys = false, sortArray = false } = options ?? {};\n\tconst indentUnit = \" \".repeat(indent);\n\tfunction formatRecursive(input, depth = 0) {\n\t\tconst currentIndent = indentUnit.repeat(depth);\n\t\tconst nextIndent = indentUnit.repeat(depth + 1);\n\t\tconst joinInline = picocolors.dim(\", \");\n\t\tconst joinPretty = `,${EOL}`;\n\t\tif (isSet(input)) return formatRecursive([...input], depth);\n\t\tif (isMap(input)) return formatRecursive(Object.fromEntries(input), depth);\n\t\tif (isArray(input)) {\n\t\t\tconst arr = sortArray ? [...input].sort() : input;\n\t\t\tif (arr.length === 0) return picocolors.gray(\"[]\");\n\t\t\tif (!pretty) {\n\t\t\t\tconst items = arr.map((v) => formatRecursive(v, depth)).join(joinInline);\n\t\t\t\treturn picocolors.gray(\"[\") + items + picocolors.gray(\"]\");\n\t\t\t}\n\t\t\tconst items = arr.map((v) => nextIndent + formatRecursive(v, depth + 1)).join(joinPretty);\n\t\t\treturn picocolors.gray(`[${EOL}`) + items + EOL + currentIndent + picocolors.gray(\"]\");\n\t\t}\n\t\tif (isPlainObject(input)) {\n\t\t\tlet entries = Object.entries(input);\n\t\t\tif (sortKeys) entries = entries.sort(([a], [b]) => a.localeCompare(b));\n\t\t\tif (entries.length === 0) return picocolors.gray(\"{}\");\n\t\t\tif (!pretty) {\n\t\t\t\tconst props = entries.map(([key, val]) => {\n\t\t\t\t\treturn picocolors.dim(key) + picocolors.gray(\": \") + formatRecursive(val, depth);\n\t\t\t\t}).join(joinInline);\n\t\t\t\treturn picocolors.gray(\"{ \") + props + picocolors.gray(\" }\");\n\t\t\t}\n\t\t\tconst props = entries.map(([key, val]) => {\n\t\t\t\treturn nextIndent + picocolors.dim(key) + picocolors.gray(\": \") + formatRecursive(val, depth + 1);\n\t\t\t}).join(joinPretty);\n\t\t\treturn picocolors.gray(`{${EOL}`) + props + EOL + currentIndent + picocolors.gray(\"}\");\n\t\t}\n\t\tif (isRegExp(input)) return picocolors.greenBright(\"/\") + picocolors.redBright(input.source) + picocolors.greenBright(\"/\") + picocolors.magentaBright(input.flags);\n\t\tif (isString(input)) return picocolors.gray(`\"${input}\"`);\n\t\tif (isNumber(input, { includeNaN: true })) return picocolors.redBright(String(input));\n\t\tif (isBoolean(input)) return picocolors.redBright(String(input));\n\t\tif (isNil(input)) return picocolors.redBright(String(input));\n\t\tif (isObject(input)) return picocolors.cyanBright(Object.prototype.toString.call(input));\n\t\treturn picocolors.cyanBright(String(input));\n\t}\n\treturn formatRecursive(value);\n}\nexport { isString as C, toArray as D, safeStableStringify as E, toObjectSet as O, isSet as S, normalizeSpaces as T, isNonEmptyString as _, joinLines as a, isPlainObject as b, picocolors as c, flattenStrings as d, isArray as f, isNil as g, isFunction as h, joinInline as i, toStringSet as k, plural as l, isError as m, NEWLINE as n, joinLinesLoose as o, isBoolean as p, formatOptionValue as r, padText as s, EOL as t, deepFreeze as u, isNull as v, isUndefined as w, isRegExp as x, isNumber as y };\n//# sourceMappingURL=formatter-BS3omf7k.js.map\n","","","import { joinLines, EOL } from \"@rzl-zone/build-tools/utils\";\n\nimport { punycodeUtilsJS } from \"@/urls/utils/punyCode\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport sldMap from \"./_private/data/domain/sldMap.json\";\nimport ccTldMap from \"./_private/data/domain/ccTldMap.json\";\n\nimport { isString } from \"./isString\";\nimport { isBoolean } from \"./isBoolean\";\n\nimport { getPreciseType } from \"../type/getPreciseType\";\n\n/** ---------------------------------------------------------\n * * ***Options for `isValidDomain` predicate.***\n * ---------------------------------------------------------\n * **Customize the behavior of domain validation.**\n */\ntype IsValidDomainOptions = {\n /** * ***Enable conversion of Unicode domains (IDN) to ASCII (punycode).***\n *\n * - Example: `\"пример.рф\"` ➔ `\"xn--e1afmkfd.xn--p1ai\"`\n * - Allows validating Unicode domains correctly.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowUnicode?: boolean;\n\n /** * ***If `true`, validates **only top-level domains (TLDs)** that are not part of any SLD/second-level domain.***\n *\n * - Accepts country-code TLDs like `\"ai\"` or `\"ai.\"` ✅\n * - Rejects common TLDs that are part of SLDs like `\"com\"` ❌\n * - Only the final label is checked; subdomains are ignored.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n topLevel?: boolean;\n\n /** * ***Allow or disallow subdomains.***\n *\n * - Example: `\"sub.example.com\"` ✅ if `subdomain` is `true`, ❌ if `false`\n * - Wildcards and SLDs are considered when evaluating subdomains.\n * - Default: `true`\n *\n * @defaultValue `true`.\n */\n subdomain?: boolean;\n\n /** * ***Allow a wildcard `*` in the left-most label.***\n *\n * - Example: `\"*.example.com\"` ✅ if `wildcard` is `true`, ❌ if `false`\n * - Wildcards are only valid in the first label and require at least one additional label.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n wildcard?: boolean;\n\n /** * ***Allow a port after the domain.***\n *\n * - Example: `\"localhost:3000\"` or `\"example.com:8080\"` ✅ if `allowPort` is `true`\n * - Validates that the port is a number between `1` and `65535`.\n * - Does not affect domain validation rules otherwise.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowPort?: boolean;\n\n /** * ***Allow special domains like `localhost`.***\n *\n * - Example: `\"localhost\"` ✅ if `allowLocalhost` is `true`\n * - Works with or without a port if `allowPort` is enabled.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowLocalhost?: boolean;\n\n /** * ***Allow URLs with protocol (`http`/`https`) and automatically extract the hostname.***\n *\n * - Example: `\"https://example.com/foo/bar\"` ➔ `\"example.com\"`\n * - The function will validate only the hostname part and ignore the path, query, and fragment.\n * - Default: `false`\n *\n * @defaultValue `false`.\n */\n allowProtocol?: boolean;\n};\n\n/** ---------------------------------------------------------\n * * ***Predicate: `isValidDomain`.***\n * ---------------------------------------------------------\n * **Validates whether a given string is a properly formatted domain name.**\n *\n * - **Supports options for:**\n * - `allowUnicode` ➔ allows internationalized domain names (IDN) with Unicode characters.\n * - `topLevel` ➔ validates **only top-level domains (TLDs)**; ignores subdomains and SLDs.\n * - `subdomain` ➔ allows or disallows subdomains.\n * - `wildcard` ➔ allows wildcard (`*`) in the left-most label.\n * - `allowPort` ➔ allows a port number after the domain (e.g., `example.com:8080`).\n * - `allowLocalhost` ➔ allows the special domain `\"localhost\"`.\n * - `allowProtocol` ➔ allows a URL with protocol (`http`/`https`) and extracts the hostname.\n *\n * - **Behavior:**\n * - ✅ Converts Unicode to ASCII (punycode) if `allowUnicode` is `true`.\n * - ✅ Checks label lengths (≤63 chars), valid characters, and punycode consistency.\n * - ✅ Validates port if `allowPort` is `true` (must be 1–65535).\n * - ✅ Accepts `\"localhost\"` if `allowLocalhost` is `true`.\n * - ✅ Extracts hostname from URLs if `allowProtocol` is `true`.\n * - ❌ Rejects invalid domains, labels starting/ending with `-`, double dots, malformed TLDs, or invalid port numbers.\n * - ✅ Handles both standard domains (example.com), URLs with protocols (https://example.com/foo), and IDNs (пример.рф).\n *\n * @param {*} value - The value to validate; only strings are valid domains.\n * @param {IsValidDomainOptions} [options] - Optional configuration for domain validation.\n * @param {boolean} [options.allowUnicode=false] - Enable punycode conversion for Unicode domains.\n * @param {boolean} [options.topLevel=false] - Validate only TLDs (e.g., `ai`, `uk.`); ignores SLDs like `com`.\n * @param {boolean} [options.subdomain=true] - Allow subdomains; set `false` to reject any subdomain.\n * @param {boolean} [options.wildcard=false] - Allow wildcard `*` in the left-most label (e.g., `*.example.com`).\n * @param {boolean} [options.allowPort=false] - Allow port number after domain (e.g., `:3000`); must be 1–65535.\n * @param {boolean} [options.allowLocalhost=false] - Allow special domain `\"localhost\"`.\n * @param {boolean} [options.allowProtocol=false] - Allow URLs with protocol (`http`/`https`) and extract hostname only.\n * @returns {boolean} Returns `true` if the value is a valid domain according to the rules and options; otherwise `false`.\n *\n * @example\n * isValidDomain(\"google.com\");\n * // ➔ true\n * isValidDomain(\"пример.рф\", { allowUnicode: true });\n * // ➔ true\n * isValidDomain(\"sub.example.com\", { subdomain: false });\n * // ➔ false\n * isValidDomain(\"*.example.com\", { wildcard: true });\n * // ➔ true\n * isValidDomain(\"com\", { topLevel: true });\n * // ➔ false (common TLD rejected because it's part of SLD)\n * isValidDomain(\"ai.\", { topLevel: true });\n * // ➔ true (country-code TLD accepted)\n * isValidDomain(\"localhost\", { allowLocalhost: true });\n * // ➔ true\n * isValidDomain(\"localhost:3000\", { allowLocalhost: true, allowPort: true });\n * // ➔ true\n * isValidDomain(\"example.com:8080\", { allowPort: true });\n * // ➔ true\n * isValidDomain(\"https://example.com/foo/bar\", { allowProtocol: true });\n * // ➔ true (protocol stripped and hostname validated)\n * isValidDomain(\"invalid_domain.com\");\n * // ➔ false\n */\nexport function isValidDomain(\n value: unknown,\n options: IsValidDomainOptions = {}\n): boolean {\n if (!isString(value)) return false;\n\n assertIsPlainObject(options, {\n message: ({ currentType, validType }) =>\n `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n });\n\n const {\n subdomain = true,\n topLevel = false,\n wildcard = false,\n allowUnicode = false,\n allowPort = false,\n allowLocalhost = false,\n allowProtocol = false\n } = options;\n\n // Validate Options:\n const invalid = Object.entries({\n subdomain,\n topLevel,\n wildcard,\n allowUnicode,\n allowProtocol,\n allowPort,\n allowLocalhost\n }).filter(([, value]) => !isBoolean(value));\n\n if (invalid.length) {\n const msg = invalid\n .map(([key, value], i) => {\n return joinLines(\n ` ${i + 1}. option: \"${key}\"`,\n \" expected: boolean\",\n ` received: ${getPreciseType(value)} (${safeStableStringify(\n value,\n {\n keepUndefined: true\n }\n )})`\n );\n })\n .join(EOL);\n\n throw new TypeError(\n joinLines(\n \"\",\n \"> Invalid options detected in second parameter of `isValidDomain`:\",\n msg\n )\n );\n }\n // -----------------\n\n let _value = value.toLowerCase();\n\n if (allowProtocol) {\n try {\n const url = new URL(value); // use original input\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return false; // reject non-http(s)\n if (!allowPort && url.port) return false; // reject port if allowPort=false\n _value = url.hostname.toLowerCase(); // extract only hostname\n\n // wildcard check\n const labels = _value.split(\".\");\n if (labels[0] === \"*\" && !wildcard) return false;\n } catch {\n // if parsing fails, leave _value unchanged\n }\n }\n\n if (value.endsWith(\".\")) {\n _value = _value.slice(0, _value.length - 1);\n }\n\n // Handle port\n let port: string;\n if (allowPort) {\n const portMatch = _value.match(/:(\\d{1,5})$/);\n if (portMatch) {\n port = portMatch[0];\n _value = _value.slice(0, -port.length);\n const portNum = Number(portMatch[1]);\n if (portNum < 1 || portNum > 65535) return false;\n }\n }\n\n // Allow localhost\n if (allowLocalhost && _value === \"localhost\") return true;\n\n if (allowUnicode) {\n try {\n _value = punycodeUtilsJS.toASCII(_value);\n } catch {\n return false;\n }\n }\n\n if (_value.length > 253) return false;\n\n const validChars = /^([\\u0E00-\\u0E7Fa-z0-9-._*]+)$/g;\n if (!validChars.test(_value)) return false;\n\n if (topLevel) {\n if (ccTldMap[_value.replace(/\\.$/, \"\") as keyof typeof ccTldMap]) {\n return true;\n }\n }\n\n const sldRegex = /(.*)\\.(([\\u0E00-\\u0E7Fa-z0-9]+)(\\.[a-z0-9]+))/;\n const matches = _value.match(sldRegex);\n // eslint-disable-next-line no-useless-assignment\n let tld: string | null = null;\n let labels: string[] | null = null;\n\n if (matches && matches.length > 2) {\n if (sldMap[matches[2] as keyof typeof sldMap]) {\n // eslint-disable-next-line no-useless-assignment\n tld = matches[2] || null;\n labels = matches[1]?.split(\".\") || null;\n }\n }\n\n if (!labels) {\n labels = _value.split(\".\");\n if (labels.length <= 1) return false;\n\n tld = labels.pop()!;\n const tldRegex = /^(?:xn--)?(?!^\\d+$)[\\u0E00-\\u0E7Fa-z0-9]+$/gi;\n if (!tldRegex.test(tld)) return false;\n }\n\n if (subdomain === false && labels.length > 1) return false;\n\n return labels.every((label, index) => {\n if (wildcard && index === 0 && label === \"*\" && labels.length > 1) {\n return true;\n }\n\n let validLabelChars = /^([\\u0E00-\\u0E7Fa-zA-Z0-9-_]+)$/g;\n if (index === labels.length - 1) {\n validLabelChars = /^([\\u0E00-\\u0E7Fa-zA-Z0-9-]+)$/g;\n }\n\n const doubleDashCount = (label.match(/--(--)?/g) || []).length;\n const xnDashCount = (label.match(/xn--/g) || []).length;\n if (index === labels.length - 1 && doubleDashCount !== xnDashCount) {\n return false;\n }\n\n return (\n validLabelChars.test(label) &&\n label.length < 64 &&\n !label.startsWith(\"-\") &&\n !label.endsWith(\"-\")\n );\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,MAAa,SAAS,UAAiC;CACrD,OAAO,iBAAiB;;;;;;;;;;;;;;ACiC1B,SAAS,QAAQ,OAAO;CACvB,OAAO,MAAM,QAAQ,MAAM;;AAQ5B,SAAS,SAAS,OAAO;CACxB,OAAO,OAAO,UAAU,YAAY,CAAC,MAAM,MAAM,IAAI,CAAC,QAAQ,MAAM;;AAKrE,MAAM,SAAS,UAAU;CACxB,OAAO,SAAS;;AAQjB,MAAM,cAAc,UAAU;CAC7B,OAAO,OAAO,UAAU;;AA2IzB,MAAM,oBAAoB,UAAU,SAAS,MAAM,IAAI,WAAW,MAAM,QAAQ;AAChF,MAAM,0BAA0B;CAC/B,IAAI,CAAC,iBAAiB,WAAW,EAAE,OAAO,KAAK;CAC/C,OAAO,WAAW;;AAEnB,MAAM,qBAAqB,MAAM;CAChC,MAAM,IAAI,mBAAmB;CAC7B,IAAI,GAAG,OAAO;CACd,IAAI,OAAO,UAAU,aAAa,OAAO,IAAI,MAAM,GAAG,EAAE,IAAI,QAAQ,MAAM;EACzE,MAAM,KAAK,mBAAmB;EAC9B,OAAO,KAAK,GAAG,QAAQ,OAAO;IAC5B,CAAC;CACJ,OAAO;GACL,SAAS,IAAI;CACf,MAAM,IAAI,mBAAmB;CAC7B,IAAI,GAAG,OAAO,EAAE,KAAK,MAAM,GAAG;CAC9B,MAAM,IAAI,MAAM,4BAA4B,GAAG,mEAAmE;EACjH;AAEF,MAAM,UAAU,KAAK,OAAO;AAC5B,MAAM,MAAM,iBAAiB,WAAW,GAAG,iBAAiB,UAAU,CAAC,MAAM;AAa7E,SAAS,UAAU,GAAG,MAAM;CAC3B,OAAO,KAAK,OAAO,QAAQ,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|