An Elixir toolkit for the AT Protocol. hexdocs.pm/atex
elixir bluesky atproto decentralization

fix(xrpc): convert lexicon params struct to a map before passing to request

Fixes a problem where passing a `%<LexiconId>.Params` struct to an XRPC call
would fail due to not having the Enumerable protocol implemented.

ovyerus.com 3e446b64 b5286b82

verified
+19 -13
+4 -1
CHANGELOG.md
··· 6 6 and this project adheres to 7 7 [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 8 8 9 - <!-- ## [Unreleased] --> 9 + ## [Unreleased] 10 + 11 + - Fix a problem where generated `%<LexiconId>.Params` structs could not be 12 + passed to an XRPC call due to not having the Enumerable protocol implemented. 10 13 11 14 ## [0.7.1] - 2026-02-06 12 15
+15 -12
lib/atex/xrpc.ex
··· 1 1 defmodule Atex.XRPC do 2 2 @moduledoc """ 3 - XRPC client module for AT Protocol RPC calls. 3 + Client module for AT Protocol XRPC. 4 4 5 5 This module provides both authenticated and unauthenticated access to AT Protocol 6 6 XRPC endpoints. The authenticated functions (`get/3`, `post/3`) work with any ··· 60 60 end 61 61 62 62 def get(client, %{__struct__: module} = query, opts) do 63 - opts = if Map.get(query, :params), do: Keyword.put(opts, :params, query.params), else: opts 63 + opts = put_params(opts, query) 64 64 output_struct = Module.concat(module, Output) 65 65 output_exists = Code.ensure_loaded?(output_struct) 66 66 ··· 143 143 def post(client, %{__struct__: module} = procedure, opts) do 144 144 opts = 145 145 opts 146 - |> then( 147 - &if Map.get(procedure, :params), do: Keyword.put(&1, :params, procedure.params), else: &1 148 - ) 149 - |> then( 150 - &cond do 151 - Map.get(procedure, :input) -> Keyword.put(&1, :json, procedure.input) 152 - Map.get(procedure, :raw_input) -> Keyword.put(&1, :body, procedure.raw_input) 153 - true -> &1 154 - end 155 - ) 146 + |> put_params(procedure) 147 + |> put_body(procedure) 156 148 157 149 output_struct = Module.concat(module, Output) 158 150 output_exists = Code.ensure_loaded?(output_struct) ··· 207 199 """ 208 200 @spec url(String.t(), String.t()) :: String.t() 209 201 def url(endpoint, resource) when is_binary(endpoint), do: "#{endpoint}/xrpc/#{resource}" 202 + 203 + @spec put_params(keyword(), struct()) :: keyword() 204 + defp put_params(keyword, %{params: params}), 205 + do: Keyword.put(keyword, :params, Map.from_struct(params)) 206 + 207 + defp put_params(keyword, _), do: keyword 208 + 209 + @spec put_body(keyword(), struct()) :: keyword() 210 + defp put_body(keyword, %{input: json}), do: Keyword.put(keyword, :json, json) 211 + defp put_body(keyword, %{raw_input: body}), do: Keyword.put(keyword, :body, body) 212 + defp put_body(keyword, _), do: keyword 210 213 end