# Envlet

Pull your Envlet environment at runtime. The host platform holds one secret, an
Envlet token, and your app loads everything else at boot.

Add `envlet` to your dependencies:

```elixir
def deps do
  [
    {:envlet, "~> 0.1.0"}
  ]
end
```

Envlet requires Elixir 1.17 or later and Erlang/OTP 25 or later.

Load values into the process environment:

```elixir
Envlet.inject!()
```

`inject!/0` fetches every value the token identity can read and sets the process
environment. Values already set by the host are not overwritten. Pass
`override: true` to replace host values with Envlet values.

```elixir
Envlet.inject!(override: true)
```

Fetch all values or one value without changing the process environment:

```elixir
values = Envlet.load!()
stripe_key = Envlet.get!("STRIPE_KEY")
```

The non-bang functions return tagged tuples:

```elixir
case Envlet.get("STRIPE_KEY") do
  {:ok, value} -> value
  {:error, %Envlet.Error{code: code, status: status}} -> {code, status}
end
```

Configuration comes from `ENVLET_TOKEN` or the `:token` option. The API URL
comes from `ENVLET_API_URL`, then defaults to `https://api.envlet.dev`. Use the
`:api_url` option to set it for one call. Network errors and 5xx responses make
at most three attempts by default. Pass `retry: false` to make one attempt.

```elixir
Envlet.load!(
  token: System.fetch_env!("ENVLET_TOKEN"),
  api_url: "https://api.envlet.dev",
  retry: true
)
```

Requests never return cached, stale, or partial values. A missing token returns
`config_missing`. A 401 or 403 response keeps the API error code, including
`token_expired` and `unauthorized`. A withheld or absent value returns
`not_found` with status 404. Network failures return `network_error`. Injection
failures return `environment_error` without leaving partial changes.

For releases, add `Envlet.ConfigProvider` so values enter the process
environment before applications start:

```elixir
def project do
  [
    releases: [
      my_app: [
        config_providers: [{Envlet.ConfigProvider, []}]
      ]
    ]
  ]
end
```

The provider accepts the same options as `Envlet.inject!/1`, including
`override: true`.
