git.iko.soy/rowtype-yoga/purescript-fetch
on main help sign in
Make response headers a map
bd6537dsigma-andex
CHANGELOG.md+1
@@ -5,6 +5,7 @@ Notable changes to this project are documented in this file. The format is based
5## [Unreleased]
5## [Unreleased]
6
6
7Breaking changes:
7Breaking changes:
8+- Switch response headers to `Map CaseInsensitiveString String`
8
9
9New features:
10New features:
10Bugfixes:
11Bugfixes:
spago.dhall+3
@@ -3,11 +3,14 @@
3 [ "aff"
3 [ "aff"
4 , "aff-promise"
4 , "aff-promise"
5 , "arraybuffer-types"
5 , "arraybuffer-types"
6+ , "bifunctors"
6 , "effect"
7 , "effect"
7 , "fetch-core"
8 , "fetch-core"
8 , "foreign"
9 , "foreign"
9 , "http-methods"
10 , "http-methods"
11+ , "maybe"
10 , "newtype"
12 , "newtype"
13+ , "ordered-collections"
11 , "prelude"
14 , "prelude"
12 , "record"
15 , "record"
13 , "typelevel-prelude"
16 , "typelevel-prelude"
src/Fetch.purs+2
@@ -10,6 +10,7 @@ module Fetch
10 , module Fetch.Internal.Request
10 , module Fetch.Internal.Request
11 , module Fetch.Internal.RequestBody
11 , module Fetch.Internal.RequestBody
12 , module Fetch.Internal.Response
12 , module Fetch.Internal.Response
13+ , module Fetch.Internal.Headers
13 ) where
14 ) where
14
15
15import Prelude
16import Prelude
@@ -27,6 +28,7 @@ import Fetch.Core.RequestCredentials (RequestCredentials(Omit, Include))
27import Fetch.Core.RequestMode (RequestMode(Cors, NoCors, Navigate))
28import Fetch.Core.RequestMode (RequestMode(Cors, NoCors, Navigate))
28import Fetch.Internal.Request (class ToCoreRequestOptions, class ToCoreRequestOptionsConverter, class ToCoreRequestOptionsHelper, HighlevelRequestOptions, convertHelper, convertImpl, new)
29import Fetch.Internal.Request (class ToCoreRequestOptions, class ToCoreRequestOptionsConverter, class ToCoreRequestOptionsHelper, HighlevelRequestOptions, convertHelper, convertImpl, new)
29import Fetch.Internal.Request as Request
30import Fetch.Internal.Request as Request
31+import Fetch.Internal.Headers (lookup, toHeaders, contains)
30import Fetch.Internal.RequestBody (class ToRequestBody, toRequestBody)
32import Fetch.Internal.RequestBody (class ToRequestBody, toRequestBody)
31import Fetch.Internal.Response (Response, ResponseR, arrayBuffer, blob, body, json, promiseToPromise, text)
33import Fetch.Internal.Response (Response, ResponseR, arrayBuffer, blob, body, json, promiseToPromise, text)
32import Fetch.Internal.Response as Response
34import 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
15import Control.Promise as Control
15import Control.Promise as Control
16import Control.Promise as Promise
16import Control.Promise as Promise
17import Data.ArrayBuffer.Types (ArrayBuffer, Uint8Array)
17import Data.ArrayBuffer.Types (ArrayBuffer, Uint8Array)
18+import Data.Bifunctor (lmap)
19+import Data.Map as Map
20+import Data.String.CaseInsensitive (CaseInsensitiveString(..))
18import Effect (Effect)
21import Effect (Effect)
19import Effect.Aff (Aff)
22import Effect.Aff (Aff)
20−import Fetch.Core.Headers (Headers)
23+import Fetch.Core.Headers as CoreHeaders
21import Fetch.Core.Response as CoreResponse
24import Fetch.Core.Response as CoreResponse
25+import Fetch.Internal.Headers (toHeaders)
22import Foreign (Foreign)
26import Foreign (Foreign)
23import Unsafe.Coerce (unsafeCoerce)
27import Unsafe.Coerce (unsafeCoerce)
24import Web.File.Blob (Blob)
28import Web.File.Blob (Blob)
@@ -26,7 +30,7 @@ import Web.Promise as Web
26import Web.Streams.ReadableStream (ReadableStream)
30import Web.Streams.ReadableStream (ReadableStream)
27
31
28type ResponseR =
32type ResponseR =
29− ( headers :: Headers
33+ ( headers :: Map.Map CaseInsensitiveString String
30 , ok :: Boolean
34 , ok :: Boolean
31 , redirected :: Boolean
35 , redirected :: Boolean
32 , status :: Int
36 , status :: Int
@@ -63,7 +67,7 @@ promiseToPromise = unsafeCoerce
63
67
64convert :: CoreResponse.Response -> Response
68convert :: CoreResponse.Response -> Response
65convert response =
69convert response =
66− { headers: CoreResponse.headers response
70+ { headers: CoreResponse.headers response # toHeaders
67 , ok: CoreResponse.ok response
71 , ok: CoreResponse.ok response
68 , redirected: CoreResponse.redirected response
72 , redirected: CoreResponse.redirected response
69 , status: CoreResponse.status response
73 , status: CoreResponse.status response
test/Test/FetchSpec.purs+14
@@ -3,7 +3,9 @@ module Test.FetchSpec where
3import Prelude
3import Prelude
4
4
5import Data.ArrayBuffer.Types (Uint8Array)
5import Data.ArrayBuffer.Types (Uint8Array)
6+import Data.Maybe (Maybe(..))
6import Fetch (Method(..), Referrer(..), RequestMode(..), fetch, fetchBody)
7import Fetch (Method(..), Referrer(..), RequestMode(..), fetch, fetchBody)
8+import Fetch as Fetch
7import Foreign (unsafeFromForeign)
9import Foreign (unsafeFromForeign)
8import Test.Spec (Spec, describe, it)
10import Test.Spec (Spec, describe, it)
9import Test.Spec.Assertions (shouldEqual)
11import Test.Spec.Assertions (shouldEqual)
@@ -49,3 +51,15 @@ spec =
49 { json: j } <- json <#> unsafeFromForeign
51 { json: j } <- json <#> unsafeFromForeign
50 j `shouldEqual` { hello: "world" }
52 j `shouldEqual` { hello: "world" }
51 status `shouldEqual` 200
53 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