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

Remote collaboration API for TerminusDB.

Wraps the `/api/clone`, `/api/fetch`, `/api/push`, and `/api/pull` endpoints
for working with remote TerminusDB repositories.

All functions require a `TerminusDB.Config` scoped to a database (except
`clone/3` which creates a new database).

## Quick start

    config =
      TerminusDB.Config.new(endpoint: "http://localhost:6363")

    # Clone a remote database
    {:ok, _} = TerminusDB.Remote.clone(config, "https://data.terminusdb.org/public/star-wars", "star-wars",
      label: "Star Wars", comment: "Star Wars dataset")

    # Push current branch to remote
    {:ok, _} = TerminusDB.Remote.push(config, "origin", "main",
      author: "admin", message: "push changes")

# `remote_opt`

```elixir
@type remote_opt() ::
  {:organization, String.t()}
  | {:repo, String.t()}
  | {:label, String.t()}
  | {:comment, String.t()}
  | {:author, String.t()}
  | {:message, String.t()}
  | {:remote_branch, String.t()}
  | {:push_prefixes, boolean()}
```

# `clone`

```elixir
@spec clone(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) ::
  {:ok, map()} | {:error, TerminusDB.Error.t()}
```

Clones a remote repository into a new local database.

## Options

- `:label` — database label (defaults to `newid`).
- `:comment` — database comment (defaults to `""`).
- `:organization` — target organization (defaults to `config.organization`).

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success"})} end
    ...> )
    iex> {:ok, resp} = TerminusDB.Remote.clone(config, "https://data.terminusdb.org/public/star-wars", "star-wars", label: "Star Wars")
    iex> resp["api:status"]
    "api:success"

# `clone!`

```elixir
@spec clone!(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) :: map()
```

Clones a remote repository, or raises.

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success"})} end
    ...> )
    iex> TerminusDB.Remote.clone!(config, "https://data.terminusdb.org/public/star-wars", "star-wars")
    %{"api:status" => "api:success"}

# `fetch`

```elixir
@spec fetch(TerminusDB.Config.t(), [remote_opt()]) ::
  {:ok, map()} | {:error, TerminusDB.Error.t()}
```

Fetches branches from a remote repository.

## Options

- `:organization` — overrides `config.organization`.
- `:repo` — overrides `config.repo`.
- `:remote_id` — remote repository ID (default `"origin"`).

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success", "api:head_has_changed" => true})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> {:ok, resp} = TerminusDB.Remote.fetch(config)
    iex> resp["api:head_has_changed"]
    true

# `fetch!`

```elixir
@spec fetch!(TerminusDB.Config.t(), [remote_opt()]) :: map()
```

Fetches from remote, or raises.

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success", "api:head_has_changed" => false})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> TerminusDB.Remote.fetch!(config)
    %{"api:head_has_changed" => false}

# `pull`

```elixir
@spec pull(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) ::
  {:ok, map()} | {:error, TerminusDB.Error.t()}
```

Pulls updates from a remote repository into the current branch.

## Options

Same as `push/4`.

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success"})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> {:ok, resp} = TerminusDB.Remote.pull(config, "origin", "main", author: "admin", message: "pull")
    iex> resp["api:status"]
    "api:success"

# `pull!`

```elixir
@spec pull!(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) :: map()
```

Pulls from remote, or raises.

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success"})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> TerminusDB.Remote.pull!(config, "origin", "main")
    %{"api:status" => "api:success"}

# `push`

```elixir
@spec push(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) ::
  {:ok, map()} | {:error, TerminusDB.Error.t()}
```

Pushes the current branch to a remote repository.

## Options

- `:remote` — remote name (default `"origin"`).
- `:remote_branch` — remote branch name (default `config.branch`).
- `:author` — commit author.
- `:message` — commit message.
- `:organization` — overrides `config.organization`.
- `:repo` — overrides `config.repo`.
- `:push_prefixes` — also push prefixes (default `false`).

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success", "api:repo_head_updated" => true})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> {:ok, resp} = TerminusDB.Remote.push(config, "origin", "main", author: "admin", message: "push")
    iex> resp["api:repo_head_updated"]
    true

# `push!`

```elixir
@spec push!(TerminusDB.Config.t(), String.t(), String.t(), [remote_opt()]) :: map()
```

Pushes to remote, or raises.

## Examples

    iex> config = TerminusDB.Config.new(
    ...>   endpoint: "http://localhost:6363",
    ...>   adapter: fn req -> {req, Req.Response.new(status: 200, body: %{"api:status" => "api:success", "api:repo_head_updated" => true})} end
    ...> ) |> TerminusDB.Config.with_database("mydb")
    iex> TerminusDB.Remote.push!(config, "origin", "main")
    %{"api:repo_head_updated" => true}

---

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