git.iko.soy/rowtype-yoga/purescript-fetch
on main help sign in
Make response headers a map
commitbd6537df1c2653b1fcc97bd5d8731f6783730acf authorsigma-andex <77549848+sigma-andex@users.noreply.github.com> dateSat 27 Aug 2022, 11:54 (4 years ago) parentc3a2fb8
6 files changed+49−3
CHANGELOG.md+1 spago.dhall+3 src/Fetch.purs+2 src/Fetch/Internal/Headers.purs+22 src/Fetch/Internal/Response.purs+7−3 test/Test/FetchSpec.purs+14
CHANGELOG.md+1
@@ -5,6 +5,7 @@ Notable changes to this project are documented in this file. The format is based
55## [Unreleased]
66
77Breaking changes:
8+- Switch response headers to `Map CaseInsensitiveString String`
89
910New features:
1011Bugfixes:
spago.dhall+3
@@ -3,11 +3,14 @@
33 [ "aff"
44 , "aff-promise"
55 , "arraybuffer-types"
6+ , "bifunctors"
67 , "effect"
78 , "fetch-core"
89 , "foreign"
910 , "http-methods"
11+ , "maybe"
1012 , "newtype"
13+ , "ordered-collections"
1114 , "prelude"
1215 , "record"
1316 , "typelevel-prelude"
src/Fetch.purs+2
@@ -10,6 +10,7 @@ module Fetch
1010 , module Fetch.Internal.Request
1111 , module Fetch.Internal.RequestBody
1212 , module Fetch.Internal.Response
13+ , module Fetch.Internal.Headers
1314 ) where
1415
1516import Prelude
@@ -27,6 +28,7 @@ import Fetch.Core.RequestCredentials (RequestCredentials(Omit, Include))
2728import Fetch.Core.RequestMode (RequestMode(Cors, NoCors, Navigate))
2829import Fetch.Internal.Request (class ToCoreRequestOptions, class ToCoreRequestOptionsConverter, class ToCoreRequestOptionsHelper, HighlevelRequestOptions, convertHelper, convertImpl, new)
2930import Fetch.Internal.Request as Request
31+import Fetch.Internal.Headers (lookup, toHeaders, contains)
3032import Fetch.Internal.RequestBody (class ToRequestBody, toRequestBody)
3133import Fetch.Internal.Response (Response, ResponseR, arrayBuffer, blob, body, json, promiseToPromise, text)
3234import Fetch.Internal.Response as Response
src/Fetch/Internal/Headers.pursnew file+22
@@ -0,0 +1,22 @@
1+module Fetch.Internal.Headers
2+ ( contains
3+ , lookup
4+ , toHeaders
5+ ) where
6+
7+import Prelude
8+
9+import Data.Bifunctor (lmap)
10+import Data.Map as Map
11+import Data.Maybe (Maybe)
12+import Data.String.CaseInsensitive (CaseInsensitiveString(..))
13+import Fetch.Core.Headers as CoreHeaders
14+
15+toHeaders :: CoreHeaders.Headers -> Map.Map CaseInsensitiveString String
16+toHeaders = CoreHeaders.toArray >>> map (lmap CaseInsensitiveString) >>> Map.fromFoldable
17+
18+lookup :: String -> Map.Map CaseInsensitiveString String -> Maybe String
19+lookup key headers = Map.lookup (CaseInsensitiveString key) headers
20+
21+contains ∷ String → Map.Map CaseInsensitiveString String → Boolean
22+contains key headers = Map.member (CaseInsensitiveString key) headers
src/Fetch/Internal/Response.purs+7−3
@@ -15,10 +15,14 @@ import Prelude
1515import Control.Promise as Control
1616import Control.Promise as Promise
1717import Data.ArrayBuffer.Types (ArrayBuffer, Uint8Array)
18+import Data.Bifunctor (lmap)
19+import Data.Map as Map
20+import Data.String.CaseInsensitive (CaseInsensitiveString(..))
1821import Effect (Effect)
1922import Effect.Aff (Aff)
20−import Fetch.Core.Headers (Headers)
23+import Fetch.Core.Headers as CoreHeaders
2124import Fetch.Core.Response as CoreResponse
25+import Fetch.Internal.Headers (toHeaders)
2226import Foreign (Foreign)
2327import Unsafe.Coerce (unsafeCoerce)
2428import Web.File.Blob (Blob)
@@ -26,7 +30,7 @@ import Web.Promise as Web
2630import Web.Streams.ReadableStream (ReadableStream)
2731
2832type ResponseR =
29− ( headers :: Headers
33+ ( headers :: Map.Map CaseInsensitiveString String
3034 , ok :: Boolean
3135 , redirected :: Boolean
3236 , status :: Int
@@ -63,7 +67,7 @@ promiseToPromise = unsafeCoerce
6367
6468convert :: CoreResponse.Response -> Response
6569convert response =
66− { headers: CoreResponse.headers response
70+ { headers: CoreResponse.headers response # toHeaders
6771 , ok: CoreResponse.ok response
6872 , redirected: CoreResponse.redirected response
6973 , status: CoreResponse.status response
test/Test/FetchSpec.purs+14
@@ -3,7 +3,9 @@ module Test.FetchSpec where
33import Prelude
44
55import Data.ArrayBuffer.Types (Uint8Array)
6+import Data.Maybe (Maybe(..))
67import Fetch (Method(..), Referrer(..), RequestMode(..), fetch, fetchBody)
8+import Fetch as Fetch
79import Foreign (unsafeFromForeign)
810import Test.Spec (Spec, describe, it)
911import Test.Spec.Assertions (shouldEqual)
@@ -49,3 +51,15 @@ spec =
4951 { json: j } <- json <#> unsafeFromForeign
5052 j `shouldEqual` { hello: "world" }
5153 status `shouldEqual` 200
54+
55+ it "should retrieve correct headers" do
56+
57+ { status, headers } <- fetch "https://httpbin.org/post"
58+ { method: POST
59+ , body: """{"hello":"world"}"""
60+ , headers: { "Content-Type": "application/json" }
61+ }
62+ Fetch.lookup "Access-Control-Allow-Origin" headers `shouldEqual` Just "*"
63+ Fetch.lookup "Content-Type" headers `shouldEqual` Just "application/json"
64+ Fetch.contains "Content-Length" headers `shouldEqual` true
65+ status `shouldEqual` 200