# `Image.Plug.Options`
[🔗](https://github.com/elixir-image/image_plug/blob/v0.1.0/lib/image/plug/options.ex#L1)

Validated, frozen configuration for `Image.Plug`.

Built once at compile/boot time by `Image.Plug.init/1`. The
request path then only reads struct fields.

Construct with `new!/1`. Direct struct construction is discouraged —
the validator enforces invariants such as "the provider module must
export `parse/2`" that are not visible from the struct shape alone.

# `module_with_options`

```elixir
@type module_with_options() :: {module(), keyword()}
```

# `signing_options`

```elixir
@type signing_options() ::
  nil | %{:keys =&gt; [String.t(), ...], optional(:required?) =&gt; boolean()}
```

Signing configuration. `nil` disables signing entirely.

When set, every request URL is verified against the configured
`:keys` list (HMAC-SHA256). When `:required?` is `true`, an
unsigned URL produces `:signature_required`. When `:required?` is
`false`, unsigned URLs pass through but a signed URL with an
invalid signature still 401s — defense in depth.

# `t`

```elixir
@type t() :: %Image.Plug.Options{
  max_pixels: pos_integer(),
  on_error: Image.Plug.Pipeline.on_error(),
  provider: module(),
  provider_options: keyword(),
  request_timeout: pos_integer(),
  signing: signing_options(),
  source_resolver: module(),
  source_resolver_options: keyword(),
  telemetry_prefix: [atom(), ...],
  variant_store: module(),
  variant_store_options: keyword()
}
```

# `new!`

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

Validates a keyword list and returns an `Image.Plug.Options`
struct.

### Arguments

* `options` is a keyword list. The `:provider` and `:source_resolver`
  keys are required. Each must be a `{module, options}` tuple.

### Options

* `:provider` (required) — `{module, options}` for an
  `Image.Plug.Provider` implementation.

* `:source_resolver` (required) — `{module, options}` for an
  `Image.Plug.SourceResolver` implementation.

* `:variant_store` — `{module, options}` for an
  `Image.Plug.VariantStore` implementation. Defaults to
  `{Image.Plug.VariantStore.ETS, []}`.

* `:on_error` — error policy atom or `{:status, code}` tuple.
  Defaults to `:auto`.

* `:max_pixels` — soft upper bound on the output pixel count.
  Defaults to `25_000_000`.

* `:request_timeout` — total per-request budget in milliseconds.
  Defaults to `10_000`.

* `:telemetry_prefix` — list of atoms prepended to telemetry event
  names. Defaults to `[:image_plug]`.

### Returns

* An `Image.Plug.Options` struct.

### Examples

    iex> defmodule TestProv do
    ...>   @behaviour Image.Plug.Provider
    ...>   @impl true
    ...>   def parse(_conn, _options), do: {:error, Image.Plug.Error.new(:not_implemented, "test")}
    ...> end
    iex> defmodule TestRes do
    ...>   @behaviour Image.Plug.SourceResolver
    ...>   @impl true
    ...>   def load(_source, _options), do: {:error, Image.Plug.Error.new(:not_implemented, "test")}
    ...> end
    iex> options = Image.Plug.Options.new!(
    ...>   provider: {TestProv, []},
    ...>   source_resolver: {TestRes, []}
    ...> )
    iex> options.provider
    TestProv
    iex> options.on_error
    :auto

---

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