# `TerminusDB.Config`
[🔗](https://github.com/thanos/terminusdb-client-elixir/blob/v0.3.3/lib/terminus_db/config.ex#L1)

Immutable connection and resource context for a TerminusDB server.

A `Config` carries everything needed to address and authenticate a request:
the server `:endpoint`, credentials, and the current resource scope
(`:organization`, `:database`, `:branch`, `:repo`, `:ref`).

Unlike the official Python client — which holds mutable connection state on an
instance — `TerminusDB.Config` is **immutable data**. Scoping operations return
*derived* configs (`with_database/2`, `with_branch/2`, …) rather than mutating,
which is safe under concurrency and composes naturally with pipelines.

## Options

* `:endpoint` (`t:String.t/0`) - Required. TerminusDB server URL, e.g. `http://localhost:6363`.

* `:user` (`t:String.t/0`) - User name for HTTP Basic auth. Ignored when `:token` is set. The default value is `"admin"`.

* `:key` (`t:String.t/0`) - API key / password for HTTP Basic auth. Ignored when `:token` is set. The default value is `"root"`.

* `:token` (`t:String.t/0`) - Bearer token. When set, takes precedence over Basic auth (`:user`/`:key`).

* `:organization` (`t:String.t/0`) - Organization (team) that owns the database. The default value is `"admin"`.

* `:database` (`t:String.t/0`) - Current database name. Set with `with_database/2`.

* `:branch` (`t:String.t/0`) - Current branch. Set with `with_branch/2`. The default value is `"main"`.

* `:repo` (`t:String.t/0`) - Repository: `local` or a remote name. The default value is `"local"`.

* `:ref` (`t:String.t/0`) - A commit reference for time-travel queries.

* `:headers` (map of `t:String.t/0` keys and `t:String.t/0` values) - Extra HTTP headers merged into every request. The default value is `%{}`.

* `:receive_timeout` (`t:pos_integer/0`) - Socket receive timeout in milliseconds. The default value is `15000`.

* `:telemetry` (`t:boolean/0`) - Whether to emit `:telemetry` events for operations. The default value is `true`.

* `:adapter` (`t:term/0`) - A Req adapter function used in place of the network. Intended for testing:
  `adapter: fn req -> {req, Req.Response.new(status: 200, body: %{})} end`.

* `:user_agent` (`t:String.t/0`) - Value of the `user-agent` request header. The default value is `"terminusdb_ex/0.3.3"`.

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> config.endpoint
    "http://localhost:6363"
    iex> config.organization
    "admin"

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363", token: "tok_123")
    iex> TerminusDB.Config.auth(config)
    {:bearer, "tok_123"}

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.auth(config)
    {:basic, "admin:root"}

# `auth`

```elixir
@type auth() :: {:basic, String.t()} | {:bearer, String.t()} | nil
```

# `t`

```elixir
@type t() :: %TerminusDB.Config{
  adapter: (Req.Request.t() -&gt; {Req.Request.t(), Req.Response.t()}) | nil,
  branch: String.t(),
  database: String.t() | nil,
  endpoint: String.t(),
  headers: %{required(String.t()) =&gt; String.t()},
  key: String.t(),
  organization: String.t(),
  receive_timeout: pos_integer(),
  ref: String.t() | nil,
  repo: String.t(),
  telemetry: boolean(),
  token: String.t() | nil,
  user: String.t(),
  user_agent: String.t()
}
```

# `auth`

```elixir
@spec auth(t()) :: auth()
```

Returns the Req auth tuple derived from `config`.

A `:token` takes precedence (Bearer); otherwise Basic auth is built from
`:user` and `:key`. Returns `nil` only if no credentials are usable.

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363", token: "abc")
    iex> TerminusDB.Config.auth(config)
    {:bearer, "abc"}

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363", user: "admin", key: "root")
    iex> TerminusDB.Config.auth(config)
    {:basic, "admin:root"}

# `merge`

```elixir
@spec merge(
  t(),
  keyword()
) :: t()
```

Returns a copy of `config` with the given fields updated.

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.merge(config, database: "mydb").database
    "mydb"

# `new`

```elixir
@spec new(keyword()) :: t()
```

Builds a new, validated `TerminusDB.Config`.

## Options

See the module documentation or `schema/0` for the accepted options.

## Examples

    iex> %TerminusDB.Config{endpoint: "http://localhost:6363"} =
    ...>   TerminusDB.Config.new(endpoint: "http://localhost:6363")

    iex> TerminusDB.Config.new(endpoint: "http://localhost:6363", database: "foo").database
    "foo"

Raises `NimbleOptions.ValidationError` on invalid options.

    iex> TerminusDB.Config.new(endpoint: 123)
    ** (NimbleOptions.ValidationError) invalid value for :endpoint option: expected string, got: 123

# `redact`

```elixir
@spec redact(t()) :: t()
```

Returns `config` with sensitive fields redacted, suitable for telemetry metadata
and logging. Replaces `:key` and `:token` with `"[redacted]"`.

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363", key: "secret")
    iex> redacted = TerminusDB.Config.redact(config)
    iex> redacted.key
    "[redacted]"
    iex> redacted.endpoint
    "http://localhost:6363"

# `schema`

```elixir
@spec schema() :: keyword()
```

The NimbleOptions schema used to validate `new/1` options.

## Examples

    iex> schema = TerminusDB.Config.schema()
    iex> Keyword.has_key?(schema, :endpoint)
    true

# `with_branch`

```elixir
@spec with_branch(t(), String.t()) :: t()
```

Scopes `config` to the given branch.

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.with_branch(config, "feature").branch
    "feature"

# `with_database`

```elixir
@spec with_database(t(), String.t()) :: t()
```

Scopes `config` to the given database.

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.with_database(config, "mydb").database
    "mydb"

# `with_organization`

```elixir
@spec with_organization(t(), String.t()) :: t()
```

Scopes `config` to the given organization.

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.with_organization(config, "acme").organization
    "acme"

# `with_ref`

```elixir
@spec with_ref(t(), String.t()) :: t()
```

Pins `config` to a commit reference for time-travel queries.

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.with_ref(config, "commit/abc123").ref
    "commit/abc123"

# `with_repo`

```elixir
@spec with_repo(t(), String.t()) :: t()
```

Scopes `config` to the given repository (`local` or a remote name).

## Examples

    iex> config = TerminusDB.Config.new(endpoint: "http://localhost:6363")
    iex> TerminusDB.Config.with_repo(config, "origin").repo
    "origin"

---

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