# `Bourse.UnifiedMethod`
[🔗](https://github.com/ZenHive/bourse/blob/main/lib/bourse/unified_method.ex#L1)

Compile-time mapping of unified method names to endpoint configs.

Bridges the gap between Bourse's unified API names (e.g., `"fetchTicker"`) and
the generated endpoint functions (e.g., `:public_get_v5_market_tickers`).

The spec's `endpoints.unified` (v4; was `structure.unified_endpoints` in v3)
maps each unified method to JS interface names (e.g., `"publicGetV5MarketTickers"`).
This module converts those JS names to Elixir endpoint config atoms and resolves
them against the pre-computed `@bourse_endpoint_configs` list.

## Usage (compile time, in generator macro)

    mapping = Bourse.UnifiedMethod.build_unified_mapping(
      spec["endpoints"]["unified"],
      endpoint_configs
    )
    # => %{fetch_ticker: [%{name: :public_get_v5_market_tickers, ...}], ...}

# `build_unified_mapping`

```elixir
@spec build_unified_mapping(map() | nil, [map()], %{required(String.t()) =&gt; atom()}) ::
  %{
    required(atom()) =&gt; [map()]
  }
```

Builds a mapping from unified method atoms to endpoint configs.

Takes the spec's `unified` (endpoints.unified) map (camelCase JS names) and the
pre-computed endpoint configs list, returns a map of snake_case atoms
to lists of matching endpoint configs.

Unified methods with no matching endpoint configs are excluded from
the result (the exchange doesn't support them at the endpoint level).

## Examples

    build_unified_mapping(
      %{"fetchTicker" => ["publicGetV5MarketTickers"]},
      [%{name: :public_get_v5_market_tickers, method: :get, ...}]
    )
    #=> %{fetch_ticker: [%{name: :public_get_v5_market_tickers, ...}]}

# `endpoint_config_to_js_name`

```elixir
@spec endpoint_config_to_js_name([String.t()], atom(), String.t()) :: String.t()
```

Forward-converts an endpoint config to its camel-cased interface method name.

Used to validate the mapping and for cross-referencing with spec data.
Sections are joined with camelCase (first as-is, subsequent capitalized).
Path segments split on `/ - . _ { } :` and each capitalized.

## Examples

    endpoint_config_to_js_name(["public"], :get, "v5/market/tickers")
    #=> "publicGetV5MarketTickers"

    endpoint_config_to_js_name(["private", "options"], :delete, "{settle}/orders")
    #=> "privateOptionsDeleteSettleOrders"

    endpoint_config_to_js_name(["dapiPublic"], :get, "ticker/24hr")
    #=> "dapiPublicGetTicker24hr"

---

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