# `JSONSchex.URIUtil`
[🔗](https://github.com/xinz/jsonschex/blob/main/lib/jsonschex/uri_util.ex#L1)

Utilities for URI resolution and manipulation.

# `fragment`

```elixir
@spec fragment(String.t()) :: String.t() | nil
```

Returns only the fragment portion of a URI or reference, without the leading `#`.

## Examples

    iex> JSONSchex.URIUtil.fragment("https://example.com/schema#meta")
    "meta"

    iex> JSONSchex.URIUtil.fragment("#/$defs/foo")
    "/$defs/foo"

    iex> JSONSchex.URIUtil.fragment("https://example.com/schema")
    nil

# `local_ref`

```elixir
@spec local_ref(String.t() | nil) :: String.t()
```

Converts a fragment into a local reference string.

The fragment should be provided without the leading `#`. Passing `nil` returns `"#"`.

## Examples

    iex> JSONSchex.URIUtil.local_ref("meta")
    "#meta"

    iex> JSONSchex.URIUtil.local_ref("/$defs/foo")
    "#/$defs/foo"

    iex> JSONSchex.URIUtil.local_ref(nil)
    "#"

# `remote_ref?`

```elixir
@spec remote_ref?(String.t()) :: boolean()
```

Checks if a reference string represents a remote URI (http or https).

## Examples

    iex> JSONSchex.URIUtil.remote_ref?("https://example.com/schema.json")
    true

    iex> JSONSchex.URIUtil.remote_ref?("http://example.com/schema.json")
    true

    iex> JSONSchex.URIUtil.remote_ref?("#/definitions/user")
    false

    iex> JSONSchex.URIUtil.remote_ref?("urn:uuid:12345")
    false

# `resolve`

```elixir
@spec resolve(String.t() | nil, String.t() | nil) :: String.t() | nil
```

Resolves a relative URI against a base URI.
Safely handles cases where URIs are invalid or nil.

If merging fails (e.g. invalid URI format), it falls back to returning the child URI
(or the base if child is nil).

## Examples

    iex> JSONSchex.URIUtil.resolve("https://example.com/schema.json", "user.json")
    "https://example.com/user.json"

    iex> JSONSchex.URIUtil.resolve("https://example.com/schemas/", "#/definitions/user")
    "https://example.com/schemas/#/definitions/user"

    iex> JSONSchex.URIUtil.resolve(nil, "https://example.com/schema.json")
    "https://example.com/schema.json"

# `split_fragment`

```elixir
@spec split_fragment(String.t()) :: {String.t(), String.t() | nil}
```

Splits a URI or reference into `{base, fragment}`.

The fragment is returned without the leading `#`. If no fragment is present,
the second element is `nil`. An empty fragment (`"#"`) is also normalized to `nil`.

## Examples

    iex> JSONSchex.URIUtil.split_fragment("https://example.com/schema")
    {"https://example.com/schema", nil}

    iex> JSONSchex.URIUtil.split_fragment("https://example.com/schema#meta")
    {"https://example.com/schema", "meta"}

    iex> JSONSchex.URIUtil.split_fragment("#/$defs/foo")
    {"", "/$defs/foo"}

    iex> JSONSchex.URIUtil.split_fragment("https://example.com/schema#")
    {"https://example.com/schema", nil}

# `with_fragment`

```elixir
@spec with_fragment(String.t(), String.t() | nil) :: String.t()
```

Joins a base URI and fragment into a URI reference.

The fragment should be provided without the leading `#`. Passing `nil` returns
the base unchanged.

## Examples

    iex> JSONSchex.URIUtil.with_fragment("https://example.com/schema", "meta")
    "https://example.com/schema#meta"

    iex> JSONSchex.URIUtil.with_fragment("https://example.com/schema", "/$defs/foo")
    "https://example.com/schema#/$defs/foo"

    iex> JSONSchex.URIUtil.with_fragment("https://example.com/schema", nil)
    "https://example.com/schema"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
