Current section
Files
Jump to
Current section
Files
src/kv_sessions.erl
-module(kv_sessions).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([get_session/1, delete_session/1, key/2, with_codec/3, get/1, set/2, delete/2, replace_session/3, middleware/3]).
-export_type([current_session/0, session_key/1]).
-type current_session() :: {current_session,
gleam@http@request:request(wisp:connection()),
kv_sessions@session_config:config()}.
-type session_key(TSG) :: {session_key,
current_session(),
binary(),
fun((gleam@dynamic:dynamic_()) -> {ok, TSG} |
{error, list(gleam@dynamic:decode_error())}),
fun((TSG) -> binary())}.
-spec get_session_with_cache(
kv_sessions@session:session_id(),
kv_sessions@session_config:config(),
boolean()
) -> {ok, gleam@option:option(kv_sessions@session:session())} |
{error, kv_sessions@session:session_error()}.
get_session_with_cache(Session_id, Config, Cache) ->
case {Cache, erlang:element(5, Config)} of
{true, {some, Cache@1}} ->
case (erlang:element(2, Cache@1))(Session_id) of
{ok, {some, Session}} ->
{ok, {some, Session}};
_ ->
get_session_with_cache(Session_id, Config, false)
end;
{_, _} ->
(erlang:element(2, erlang:element(4, Config)))(Session_id)
end.
-spec save_session(
kv_sessions@session_config:config(),
kv_sessions@session:session()
) -> {ok, kv_sessions@session:session()} |
{error, kv_sessions@session:session_error()}.
save_session(Config, Session) ->
_pipe = erlang:element(5, Config),
gleam@option:map(
_pipe,
fun(Cache) -> (erlang:element(3, Cache))(Session) end
),
(erlang:element(3, erlang:element(4, Config)))(Session).
-spec get_session(current_session()) -> {ok, kv_sessions@session:session()} |
{error, kv_sessions@session:session_error()}.
get_session(Current_session) ->
gleam@result:'try'(
kv_sessions@internal@utils:get_session_id(
erlang:element(3, erlang:element(3, Current_session)),
erlang:element(2, Current_session)
),
fun(Session_id) ->
gleam@result:'try'(
get_session_with_cache(
Session_id,
erlang:element(3, Current_session),
true
),
fun(Maybe_session) -> case Maybe_session of
{some, Session} ->
case kv_sessions@internal@utils:is_session_expired(
Session
) of
true ->
{error, session_expired_error};
false ->
{ok, Session}
end;
none ->
Session@1 = begin
_pipe = kv_sessions@session:builder(),
_pipe@1 = kv_sessions@session:with_id(
_pipe,
Session_id
),
_pipe@2 = kv_sessions@session:with_expiry(
_pipe@1,
erlang:element(
2,
erlang:element(3, Current_session)
)
),
kv_sessions@session:build(_pipe@2)
end,
save_session(
erlang:element(3, Current_session),
Session@1
)
end end
)
end
).
-spec delete_session(current_session()) -> {ok, nil} |
{error, kv_sessions@session:session_error()}.
delete_session(Current_session) ->
{current_session, Req, Config} = Current_session,
gleam@result:'try'(
kv_sessions@internal@utils:get_session_id(
erlang:element(3, Config),
Req
),
fun(Session_id) ->
_pipe = erlang:element(5, Config),
gleam@option:map(
_pipe,
fun(Cache) -> (erlang:element(4, Cache))(Session_id) end
),
(erlang:element(4, erlang:element(4, Config)))(Session_id)
end
).
-spec key(current_session(), binary()) -> session_key(binary()).
key(Current_session, Key) ->
{session_key,
Current_session,
Key,
fun gleam@dynamic:string/1,
fun(Str) -> _pipe = gleam@json:string(Str),
gleam@json:to_string(_pipe) end}.
-spec with_codec(
session_key(any()),
fun((gleam@dynamic:dynamic_()) -> {ok, TSO} |
{error, list(gleam@dynamic:decode_error())}),
fun((TSO) -> binary())
) -> session_key(TSO).
with_codec(Session_key, Decode, Encode) ->
{session_key,
erlang:element(2, Session_key),
erlang:element(3, Session_key),
Decode,
Encode}.
-spec get(session_key(TSR)) -> {ok, gleam@option:option(TSR)} |
{error, kv_sessions@session:session_error()}.
get(Entry) ->
gleam@result:'try'(
get_session(erlang:element(2, Entry)),
fun(Session) ->
case begin
_pipe = gleam@dict:get(
erlang:element(4, Session),
erlang:element(3, Entry)
),
gleam@option:from_result(_pipe)
end of
none ->
{ok, none};
{some, Data} ->
_pipe@1 = gleam@json:decode(Data, erlang:element(4, Entry)),
_pipe@2 = gleam@result:replace_error(_pipe@1, decode_error),
gleam@result:map(_pipe@2, fun(D) -> {some, D} end)
end
end
).
-spec set(session_key(TSU), TSU) -> {ok, TSU} |
{error, kv_sessions@session:session_error()}.
set(Entry, Data) ->
gleam@result:'try'(
get_session(erlang:element(2, Entry)),
fun(Session) ->
Session@1 = begin
_pipe = kv_sessions@session:builder_from(Session),
_pipe@1 = kv_sessions@session:with_entry(
_pipe,
erlang:element(3, Entry),
(erlang:element(5, Entry))(Data)
),
kv_sessions@session:build(_pipe@1)
end,
gleam@result:map(
save_session(
erlang:element(3, erlang:element(2, Entry)),
Session@1
),
fun(_) -> Data end
)
end
).
-spec delete(current_session(), binary()) -> {ok, kv_sessions@session:session()} |
{error, kv_sessions@session:session_error()}.
delete(Current_session, Key) ->
{current_session, _, Config} = Current_session,
gleam@result:'try'(
get_session(Current_session),
fun(Session) ->
save_session(
Config,
erlang:setelement(
4,
Session,
gleam@dict:delete(erlang:element(4, Session), Key)
)
)
end
).
-spec replace_session(
current_session(),
gleam@http@response:response(wisp:body()),
kv_sessions@session:session()
) -> {ok, gleam@http@response:response(wisp:body())} |
{error, kv_sessions@session:session_error()}.
replace_session(Current_session, Res, New_session) ->
{current_session, Req, Config} = Current_session,
gleam@result:'try'(
delete_session(Current_session),
fun(_) ->
gleam@result:map(
save_session(Config, New_session),
fun(_) ->
kv_sessions@internal@utils:set_session_cookie(
erlang:element(3, Config),
Res,
Req,
New_session
)
end
)
end
).
-spec middleware(
gleam@http@request:request(wisp:connection()),
kv_sessions@session_config:config(),
fun((gleam@http@request:request(wisp:connection())) -> gleam@http@response:response(wisp:body()))
) -> gleam@http@response:response(wisp:body()).
middleware(Req, Config, Handle_request) ->
case kv_sessions@internal@utils:get_session_id(
erlang:element(3, Config),
Req
) of
{ok, _} ->
Handle_request(Req);
{error, _} ->
Session = begin
_pipe = kv_sessions@session:builder(),
_pipe@1 = kv_sessions@session:with_expiry(
_pipe,
erlang:element(2, Config)
),
kv_sessions@session:build(_pipe@1)
end,
_ = (erlang:element(3, erlang:element(4, Config)))(Session),
Res = begin
_pipe@2 = kv_sessions@internal@utils:inject_session_cookie(
erlang:element(3, Config),
Req,
erlang:element(2, Session),
signed
),
Handle_request(_pipe@2)
end,
_pipe@3 = Res,
_pipe@4 = gleam@http@response:get_cookies(_pipe@3),
_pipe@5 = gleam@list:key_find(_pipe@4, erlang:element(3, Config)),
(fun(Cookie) -> case Cookie of
{ok, _} ->
Res;
{error, _} ->
kv_sessions@internal@utils:set_session_cookie(
erlang:element(3, Config),
Res,
Req,
Session
)
end end)(_pipe@5)
end.