# `Backplane.JsonSchema.URIUtil`

Utilities for URI resolution and manipulation.

# `base`

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

Returns the URI or reference without its fragment.

Removes the first literal `#` and everything after it, without decoding or
normalizing the URI. Fragment-only references return `""`; a missing URI
remains `nil`, so absence is not confused with an explicitly empty reference.
Callers that require an empty resource key can normalize with `base(uri) || ""`.

## Examples

    iex> Backplane.JsonSchema.URIUtil.base("https://example.com/schema#meta")
    "https://example.com/schema"

    iex> Backplane.JsonSchema.URIUtil.base("schema.json?version=1#/definitions/value")
    "schema.json?version=1"

    iex> Backplane.JsonSchema.URIUtil.base("urn:example:schema")
    "urn:example:schema"

    iex> Backplane.JsonSchema.URIUtil.base("#/definitions/value")
    ""

    iex> Backplane.JsonSchema.URIUtil.base("")
    ""

    iex> Backplane.JsonSchema.URIUtil.base(nil)
    nil

# `fragment`

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

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

## Examples

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

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

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

# `join_fragment`

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

Joins a fragment-free base URI and a fragment into a URI reference.

The fragment should be provided without the leading `#`. Passing `nil` returns
the base unchanged; an empty fragment appends `#`. No URI parsing, encoding,
normalization, or replacement of an existing fragment is performed.

## Examples

    iex> Backplane.JsonSchema.URIUtil.join_fragment("https://example.com/schema", "meta")
    "https://example.com/schema#meta"

    iex> Backplane.JsonSchema.URIUtil.join_fragment("https://example.com/schema", "/$defs/foo")
    "https://example.com/schema#/$defs/foo"

    iex> Backplane.JsonSchema.URIUtil.join_fragment("https://example.com/schema", nil)
    "https://example.com/schema"

    iex> Backplane.JsonSchema.URIUtil.join_fragment("https://example.com/schema", "")
    "https://example.com/schema#"

    iex> Backplane.JsonSchema.URIUtil.join_fragment("", "/$defs/foo")
    "#/$defs/foo"

# `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> Backplane.JsonSchema.URIUtil.local_ref("meta")
    "#meta"

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

    iex> Backplane.JsonSchema.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> Backplane.JsonSchema.URIUtil.remote_ref?("https://example.com/schema.json")
    true

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

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

    iex> Backplane.JsonSchema.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> Backplane.JsonSchema.URIUtil.resolve("https://example.com/schema.json", "user.json")
    "https://example.com/user.json"

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

    iex> Backplane.JsonSchema.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}`.

Only the first literal `#` separates the base from the fragment. The fragment
is returned without that leading `#`. If no fragment is present, the second
element is `nil`. An empty fragment (`"#"`) is also normalized to `nil`.

## Examples

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

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

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

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

# `with_fragment`

> This function is deprecated. Use join_fragment/2 instead.

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

Deprecated alias for `join_fragment/2`.

---

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