src/aws@lambda@event.erl
-module(aws@lambda@event).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/lambda/event.gleam").
-export([sqs_decoder/0, api_gateway_decoder/0, api_gateway_v2_decoder/0, eventbridge_decoder/1, s3_decoder/0, sns_decoder/0]).
-export_type([sqs_event/0, sqs_message/0, sqs_message_attribute/0, api_gateway_proxy_request/0, api_gateway_v2_request/0, event_bridge_event/1, s3_event/0, s3_record/0, sns_event/0, sns_record/0, sns_message/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(
" Typed envelopes for the events Lambda delivers, with decoders for the\n"
" common trigger sources. Lambda hands every trigger to the handler as a\n"
" JSON document; these turn that document into a Gleam record.\n"
"\n"
" Pair them with `aws/lambda.start_json`:\n"
"\n"
" ```gleam\n"
" import aws/lambda\n"
" import aws/lambda/event\n"
"\n"
" pub fn main() {\n"
" lambda.start_json(\n"
" event.sqs_decoder(),\n"
" fn(sqs, _ctx) {\n"
" list.each(sqs.records, fn(msg) { process(msg.body) })\n"
" Ok(Nil)\n"
" },\n"
" fn(_) { json.null() },\n"
" )\n"
" }\n"
" ```\n"
"\n"
" Each decoder models the fields handlers actually reach for and tolerates\n"
" missing/null members so a slightly different payload shape never crashes\n"
" decoding. Open-ended members are left for the caller to decode: an SQS\n"
" `body` and an SNS `message` are raw `String`s (often JSON you parse with\n"
" your own decoder), and an EventBridge `detail` is decoded by a decoder\n"
" you supply. Field shapes follow the AWS sample events documented under\n"
" \"Using AWS Lambda with <service>\".\n"
).
-type sqs_event() :: {sqs_event, list(sqs_message())}.
-type sqs_message() :: {sqs_message,
binary(),
binary(),
binary(),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), sqs_message_attribute()),
binary(),
binary(),
binary(),
binary()}.
-type sqs_message_attribute() :: {sqs_message_attribute,
binary(),
gleam@option:option(binary())}.
-type api_gateway_proxy_request() :: {api_gateway_proxy_request,
binary(),
binary(),
binary(),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
gleam@option:option(binary()),
boolean()}.
-type api_gateway_v2_request() :: {api_gateway_v2_request,
binary(),
binary(),
binary(),
binary(),
list(binary()),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), binary()),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
boolean()}.
-type event_bridge_event(ODD) :: {event_bridge_event,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
list(binary()),
ODD}.
-type s3_event() :: {s3_event, list(s3_record())}.
-type s3_record() :: {s3_record,
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
binary(),
gleam@option:option(integer()),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-type sns_event() :: {sns_event, list(sns_record())}.
-type sns_record() :: {sns_record, binary(), binary(), sns_message()}.
-type sns_message() :: {sns_message,
binary(),
binary(),
gleam@option:option(binary()),
binary(),
binary(),
binary()}.
-file("src/aws/lambda/event.gleam", 109).
-spec sqs_message_attribute_decoder() -> gleam@dynamic@decode:decoder(sqs_message_attribute()).
sqs_message_attribute_decoder() ->
gleam@dynamic@decode:optional_field(
<<"dataType"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Data_type) ->
gleam@dynamic@decode:optional_field(
<<"stringValue"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(String_value) ->
gleam@dynamic@decode:success(
{sqs_message_attribute, Data_type, String_value}
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 506).
-spec optional_dict(gleam@dynamic@decode:decoder(ODV)) -> gleam@dynamic@decode:decoder(gleam@dict:dict(binary(), ODV)).
optional_dict(Value) ->
_pipe = gleam@dynamic@decode:dict(
{decoder, fun gleam@dynamic@decode:decode_string/1},
Value
),
_pipe@1 = gleam@dynamic@decode:optional(_pipe),
gleam@dynamic@decode:map(
_pipe@1,
fun(Maybe) -> gleam@option:unwrap(Maybe, maps:new()) end
).
-file("src/aws/lambda/event.gleam", 502).
-spec string_dict() -> gleam@dynamic@decode:decoder(gleam@dict:dict(binary(), binary())).
string_dict() ->
optional_dict({decoder, fun gleam@dynamic@decode:decode_string/1}).
-file("src/aws/lambda/event.gleam", 74).
-spec sqs_message_decoder() -> gleam@dynamic@decode:decoder(sqs_message()).
sqs_message_decoder() ->
gleam@dynamic@decode:field(
<<"messageId"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Message_id) ->
gleam@dynamic@decode:field(
<<"receiptHandle"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Receipt_handle) ->
gleam@dynamic@decode:field(
<<"body"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Body) ->
gleam@dynamic@decode:optional_field(
<<"attributes"/utf8>>,
maps:new(),
string_dict(),
fun(Attributes) ->
gleam@dynamic@decode:optional_field(
<<"messageAttributes"/utf8>>,
maps:new(),
optional_dict(
sqs_message_attribute_decoder()
),
fun(Message_attributes) ->
gleam@dynamic@decode:optional_field(
<<"md5OfBody"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Md5_of_body) ->
gleam@dynamic@decode:optional_field(
<<"eventSource"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Event_source) ->
gleam@dynamic@decode:optional_field(
<<"eventSourceARN"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(
Event_source_arn
) ->
gleam@dynamic@decode:optional_field(
<<"awsRegion"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(
Aws_region
) ->
gleam@dynamic@decode:success(
{sqs_message,
Message_id,
Receipt_handle,
Body,
Attributes,
Message_attributes,
Md5_of_body,
Event_source,
Event_source_arn,
Aws_region}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 65).
?DOC(" Decoder for the SQS event envelope.\n").
-spec sqs_decoder() -> gleam@dynamic@decode:decoder(sqs_event()).
sqs_decoder() ->
gleam@dynamic@decode:optional_field(
<<"Records"/utf8>>,
[],
gleam@dynamic@decode:list(sqs_message_decoder()),
fun(Records) -> gleam@dynamic@decode:success({sqs_event, Records}) end
).
-file("src/aws/lambda/event.gleam", 512).
-spec optional_bool() -> gleam@dynamic@decode:decoder(boolean()).
optional_bool() ->
_pipe = {decoder, fun gleam@dynamic@decode:decode_bool/1},
_pipe@1 = gleam@dynamic@decode:optional(_pipe),
gleam@dynamic@decode:map(
_pipe@1,
fun(Maybe) -> gleam@option:unwrap(Maybe, false) end
).
-file("src/aws/lambda/event.gleam", 142).
?DOC(" Decoder for the API Gateway REST proxy request (payload format 1.0).\n").
-spec api_gateway_decoder() -> gleam@dynamic@decode:decoder(api_gateway_proxy_request()).
api_gateway_decoder() ->
gleam@dynamic@decode:optional_field(
<<"resource"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Resource) ->
gleam@dynamic@decode:optional_field(
<<"path"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Path) ->
gleam@dynamic@decode:optional_field(
<<"httpMethod"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Http_method) ->
gleam@dynamic@decode:optional_field(
<<"headers"/utf8>>,
maps:new(),
string_dict(),
fun(Headers) ->
gleam@dynamic@decode:optional_field(
<<"queryStringParameters"/utf8>>,
maps:new(),
string_dict(),
fun(Query_string_parameters) ->
gleam@dynamic@decode:optional_field(
<<"pathParameters"/utf8>>,
maps:new(),
string_dict(),
fun(Path_parameters) ->
gleam@dynamic@decode:optional_field(
<<"stageVariables"/utf8>>,
maps:new(),
string_dict(),
fun(Stage_variables) ->
gleam@dynamic@decode:optional_field(
<<"body"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Body) ->
gleam@dynamic@decode:optional_field(
<<"isBase64Encoded"/utf8>>,
false,
optional_bool(
),
fun(
Is_base64_encoded
) ->
gleam@dynamic@decode:success(
{api_gateway_proxy_request,
Resource,
Path,
Http_method,
Headers,
Query_string_parameters,
Path_parameters,
Stage_variables,
Body,
Is_base64_encoded}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 210).
?DOC(" Decoder for the API Gateway HTTP API request (payload format 2.0).\n").
-spec api_gateway_v2_decoder() -> gleam@dynamic@decode:decoder(api_gateway_v2_request()).
api_gateway_v2_decoder() ->
gleam@dynamic@decode:optional_field(
<<"version"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Version) ->
gleam@dynamic@decode:optional_field(
<<"routeKey"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Route_key) ->
gleam@dynamic@decode:optional_field(
<<"rawPath"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Raw_path) ->
gleam@dynamic@decode:optional_field(
<<"rawQueryString"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Raw_query_string) ->
gleam@dynamic@decode:optional_field(
<<"cookies"/utf8>>,
[],
gleam@dynamic@decode:list(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Cookies) ->
gleam@dynamic@decode:optional_field(
<<"headers"/utf8>>,
maps:new(),
string_dict(),
fun(Headers) ->
gleam@dynamic@decode:optional_field(
<<"queryStringParameters"/utf8>>,
maps:new(),
string_dict(),
fun(
Query_string_parameters
) ->
gleam@dynamic@decode:optional_field(
<<"pathParameters"/utf8>>,
maps:new(),
string_dict(),
fun(
Path_parameters
) ->
gleam@dynamic@decode:optional_field(
<<"stageVariables"/utf8>>,
maps:new(
),
string_dict(
),
fun(
Stage_variables
) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"requestContext"/utf8>>,
<<"http"/utf8>>,
<<"method"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Method
) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"requestContext"/utf8>>,
<<"http"/utf8>>,
<<"path"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Path
) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"requestContext"/utf8>>,
<<"http"/utf8>>,
<<"sourceIp"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Source_ip
) ->
gleam@dynamic@decode:optional_field(
<<"body"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Body
) ->
gleam@dynamic@decode:optional_field(
<<"isBase64Encoded"/utf8>>,
false,
optional_bool(
),
fun(
Is_base64_encoded
) ->
gleam@dynamic@decode:success(
{api_gateway_v2_request,
Version,
Route_key,
Raw_path,
Raw_query_string,
Cookies,
Headers,
Query_string_parameters,
Path_parameters,
Stage_variables,
Method,
Path,
Source_ip,
Body,
Is_base64_encoded}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 304).
?DOC(" Decoder for an EventBridge event, decoding `detail` with `detail_decoder`.\n").
-spec eventbridge_decoder(gleam@dynamic@decode:decoder(ODJ)) -> gleam@dynamic@decode:decoder(event_bridge_event(ODJ)).
eventbridge_decoder(Detail_decoder) ->
gleam@dynamic@decode:optional_field(
<<"id"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Id) ->
gleam@dynamic@decode:optional_field(
<<"version"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Version) ->
gleam@dynamic@decode:optional_field(
<<"detail-type"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Detail_type) ->
gleam@dynamic@decode:optional_field(
<<"source"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Source) ->
gleam@dynamic@decode:optional_field(
<<"account"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Account) ->
gleam@dynamic@decode:optional_field(
<<"time"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Time) ->
gleam@dynamic@decode:optional_field(
<<"region"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Region) ->
gleam@dynamic@decode:optional_field(
<<"resources"/utf8>>,
[],
gleam@dynamic@decode:list(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Resources) ->
gleam@dynamic@decode:field(
<<"detail"/utf8>>,
Detail_decoder,
fun(
Detail
) ->
gleam@dynamic@decode:success(
{event_bridge_event,
Id,
Version,
Detail_type,
Source,
Account,
Time,
Region,
Resources,
Detail}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 368).
-spec s3_record_decoder() -> gleam@dynamic@decode:decoder(s3_record()).
s3_record_decoder() ->
gleam@dynamic@decode:optional_field(
<<"awsRegion"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Aws_region) ->
gleam@dynamic@decode:optional_field(
<<"eventName"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Event_name) ->
gleam@dynamic@decode:optional_field(
<<"eventTime"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Event_time) ->
gleam@dynamic@decode:optional_field(
<<"eventSource"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Event_source) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"bucket"/utf8>>,
<<"name"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Bucket_name) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"bucket"/utf8>>,
<<"arn"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Bucket_arn) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"object"/utf8>>,
<<"key"/utf8>>],
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Object_key) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"object"/utf8>>,
<<"size"/utf8>>],
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_int/1}
)
),
fun(Object_size) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"object"/utf8>>,
<<"eTag"/utf8>>],
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
fun(
Object_etag
) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"s3"/utf8>>,
<<"object"/utf8>>,
<<"sequencer"/utf8>>],
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
fun(
Object_sequencer
) ->
gleam@dynamic@decode:success(
{s3_record,
Aws_region,
Event_name,
Event_time,
Event_source,
Bucket_name,
Bucket_arn,
Object_key,
Object_size,
Object_etag,
Object_sequencer}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 359).
?DOC(" Decoder for the S3 event-notification envelope.\n").
-spec s3_decoder() -> gleam@dynamic@decode:decoder(s3_event()).
s3_decoder() ->
gleam@dynamic@decode:optional_field(
<<"Records"/utf8>>,
[],
gleam@dynamic@decode:list(s3_record_decoder()),
fun(Records) -> gleam@dynamic@decode:success({s3_event, Records}) end
).
-file("src/aws/lambda/event.gleam", 471).
-spec sns_message_decoder() -> gleam@dynamic@decode:decoder(sns_message()).
sns_message_decoder() ->
gleam@dynamic@decode:field(
<<"MessageId"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Message_id) ->
gleam@dynamic@decode:optional_field(
<<"TopicArn"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Topic_arn) ->
gleam@dynamic@decode:optional_field(
<<"Subject"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Subject) ->
gleam@dynamic@decode:field(
<<"Message"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Message) ->
gleam@dynamic@decode:optional_field(
<<"Timestamp"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Timestamp) ->
gleam@dynamic@decode:optional_field(
<<"Type"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Message_type) ->
gleam@dynamic@decode:success(
{sns_message,
Message_id,
Topic_arn,
Subject,
Message,
Timestamp,
Message_type}
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 456).
-spec sns_record_decoder() -> gleam@dynamic@decode:decoder(sns_record()).
sns_record_decoder() ->
gleam@dynamic@decode:optional_field(
<<"EventSource"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Event_source) ->
gleam@dynamic@decode:optional_field(
<<"EventSubscriptionArn"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Event_subscription_arn) ->
gleam@dynamic@decode:field(
<<"Sns"/utf8>>,
sns_message_decoder(),
fun(Sns) ->
gleam@dynamic@decode:success(
{sns_record,
Event_source,
Event_subscription_arn,
Sns}
)
end
)
end
)
end
).
-file("src/aws/lambda/event.gleam", 447).
?DOC(" Decoder for the SNS event envelope.\n").
-spec sns_decoder() -> gleam@dynamic@decode:decoder(sns_event()).
sns_decoder() ->
gleam@dynamic@decode:optional_field(
<<"Records"/utf8>>,
[],
gleam@dynamic@decode:list(sns_record_decoder()),
fun(Records) -> gleam@dynamic@decode:success({sns_event, Records}) end
).