Current section
Files
Jump to
Current section
Files
src/pify.erl
-module(pify).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pify.gleam").
-export([admin_response_errors_decoder/0, create_admin_api_client/1, admin_handler/1, handler/1, create_store_front_api_client/1]).
-export_type([create_admin_api_client/0, admin_api_client_config/0, admin_handler/1, admin_client_response/1, admin_response_errors/0, create_storefront_api_client/0, shopify_error/0, error_reason/0, storefront_api_client_config/0, shopify_handler/1, access_token/0]).
-type create_admin_api_client() :: {create_admin_api_client,
binary(),
binary(),
binary(),
gleam@option:option(integer())}.
-type admin_api_client_config() :: {admin_api_client_config,
binary(),
binary(),
binary(),
{binary(), list({binary(), binary()})},
binary(),
gleam@option:option(integer())}.
-type admin_handler(ICA) :: {admin_handler,
admin_api_client_config(),
fun((binary(), gleam@option:option(gleam@json:json()), gleam@dynamic@decode:decoder(admin_client_response(ICA))) -> midas@task:effect(admin_client_response(ICA), admin_response_errors()))}.
-type admin_client_response(ICB) :: {admin_client_response,
gleam@option:option(ICB)}.
-type admin_response_errors() :: {admin_response_errors,
gleam@option:option(integer()),
gleam@option:option(binary()),
gleam@option:option(list(binary())),
gleam@option:option(gleam@http@response:response(binary()))}.
-type create_storefront_api_client() :: {create_storefront_api_client,
binary(),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(integer())}.
-type shopify_error() :: {bad_url, binary()} |
{http_error, gleam@http@response:response(binary())} |
{json_error, gleam@json:decode_error()} |
network_error |
{unhandled_response, gleam@http@response:response(binary())} |
rate_limit_error |
{client_error, binary()}.
-type error_reason() :: {error_reason, binary(), binary()}.
-type storefront_api_client_config() :: {storefront_api_client_config,
binary(),
gleam@option:option(binary()),
access_token(),
{binary(), list({binary(), binary()})},
binary(),
gleam@option:option(binary()),
gleam@option:option(integer())}.
-type shopify_handler(ICC) :: {shopify_handler,
storefront_api_client_config(),
fun((gleam@option:option({binary(), list({binary(), binary()})})) -> {binary(),
list({binary(), binary()})}),
fun((binary(), gleam@option:option(gleam@json:json()), gleam@dynamic@decode:decoder(ICC)) -> midas@task:effect(ICC, shopify_error()))}.
-opaque access_token() :: {public_access_token, binary()} |
{private_access_token, binary()}.
-file("src/pify.gleam", 105).
-spec response_string_decoder() -> gleam@dynamic@decode:decoder(gleam@http@response:response(binary())).
response_string_decoder() ->
gleam@dynamic@decode:field(
<<"status"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Status) ->
gleam@dynamic@decode:field(
<<"headers"/utf8>>,
gleam@dynamic@decode:list(
begin
gleam@dynamic@decode:field(
0,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(A) ->
gleam@dynamic@decode:field(
1,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(B) ->
gleam@dynamic@decode:success({A, B})
end
)
end
)
end
),
fun(Headers) ->
gleam@dynamic@decode:field(
<<"body"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Body) ->
gleam@dynamic@decode:success(
{response, Status, Headers, Body}
)
end
)
end
)
end
).
-file("src/pify.gleam", 83).
-spec admin_response_errors_decoder() -> gleam@dynamic@decode:decoder(admin_response_errors()).
admin_response_errors_decoder() ->
gleam@dynamic@decode:field(
<<"network_status_code"/utf8>>,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_int/1}
),
fun(Network_status_code) ->
gleam@dynamic@decode:field(
<<"message"/utf8>>,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Message) ->
gleam@dynamic@decode:field(
<<"graphql_errors"/utf8>>,
gleam@dynamic@decode:optional(
gleam@dynamic@decode:list(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Graphql_errors) ->
gleam@dynamic@decode:field(
<<"response"/utf8>>,
gleam@dynamic@decode:optional(
response_string_decoder()
),
fun(Response) ->
gleam@dynamic@decode:success(
{admin_response_errors,
Network_status_code,
Message,
Graphql_errors,
Response}
)
end
)
end
)
end
)
end
).
-file("src/pify.gleam", 176).
-spec generate_admin_api_url_formatter(create_admin_api_client()) -> binary().
generate_admin_api_url_formatter(Config) ->
<<<<<<(erlang:element(2, Config))/binary, "/admin/api/"/utf8>>/binary,
(gleam@string:trim(erlang:element(3, Config)))/binary>>/binary,
"/graphql.json"/utf8>>.
-file("src/pify.gleam", 183).
-spec admin_base(admin_api_client_config()) -> gleam@http@request:request(binary()).
admin_base(Client) ->
Parsed_url@1 = case gleam_stdlib:uri_parse(
<<"https://"/utf8, (erlang:element(6, Client))/binary>>
) of
{ok, Parsed_url} -> Parsed_url;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"admin_base"/utf8>>,
line => 184,
value => _assert_fail,
start => 5511,
'end' => 5578,
pattern_start => 5522,
pattern_end => 5536})
end,
Host@1 = case erlang:element(4, Parsed_url@1) of
{some, Host} -> Host;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"admin_base"/utf8>>,
line => 185,
value => _assert_fail@1,
start => 5581,
'end' => 5620,
pattern_start => 5592,
pattern_end => 5602})
end,
Original_schema@1 = case erlang:element(2, Parsed_url@1) of
{some, Original_schema} -> Original_schema;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"admin_base"/utf8>>,
line => 186,
value => _assert_fail@2,
start => 5623,
'end' => 5675,
pattern_start => 5634,
pattern_end => 5655})
end,
Scheme@1 = case gleam@http:scheme_from_string(Original_schema@1) of
{ok, Scheme} -> Scheme;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"admin_base"/utf8>>,
line => 187,
value => _assert_fail@3,
start => 5678,
'end' => 5742,
pattern_start => 5689,
pattern_end => 5699})
end,
_pipe = gleam@http@request:new(),
_pipe@1 = gleam@http@request:set_scheme(_pipe, Scheme@1),
_pipe@2 = gleam@http@request:set_host(_pipe@1, Host@1),
_pipe@3 = gleam@http@request:set_path(
_pipe@2,
erlang:element(6, Parsed_url@1)
),
_pipe@4 = gleam@http@request:set_method(_pipe@3, post),
_pipe@5 = gleam@http@request:set_header(
_pipe@4,
<<"Content-Type"/utf8>>,
<<"application/json"/utf8>>
),
_pipe@6 = gleam@http@request:set_header(
_pipe@5,
<<"Accept"/utf8>>,
<<"application/json"/utf8>>
),
gleam@http@request:set_header(
_pipe@6,
<<"X-Shopify-Access-Token"/utf8>>,
erlang:element(4, Client)
).
-file("src/pify.gleam", 198).
-spec get_admin_headers(create_admin_api_client()) -> {binary(),
list({binary(), binary()})}.
get_admin_headers(Config) ->
Token = erlang:element(4, Config),
{<<"headers"/utf8>>,
[{<<"Content-Type"/utf8>>, <<"application/json"/utf8>>},
{<<"Accept"/utf8>>, <<"application/json"/utf8>>},
{<<"X-Shopify-Access-Token"/utf8>>, Token},
{<<"X-SDK-Version"/utf8>>, <<"rollup_replace_client_version"/utf8>>}]}.
-file("src/pify.gleam", 120).
-spec create_admin_api_client(create_admin_api_client()) -> {ok,
admin_api_client_config()} |
{error, shopify_error()}.
create_admin_api_client(Config) ->
Api_url = generate_admin_api_url_formatter(Config),
{ok,
{admin_api_client_config,
erlang:element(2, Config),
erlang:element(3, Config),
erlang:element(4, Config),
get_admin_headers(Config),
Api_url,
{some, 0}}}.
-file("src/pify.gleam", 257).
-spec error_reason_decoder() -> gleam@dynamic@decode:decoder(error_reason()).
error_reason_decoder() ->
gleam@dynamic@decode:field(
<<"error"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Error) ->
gleam@dynamic@decode:field(
<<"message"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Message) ->
gleam@dynamic@decode:success({error_reason, Error, Message})
end
)
end
).
-file("src/pify.gleam", 158).
-spec admin_decode_response(
gleam@http@response:response(bitstring()),
gleam@dynamic@decode:decoder(admin_client_response(ICO))
) -> midas@task:effect(admin_client_response(ICO), admin_response_errors()).
admin_decode_response(Response, Decoder) ->
case erlang:element(2, Response) of
200 ->
case gleam@json:parse_bits(erlang:element(4, Response), Decoder) of
{ok, Data} ->
midas@task:done(Data);
{error, Reason} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason)))
end;
201 ->
case gleam@json:parse_bits(erlang:element(4, Response), Decoder) of
{ok, Data} ->
midas@task:done(Data);
{error, Reason} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason)))
end;
_ ->
case gleam@json:parse_bits(
erlang:element(4, Response),
error_reason_decoder()
) of
{ok, Reason@1} ->
midas@task:abort(snag:new(erlang:element(3, Reason@1)));
{error, Reason@2} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason@2)))
end
end.
-file("src/pify.gleam", 134).
-spec admin_handler(admin_api_client_config()) -> admin_handler(any()).
admin_handler(Config) ->
{admin_handler,
Config,
fun(Query, Variables, Decoder) ->
Request = begin
Graphql_body = case Variables of
{some, Vars} ->
gleam@json:object(
[{<<"query"/utf8>>, gleam@json:string(Query)},
{<<"variables"/utf8>>, Vars}]
);
none ->
gleam@json:object(
[{<<"query"/utf8>>, gleam@json:string(Query)}]
)
end,
_pipe = admin_base(Config),
_pipe@1 = gleam@http@request:set_method(_pipe, post),
gleam@http@request:set_body(
_pipe@1,
<<(gleam@json:to_string(Graphql_body))/binary>>
)
end,
midas@task:do(
midas@task:fetch(Request),
fun(Response) -> admin_decode_response(Response, Decoder) end
)
end}.
-file("src/pify.gleam", 337).
-spec decode_response(
gleam@http@response:response(bitstring()),
gleam@dynamic@decode:decoder(IDD)
) -> midas@task:effect(IDD, any()).
decode_response(Response, Decoder) ->
case erlang:element(2, Response) of
200 ->
case gleam@json:parse_bits(erlang:element(4, Response), Decoder) of
{ok, Data} ->
midas@task:done(Data);
{error, Reason} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason)))
end;
201 ->
case gleam@json:parse_bits(erlang:element(4, Response), Decoder) of
{ok, Data} ->
midas@task:done(Data);
{error, Reason} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason)))
end;
_ ->
case gleam@json:parse_bits(
erlang:element(4, Response),
error_reason_decoder()
) of
{ok, Reason@1} ->
midas@task:abort(snag:new(erlang:element(3, Reason@1)));
{error, Reason@2} ->
midas@task:abort(snag:new(gleam@string:inspect(Reason@2)))
end
end.
-file("src/pify.gleam", 355).
-spec get_headers(gleam@option:option({binary(), list({binary(), binary()})})) -> {binary(),
list({binary(), binary()})}.
get_headers(Headers) ->
case Headers of
{some, Header} ->
Header;
none ->
{<<"headers"/utf8>>,
[{<<"Content-Type"/utf8>>, <<"application/json"/utf8>>},
{<<"Accept"/utf8>>, <<"application/json"/utf8>>},
{<<"X-SDK-Variant"/utf8>>, <<"storefront-api-client"/utf8>>},
{<<"X-SDK-Version"/utf8>>,
<<"rollup_replace_client_version"/utf8>>}]}
end.
-file("src/pify.gleam", 373).
-spec base(storefront_api_client_config()) -> gleam@http@request:request(binary()).
base(Client) ->
Access = case erlang:element(4, Client) of
{public_access_token, Token} ->
{<<"X-Shopify-Access-Token"/utf8>>, Token};
{private_access_token, Token@1} ->
{<<"X-Shopify-Access-Token"/utf8>>, Token@1}
end,
Parsed_url@1 = case gleam_stdlib:uri_parse(
<<"https://"/utf8, (erlang:element(6, Client))/binary>>
) of
{ok, Parsed_url} -> Parsed_url;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"base"/utf8>>,
line => 379,
value => _assert_fail,
start => 12032,
'end' => 12099,
pattern_start => 12043,
pattern_end => 12057})
end,
Host@1 = case erlang:element(4, Parsed_url@1) of
{some, Host} -> Host;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"base"/utf8>>,
line => 380,
value => _assert_fail@1,
start => 12102,
'end' => 12141,
pattern_start => 12113,
pattern_end => 12123})
end,
Original_schema@1 = case erlang:element(2, Parsed_url@1) of
{some, Original_schema} -> Original_schema;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"base"/utf8>>,
line => 381,
value => _assert_fail@2,
start => 12144,
'end' => 12196,
pattern_start => 12155,
pattern_end => 12176})
end,
Scheme@1 = case gleam@http:scheme_from_string(Original_schema@1) of
{ok, Scheme} -> Scheme;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"base"/utf8>>,
line => 382,
value => _assert_fail@3,
start => 12199,
'end' => 12263,
pattern_start => 12210,
pattern_end => 12220})
end,
_pipe = gleam@http@request:new(),
_pipe@1 = gleam@http@request:set_scheme(_pipe, Scheme@1),
_pipe@2 = gleam@http@request:set_host(_pipe@1, Host@1),
_pipe@3 = gleam@http@request:set_path(
_pipe@2,
erlang:element(6, Parsed_url@1)
),
_pipe@4 = gleam@http@request:set_method(_pipe@3, post),
_pipe@5 = gleam@http@request:set_header(
_pipe@4,
<<"Content-Type"/utf8>>,
<<"application/json"/utf8>>
),
_pipe@6 = gleam@http@request:set_header(
_pipe@5,
<<"Accept"/utf8>>,
<<"application/json"/utf8>>
),
gleam@http@request:set_header(
_pipe@6,
erlang:element(1, Access),
erlang:element(2, Access)
).
-file("src/pify.gleam", 316).
-spec handler(storefront_api_client_config()) -> shopify_handler(any()).
handler(Config) ->
{shopify_handler,
Config,
fun get_headers/1,
fun(Query, Variables, Decoder) ->
Request = begin
Graphql_body = case Variables of
{some, Vars} ->
gleam@json:object(
[{<<"query"/utf8>>, gleam@json:string(Query)},
{<<"variables"/utf8>>, Vars}]
);
none ->
gleam@json:object(
[{<<"query"/utf8>>, gleam@json:string(Query)}]
)
end,
_pipe = base(Config),
_pipe@1 = gleam@http@request:set_method(_pipe, post),
gleam@http@request:set_body(
_pipe@1,
<<(gleam@json:to_string(Graphql_body))/binary>>
)
end,
midas@task:do(
midas@task:fetch(Request),
fun(Response) -> decode_response(Response, Decoder) end
)
end}.
-file("src/pify.gleam", 400).
-spec validate_required_access_token_usage(
gleam@option:option(binary()),
gleam@option:option(binary())
) -> {ok, access_token()} | {error, shopify_error()}.
validate_required_access_token_usage(Private_access_token, Public_access_token) ->
Is_valid_private_access_token = gleam@option:is_some(Private_access_token),
Is_valid_public_access_token = gleam@option:is_some(Public_access_token),
case not Is_valid_private_access_token andalso not Is_valid_public_access_token of
true ->
{error,
{client_error,
begin
_pipe = snag:new(
<<"Storefront API Client: an access token must be provided."/utf8>>
),
snag:line_print(_pipe)
end}};
false ->
case Is_valid_private_access_token andalso Is_valid_public_access_token of
true ->
{error,
{client_error,
begin
_pipe@1 = snag:new(
<<"Storefront API Client: only provide either a public or private access token."/utf8>>
),
snag:line_print(_pipe@1)
end}};
false ->
case Public_access_token of
{some, Key} ->
{ok, {public_access_token, Key}};
none ->
case Private_access_token of
{some, Key@1} ->
{ok, {private_access_token, Key@1}};
none ->
{error,
{client_error,
begin
_pipe@2 = snag:new(
<<"Storefront API Client: an access token must be provided."/utf8>>
),
snag:line_print(_pipe@2)
end}}
end
end
end
end.
-file("src/pify.gleam", 445).
-spec create_headers(access_token(), gleam@option:option(binary())) -> {binary(),
list({binary(), binary()})}.
create_headers(Access_token, Client_variant) ->
Access = case Access_token of
{public_access_token, Token} ->
{<<"X-Shopify-Access-Token"/utf8>>, Token};
{private_access_token, Token@1} ->
{<<"X-Shopify-Access-Token"/utf8>>, Token@1}
end,
Client = case Client_variant of
none ->
{<<"X-SDK-Variant-Source"/utf8>>, <<""/utf8>>};
{some, Key} ->
{<<"X-SDK-Variant-Source"/utf8>>, Key}
end,
{<<"headers"/utf8>>,
[{<<"Content-Type"/utf8>>, <<"application/json"/utf8>>},
{<<"Accept"/utf8>>, <<"application/json"/utf8>>},
{<<"X-SDK-Variant"/utf8>>, <<"storefront-api-client"/utf8>>},
{<<"X-SDK-Version"/utf8>>, <<"rollup_replace_client_version"/utf8>>},
Access,
Client]}.
-file("src/pify.gleam", 468).
-spec generate_api_url_formatter(create_storefront_api_client()) -> binary().
generate_api_url_formatter(Config) ->
case erlang:element(3, Config) of
{some, Api} ->
<<<<<<(erlang:element(2, Config))/binary, "/admin/api/"/utf8>>/binary,
(gleam@string:trim(Api))/binary>>/binary,
"/graphql.json"/utf8>>;
none ->
<<<<<<(erlang:element(2, Config))/binary, "/admin/api/"/utf8>>/binary,
(gleam@string:trim(<<"2023-10"/utf8>>))/binary>>/binary,
"/graphql.json"/utf8>>
end.
-file("src/pify.gleam", 291).
-spec create_store_front_api_client(create_storefront_api_client()) -> {ok,
storefront_api_client_config()} |
{error, shopify_error()}.
create_store_front_api_client(Config) ->
Access_token = validate_required_access_token_usage(
erlang:element(4, Config),
erlang:element(5, Config)
),
Token@2 = case Access_token of
{ok, {public_access_token, Token}} ->
{public_access_token, Token};
{ok, {private_access_token, Token@1}} ->
{private_access_token, Token@1};
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"`panic` expression evaluated."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"pify"/utf8>>,
function => <<"create_store_front_api_client"/utf8>>,
line => 302})
end,
{ok,
{storefront_api_client_config,
erlang:element(2, Config),
erlang:element(3, Config),
Token@2,
create_headers(Token@2, erlang:element(6, Config)),
generate_api_url_formatter(Config),
erlang:element(6, Config),
{some, 0}}}.