Skip to main content

src/aws@config.erl

-module(aws@config).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/config.gleam").
-export([default_settings/0, resolve/3]).
-export_type([settings/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(
    " Customer-facing construction settings — the service-agnostic knobs\n"
    " every `Client` is built from. AWS endpoint-rule-set parameters\n"
    " (`UseFIPS`, `UseDualStack`, S3 `ForcePathStyle`, …) are NOT here:\n"
    " they vary per service and live on each service's own typed\n"
    " `EndpointParams` record, kept separate so customer config and AWS\n"
    " rule-set attributes never mix.\n"
    "\n"
    " Two construction entry points per service:\n"
    "   1. `<service>.new()` — full auto: region resolves from the standard\n"
    "      AWS sources, credentials from the default chain. Zero config.\n"
    "   2. `<service>.new_with(settings, endpoint_params)` — start each\n"
    "      record from its defaults and override only the fields you need:\n"
    "\n"
    "        import aws/config.{Settings, default_settings}\n"
    "        import aws/services/s3\n"
    "\n"
    "        let assert Ok(client) =\n"
    "          s3.new_with(\n"
    "            Settings(..default_settings(), region: Some(\"eu-west-1\")),\n"
    "            s3.EndpointParams(..s3.default_endpoint_params(), use_fips: Some(True)),\n"
    "          )\n"
).

-type settings() :: {settings,
        gleam@option:option(binary()),
        binary(),
        gleam@option:option(aws@credentials:provider()),
        gleam@option:option(binary()),
        gleam@option:option(integer()),
        gleam@option:option(aws@retry:strategy()),
        gleam@option:option(fun((gleam@http@request:request(bitstring())) -> {ok,
                gleam@http@response:response(bitstring())} |
            {error, aws@internal@http_send:http_error()})),
        gleam@option:option(fun((gleam@http@request:request(bitstring())) -> {ok,
                gleam@http@response:response(aws@streaming:streaming_body())} |
            {error, aws@internal@http_send:http_error()})),
        boolean(),
        gleam@option:option(list(binary())),
        boolean()}.

-file("src/aws/config.gleam", 81).
?DOC(
    " The full-auto baseline: region + credentials resolve themselves and\n"
    " every other knob keeps the runtime default. Spread this with a\n"
    " record update and override only the fields you need.\n"
).
-spec default_settings() -> settings().
default_settings() ->
    {settings,
        none,
        <<"default"/utf8>>,
        none,
        none,
        none,
        none,
        none,
        none,
        false,
        none,
        true}.

-file("src/aws/config.gleam", 172).
-spec apply_sigv4a(aws@internal@client@runtime:client_config(), settings()) -> aws@internal@client@runtime:client_config().
apply_sigv4a(Config, Settings) ->
    case erlang:element(11, Settings) of
        none ->
            Config;

        {some, Region_set} ->
            _pipe = aws@internal@client@runtime:with_sigv4a_region_set(
                Config,
                Region_set
            ),
            aws@internal@client@runtime:with_sigv4a_path_normalization(
                _pipe,
                erlang:element(12, Settings)
            )
    end.

-file("src/aws/config.gleam", 157).
-spec apply_transports(aws@internal@client@runtime:client_config(), settings()) -> aws@internal@client@runtime:client_config().
apply_transports(Config, Settings) ->
    Config@1 = case erlang:element(8, Settings) of
        {some, Send} ->
            aws@internal@client@runtime:with_http_send(Config, Send);

        none ->
            Config
    end,
    Config@2 = case erlang:element(9, Settings) of
        {some, Send@1} ->
            aws@internal@client@runtime:with_streaming_http_send(
                Config@1,
                Send@1
            );

        none ->
            Config@1
    end,
    case erlang:element(10, Settings) of
        true ->
            aws@internal@client@runtime:with_http2(Config@2);

        false ->
            Config@2
    end.

-file("src/aws/config.gleam", 146).
-spec apply_retry(aws@internal@client@runtime:client_config(), settings()) -> aws@internal@client@runtime:client_config().
apply_retry(Config, Settings) ->
    Config@1 = case erlang:element(7, Settings) of
        {some, Strategy} ->
            aws@internal@client@runtime:with_retry_strategy(Config, Strategy);

        none ->
            Config
    end,
    case erlang:element(6, Settings) of
        {some, N} ->
            aws@internal@client@runtime:with_max_attempts(Config@1, N);

        none ->
            Config@1
    end.

-file("src/aws/config.gleam", 136).
-spec apply_endpoint_url(
    aws@internal@client@runtime:client_config(),
    settings()
) -> aws@internal@client@runtime:client_config().
apply_endpoint_url(Config, Settings) ->
    case erlang:element(5, Settings) of
        {some, Url} ->
            aws@internal@client@runtime:with_endpoint_url(Config, Url);

        none ->
            Config
    end.

-file("src/aws/config.gleam", 129).
-spec resolve_region(settings()) -> {ok, binary()} |
    {error, aws@region:resolve_error()}.
resolve_region(Settings) ->
    case erlang:element(2, Settings) of
        {some, R} ->
            {ok, R};

        none ->
            aws@region:resolve(erlang:element(3, Settings))
    end.

-file("src/aws/config.gleam", 107).
?DOC(
    " Resolve `Settings` into a runtime `ClientConfig` for a service,\n"
    " identified by its endpoint prefix + SigV4 signing name. The only\n"
    " failure is region resolution when `region` is `None` and no source\n"
    " supplies one; credentials stay lazy (the per-Client cache fetches them\n"
    " on the first request), so a missing chain surfaces at call time, not\n"
    " here.\n"
    "\n"
    " Generated `new` / `new_with` call this, then apply the service's typed\n"
    " `EndpointParams`, attach its endpoint rule set, and start the\n"
    " credentials cache.\n"
).
-spec resolve(settings(), binary(), binary()) -> {ok,
        aws@internal@client@runtime:client_config()} |
    {error, aws@region:resolve_error()}.
resolve(Settings, Endpoint_prefix, Signing_name) ->
    gleam@result:map(
        resolve_region(Settings),
        fun(Resolved) ->
            Provider = case erlang:element(4, Settings) of
                {some, P} ->
                    P;

                none ->
                    aws@credentials:default_chain(
                        fun aws@internal@http_send:default_send/1,
                        erlang:element(3, Settings)
                    )
            end,
            _pipe = aws@internal@client@runtime:default_config(
                Resolved,
                Endpoint_prefix,
                Signing_name
            ),
            _pipe@1 = aws@internal@client@runtime:with_credentials_provider(
                _pipe,
                Provider
            ),
            _pipe@2 = apply_endpoint_url(_pipe@1, Settings),
            _pipe@3 = apply_retry(_pipe@2, Settings),
            _pipe@4 = apply_transports(_pipe@3, Settings),
            apply_sigv4a(_pipe@4, Settings)
        end
    ).