# `Lotus.Source`
[🔗](https://github.com/elixir-lotus/lotus/blob/v1.0.0/lib/lotus/source.ex#L1)

Public facade for data sources in Lotus.

Provides convenience functions for resolving, listing, and querying data
sources. All functions accept `%Adapter{}` structs, source name strings,
or raw repo modules, resolving lazily as needed.

# `default_source`

```elixir
@spec default_source() :: Lotus.Source.Adapter.t()
```

Returns the default source as an `%Adapter{}` struct.

# `editor_config`

```elixir
@spec editor_config(Lotus.Source.Adapter.t() | String.t()) :: map()
```

Return the editor configuration for a source.

# `example_query`

```elixir
@spec example_query(
  Lotus.Source.Adapter.t() | String.t(),
  String.t(),
  String.t() | nil
) :: String.t()
```

Return an example query string suitable for placeholder text.

# `get_source!`

```elixir
@spec get_source!(String.t()) :: Lotus.Source.Adapter.t()
```

Gets a source adapter by name. Raises if not found.

# `hierarchy_label`

```elixir
@spec hierarchy_label(Lotus.Source.Adapter.t() | String.t()) :: String.t()
```

Return the human-readable label for the top-level hierarchy in a source.

# `limit_query`

```elixir
@spec limit_query(
  Lotus.Source.Adapter.t() | String.t(),
  Lotus.Query.Statement.t(),
  pos_integer()
) ::
  Lotus.Query.Statement.t()
```

Wrap a statement with a limit clause using the source's syntax.

# `list_sources`

```elixir
@spec list_sources() :: [Lotus.Source.Adapter.t()]
```

Lists all configured source adapters.

# `prepare_for_analysis`

```elixir
@spec prepare_for_analysis(
  Lotus.Source.Adapter.t() | String.t(),
  Lotus.Query.Statement.t()
) ::
  {:ok, Lotus.Query.Statement.t()} | {:error, term()}
```

Ask the adapter to resolve a statement into a form suitable for
optimization analysis (e.g. neutralizing `{{var}}` placeholders and
stripping `[[...]]` optional clauses so the engine's EXPLAIN / profile
endpoint can parse it).

Returns `{:error, :unsupported}` when the adapter does not implement
`prepare_for_analysis/2` — callers should treat that as "skip
optimization for this source".

# `query_language`

```elixir
@spec query_language(Lotus.Source.Adapter.t() | String.t()) :: String.t()
```

Return the query language identifier for a source.

# `resolve!`

```elixir
@spec resolve!(nil | String.t() | module(), nil | String.t() | module()) ::
  Lotus.Source.Adapter.t()
```

Resolve to an `%Adapter{}` struct.

Accepts:
  * `source_opt` — configured name (string) or source module (atom) or nil
  * `q_source`   — query's stored source (string or module) or nil

Falls back to the default source. Raises on resolution failure.

# `source_type`

```elixir
@spec source_type(Lotus.Source.Adapter.t() | module() | String.t()) ::
  Lotus.Source.Adapter.source_type()
```

Detect the source type from an adapter, repository module, or name.

# `supported_filter_operators`

```elixir
@spec supported_filter_operators(Lotus.Source.Adapter.t() | String.t()) :: [atom()]
```

Return the `Lotus.Query.Filter` operators this source's adapter supports.

UIs that expose a filter operator dropdown should read this list and
gate the options per source — attempting to use an operator outside
the declared list raises `Lotus.UnsupportedOperatorError` when filters
are applied.

# `supports_feature?`

```elixir
@spec supports_feature?(Lotus.Source.Adapter.t() | String.t() | module(), atom()) ::
  boolean()
```

Whether a source supports a specific feature.

Accepts an `%Adapter{}` struct or a source name/repo module (resolved to adapter).

---

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