Skip to content

Commit 02032c0

Browse files
author
Ryan Miville
authored
Merge pull request #1 from ryanmiville/apigw
apigw
2 parents 49c27b4 + 9859580 commit 02032c0

26 files changed

+241
-16
lines changed

examples/apigw/.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.beam
2+
*.ez
3+
/build
4+
erl_crash.dump
5+
6+
# sst
7+
.sst
8+
node_modules
9+
.DS_Store

examples/apigw/README.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# apigw
2+
3+
[![Package Version](https://img.shields.io/hexpm/v/apigw)](https://hex.pm/packages/apigw)
4+
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/apigw/)
5+
6+
```sh
7+
gleam add apigw@1
8+
```
9+
```gleam
10+
import apigw
11+
12+
pub fn main() {
13+
// TODO: An example of the project in use
14+
}
15+
```
16+
17+
Further documentation can be found at <https://hexdocs.pm/apigw>.
18+
19+
## Development
20+
21+
```sh
22+
gleam run # Run the project
23+
gleam test # Run the tests
24+
```

examples/apigw/bun.lockb

8.39 KB
Binary file not shown.

examples/apigw/gleam.toml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name = "apigw"
2+
version = "1.0.0"
3+
target = "javascript"
4+
5+
[dependencies]
6+
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
7+
glambda = { path = "../.." }
8+
gleam_javascript = ">= 0.13.0 and < 1.0.0"
9+
10+
[dev-dependencies]
11+
gleeunit = ">= 1.0.0 and < 2.0.0"

examples/apigw/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("Hello via Bun!");

examples/apigw/manifest.toml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# This file was generated by Gleam
2+
# You typically do not need to edit this file
3+
4+
packages = [
5+
{ name = "glambda", version = "0.1.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_javascript", "gleam_stdlib"], source = "local", path = "../.." },
6+
{ name = "gleam_http", version = "3.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "EA66440C2269F7CED0F6845E5BD0DB68095775D627FA709A841CA78A398D6D56" },
7+
{ name = "gleam_javascript", version = "0.13.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "F98328FCF573DA6F3A35D7F6CB3F9FF19FD5224CCBA9151FCBEAA0B983AF2F58" },
8+
{ name = "gleam_stdlib", version = "0.40.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "86606B75A600BBD05E539EB59FABC6E307EEEA7B1E5865AFB6D980A93BCB2181" },
9+
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
10+
]
11+
12+
[requirements]
13+
glambda = { path = "../.." }
14+
gleam_javascript = { version = ">= 0.13.0 and < 1.0.0" }
15+
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
16+
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }

examples/apigw/package.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "apigw",
3+
"type": "module",
4+
"scripts": {
5+
"dev": "gleam build && sst dev"
6+
},
7+
"devDependencies": {
8+
"@types/aws-lambda": "8.10.145",
9+
"@types/bun": "latest"
10+
},
11+
"peerDependencies": {
12+
"typescript": "^5.0.0"
13+
},
14+
"dependencies": {
15+
"sst": "3.2.59"
16+
}
17+
}

examples/apigw/src/apigw.gleam

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import glambda.{
2+
type ApiGatewayProxyEventV2, type ApiGatewayProxyResultV2, type Context,
3+
ApiGatewayProxyResultV2,
4+
}
5+
import gleam/dict
6+
import gleam/javascript/promise.{type Promise}
7+
import gleam/option.{Some}
8+
9+
fn handle_request(
10+
_event: ApiGatewayProxyEventV2,
11+
ctx: Context,
12+
) -> Promise(ApiGatewayProxyResultV2) {
13+
ApiGatewayProxyResultV2(
14+
status_code: 200,
15+
headers: dict.from_list([#("content-type", "application/json")]),
16+
body: Some("{\"functionName\": \"" <> ctx.function_name <> "\"}"),
17+
is_base64_encoded: False,
18+
cookies: [],
19+
)
20+
|> promise.resolve
21+
}
22+
23+
pub fn handler(event, ctx) {
24+
glambda.api_gateway_proxy_v2_handler(handle_request)(event, ctx)
25+
}

examples/apigw/sst-env.d.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* This file is auto-generated by SST. Do not edit. */
2+
/* tslint:disable */
3+
/* eslint-disable */
4+
/* deno-fmt-ignore-file */
5+
import "sst"
6+
export {}
7+
declare module "sst" {
8+
export interface Resource {
9+
"ApiGatewayExample": {
10+
"name": string
11+
"type": "sst.aws.Function"
12+
"url": string
13+
}
14+
}
15+
}

examples/simple/sst.config.ts examples/apigw/sst.config.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
export default $config({
44
app(input) {
55
return {
6-
name: "simple-example",
6+
name: "apigw",
77
removal: input?.stage === "production" ? "retain" : "remove",
88
home: "aws",
99
providers: {
@@ -15,8 +15,8 @@ export default $config({
1515
};
1616
},
1717
async run() {
18-
const api = new sst.aws.Function("SimpleExample", {
19-
handler: "build/dev/javascript/handler/handler.handler",
18+
const api = new sst.aws.Function("ApiGatewayExample", {
19+
handler: "build/dev/javascript/apigw/apigw.handler",
2020
url: true,
2121
});
2222
return {

examples/apigw/test/apigw_test.gleam

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import gleeunit
2+
import gleeunit/should
3+
4+
pub fn main() {
5+
gleeunit.main()
6+
}
7+
8+
// gleeunit test functions end in `_test`
9+
pub fn hello_world_test() {
10+
1
11+
|> should.equal(1)
12+
}
File renamed without changes.
+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
File renamed without changes.
File renamed without changes.
File renamed without changes.

examples/simple/gleam.toml examples/http/gleam.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name = "handler"
1+
name = "http"
22
version = "1.0.0"
33
target = "javascript"
44

File renamed without changes.

examples/simple/package.json examples/http/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "simple",
2+
"name": "http",
33
"version": "1.0.0",
44
"type": "module",
55
"scripts": {
File renamed without changes.

examples/simple/sst-env.d.ts examples/http/sst-env.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import "sst"
66
export {}
77
declare module "sst" {
88
export interface Resource {
9-
"SimpleExample": {
9+
"HttpExample": {
1010
"name": string
1111
"type": "sst.aws.Function"
1212
"url": string

examples/http/sst.config.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/// <reference path="./.sst/platform/config.d.ts" />
2+
3+
export default $config({
4+
app(input) {
5+
return {
6+
name: "http",
7+
removal: input?.stage === "production" ? "retain" : "remove",
8+
home: "aws",
9+
providers: {
10+
aws: {
11+
region: "us-east-1",
12+
profile: "personal",
13+
},
14+
},
15+
};
16+
},
17+
async run() {
18+
const api = new sst.aws.Function("HttpExample", {
19+
handler: "build/dev/javascript/http/http.handler",
20+
url: true,
21+
});
22+
return {
23+
url: api.url,
24+
};
25+
},
26+
});
File renamed without changes.

examples/http/tsconfig.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"compilerOptions": {
3+
// Enable latest features
4+
"lib": ["ESNext", "DOM"],
5+
"target": "ESNext",
6+
"module": "ESNext",
7+
"moduleDetection": "force",
8+
"jsx": "react-jsx",
9+
"allowJs": true,
10+
11+
// Bundler mode
12+
"moduleResolution": "bundler",
13+
"allowImportingTsExtensions": true,
14+
"verbatimModuleSyntax": true,
15+
"noEmit": true,
16+
17+
// Best practices
18+
"strict": true,
19+
"skipLibCheck": true,
20+
"noFallthroughCasesInSwitch": true,
21+
22+
// Some stricter flags (disabled by default)
23+
"noUnusedLocals": false,
24+
"noUnusedParameters": false,
25+
"noPropertyAccessFromIndexSignature": false
26+
}
27+
}

src/glambda.gleam

+29-10
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,53 @@
11
//// This module provides types and adapters to write AWS Lambda functions that target the Node runtime.
22
////
3-
//// # Example
3+
//// The core type of glambda is the `Handler(event, result)`, which is simply a
4+
//// function, `fn(event, Context) -> Promise(result)`. Then you use one of the
5+
//// handler adapters to wrap your handler to make it compatible with AWS Lambda.
46
////
5-
//// You can use handle API Gateway events using Gleam HTTP types
7+
//// The adapter creates a new function,
8+
//// `fn(JsEvent, JsContext) -> Promise(JsResult)`. You shouldn't need to use
9+
//// these types in your code. In fact, you typically do not need to reference
10+
//// them at all due to type inference.
11+
////
12+
//// # Examples
13+
////
14+
//// You can handle API Gateway proxy v2 events using Gleam HTTP types
615
////
716
//// ```gleam
8-
//// fn handle_request(request: Request(Option(String)), ctx: Context) -> Promise(Response(Option(String))) {
17+
//// fn handle_request(
18+
//// request: Request(Option(String)),
19+
//// ctx: Context,
20+
//// ) -> Promise(Response(Option(String))) {
921
//// Response(200, [], None)
1022
//// |> promise.resolve
1123
//// }
1224
////
13-
//// // this is the actual lambda function
14-
//// fn handler(event, ctx) {
15-
//// glambda.http_handler(handle_request)
25+
//// // this is the actual function lambda will invoke
26+
//// pub fn handler(event, ctx) {
27+
//// glambda.http_handler(handle_request)(event, ctx)
1628
//// }
1729
//// ```
1830
////
19-
//// This module also supports other types of events, such as EventBridge.
31+
//// You can also handle the API Gateway event directly, or several other
32+
//// supported event types, such as EventBridge.
2033
////
2134
//// ```gleam
2235
//// fn handle_request(event: EventBridgeEvent, ctx: Context) -> Promise(Nil) {
2336
//// io.debug(event)
2437
//// promise.resolve(Nil)
2538
//// }
2639
////
27-
//// // this is the actual lambda function
28-
//// fn handler(event, ctx) {
29-
//// glambda.eventbridge_event_handler(handle_request)
40+
//// // this is the actual function lambda will invoke
41+
//// pub fn handler(event, ctx) {
42+
//// glambda.eventbridge_event_handler(handle_request)(event, ctx)
3043
//// }
3144
//// ```
45+
//// # Supported Events
46+
//// * `ApiGatewayProxyEventV2` (handled directly or as a `Request(Option(String))`)
47+
//// * `EventBridgeEvent`
48+
//// * `SqsEvent`
49+
////
50+
//// Reference the `*_handler` functions for the correct signatures.
3251

3352
import gleam/bit_array
3453
import gleam/dict.{type Dict}

0 commit comments

Comments
 (0)