🧚 A practical web framework for Gleam

Update

+39 -43
+1 -1
.github/workflows/ci.yml
··· 14 14 - uses: erlef/setup-beam@v1 15 15 with: 16 16 otp-version: "26.0" 17 - gleam-version: "0.32.4" 17 + gleam-version: "0.34.0-rc2" 18 18 rebar3-version: "3" 19 19 # elixir-version: "1.14.2" 20 20 - run: gleam format --check src test
+1 -1
gleam.toml
··· 11 11 12 12 [dependencies] 13 13 exception = "~> 1.0" 14 - gleam_crypto = "~> 0.4" 14 + gleam_crypto = "~> 1.0" 15 15 gleam_erlang = "~> 0.21" 16 16 gleam_http = "~> 3.5" 17 17 gleam_json = "~> 0.6"
+10 -11
manifest.toml
··· 3 3 4 4 packages = [ 5 5 { name = "exception", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "5122A559032E971E060F0EB68FDCE5961506917D64612B4F7DD958B699BE4425" }, 6 - { name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" }, 7 - { name = "gleam_crypto", version = "0.5.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "B9F23F1902341FC94FA246FA21F11246665D9CE745D50CB3E719A16DA30AD569" }, 8 - { name = "gleam_erlang", version = "0.23.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "DA7A8E5540948DE10EB01B530869F8FF2FF6CAD8CFDA87626CE6EF63EBBF87CB" }, 9 - { name = "gleam_http", version = "3.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "0B09AAE8EB547C4F2F2D3F8917A0A4D2EF75DFF0232389332BAFE19DBBFDB92B" }, 6 + { name = "gleam_crypto", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "DE1FC4E631CA374AB29CCAEAC043EE171B86114D7DC66DD483F0A93BF0C4C6FF" }, 7 + { name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" }, 8 + { name = "gleam_http", version = "3.5.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "C2FC3322203B16F897C1818D9810F5DEFCE347F0751F3B44421E1261277A7373" }, 10 9 { name = "gleam_json", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "CB405BD93A8828BCD870463DE29375E7B2D252D9D124C109E5B618AAC00B86FC" }, 11 - { name = "gleam_otp", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "18EF8242A5E54BA92F717C7222F03B3228AEE00D1F286D4C56C3E8C18AA2588E" }, 12 - { name = "gleam_stdlib", version = "0.32.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "ABF00CDCCB66FABBCE351A50060964C4ACE798F95A0D78622C8A7DC838792577" }, 13 - { name = "gleeunit", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D3682ED8C5F9CAE1C928F2506DE91625588CC752495988CBE0F5653A42A6F334" }, 14 - { name = "glisten", version = "0.9.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "glisten", source = "hex", outer_checksum = "C960B6CF25D4AABAB01211146E9B57E11827B9C49E4175217E0FB7EF5BCB0FF7" }, 10 + { name = "gleam_otp", version = "0.9.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5FADBBEC5ECF3F8B6BE91101D432758503192AE2ADBAD5602158977341489F71" }, 11 + { name = "gleam_stdlib", version = "0.34.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1FB8454D2991E9B4C0C804544D8A9AD0F6184725E20D63C3155F0AEB4230B016" }, 12 + { name = "gleeunit", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D364C87AFEB26BDB4FB8A5ABDE67D635DC9FA52D6AB68416044C35B096C6882D" }, 13 + { name = "glisten", version = "0.9.2", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_erlang", "gleam_otp"], otp_app = "glisten", source = "hex", outer_checksum = "C960B6CF25D4AABAB01211146E9B57E11827B9C49E4175217E0FB7EF5BCB0FF7" }, 15 14 { name = "marceau", version = "1.1.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "1AAD727A30BE0F95562C3403BB9B27C823797AD90037714255EEBF617B1CDA81" }, 16 - { name = "mist", version = "0.14.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "glisten", "gleam_stdlib", "gleam_otp", "gleam_http"], otp_app = "mist", source = "hex", outer_checksum = "1AA0E3BB76A9B524800F31E1C94C4640FBB0890BC76B492DBAD541A392820BB3" }, 17 - { name = "simplifile", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0BD6F0E7DA1A7E11D18B8AD48453225CAFCA4C8CFB4513D217B372D2866C501C" }, 15 + { name = "mist", version = "0.15.0", build_tools = ["gleam"], requirements = ["gleam_otp", "gleam_erlang", "gleam_http", "gleam_stdlib", "glisten"], otp_app = "mist", source = "hex", outer_checksum = "49F51DDB64D7B2832F72727CC9721C478D6B524C96EA444C601A19D01E023C03" }, 16 + { name = "simplifile", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "359CD7006E2F69255025C858CCC6407C11A876EC179E6ED1E46809E8DC6B1AAD" }, 18 17 { name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" }, 19 18 ] 20 19 21 20 [requirements] 22 21 exception = { version = "~> 1.0" } 23 - gleam_crypto = { version = "~> 0.4" } 22 + gleam_crypto = { version = "~> 1.0" } 24 23 gleam_erlang = { version = "~> 0.21" } 25 24 gleam_http = { version = "~> 3.5" } 26 25 gleam_json = { version = "~> 0.6" }
+5 -5
src/wisp/internal/logger.gleam
··· 1 - import gleam/map.{type Map} 1 + import gleam/dict.{type Dict} 2 2 import gleam/erlang/atom.{type Atom} 3 3 import gleam/dynamic.{type Dynamic} 4 4 ··· 16 16 type DoNotLeak 17 17 18 18 pub fn configure_logger() -> Nil { 19 - update_primary_config(map.from_list([ 20 - #(atom.create_from_string("level"), dynamic.from(Info)), 21 - ])) 19 + update_primary_config( 20 + dict.from_list([#(atom.create_from_string("level"), dynamic.from(Info))]), 21 + ) 22 22 Nil 23 23 } 24 24 25 25 @external(erlang, "logger", "update_primary_config") 26 - fn update_primary_config(config: Map(Atom, Dynamic)) -> DoNotLeak 26 + fn update_primary_config(config: Dict(Atom, Dynamic)) -> DoNotLeak 27 27 28 28 pub fn log(level: LogLevel, message: String) -> Nil { 29 29 erlang_log(level, message)
+22 -25
test/wisp_test.gleam
··· 7 7 import gleam/http/response.{Response} 8 8 import gleam/int 9 9 import gleam/list 10 - import gleam/map 10 + import gleam/dict 11 11 import gleam/set 12 12 import gleam/string 13 13 import gleam/string_builder ··· 513 513 |> request.set_header("content-type", "application/json") 514 514 |> json_handler(fn(json) { 515 515 json 516 - |> should.equal(dynamic.from(map.from_list([#("one", 1), #("two", 2)]))) 516 + |> should.equal(dynamic.from(dict.from_list([#("one", 1), #("two", 2)]))) 517 517 }) 518 518 |> should.equal(wisp.ok()) 519 519 } ··· 678 678 } 679 679 680 680 pub fn multipart_form_files_too_big_test() { 681 - let test = fn(limit, callback) { 681 + let testcase = fn(limit, callback) { 682 682 "--theboundary\r 683 683 Content-Disposition: form-data; name=\"two\"; filename=\"file.txt\"\r 684 684 \r ··· 702 702 |> form_handler(callback) 703 703 } 704 704 705 - test(1, fn(_) { panic as "should be unreachable for limit of 1" }) 705 + testcase(1, fn(_) { panic as "should be unreachable for limit of 1" }) 706 706 |> should.equal(Response(413, [], wisp.Empty)) 707 707 708 - test(2, fn(_) { panic as "should be unreachable for limit of 2" }) 708 + testcase(2, fn(_) { panic as "should be unreachable for limit of 2" }) 709 709 |> should.equal(Response(413, [], wisp.Empty)) 710 710 711 - test(3, fn(_) { panic as "should be unreachable for limit of 3" }) 711 + testcase(3, fn(_) { panic as "should be unreachable for limit of 3" }) 712 712 |> should.equal(Response(413, [], wisp.Empty)) 713 713 714 - test(4, fn(_) { Nil }) 714 + testcase(4, fn(_) { Nil }) 715 715 |> should.equal(Response(200, [], wisp.Empty)) 716 716 } 717 717 ··· 944 944 945 945 pub fn get_cookie_test() { 946 946 let request = 947 - testing.get( 948 - "/", 949 - [ 950 - // Plain text 951 - #("cookie", "plain=MTIz"), 952 - // Signed 953 - #( 954 - "cookie", 955 - "signed=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wA", 956 - ), 957 - // Signed but tampered with 958 - #( 959 - "cookie", 960 - "signed-and-tampered-with=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wAA", 961 - ), 962 - ], 963 - ) 947 + testing.get("/", [ 948 + // Plain text 949 + #("cookie", "plain=MTIz"), 950 + // Signed 951 + #( 952 + "cookie", 953 + "signed=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wA", 954 + ), 955 + // Signed but tampered with 956 + #( 957 + "cookie", 958 + "signed-and-tampered-with=SFM1MTI.aGktdGhlcmU.uWUWvrAleKQ2jsWcU97HzGgPqtLjjUgl4oe40-RPJ5qRRcE_soXPacgmaHTLxK3xZbOJ5DOTIRMI0szD4Re7wAA", 959 + ), 960 + ]) 964 961 965 962 request 966 963 |> wisp.get_cookie("plain", wisp.PlainText) ··· 996 993 pub fn cookie_sign_roundtrip_test() { 997 994 use _ <- list.each(list.repeat(1, 10_000)) 998 995 let message = 999 - <<int.to_string(int.random(0, 1_000_000_000_000_000)):utf8>> 996 + <<int.to_string(int.random(1_000_000_000_000_000)):utf8>> 1000 997 |> bit_array.base64_encode(True) 1001 998 let req = testing.get("/", []) 1002 999 let signed = wisp.sign_message(req, <<message:utf8>>, crypto.Sha512)