-module(oaspec@transport). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/transport.gleam"). -export([from_callback/1, resolve/1, run/2, map/2, await/2, map_try/2, try_await/2, credentials/0, with_api_key/3, with_bearer_token/3, with_basic_auth/3, with_digest_auth/3, with_base_url/2, with_default_header/3, with_default_headers/2, with_security/2]). -export_type([method/0, body/0, security_requirement/0, security_alternative/0, request/0, response/0, transport_error/0, async/1, credentials/0, credential_entry/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( " Pure, runtime-agnostic transport contract for generated OpenAPI clients.\n" "\n" " Generated client code depends on this module instead of any concrete\n" " HTTP runtime. Adapters (e.g. `oaspec/httpc`, `oaspec/fetch`) bridge\n" " `Send` / `AsyncSend` to a real runtime; tests can plug in arbitrary\n" " fake transport values via `oaspec/mock`.\n" ). -type method() :: get | post | put | delete | patch | head | options | trace | connect. -type body() :: empty_body | {text_body, binary()} | {bytes_body, bitstring()}. -type security_requirement() :: {api_key_header, binary(), binary()} | {api_key_query, binary(), binary()} | {api_key_cookie, binary(), binary()} | {http_authorization, binary(), binary()}. -type security_alternative() :: {security_alternative, list(security_requirement())}. -type request() :: {request, method(), gleam@option:option(binary()), binary(), list({binary(), binary()}), list({binary(), binary()}), body(), list(security_alternative())}. -type response() :: {response, integer(), list({binary(), binary()}), body()}. -type transport_error() :: {connection_failed, binary()} | timeout | {invalid_base_url, binary()} | {tls_failure, binary()} | {unsupported, binary()}. -opaque async(YUE) :: {async, fun((fun((YUE) -> nil)) -> nil)}. -opaque credentials() :: {credentials, list(credential_entry())}. -type credential_entry() :: {cred_api_key, binary(), binary()} | {cred_bearer, binary(), binary()} | {cred_basic, binary(), binary()} | {cred_digest, binary(), binary()}. -file("src/oaspec/transport.gleam", 90). -spec from_callback(fun((fun((YUK) -> nil)) -> nil)) -> async(YUK). from_callback(Register) -> {async, Register}. -file("src/oaspec/transport.gleam", 96). -spec resolve(YUM) -> async(YUM). resolve(Value) -> {async, fun(Done) -> Done(Value) end}. -file("src/oaspec/transport.gleam", 100). -spec run(async(YUO), fun((YUO) -> nil)) -> nil. run(Async, Done) -> {async, Register} = Async, Register(Done). -file("src/oaspec/transport.gleam", 105). -spec map(async(YUQ), fun((YUQ) -> YUS)) -> async(YUS). map(Async, With_) -> {async, fun(Done) -> run(Async, fun(Value) -> Done(With_(Value)) end) end}. -file("src/oaspec/transport.gleam", 109). -spec await(async(YUU), fun((YUU) -> async(YUW))) -> async(YUW). await(Async, Next) -> {async, fun(Done) -> run(Async, fun(Value) -> run(Next(Value), Done) end) end}. -file("src/oaspec/transport.gleam", 115). -spec map_try( async({ok, YUZ} | {error, YVA}), fun((YUZ) -> {ok, YVE} | {error, YVA}) ) -> async({ok, YVE} | {error, YVA}). map_try(Async, With_) -> _pipe = Async, map(_pipe, fun(Result) -> case Result of {ok, Value} -> With_(Value); {error, Error} -> {error, Error} end end). -file("src/oaspec/transport.gleam", 128). -spec try_await( async({ok, YVK} | {error, YVL}), fun((YVK) -> async({ok, YVP} | {error, YVL})) ) -> async({ok, YVP} | {error, YVL}). try_await(Async, Next) -> _pipe = Async, await(_pipe, fun(Result) -> case Result of {ok, Value} -> Next(Value); {error, Error} -> resolve({error, Error}) end end). -file("src/oaspec/transport.gleam", 159). -spec credentials() -> credentials(). credentials() -> {credentials, []}. -file("src/oaspec/transport.gleam", 195). -spec add_credential(credentials(), credential_entry()) -> credentials(). add_credential(Creds, Entry) -> {credentials, Entries} = Creds, {credentials, lists:append(Entries, [Entry])}. -file("src/oaspec/transport.gleam", 163). -spec with_api_key(credentials(), binary(), binary()) -> credentials(). with_api_key(Creds, Scheme_name, Value) -> add_credential(Creds, {cred_api_key, Scheme_name, Value}). -file("src/oaspec/transport.gleam", 171). -spec with_bearer_token(credentials(), binary(), binary()) -> credentials(). with_bearer_token(Creds, Scheme_name, Token) -> add_credential(Creds, {cred_bearer, Scheme_name, Token}). -file("src/oaspec/transport.gleam", 179). -spec with_basic_auth(credentials(), binary(), binary()) -> credentials(). with_basic_auth(Creds, Scheme_name, Value) -> add_credential(Creds, {cred_basic, Scheme_name, Value}). -file("src/oaspec/transport.gleam", 187). -spec with_digest_auth(credentials(), binary(), binary()) -> credentials(). with_digest_auth(Creds, Scheme_name, Value) -> add_credential(Creds, {cred_digest, Scheme_name, Value}). -file("src/oaspec/transport.gleam", 208). -spec with_base_url(fun((request()) -> YVW), binary()) -> fun((request()) -> YVW). with_base_url(Send, Base_url) -> fun(Req) -> Send( {request, erlang:element(2, Req), {some, Base_url}, erlang:element(4, Req), erlang:element(5, Req), erlang:element(6, Req), erlang:element(7, Req), erlang:element(8, Req)} ) end. -file("src/oaspec/transport.gleam", 283). -spec has_header(list({binary(), binary()}), binary()) -> boolean(). has_header(Headers, Name) -> Lowered = string:lowercase(Name), gleam@list:any( Headers, fun(H) -> {K, _} = H, string:lowercase(K) =:= Lowered end ). -file("src/oaspec/transport.gleam", 218). -spec with_default_header(fun((request()) -> YVX), binary(), binary()) -> fun((request()) -> YVX). with_default_header(Send, Name, Value) -> fun(Req) -> case has_header(erlang:element(6, Req), Name) of true -> Send(Req); false -> Send( {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), erlang:element(5, Req), lists:append(erlang:element(6, Req), [{Name, Value}]), erlang:element(7, Req), erlang:element(8, Req)} ) end end. -file("src/oaspec/transport.gleam", 237). -spec with_default_headers(fun((request()) -> YVY), list({binary(), binary()})) -> fun((request()) -> YVY). with_default_headers(Send, Headers) -> fun(Req) -> Merged_rev = gleam@list:fold( Headers, lists:reverse(erlang:element(6, Req)), fun(Acc_rev, Kv) -> {Name, Value} = Kv, case has_header(Acc_rev, Name) of true -> Acc_rev; false -> [{Name, Value} | Acc_rev] end end ), Send( {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), erlang:element(5, Req), lists:reverse(Merged_rev), erlang:element(7, Req), erlang:element(8, Req)} ) end. -file("src/oaspec/transport.gleam", 318). -spec credential_matches(credential_entry(), security_requirement()) -> boolean(). credential_matches(Cred, Req) -> case {Cred, Req} of {{cred_api_key, S, _}, {api_key_header, T, _}} when S =:= T -> true; {{cred_api_key, S@1, _}, {api_key_query, T@1, _}} when S@1 =:= T@1 -> true; {{cred_api_key, S@2, _}, {api_key_cookie, T@2, _}} when S@2 =:= T@2 -> true; {{cred_bearer, S@3, _}, {http_authorization, T@3, Prefix}} when S@3 =:= T@3 -> string:lowercase(Prefix) =:= <<"bearer"/utf8>>; {{cred_basic, S@4, _}, {http_authorization, T@4, Prefix@1}} when S@4 =:= T@4 -> string:lowercase(Prefix@1) =:= <<"basic"/utf8>>; {{cred_digest, S@5, _}, {http_authorization, T@5, Prefix@2}} when S@5 =:= T@5 -> string:lowercase(Prefix@2) =:= <<"digest"/utf8>>; {_, _} -> false end. -file("src/oaspec/transport.gleam", 309). -spec find_credential(credentials(), security_requirement()) -> gleam@option:option(credential_entry()). find_credential(Creds, Req) -> {credentials, Entries} = Creds, _pipe = gleam@list:find(Entries, fun(C) -> credential_matches(C, Req) end), gleam@option:from_result(_pipe). -file("src/oaspec/transport.gleam", 305). -spec satisfiable(security_alternative(), credentials()) -> boolean(). satisfiable(Alt, Creds) -> gleam@list:all( erlang:element(2, Alt), fun(Req) -> find_credential(Creds, Req) /= none end ). -file("src/oaspec/transport.gleam", 291). -spec pick_alternative(list(security_alternative()), credentials()) -> gleam@option:option(security_alternative()). pick_alternative(Alts, Creds) -> case Alts of [] -> none; [Alt | Rest] -> case satisfiable(Alt, Creds) of true -> {some, Alt}; false -> pick_alternative(Rest, Creds) end end. -file("src/oaspec/transport.gleam", 374). -spec set_authorization(request(), binary(), binary()) -> request(). set_authorization(Req, Prefix, Value) -> Header_value = <<<>/binary, Value/binary>>, {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), erlang:element(5, Req), lists:append( erlang:element(6, Req), [{<<"authorization"/utf8>>, Header_value}] ), erlang:element(7, Req), erlang:element(8, Req)}. -file("src/oaspec/transport.gleam", 386). -spec merge_cookie(request(), binary(), binary()) -> request(). merge_cookie(Req, Cookie_name, Value) -> Pair = <<<>, {Existing, Others} = gleam@list:partition( erlang:element(6, Req), fun(H) -> {K, _} = H, string:lowercase(K) =:= Lowered end ), Merged_value = case Existing of [] -> Pair; [_ | _] -> _pipe = gleam@list:map( Existing, fun(H@1) -> {_, V} = H@1, V end ), _pipe@1 = lists:append(_pipe, [Pair]), gleam@string:join(_pipe@1, <<"; "/utf8>>) end, {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), erlang:element(5, Req), lists:append(Others, [{<<"Cookie"/utf8>>, Merged_value}]), erlang:element(7, Req), erlang:element(8, Req)}. -file("src/oaspec/transport.gleam", 346). -spec apply_one(request(), security_requirement(), credential_entry()) -> request(). apply_one(Req, Requirement, Cred) -> case {Requirement, Cred} of {{api_key_header, _, Header_name}, {cred_api_key, _, Value}} -> {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), erlang:element(5, Req), lists:append(erlang:element(6, Req), [{Header_name, Value}]), erlang:element(7, Req), erlang:element(8, Req)}; {{api_key_query, _, Query_name}, {cred_api_key, _, Value@1}} -> {request, erlang:element(2, Req), erlang:element(3, Req), erlang:element(4, Req), lists:append(erlang:element(5, Req), [{Query_name, Value@1}]), erlang:element(6, Req), erlang:element(7, Req), erlang:element(8, Req)}; {{api_key_cookie, _, Cookie_name}, {cred_api_key, _, Value@2}} -> merge_cookie(Req, Cookie_name, Value@2); {{http_authorization, _, Prefix}, {cred_bearer, _, Token}} -> set_authorization(Req, Prefix, Token); {{http_authorization, _, Prefix@1}, {cred_basic, _, Value@3}} -> set_authorization(Req, Prefix@1, Value@3); {{http_authorization, _, Prefix@2}, {cred_digest, _, Value@4}} -> set_authorization(Req, Prefix@2, Value@4); {_, _} -> Req end. -file("src/oaspec/transport.gleam", 333). -spec apply_alternative(request(), security_alternative(), credentials()) -> request(). apply_alternative(Req, Alt, Creds) -> gleam@list:fold( erlang:element(2, Alt), Req, fun(Acc, Requirement) -> case find_credential(Creds, Requirement) of {some, Cred} -> apply_one(Acc, Requirement, Cred); none -> Acc end end ). -file("src/oaspec/transport.gleam", 266). -spec with_security(fun((request()) -> YWA), credentials()) -> fun((request()) -> YWA). with_security(Send, Creds) -> fun(Req) -> Prepared = case pick_alternative(erlang:element(8, Req), Creds) of {some, Alt} -> apply_alternative(Req, Alt, Creds); none -> Req end, Send(Prepared) end.