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

OCI artifact packaging for LEI cache snapshots.

Builds OCI Image Manifest v2 artifacts containing LEI analysis cache data
with custom media types for Zarf air-gap deployment.

## OCI Artifact Structure

    ghcr.io/defenseunicorns/lei-cache:2026-02-05
    ├── manifest.json   (application/vnd.lei.cache.manifest+json)
    └── cache.jsonl.gz  (application/vnd.lei.cache.jsonl+gzip)

The OCI manifest wraps these as layers with proper digests and sizes.

# `blob_descriptor`

```elixir
@spec blob_descriptor(binary(), String.t()) :: map()
```

Creates a blob descriptor from raw content bytes.

Returns a map with `:media_type`, `:digest`, `:size`, and the raw `:data`.

# `build_manifest`

```elixir
@spec build_manifest(map(), [map()]) :: map()
```

Builds an OCI image manifest for the given cache layers.

Accepts a list of layer descriptors (each with `:media_type`, `:digest`, `:size`,
and optional `:annotations`) and a config descriptor.

Returns the manifest as a map ready for JSON encoding.

# `cache_jsonl_media_type`

Returns the cache JSONL layer media type.

# `cache_manifest_media_type`

Returns the cache manifest layer media type.

# `config_media_type`

Returns the config media type.

# `manifest_media_type`

Returns the OCI manifest media type.

# `media_type_to_filename`

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

Maps an OCI layer media type to its expected filename.

# `package`

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

Packages cache files into OCI artifact layers.

Takes a directory containing exported cache files and returns
`{:ok, manifest_json, blobs}` where blobs is a list of `{digest, data}` tuples.

# `unpack`

```elixir
@spec unpack(
  map(),
  String.t(),
  (String.t() -&gt; {:ok, binary()} | {:error, String.t()})
) ::
  :ok | {:error, String.t()}
```

Unpacks OCI artifact blobs into a target directory.

Given a parsed OCI manifest and a function to fetch blobs by digest,
writes the cache files to `target_dir`.

---

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