8
8
9
9
#[ macro_use]
10
10
pub extern crate graphql_client;
11
+ extern crate js_sys;
11
12
#[ macro_use]
12
13
extern crate wasm_bindgen;
13
14
14
- pub use graphql_client:: GraphQLQuery ;
15
15
use failure:: * ;
16
16
use futures:: { Future , IntoFuture } ;
17
+ pub use graphql_client:: GraphQLQuery ;
17
18
use log:: * ;
18
19
use std:: collections:: HashMap ;
19
- use wasm_bindgen_futures:: JsFuture ;
20
20
use wasm_bindgen:: { JsCast , JsValue } ;
21
+ use wasm_bindgen_futures:: JsFuture ;
21
22
22
23
/// The main interface to the library.
23
24
///
@@ -34,15 +35,15 @@ pub struct Client {
34
35
/// All the ways a request can go wrong.
35
36
///
36
37
/// not exhaustive
37
- #[ derive( Debug , Fail ) ]
38
+ #[ derive( Debug , Fail , PartialEq ) ]
38
39
#[ non_exhaustive]
39
40
pub enum ClientError {
40
41
/// The body couldn't be built
41
42
#[ fail( display = "Request body is not a valid string" ) ]
42
43
Body ,
43
44
/// An error caused by window.fetch
44
45
#[ fail( display = "Network error" ) ]
45
- Network ,
46
+ Network ( String ) ,
46
47
/// Error in a dynamic JS cast that should have worked
47
48
#[ fail( display = "JS casting error" ) ]
48
49
Cast ,
@@ -52,13 +53,13 @@ pub enum ClientError {
52
53
) ]
53
54
NoWindow ,
54
55
/// Response shape does not match the generated code
55
- #[ fail( display = "Response shape error" , ) ]
56
+ #[ fail( display = "Response shape error" ) ]
56
57
ResponseShape ,
57
58
/// Response could not be converted to text
58
59
#[ fail( display = "Response conversion to text failed (Response.text threw)" ) ]
59
60
ResponseText ,
60
61
/// Exception thrown when building the request
61
- #[ fail( display = "Error building the request" , ) ]
62
+ #[ fail( display = "Error building the request" ) ]
62
63
RequestError ,
63
64
/// Other JS exception
64
65
#[ fail( display = "Unexpected JS exception" ) ]
@@ -73,9 +74,15 @@ impl Client {
73
74
{
74
75
Client {
75
76
endpoint : endpoint. into ( ) ,
77
+ headers : HashMap :: new ( ) ,
76
78
}
77
79
}
78
80
81
+ /// Add a header to those sent with the requests. Can be used for things like authorization.
82
+ pub fn add_header ( & mut self , name : & str , value : & str ) {
83
+ self . headers . insert ( name. into ( ) , value. into ( ) ) ;
84
+ }
85
+
79
86
/// Perform a query.
80
87
pub fn call < Q : GraphQLQuery + ' static > (
81
88
& self ,
@@ -93,7 +100,8 @@ impl Client {
93
100
serde_json:: to_string ( & Q :: build_query ( variables) )
94
101
. map_err ( |_| ClientError :: Body )
95
102
. map ( move |body| ( window, body) )
96
- } ) . and_then ( move |( window, body) | {
103
+ } )
104
+ . and_then ( move |( window, body) | {
97
105
let mut request_init = web_sys:: RequestInit :: new ( ) ;
98
106
request_init
99
107
. method ( "POST" )
@@ -103,7 +111,8 @@ impl Client {
103
111
. map_err ( |_| ClientError :: JsException )
104
112
. map ( |request| ( window, request) )
105
113
// "Request constructor threw");
106
- } ) . and_then ( move |( window, request) | {
114
+ } )
115
+ . and_then ( move |( window, request) | {
107
116
let request: Result < web_sys:: Request , _ > = request
108
117
. headers ( )
109
118
. set ( "Content-Type" , "application/json" )
@@ -118,18 +127,23 @@ impl Client {
118
127
} ) ;
119
128
120
129
request. map ( move |request| ( window, request) )
121
- } ) . and_then ( move |( window, request) | {
130
+ } )
131
+ . and_then ( move |( window, request) | {
122
132
JsFuture :: from ( window. fetch_with_request ( & request) )
123
- . map_err ( |_| ClientError :: Network )
124
- } ) . and_then ( move |res| {
133
+ . map_err ( |err| ClientError :: Network ( js_sys:: Error :: from ( err) . message ( ) . into ( ) ) )
134
+ } )
135
+ . and_then ( move |res| {
125
136
debug ! ( "response: {:?}" , res) ;
126
137
res. dyn_into :: < web_sys:: Response > ( )
127
138
. map_err ( |_| ClientError :: Cast )
128
- } ) . and_then ( move |cast_response| {
139
+ } )
140
+ . and_then ( move |cast_response| {
129
141
cast_response. text ( ) . map_err ( |_| ClientError :: ResponseText )
130
- } ) . and_then ( move |text_promise| {
142
+ } )
143
+ . and_then ( move |text_promise| {
131
144
JsFuture :: from ( text_promise) . map_err ( |_| ClientError :: ResponseText )
132
- } ) . and_then ( |text| {
145
+ } )
146
+ . and_then ( |text| {
133
147
let response_text = text. as_string ( ) . unwrap_or_else ( || String :: new ( ) ) ;
134
148
debug ! ( "response text as string: {:?}" , response_text) ;
135
149
serde_json:: from_str ( & response_text) . map_err ( |_| ClientError :: ResponseShape )
0 commit comments