README.md

# Etoex

Etoex — библиотека для последовательного выполнения HTTP-операций (pipeline) с:

- `assigns` + интерполяция `<VAR>` в path/body
- `save`: извлечение значений из ответа по JSONPath (`a.b[0].id`, `[0].id`, `["a","b",0,"id"]`)
- `func`: динамическая модификация запроса на основе предыдущих результатов
- pluggable `auth` (Bearer / Static headers / Stack) и `transport` (Tesla / Mock)
- опциональный `draw/3` для Livebook (Kino)

## Installation

```elixir
def deps do
  [
    {:etoex, "~> 0.1"}
  ]
end

## Quick start

```elixir
  client =
    Etoex.client(
      base_url: "https://jsonplaceholder.typicode.com",
      recv_timeout: 30_000
    )
  
  ops = [
    %{request: {:get, "/posts/1"}, save: %{USER_ID: "userId"}},
    %{request: {:get, "/users/<USER_ID>"}}
  ]
  
  {:ok, report} = Etoex.run(client, ops)
  report.assigns
  report.results
```

## Auth

### Bearer

```elixir
client =
  Etoex.client(
    base_url: "https://api.example.com",
    auth: {Etoex.Auth.Bearer, token: "TOKEN"}
  )
```

### Static headers

```elixir
client =
  Etoex.client(
    base_url: "https://api.example.com",
    auth: {Etoex.Auth.StaticHeaders, headers: [{"Authorization", "Bearer TOKEN"}]}
  )
```

### Stack

```elixir
client =
  Etoex.client(
    base_url: "https://api.example.com",
    auth: {Etoex.Auth.Stack, auths: [
      {Etoex.Auth.Bearer, token: "TOKEN"},
      {Etoex.Auth.StaticHeaders, headers: %{"X-Trace-Id" => "abc"}}
    ]}
  )
```

### TLS

client.tls прокидывается в hackney как ssl_options.
Пример (если используешь certifi в своём приложении):

```elixir
client =
  Etoex.client(
    base_url: "https://api.example.com",
    tls: [verify: :verify_peer, cacertfile: :certifi.cacertfile()]
  )
```

### Livebook (Kino)

```elixir
Etoex.draw(client, ops)
```

### Integration tests

По умолчанию внешняя сеть выключена:

```bash
mix test
mix test --include integration
```