# `Storehouse.Purge`
[🔗](https://github.com/hattoriai/storehouse/blob/v0.2.0/lib/storehouse/purge.ex#L1)

What a CDN in front forgets when a file is deleted: the file's URLs, its
variants' (`Storehouse.Variants`), and its cache tag. Keys are never
reused, so a file kept for a year never changes; it only goes, and a
CDN would go on serving it. A purger tells the CDN.

    config :storehouse, Storehouse.Purge,
      purger:
        {Storehouse.Purge.Cloudflare,
         zone_id: System.fetch_env!("CLOUDFLARE_ZONE_ID"),
         api_token: System.fetch_env!("CLOUDFLARE_API_TOKEN")},
      base_url: "https://example.com"

After `Storehouse.delete/2` of a file (a file replaced is the old one
deleted), the purger is given its URLs, its variants' URLs and its
cache tag, once. After `Storehouse.delete_prefix/2` (an account's files),
the prefix's URLs, for a CDN that purges by prefix. It runs as a job of
the app's runner (`Storehouse.Runner`), tried again when the CDN fails,
and its job holds the URLs, never the purger's credentials, which are
read from the config when it runs.

## Configuration

  * `:purger` - a module of this behaviour, or `{module, options}`.
    Without it, nothing is purged.
  * `:base_url` - put before a URL that is a path (`Storehouse.Local`'s,
    `Storehouse.Variants.Plug`'s): the CDN's host.
  * `:urls` - a function of a key that gives more URLs of it: the app's
    own routes to it, through `Storehouse.Proxy` or `Storehouse.Redirect`.

## Cache tags

`Storehouse.Proxy`, `Storehouse.Variants.Plug` and `Storehouse.Local.Plug`
send a file's `Cache-Tag` (`cache_tag/1`) with `cache_tag: true`, its
variants' with the original's: a purge by tag forgets them all, however
many URLs they were served at.

# `request`

```elixir
@type request() :: %{urls: [String.t()], tags: [String.t()], prefixes: [String.t()]}
```

What to forget: URLs, cache tags, and URL prefixes.

# `purge`

```elixir
@callback purge(request(), opts :: keyword()) :: :ok | {:error, term()}
```

Tells the CDN to forget what `request` names.

# `cache_tag`

```elixir
@spec cache_tag(String.t()) :: String.t()
```

The cache tag of the file with `key`, and of its variants: `sh-` and 20
hex digits of its SHA-256, short, and the same however the key is
written in a URL.

    iex> Storehouse.Purge.cache_tag("2026/10/0b6-harbour.jpg")
    "sh-cddbf11b0099a58fca2e"

# `request`

```elixir
@spec request(String.t(), keyword()) :: request()
```

What the purger is given when the file with `key` is deleted: its URL,
its variants' URLs and the app's (`:urls`), absolute, and its cache tag.

---

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