# `Lei.Cache.OCIClient`
[🔗](https://github.com/gtri/lowendinsight/blob/main/lib/cache/oci_client.ex#L5)

OCI Distribution Spec client for pushing and pulling LEI cache artifacts.

Implements the subset of the OCI Distribution Specification needed to:
- Push blobs and manifests to an OCI registry
- Pull manifests and blobs from an OCI registry

Supports token-based authentication (Bearer) as used by ghcr.io and
other OCI-compliant registries.

# `generate_tags`

```elixir
@spec generate_tags(Date.t()) :: [String.t()]
```

Generates OCI tags for a given date.

Returns a list of tags: the date tag, "latest", and optionally "weekly"
if the date falls on a Sunday.

# `parse_reference`

```elixir
@spec parse_reference(String.t()) ::
  {:ok, String.t(), String.t(), String.t()} | {:error, String.t()}
```

Parses an OCI reference string into components.

Supports formats:
- `oci://registry/repo:tag`
- `registry/repo:tag`

Returns `{:ok, registry, repository, tag}` or `{:error, reason}`.

# `pull_blob`

```elixir
@spec pull_blob(String.t(), String.t(), String.t(), keyword()) ::
  {:ok, binary()} | {:error, String.t()}
```

Pulls a blob from a registry by digest.

Returns `{:ok, binary_data}` or `{:error, reason}`.

# `pull_manifest`

```elixir
@spec pull_manifest(String.t(), String.t(), String.t(), keyword()) ::
  {:ok, map()} | {:error, String.t()}
```

Pulls an OCI manifest from a registry.

Returns `{:ok, manifest_map}` or `{:error, reason}`.

# `push`

```elixir
@spec push(
  String.t(),
  String.t(),
  [String.t()],
  String.t(),
  [{String.t(), binary()}],
  keyword()
) ::
  :ok | {:error, String.t()}
```

Pushes an OCI artifact to a registry.

## Parameters
- `registry` - Registry host (e.g., "ghcr.io")
- `repository` - Repository path (e.g., "defenseunicorns/lei-cache")
- `tags` - List of tags to apply (e.g., ["2026-02-05", "latest"])
- `manifest_json` - The OCI manifest JSON string
- `blobs` - List of `{digest, data}` tuples
- `opts` - Options including `:token` for auth

Returns `:ok` or `{:error, reason}`.

---

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