🧚 A practical web framework for Gleam

Update application

+55 -15
+3 -3
action/test/action_test.gleam
··· 4 4 import action/web.{Context} 5 5 import action/database 6 6 import gleam/string 7 - import gleam/http/request.{Request} 7 + import gleam/http/request 8 8 import gleam/http.{Get, Method, Post} 9 9 import gleam/string_builder 10 10 import framework ··· 20 20 } 21 21 22 22 // TODO: move this to a helper module 23 - pub fn request(method: Method, path: String) -> Request(BitString) { 23 + pub fn request(method: Method, path: String) -> framework.Request { 24 24 request.new() 25 25 |> request.set_method(method) 26 26 |> request.set_path(path) 27 - |> request.set_body(<<>>) 27 + |> request.set_body(framework.test_connection(<<>>)) 28 28 } 29 29 30 30 // TODO: move this to a helper module
+52 -12
framework/src/framework.gleam
··· 1 + // - [ ] Test helpers 2 + // - [ ] Body reading 3 + // - [ ] Form data 4 + // - [ ] Multipart 5 + // - [ ] Json 6 + // - [ ] String 7 + // - [ ] Bit string 8 + // - [ ] Body writing 9 + // - [x] Html 10 + // - [x] Json 11 + // - [ ] Static files 12 + // - [ ] Cookies 13 + // - [ ] Signed cookies 14 + // - [ ] Secret keys 15 + // - [ ] Key rotation 16 + // - [ ] Sessions 17 + // - [ ] Flash messages 18 + // - [ ] Websockets 19 + // - [ ] CSRF 20 + // - [ ] Project generators 21 + // - [ ] Exception recovery 22 + 1 23 import gleam/string_builder.{StringBuilder} 2 24 import gleam/bit_builder.{BitBuilder} 3 25 import gleam/bit_string ··· 15 37 // Running the server 16 38 // 17 39 40 + // TODO: test 41 + // TODO: document 18 42 pub fn mist_service( 19 43 service: fn(Request) -> Response, 20 44 ) -> fn(HttpRequest(mist.Connection)) -> HttpResponse(mist.ResponseData) { 21 45 fn(request: HttpRequest(_)) { 22 - let connection = 23 - Connection( 24 - reader: mist_body_reader(request), 25 - max_body_size: 8_000_000, 26 - max_files_size: 32_000_000, 27 - read_chunk_size: 1_000_000, 28 - ) 46 + let connection = make_connection(mist_body_reader(request)) 29 47 request 30 48 |> request.set_body(connection) 31 49 |> service ··· 33 51 } 34 52 } 35 53 54 + fn make_connection(body_reader: Reader) -> Connection { 55 + Connection( 56 + reader: body_reader, 57 + max_body_size: 8_000_000, 58 + max_files_size: 32_000_000, 59 + read_chunk_size: 1_000_000, 60 + ) 61 + } 62 + 36 63 fn mist_body_reader(request: HttpRequest(mist.Connection)) -> Reader { 37 64 case mist.stream(request) { 38 65 Error(_) -> fn(_) { Ok(ReadingFinished) } ··· 67 94 // Responses 68 95 // 69 96 70 - pub type Body { 97 + pub type ResponseBody { 71 98 Empty 72 99 Text(StringBuilder) 73 100 } 74 101 75 - /// An alias for a HTTP response containing a `Body`. 102 + /// An alias for a HTTP response containing a `ResponseBody`. 76 103 pub type Response = 77 - HttpResponse(Body) 104 + HttpResponse(ResponseBody) 78 105 79 106 // TODO: test 80 107 // TODO: document ··· 120 147 121 148 // TODO: test 122 149 // TODO: document 123 - pub fn body_to_string_builder(body: Body) -> StringBuilder { 150 + pub fn body_to_string_builder(body: ResponseBody) -> StringBuilder { 124 151 case body { 125 152 Empty -> string_builder.new() 126 153 Text(text) -> text ··· 129 156 130 157 // TODO: test 131 158 // TODO: document 132 - pub fn body_to_bit_builder(body: Body) -> BitBuilder { 159 + pub fn body_to_bit_builder(body: ResponseBody) -> BitBuilder { 133 160 case body { 134 161 Empty -> bit_builder.new() 135 162 Text(text) -> bit_builder.from_string_builder(text) ··· 246 273 // TODO: document 247 274 // TODO: note you probably want a `require_` function 248 275 // TODO: note it'll hang if you call it twice 276 + // TODO: note it respects the max body size 249 277 fn read_entire_body(request: Request) -> Result(BitString, Nil) { 250 278 let connection = request.body 251 279 read_body_loop( ··· 298 326 Error(_) -> bad_request() 299 327 } 300 328 } 329 + 330 + // 331 + // Testing 332 + // 333 + 334 + // TODO: test 335 + // TODO: document 336 + pub fn test_connection(body: BitString) -> Connection { 337 + make_connection(fn(_size) { 338 + Ok(Chunk(body, fn(_size) { Ok(ReadingFinished) })) 339 + }) 340 + }