-module(acumen@list_orders). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/acumen/list_orders.gleam"). -export([build/3, response/1]). -export_type([orders_list/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " List orders associated with an ACME account.\n" "\n" " The ACME server provides a paginated list of order URLs for each account.\n" " Use the `next` field in the response to fetch subsequent pages.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " import acumen\n" " import acumen/list_orders.{type OrdersList}\n" " import gleam/option\n" "\n" " let assert option.Some(orders_url) = account.orders_url\n" " let assert Ok(#(resp, ctx)) = acumen.execute(\n" " ctx,\n" " build: list_orders.build(orders_url, _, registered_key),\n" " send: httpc.send,\n" " )\n" "\n" " let assert Ok(orders_list) = list_orders.response(resp)\n" " ```\n" ). -type orders_list() :: {orders_list, list(acumen@url:url()), gleam@option:option(acumen@url:url())}. -file("src/acumen/list_orders.gleam", 49). ?DOC( " Builds a signed POST-as-GET request to list orders for an account.\n" "\n" " Targets the account's `orders` URL from the registration response.\n" ). -spec build(acumen@url:url(), acumen:context(), acumen:registered_key()) -> {ok, gleam@http@request:request(binary())} | {error, acumen:acme_error()}. build(Url, Context, Key) -> acumen:build_fetch(Url, Context, Key). -file("src/acumen/list_orders.gleam", 107). -spec parse_next_link(gleam@http@response:response(binary())) -> {ok, acumen@url:url()} | {error, nil}. parse_next_link(Resp) -> _pipe = erlang:element(3, Resp), gleam@list:find_map( _pipe, fun(Header) -> {Name, Value} = Header, case string:lowercase(Name) =:= <<"link"/utf8>> of true -> acumen@internal@link_header:find_by_rel( Value, <<"next"/utf8>> ); false -> {error, nil} end end ). -file("src/acumen/list_orders.gleam", 91). -spec parse_orders_response(gleam@http@response:response(binary())) -> {ok, orders_list()} | {error, acumen:acme_error()}. parse_orders_response(Resp) -> Decoder = gleam@dynamic@decode:field( <<"orders"/utf8>>, gleam@dynamic@decode:list(acumen@url:decoder()), fun gleam@dynamic@decode:success/1 ), _pipe = gleam@json:parse(erlang:element(4, Resp), Decoder), _pipe@1 = gleam@result:map_error( _pipe, fun(Error) -> {json_parse_error, acumen@internal@utils:json_parse_error_message( <<"orders list"/utf8>>, Error )} end ), gleam@result:map( _pipe@1, fun(Orders) -> Next = begin _pipe@2 = parse_next_link(Resp), gleam@option:from_result(_pipe@2) end, {orders_list, Orders, Next} end ). -file("src/acumen/list_orders.gleam", 81). ?DOC( " Parses the orders list response.\n" "\n" " Pagination is indicated by a `Link` header with `rel=\"next\"`.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let assert Ok(orders_list) = list_orders.response(resp)\n" "\n" " // Follow pagination if there are more pages\n" " case orders_list.next {\n" " option.Some(next_url) -> {\n" " let assert Ok(#(resp, ctx)) = acumen.execute(\n" " ctx,\n" " build: list_orders.build(next_url, _, registered_key),\n" " send: httpc.send,\n" " )\n" " let assert Ok(next_page) = list_orders.response(resp)\n" " }\n" " option.None -> {\n" " // No more pages\n" " }\n" " }\n" " ```\n" ). -spec response(gleam@http@response:response(binary())) -> {ok, orders_list()} | {error, acumen:acme_error()}. response(Resp) -> case erlang:element(2, Resp) of 200 -> parse_orders_response(Resp); _ -> {error, {invalid_response, acumen@internal@utils:unexpected_status_message( erlang:element(2, Resp) )}} end.