{"version":3,"file":"urls-D2J4zmPF.cjs","names":["isString","isEmptyString","errorMsg","normalizeString","isURL","getPreciseType","safeStableStringify","isUndefined","isNonEmptyString","isFunction","isEmptyValue","isNumber","isError","createMessage","isNonEmptyString","isFunction","errorMsg","isNonEmptyString","getPreciseType","safeStableStringify","isUndefined","isSet","isArray","isNil","isString","isNull","removeSpaces","createMessage","isValidDomain","isError","isNonEmptyString","errorMsg","getPreciseType","safeStableStringify","isArray","isString","isNil","createMessage","isString","isArray","getPreciseType","isNull","isPlainObject","isInteger","safeStableStringify","isBoolean","isNonEmptyArray","errorMsg","joinLines","EOL","isNonEmptyString","createMessage","createMessage","isNonEmptyString","isEmptyString"],"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 { createMessage } from \"@/_private/logger\";\n\nimport { 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 *\n * ---\n * @description\n * Type for `queryParams` parameter, the second parameter of ***`constructURL` utility function***.\n *\n * ---\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 *\n * ---\n * @example\n * 1. #### Valid usage:\n *    ```ts\n *    const params: QueryParamPairs = [\n *      [\"foo\", 1],\n *      [\"bar\", \"baz\"]\n *    ];\n *    constructURL(\"https://example.com\", params);\n *    ```\n *    ---\n * 2. #### Invalid: must contain at least one item:\n *    ```ts\n *    const empty: QueryParamPairs = [];\n *    ```\n *    ---\n * 3. #### Invalid: key without value pairs:\n *    ```ts\n *    const empty2: QueryParamPairs = [[\"key\"]];\n *    ```\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\n * of duplicate parameters.**\n *\n * ---\n * @param {string | URL} baseUrl\n *        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 *\n * ---\n * @throws **{@link TypeError | `TypeError`}** if `baseUrl` is not a valid non-empty string or URL object, or if `queryParams` is not iterable, or\n *        if `removeParams` is not an array of strings.\n *\n * ---\n * @returns {URL} A new URL object representing the constructed URL with merged and cleaned query parameters.\n *\n * ---\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 *    ```\n *    #### Result ➔ `URL { href: \"https://example.com/path?a=1&b=2\", ... }`\n *    ---\n * 2. #### Remove parameters from Base and Added:\n *       - #### With `new URLSearchParams({ ... }).entries();`:\n *            ```ts\n *            constructURL(\n *              \"https://example.com/path?foo=1&bar=2\",\n *              new URLSearchParams({ bar: \"ignored\", baz: \"3\" }).entries(),\n *              [\"bar\"]\n *            );\n *            ```\n *            #### Result ➔ `URL { href: \"https://example.com/path?foo=1&baz=3\", ... }`\n *            ---\n *\n *       - #### With `[[string, string | number]...]`:\n *            ```ts\n *            constructURL(\n *              \"https://example.com/path?foo=1&bar=2\",\n *              [[\"bar\", \"ignored\"],[\"baz\", 3]],\n *              [\"bar\"]\n *            );\n *            ```\n *            #### Result ➔ `URL { href: \"https://example.com/path?foo=1&baz=3\", ... }`\n *            ---\n *\n *       - #### With separated variable and `[[string, number]...]` :\n *            ```ts\n *            const params: QueryParamPairs = [\n *              [\"foo\", 1],\n *              [\"bar\", 2],\n *              [\"baz\", 3]\n *            ];\n *\n *            constructURL(\"https://example.com\", params, [\"bar\"]);\n *            ```\n *            #### Result ➔ `URL { href: \"https://example.com/?foo=1&baz=3\", ... }`\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        errorMsg(\"First parameter (`baseUrl`) cannot be an empty-string.\")\n      );\n    }\n    baseUrl = normalizeString(baseUrl);\n  } else if (!isURL(baseUrl)) {\n    throw new TypeError(\n      errorMsg(\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\n  // Check removeParams\n  if (!isUndefined(removeParams)) {\n    assertIsArray(removeParams, {\n      message: ({ currentType, validType }) => {\n        return errorMsg(\n          `Third parameter (\\`removeParams\\`) must be of type \\`${validType} of strings\\`, but received: \\`${currentType}\\`.`\n        );\n      }\n    });\n\n    if (!removeParams.every((param) => isNonEmptyString(param))) {\n      throw new TypeError(\n        errorMsg(\n          \"Third parameter (`removeParams`) must be of type `array` and contains `string` only and non empty-string.\"\n        )\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        errorMsg(\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\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              errorMsg(\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\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    const message = isError(error) ? error.message : String(error);\n\n    throw new Error(errorMsg(`Failed to construct a valid URL: ${message}`), {\n      cause: error\n    });\n  }\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"constructURL\", msg);\n","import { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\n\n/** ---------------------------------\n * * ***Utility: `extractURLs`.***\n * ---------------------------------\n * **Extracts all valid URLs from a given string.**\n *\n * ---\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 *\n * ---\n * - #### *Behavior:*\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 *           ---\n *      - #### Ignores:\n *           - Non-string inputs.\n *           - Empty or whitespace-only strings.\n *           - Non-HTTP(S) protocols (ftp, mailto, etc).\n *\n * ---\n * @param {string | null | undefined} url - The input string containing potential URLs.\n *\n * ---\n * @returns {string[] | null} An array of extracted URLs or `null` if no URLs are found.\n *\n * ---\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 { createMessage } from \"@/_private/logger\";\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 { isUndefined } from \"@/predicates/is/isUndefined\";\nimport { isValidDomain } from \"@/predicates/is/isValidDomain\";\nimport { getPreciseType } from \"@/predicates/type/getPreciseType\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\n\nimport { removeSpaces } from \"@/strings/sanitizations/removeSpaces\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\nimport { safeStableStringify } from \"@/conversions/stringify/safeStableStringify\";\n\nimport { NormalizePathnameError } from \"../_private/NormalizePathnameError\";\n\n/** --------------------------------------------------------\n * * ***Options when `keepNullable` is false (default).***\n * ---------------------------------------------------------\n * Returns `defaultPath` if `pathname` is empty or invalid.\n */\ntype UnKeepNullableOptions = {\n  /** --------------------------------------------------------\n   *  * ***Fallback value returned if `pathname` is empty-string or invalid.***\n   * ---------------------------------------------------------\n   * Must be a **`non-empty string`**, defaultValue: `\"/\"`.\n   *\n   * ---\n   * @default \"/\"\n   */\n  defaultPath?: string;\n\n  /** --------------------------------------------------------\n   * * ***Whether to preserve `null` or `undefined`, defaultValue: `false`.***\n   * ---------------------------------------------------------\n   *\n   * - ***⚠️ Warning:***\n   *      - Non-boolean values will throw `TypeError`.\n   * ---\n   * @default false\n   */\n  keepNullable?: false;\n};\n\n/** --------------------------------------------------------\n * * ***Options when `keepNullable` is true.***\n * ---------------------------------------------------------\n *\n * Preserves `null` or `undefined` instead of returning `defaultPath`.\n */\ntype KeepNullableOptions = {\n  /** --------------------------------------------------------\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   *\n   * @default \"/\"\n   */\n  defaultPath?: string;\n\n  /** --------------------------------------------------------\n   *  * ***Preserve `null` or `undefined` as-is if `true` (defaultValue: `false`).***\n   * --------------------------------------------------------\n   *\n   * - ***⚠️ Warning:***\n   *      - Keeps returning `defaultPath` when `pathname` is an empty string, even if enabled.\n   *      - Non-boolean values will throw `TypeError`.\n   * ---\n   * **Must be `true` in this type.**\n   *\n   * ---\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   * - ***⚠️ Warning:***\n   *      - Non-boolean values will throw `TypeError`.\n   * ---\n   *\n   * @default false\n   *\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   * ---\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   * - ***⚠️ Warning:***\n   *      - Non-boolean values will throw `TypeError`.\n   *\n   * @default false\n   */\n  localhostDomain?: boolean;\n\n  /** --------------------------------------------------------\n   * * ***Custom list of file extensions that prevent the first path segment from being treated as a domain.***\n   * --------------------------------------------------------\n   *\n   * - **Behavior:**\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   * ---\n   * @example\n   *\n   * 1.  #### 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   * 2.  #### 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/** --------------------------------------------------------\n * * ***Options for main `normalizePathname`.***\n * ---------------------------------------------------------\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 * **Normalizes any pathname or URL string to a clean, predictable format, useful for routing, file paths, and URL handling.**\n *\n * ---\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 * ---\n *\n * @example\n * 1.  #### Basic path cleaning:\n *     ```ts\n *     normalizePathname(\"   /foo//bar  \");\n *     // ➔ \"/foo/bar\"\n *     ```\n *     ---\n * 2.  #### Trailing slash control:\n *     ```ts\n *     normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: true });\n *     // ➔ \"/api/v1/user/\"\n *     normalizePathname(\"/api//v1//user//\", { keepTrailingSlash: false });\n *     // ➔ \"/api/v1/user\"\n *     ```\n *     ---\n * 3.  #### Full URL normalization:\n *     ```ts\n *     normalizePathname(\"https://example.com//path///to/resource?x=1#hash\");\n *     // ➔ \"/path/to/resource?x=1#hash\"\n *     ```\n *     ---\n * 4.  #### Null/undefined preservation:\n *     ```ts\n *     normalizePathname(null, { keepNullable: true });\n *     // ➔ null\n *     normalizePathname(undefined, { keepNullable: true });\n *     // ➔ undefined\n *     ```\n *     ---\n * 5.  #### Default fallback:\n *     ```ts\n *     normalizePathname(\"\", { defaultPath: \"/home\" });\n *     // ➔ \"/home\"\n *     ```\n *     ---\n * 6.  #### Localhost removal:\n *     ```ts\n *     normalizePathname(\"localhost:3000/path/to/resource\", { localhostDomain: true });\n *     // ➔ \"/path/to/resource\"\n *     ```\n *     ---\n * 7.  #### Prevent false-positive domain stripping:\n *     ```ts\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 *     ---\n * 8.  #### Emojis and Unicode:\n *     ```ts\n *     normalizePathname(\"🔥//deep//path///🚀\");\n *     // ➔ \"/🔥/deep/path/🚀\"\n *     ```\n *     ---\n * 9.  #### Query-only or hash-only:\n *     ```ts\n *     normalizePathname(\"?page=2\");\n *     // ➔ \"/?page=2\"\n *     normalizePathname(\"#section3\");\n *     // ➔ \"/#section3\"\n *     ```\n *     ---\n * 10. #### Complex nested paths:\n *     ```ts\n *     normalizePathname(\"   //nested///folder//file.txt  \");\n *     // ➔ \"/nested/folder/file.txt\"\n *     ```\n *     ---\n * 11. #### Invalid URL triggers error:\n *     ```ts\n *     try {\n *       normalizePathname(\"http://\");\n *     } catch (e) {\n *       // console.log(e);\n *     }\n *     ```\n *     ---\n * 12. #### First segment is domain but ignored due to extension:\n *     ```ts\n *     normalizePathname(\"example.tar.bz/file\", { ignoreDomainExtensions: [\".tar.bz\"] });\n *     // ➔ \"/example.tar.bz/file\"\n *     ```\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): string | null | undefined {\n  assertIsPlainObject(options, {\n    message({ currentType, validType }) {\n      return errorMsg(\n        `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n      );\n    }\n  });\n\n  let {\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      errorMsg(\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\n  assertIsBoolean(keepNullable, {\n    message({ currentType, validType }) {\n      return errorMsg(\n        `Parameter \\`keepNullable\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n      );\n    }\n  });\n  assertIsBoolean(keepTrailingSlash, {\n    message({ currentType, validType }) {\n      return errorMsg(\n        `Parameter \\`keepTrailingSlash\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n      );\n    }\n  });\n  assertIsBoolean(localhostDomain, {\n    message({ currentType, validType }) {\n      return errorMsg(\n        `Parameter \\`localhostDomain\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n      );\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        errorMsg(\n          `Parameter \\`ignoreDomainExtensions\\` must be of type a \\`Set<string>\\` or \\`string[]\\`, but received: \\`${getPreciseType(\n            ignoreDomainExtensions\n          )}\\`.`\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          errorMsg(\n            `Parameter \\`ignoreDomainExtensions[${idx}]\\` must be a \\`string\\` and \\`non-empty string\\`, but received: \\`${safeStableStringify(\n              ext,\n              { keepUndefined: true }\n            )}\\`.`\n          )\n        );\n      }\n      if (!ext.startsWith(\".\")) {\n        throw new TypeError(\n          errorMsg(\n            `Parameter \\`ignoreDomainExtensions[${idx}]\\` must start with a dot (.), but received: ${safeStableStringify(\n              ext,\n              { keepUndefined: true }\n            )}`\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 ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"normalizePathname\", msg);\n\n/**\n * @internal ***`Not part of the public API.`***\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 ***`Not part of the public API.`***\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 ***`Not part of the public API.`***\n */\nconst ensureLeadingSlash = (path: string): string => {\n  if (!path.startsWith(\"/\")) path = \"/\" + path;\n  return path;\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst throwError = (error: unknown): never => {\n  // Handle any errors that occur during processing\n  const originalError = isError(error) ? error : new Error(String(error));\n\n  throw new NormalizePathnameError(\n    errorMsg(`Failed to normalize pathname: ${originalError.message}`),\n    originalError\n  );\n};\n","import { createMessage } from \"@/_private/logger\";\n\nimport { 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\";\n\nimport { normalizePathname } from \"./normalizePathname\";\n\n/** --------------------------------------------------------\n * * ***Utility: `getFirstPrefixPathname`.***\n * --------------------------------------------------------\n * **Extract First Valid Prefix from Path Array or String.**\n *\n * ---\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 *\n * ---\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 *\n * ---\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 *\n * ---\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 *\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 *\n * ---\n * @throws **{@link TypeError | `TypeError`}** ***if `result` is not a valid type, or `defaultValue` is not a string or empty-string.***\n *\n * ---\n * @returns {string} ***The first valid normalized pathname, or the normalized default.***\n *\n * ---\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 *    ---\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);\n *    // ➔ ❌ throws TypeError\n *    getFirstPrefixPathname({} as any);\n *    // ➔ ❌ throws TypeError\n *    getFirstPrefixPathname(null, \"   \");\n *    // ➔ ❌ throws TypeError\n *    ```\n */\nexport const getFirstPrefixPathname = (\n  result: string | string[] | null | undefined,\n  defaultValue: string = \"/\"\n): string => {\n  if (!isNonEmptyString(defaultValue)) {\n    throw new TypeError(\n      errorMsg(\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\n  if (isArray(result)) {\n    if (!result.every((item) => isString(item))) {\n      throw new TypeError(\n        errorMsg(\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\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      errorMsg(\n        `First parameter (\\`result\\`) must be of type \\`string\\`, \\`array-string\\`, \\`null\\` or \\`undefined\\`, but received: \\`${getPreciseType(\n          result\n        )}\\`.`\n      )\n    );\n  }\n\n  return normalizePathname(defaultValue);\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"getFirstPrefixPathname\", msg);\n","import { joinLines, EOL } from \"@rzl-zone/build-tools/utils\";\n\nimport { createMessage } from \"@/_private/logger\";\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  /** --------------------------------------------------------\n   * * ***The number of levels to include in the prefix (default is `1`).***\n   * ---------------------------------------------------------\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  /** --------------------------------------------------------\n   * * ***Whether to remove duplicates from the result if multiple URLs are passed (default is `true`).***\n   * ---------------------------------------------------------\n   *\n   * - ***⚠️ Warning:***\n   *      - Non-boolean values will throw `TypeError`.\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 *\n * ---\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 * ---\n *\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 * ---\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 * ---\n *\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 *\n * ---\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 *\n * ---\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 *\n * ---\n * @example\n * 1.  #### 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 *      ---\n * 2.  #### Correct Usage (With Single URL and Single Base):\n *      ```ts\n *      const result = getPrefixPathname(\"/settings/profile\", \"/settings\");\n *      console.log(result);\n *      // ➔ \"/settings\"\n *      ```\n *      ---\n * 3.  #### 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);\n *      // ➔ \"/settings\"\n *\n *      const result2 = getPrefixPathname(\n *        [\"/settings/profile\", \"/other/password\"],\n *        \"/other\"\n *      );\n *      console.log(result2);\n *      // ➔ \"/other\"\n *      ```\n *      ---\n * 4.  #### 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);\n *      // ➔ [\"/settings\", \"/admin\"]\n *      ```\n *      ---\n * 5.  #### Auto-detection of Prefix:\n *      ```ts\n *      const result = getPrefixPathname(\"/settings/profile\");\n *      console.log(result);\n *      // ➔ \"/settings\"\n *\n *      const result2 = getPrefixPathname(\n *        \"/settings/profile/info\",\n *        null,\n *        { levels: 2 }\n *      );\n *      console.log(result2);\n *      // ➔ \"/settings/profile\"\n *      ```\n *      ---\n * 6.  #### Multiple URLs with Auto-detection:\n *      ```ts\n *      const result = getPrefixPathname([\"/admin/profile\", \"/settings/password\"]);\n *      console.log(result);\n *      // ➔ [\"/admin\", \"/settings\"]\n *      ```\n *      ---\n * 7.  #### Handling Duplicates:\n *      ```ts\n *      const result = getPrefixPathname(\n *        [\"/settings/profile\", \"/settings/password\"],\n *        \"/settings\"\n *      );\n *      console.log(result);\n *      // ➔ \"/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);\n *      // ➔ [\"/settings\", \"/settings\"]\n *      ```\n *      ---\n * 8.  #### Incorrect Usage (URL Does Not Match Base):\n *      ```ts\n *      const result = getPrefixPathname(\"/other-path/profile\", \"/settings\");\n *      console.log(result);\n *      // ➔ 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      errorMsg(\n        joinLines(\n          \"Invalid parameter(s) function:\",\n          `- ${errors.join(`${EOL}- `)}`\n        )\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\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"getPrefixPathname\", msg);\n","import { createMessage } from \"@/_private/logger\";\n\nimport { assertIsBoolean } from \"@/assertions/booleans/assertIsBoolean\";\n\nimport { isEmptyString } from \"@/predicates/is/isEmptyString\";\nimport { isNonEmptyString } from \"@/predicates/is/isNonEmptyString\";\nimport { assertIsPlainObject } from \"@/assertions/objects/assertIsPlainObject\";\n\ntype FormatEnvPortOptions = {\n  /** -----------------------------------------------\n   * * ***Add prefix with a colon, defaultValue: `false`.***\n   * ------------------------------------------------\n   *\n   * - ***⚠️ Warning***:\n   *      - Non-boolean values will throw `TypeError`.\n   *\n   * ---\n   * @default false\n   */\n  prefixColon?: boolean;\n};\n\n/**\n * @internal ***`Not part of the public API.`***\n */\nconst errorMsg = (msg: string) => createMessage(\"formatEnvPort\", msg);\n\n/** -----------------------------------------------\n * * ***Utility: `formatEnvPort`.***\n * ------------------------------------------------\n * **Retrieves and formats an environment port variable.**\n *\n * ---\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, invalid type `prefixColon` will throw **TypeError**.\n *\n * ---\n * @param {string | null | undefined} envVar The environment variable string.\n * @param {FormatEnvPortOptions} [options] Optional object: `{ prefixColon?: boolean }`.\n *\n * ---\n * @throws **{@link TypeError | `TypeError`}** if `options` is not an object or `prefixColon` is not boolean.\n *\n * ---\n * @returns {string} A string like `\":8080\"` or `\"8080\"`, or `\"\"` if no digits.\n *\n * ---\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 \"\";\n\n  assertIsPlainObject(options, {\n    message: ({ currentType, validType }) =>\n      errorMsg(\n        `Second parameter (\\`options\\`) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\n      )\n  });\n\n  const { prefixColon = false } = options;\n\n  assertIsBoolean(prefixColon, {\n    message({ currentType, validType }) {\n      return errorMsg(\n        `Parameter \\`prefixColon\\` property of the \\`options\\` (second parameter) must be of type \\`${validType}\\`, but received: \\`${currentType}\\`.`\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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"}
