# `DCATR.Manifest`
[🔗](https://github.com/dcat-r/dcatr-ex/blob/v0.1.0/lib/dcatr/manifest/manifest.ex#L1)

Default manifest type providing hierarchical access to DCAT-R service configuration.

A manifest is a container struct that holds the complete loaded configuration for a
DCAT-R service. It provides access to the service hierarchy (Service → Repository →
Dataset) and maintains the raw RDF dataset and load path used during loading.

## Design Rationale

The manifest is implemented as a Grax schema to provide extensibility through Grax
subclassing. Applications can extend `DCATR.Manifest` with custom properties and links,
creating specialized manifest types while preserving the base service hierarchy access.

The manifest struct serves as an extensible token that flows through the loading pipeline  
(`load_dataset/1` → `load_manifest/2`), allowing custom manifest types to inject 
application-specific data at each stage.

## Structure

- `:service` - The loaded `DCATR.Service` with full repository hierarchy
- `:dataset` - The complete RDF dataset from which the service was loaded
- `:load_path` - The load path used for file discovery

## Usage

`DCATR.Manifest` uses the `DCATR.Manifest.Type` behavior, which automatically provides
convenience functions for accessing the manifest hierarchy:

    # Load complete manifest
    {:ok, manifest} = DCATR.Manifest.manifest()

    # Direct access to service (cached)
    {:ok, service} = DCATR.Manifest.service()

    # Direct access to repository (cached)
    {:ok, repository} = DCATR.Manifest.repository()

    # Direct access to dataset (cached)
    {:ok, dataset} = DCATR.Manifest.dataset()

    # Bang variants raise on error
    service = DCATR.Manifest.service!()

All functions support options for custom load paths, explicit service IDs, and cache control.

## Loading Process

Manifests are loaded via `DCATR.Manifest.Cache` with the following pipeline:

1. Resolve load path (see `DCATR.Manifest.LoadPath`)
2. Load and merge RDF files into dataset (see `DCATR.Manifest.Loader`)
3. Extract and validate service from dataset
4. Cache result for subsequent access

## Custom Manifest Types

Applications can create specialized manifest types by extending `DCATR.Manifest`:

    defmodule MyApp.Manifest do
      use DCATR.Manifest.Type
      use Grax.Schema

      schema MyApp.NS.ManifestType < DCATR.Manifest do
        property custom_config: MyApp.NS.customConfig(), type: :string
      end
    end

See `DCATR.Manifest.Type` for details on customization patterns.

# `t`

```elixir
@type t() :: %DCATR.Manifest{
  __additional_statements__: term(),
  __id__: term(),
  dataset: term(),
  load_path: term(),
  service: term()
}
```

# `build`

# `build`

# `build!`

# `build!`

# `build_id`

# `dataset`

Loads the dataset from the cached manifest's repository.

# `dataset!`

Loads the dataset or raises on error.

# `env`

```elixir
@spec env(keyword()) :: atom()
```

Returns the currently configured environment for manifest loading.

The environment determines which manifest files are loaded (base vs environment-specific).
See `DCATR.Manifest.LoadPath` for file resolution details.

## Configuration

Resolved in order of precedence:

1. `:env` option (passed as argument)
2. `DCATR_ENV` environment variable
3. `MIX_ENV` environment variable
4. `:dcatr, :env` application config

Example:

    config :dcatr, env: Mix.env()

Raises if no environment is configured. Only environments from `environments/0` are valid.

# `environments`

```elixir
@spec environments() :: [atom()]
```

Returns the supported environments for `env/1`.

The environments are configured via the `:environments` configuration option
and defaults to `[:prod, :dev, :test]`:

    config :dcatr, :environments, [:prod, :dev, :test, :ci]

# `from`

```elixir
@spec from(Grax.Schema.t()) :: {:ok, t()} | {:error, any()}
```

# `from!`

```elixir
@spec from!(Grax.Schema.t()) :: t()
```

# `load`

```elixir
@spec load(
  RDF.Graph.t() | RDF.Description.t(),
  RDF.IRI.coercible() | RDF.BlankNode.t(),
  opts :: keyword()
) :: {:ok, t()} | {:error, any()}
```

# `load!`

```elixir
@spec load!(
  RDF.Graph.t() | RDF.Description.t(),
  RDF.IRI.coercible() | RDF.BlankNode.t(),
  opts :: keyword()
) :: t()
```

# `manifest`

```elixir
@spec manifest(keyword()) :: {:ok, t()} | {:error, DCATR.ManifestError.t()}
```

Loads the complete manifest with caching support.

## Options

- `:load_path` - Override default load path
- `:service_id` - Explicit service ID for loading
- `:reload` - Force cache reload (bypass cache)
- Additional options passed to `load_dataset/1` and `load_manifest/2`

# `manifest!`

Loads the manifest or raises on error.

# `repository`

Loads the repository from the cached manifest's service.

# `repository!`

Loads the repository or raises on error.

# `repository_manifest_graph`

```elixir
@spec repository_manifest_graph(t() | RDF.Dataset.t()) :: RDF.Graph.t() | nil
@spec repository_manifest_graph(RDF.Dataset.t()) ::
  {:ok, RDF.Graph.t()} | {:error, any()}
```

Returns the repository manifest graph, renamed to its final graph name if available.

When called with a loaded `Manifest`, returns the graph renamed per `dcatr:repositoryManifestGraph`.
When called with a raw `Dataset` (during loading), returns the graph with its well-known blank node name in an `:ok` tuple.

# `repository_manifest_graph!`

# `service`

Loads the service from the cached manifest.

# `service!`

Loads the service or raises on error.

# `service_manifest_graph`

```elixir
@spec service_manifest_graph(t()) :: RDF.Graph.t() | nil
@spec service_manifest_graph(RDF.Dataset.t()) ::
  {:ok, RDF.Graph.t()} | {:error, any()}
```

Returns the service manifest graph, renamed to its final graph name if available.

When called with a loaded `Manifest`, returns the graph renamed per `dcatr:serviceManifestGraph`.
When called with a raw `Dataset` (during loading), returns the graph with its well-known blank node name in an `:ok` tuple.

# `service_manifest_graph!`

# `service_type`

Returns the service type module used by this manifest type.

Extracts the service type from the `:service` link property definition in the
manifest's Grax schema. Used for type introspection and validation.

---

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