Skip to content

Commit d481d60

Browse files
author
Ryan Miville
committed
initial commit
0 parents  commit d481d60

19 files changed

+1215
-0
lines changed

.github/workflows/test.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- main
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: erlef/setup-beam@v1
16+
with:
17+
otp-version: "26.0.2"
18+
gleam-version: "1.5.1"
19+
rebar3-version: "3"
20+
# elixir-version: "1.15.4"
21+
- run: gleam deps download
22+
- run: gleam test
23+
- run: gleam format --check src test

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump
5+
.DS_Store

README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# glambda
2+
3+
Write AWS Lambda functions in Gleam!
4+
5+
[![Package Version](https://img.shields.io/hexpm/v/glambda)](https://hex.pm/packages/glambda)
6+
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/glambda/)
7+
8+
```sh
9+
gleam add glambda
10+
```
11+
```gleam
12+
// .src/handler.gleam
13+
import glambda.{
14+
type ApiGatewayProxyEventV2, type ApiGatewayProxyResultV2, type Context,
15+
type JsContext, type JsEvent, type JsResult, ApiGatewayProxyResultV2,
16+
}
17+
import gleam/javascript/promise.{type Promise}
18+
19+
pub fn typed_handler(event: ApiGatewayProxyEventV2, ctx: Context) -> Promise(ApiGatewayProxyResultV2) {
20+
let response =
21+
ApiGatewayProxyResultV2(
22+
status_code: 200,
23+
headers: dict.from_list([#("Content-Type", "text/plain")]),
24+
body: Some("hello! from " <> ctx.function_name),
25+
is_base64_encoded: False,
26+
cookies: [],
27+
)
28+
promise.new(fn(resolve) { resolve(response) })
29+
}
30+
31+
pub fn handler(event: JsEvent, ctx: JsContext) -> Promise(JsResult) {
32+
glambda.api_gateway_proxy_v2_handler(typed_handler)(event, ctx)
33+
}
34+
```
35+
36+
Further documentation can be found at <https://hexdocs.pm/glambda>.
37+
38+
## Development
39+
40+
```sh
41+
gleam run # Run the project
42+
gleam test # Run the tests
43+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP request with IAM authorizer
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_request_iam_marshaling_test
6+
---
7+
ApiGatewayProxyEventV2(
8+
version: "2.0",
9+
route_key: "$default",
10+
raw_path: "/my/path",
11+
raw_query_string: "parameter1=value1&parameter1=value2&parameter2=value",
12+
cookies: Some(["cookie1", "cookie2"]),
13+
headers: dict.from_list([
14+
#("Header1", "value1"),
15+
#("Header2", "value2"),
16+
]),
17+
query_string_parameters: Some(dict.from_list([
18+
#("parameter1", "value1,value2"),
19+
#("parameter2", "value"),
20+
])),
21+
path_parameters: Some(dict.from_list([
22+
#("proxy", "hello/world"),
23+
])),
24+
stage_variables: Some(dict.from_list([
25+
#("stageVariable1", "value1"),
26+
#("stageVariable2", "value2"),
27+
])),
28+
request_context: ApiGatewayRequestContextV2(
29+
route_key: "$default",
30+
account_id: "123456789012",
31+
stage: "$default",
32+
request_id: "id",
33+
authorizer: Some(Iam(iam: ApiGatewayEventRequestContextIamAuthorizer(
34+
access_key: "ARIA2ZJZYVUEREEIHAKY",
35+
account_id: "1234567890",
36+
caller_id: "AROA7ZJZYVRE7C3DUXHH6:CognitoIdentityCredentials",
37+
principal_org_id: "AwsOrgId",
38+
user_arn: "arn:aws:iam::1234567890:user/Admin",
39+
user_id: "AROA2ZJZYVRE7Y3TUXHH6",
40+
))),
41+
api_id: "api-id",
42+
domain_name: "id.execute-api.us-east-1.amazonaws.com",
43+
domain_prefix: "id",
44+
time: "12/Mar/2020:19:03:58+0000",
45+
time_epoch: 1583348638390,
46+
http: ApiGatewayEventRequestContextHttp(
47+
method: "GET",
48+
path: "/my/path",
49+
protocol: "HTTP/1.1",
50+
source_ip: "IP",
51+
user_agent: "agent",
52+
),
53+
authentication: Some(ApiGatewayEventRequestContextAuthentication(client_cert: APIGatewayEventClientCertificate(
54+
client_cert_pem: "-----BEGIN CERTIFICATE-----
55+
MIIEZTCCAk0CAQEwDQ...",
56+
issuer_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Private CA",
57+
serial_number: "1",
58+
subject_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Client",
59+
validity: APIGatewayEventValidity(
60+
not_after: "Aug 5 00:28:21 2120 GMT",
61+
not_before: "Aug 29 00:28:21 2020 GMT",
62+
),
63+
))),
64+
),
65+
body: Some("{
66+
"a": 1
67+
}"),
68+
is_base64_encoded: False,
69+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP request with JWT authorizer
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_request_jwt_authorizer_test
6+
---
7+
ApiGatewayProxyEventV2(
8+
version: "2.0",
9+
route_key: "$default",
10+
raw_path: "/my/path",
11+
raw_query_string: "parameter1=value1&parameter1=value2&parameter2=value",
12+
cookies: Some(["cookie1", "cookie2"]),
13+
headers: dict.from_list([
14+
#("Header1", "value1"),
15+
#("Header2", "value2"),
16+
]),
17+
query_string_parameters: Some(dict.from_list([
18+
#("parameter1", "value1,value2"),
19+
#("parameter2", "value"),
20+
])),
21+
path_parameters: Some(dict.from_list([
22+
#("proxy", "hello/world"),
23+
])),
24+
stage_variables: Some(dict.from_list([
25+
#("stageVariable1", "value1"),
26+
#("stageVariable2", "value2"),
27+
])),
28+
request_context: ApiGatewayRequestContextV2(
29+
route_key: "$default",
30+
account_id: "123456789012",
31+
stage: "$default",
32+
request_id: "id",
33+
authorizer: Some(Jwt(
34+
principal_id: "admin",
35+
integration_latency: 123,
36+
jwt: ApiGatewayEventRequestContextJwtAuthorizer(
37+
claims: dict.from_list([
38+
#("claim1", "value1"),
39+
#("claim2", "value2"),
40+
]),
41+
scopes: Some([
42+
"scope1",
43+
"scope2",
44+
]),
45+
),
46+
)),
47+
api_id: "api-id",
48+
domain_name: "id.execute-api.us-east-1.amazonaws.com",
49+
domain_prefix: "id",
50+
time: "12/Mar/2020:19:03:58+0000",
51+
time_epoch: 1583348638390,
52+
http: ApiGatewayEventRequestContextHttp(
53+
method: "GET",
54+
path: "/my/path",
55+
protocol: "HTTP/1.1",
56+
source_ip: "IP",
57+
user_agent: "agent",
58+
),
59+
authentication: Some(ApiGatewayEventRequestContextAuthentication(client_cert: APIGatewayEventClientCertificate(
60+
client_cert_pem: "-----BEGIN CERTIFICATE-----
61+
MIIEZTCCAk0CAQEwDQ...",
62+
issuer_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Private CA",
63+
serial_number: "1",
64+
subject_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Client",
65+
validity: APIGatewayEventValidity(
66+
not_after: "Aug 5 00:28:21 2120 GMT",
67+
not_before: "Aug 29 00:28:21 2020 GMT",
68+
),
69+
))),
70+
),
71+
body: Some("{
72+
"a": 1
73+
}"),
74+
is_base64_encoded: False,
75+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP request with Lambda authorizer
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_request_lambda_authorizer_test
6+
---
7+
ApiGatewayProxyEventV2(
8+
version: "2.0",
9+
route_key: "$default",
10+
raw_path: "/my/path",
11+
raw_query_string: "parameter1=value1&parameter1=value2&parameter2=value",
12+
cookies: Some(["cookie1", "cookie2"]),
13+
headers: dict.from_list([
14+
#("Header1", "value1"),
15+
#("Header2", "value2"),
16+
]),
17+
query_string_parameters: Some(dict.from_list([
18+
#("parameter1", "value1,value2"),
19+
#("parameter2", "value"),
20+
])),
21+
path_parameters: Some(dict.from_list([
22+
#("proxy", "hello/world"),
23+
])),
24+
stage_variables: Some(dict.from_list([
25+
#("stageVariable1", "value1"),
26+
#("stageVariable2", "value2"),
27+
])),
28+
request_context: ApiGatewayRequestContextV2(
29+
route_key: "$default",
30+
account_id: "123456789012",
31+
stage: "$default",
32+
request_id: "id",
33+
authorizer: Some(Lambda(lambda: dict.from_list([
34+
#("key", "value"),
35+
]))),
36+
api_id: "api-id",
37+
domain_name: "id.execute-api.us-east-1.amazonaws.com",
38+
domain_prefix: "id",
39+
time: "12/Mar/2020:19:03:58+0000",
40+
time_epoch: 1583348638390,
41+
http: ApiGatewayEventRequestContextHttp(
42+
method: "GET",
43+
path: "/my/path",
44+
protocol: "HTTP/1.1",
45+
source_ip: "IP",
46+
user_agent: "agent",
47+
),
48+
authentication: Some(ApiGatewayEventRequestContextAuthentication(client_cert: APIGatewayEventClientCertificate(
49+
client_cert_pem: "-----BEGIN CERTIFICATE-----
50+
MIIEZTCCAk0CAQEwDQ...",
51+
issuer_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Private CA",
52+
serial_number: "1",
53+
subject_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Client",
54+
validity: APIGatewayEventValidity(
55+
not_after: "Aug 5 00:28:21 2120 GMT",
56+
not_before: "Aug 29 00:28:21 2020 GMT",
57+
),
58+
))),
59+
),
60+
body: Some("{
61+
"a": 1
62+
}"),
63+
is_base64_encoded: False,
64+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP request with no authorizer
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_request_no_authorizer_test
6+
---
7+
ApiGatewayProxyEventV2(
8+
version: "2.0",
9+
route_key: "$default",
10+
raw_path: "/",
11+
raw_query_string: "",
12+
cookies: None,
13+
headers: dict.from_list([
14+
#("accept", "*/*"),
15+
#("content-length", "0"),
16+
#("host", "aaaaaaaaaa.execute-api.us-west-2.amazonaws.com"),
17+
#("user-agent", "curl/7.58.0"),
18+
#("x-amzn-trace-id", "Root=1-5e9f0c65-1de4d666d4dd26aced652b6c"),
19+
#("x-forwarded-for", "1.2.3.4"),
20+
#("x-forwarded-port", "443"),
21+
#("x-forwarded-proto", "https"),
22+
]),
23+
query_string_parameters: None,
24+
path_parameters: None,
25+
stage_variables: None,
26+
request_context: ApiGatewayRequestContextV2(
27+
route_key: "$default",
28+
account_id: "123456789012",
29+
stage: "$default",
30+
request_id: "LV7fzho-PHcEJPw=",
31+
authorizer: None,
32+
api_id: "aaaaaaaaaa",
33+
domain_name: "aaaaaaaaaa.execute-api.us-west-2.amazonaws.com",
34+
domain_prefix: "aaaaaaaaaa",
35+
time: "21/Apr/2020:15:08:21 +0000",
36+
time_epoch: 1587481701067,
37+
http: ApiGatewayEventRequestContextHttp(
38+
method: "GET",
39+
path: "/",
40+
protocol: "HTTP/1.1",
41+
source_ip: "1.2.3.4",
42+
user_agent: "curl/7.58.0",
43+
),
44+
authentication: Some(ApiGatewayEventRequestContextAuthentication(client_cert: APIGatewayEventClientCertificate(
45+
client_cert_pem: "-----BEGIN CERTIFICATE-----
46+
MIIEZTCCAk0CAQEwDQ...",
47+
issuer_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Private CA",
48+
serial_number: "1",
49+
subject_dn: "C=US,ST=Washington,L=Seattle,O=Amazon Web Services,OU=Security,CN=My Client",
50+
validity: APIGatewayEventValidity(
51+
not_after: "Aug 5 00:28:21 2120 GMT",
52+
not_before: "Aug 29 00:28:21 2020 GMT",
53+
),
54+
))),
55+
),
56+
body: None,
57+
is_base64_encoded: False,
58+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP Response
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_response_test
6+
---
7+
{
8+
"statusCode": 200,
9+
"headers": {
10+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
11+
"Upgrade-Insecure-Requests": "1",
12+
"CloudFront-Forwarded-Proto": "https",
13+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
14+
"Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
15+
"X-Forwarded-Proto": "https",
16+
"X-Forwarded-For": "192.168.100.1, 192.168.1.1",
17+
"CloudFront-Is-Desktop-Viewer": "true",
18+
"Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
19+
"CloudFront-Is-Tablet-Viewer": "false",
20+
"X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
21+
"CloudFront-Is-Mobile-Viewer": "false",
22+
"CloudFront-Viewer-Country": "US",
23+
"Accept-Encoding": "gzip, deflate, lzma, sdch, br",
24+
"Accept-Language": "en-US,en;q=0.8",
25+
"CloudFront-Is-SmartTV-Viewer": "false",
26+
"X-Forwarded-Port": "443"
27+
},
28+
"body": "Hello World",
29+
"isBase64Encoded": false,
30+
"cookies": [
31+
"cookie1",
32+
"cookie2"
33+
]
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
version: 1.2.3
3+
title: API Gateway V2 HTTP Response with valid empty fields
4+
file: ./test/glambda_test.gleam
5+
test_name: api_gateway_v2_http_response_valid_empty_fields_test
6+
---
7+
{
8+
"statusCode": 200,
9+
"headers": {},
10+
"isBase64Encoded": false,
11+
"cookies": []
12+
}

0 commit comments

Comments
 (0)