@@ -5,6 +5,7 @@ namespace FSharp.Data.GraphQL
55
66open  System 
77open  System.Collections .Generic  
8+ open  System.Collections .Immutable  
89open  System.Net .Http  
910open  System.Text  
1011open  System.Threading  
@@ -15,40 +16,42 @@ open FSharp.Data.GraphQL.Client
1516open  ReflectionPatterns 
1617
1718/// A requrest object for making GraphQL calls using the GraphQL client module. 
18- type  GraphQLRequest   = 
19-     {  /// Gets the URL of the GraphQL server which will be called. 
20- :  string 
21-       /// Gets custom HTTP Headers to pass with each call using this request. 
22- :  seq < string  *  string > 
23-       /// Gets the name of the operation that should run on the server. 
24- :  string option 
25-       /// Gets the query string which should be executed on the GraphQL server. 
26- :  string 
27-       /// Gets variables to be sent with the query. 
28- :  ( string  *  obj )   []   } 
19+ type  GraphQLRequest  =  { 
20+     /// Gets the URL of the GraphQL server which will be called. 
21+ :  string 
22+     /// Gets custom HTTP Headers to pass with each call using this request. 
23+ :  seq < string  *  string > 
24+     /// Gets the name of the operation that should run on the server. 
25+ :  string option 
26+     /// Gets the query string which should be executed on the GraphQL server. 
27+ :  string 
28+     /// Gets variables to be sent with the query. 
29+ :  ( string  *  obj )[] 
30+ } 
2931
3032/// Executes calls to GraphQL servers and return their responses. 
3133module  GraphQLClient  = 
3234
3335    let  private  ensureSuccessCode   ( response  :  Task < HttpResponseMessage >)  =  task  { 
3436        let!  response  =  response
35-         return  response.EnsureSuccessStatusCode() 
37+         return  response.EnsureSuccessStatusCode  () 
3638    } 
3739
3840    let  private  addHeaders   ( httpHeaders  :  seq < string  *  string >)  ( requestMessage  :  HttpRequestMessage )  = 
39-         if  not  ( isNull httpHeaders) 
40-         then  httpHeaders |>  Seq.iter ( fun   ( name ,  value )  -> ( name,  value)) 
41+         if  not  ( isNull httpHeaders)  then 
42+             httpHeaders
43+             |>  Seq.iter ( fun   ( name ,  value )  -> ( name,  value)) 
4144
4245    let  private  postAsync  ct  ( invoker  :  HttpMessageInvoker )  ( serverUrl  :  string )  ( httpHeaders  :  seq < string  *  string >)  ( content  :  HttpContent )  =  task  { 
43-         use  requestMessage =  new  HttpRequestMessage( HttpMethod.Post,  serverUrl) 
46+         use  requestMessage =  new  HttpRequestMessage  ( HttpMethod.Post,  serverUrl) 
4447        requestMessage.Content <-  content
4548        addHeaders httpHeaders requestMessage
46-         return !  invoker.SendAsync( requestMessage,  ct)  |>  ensureSuccessCode
49+         return !  invoker.SendAsync  ( requestMessage,  ct)  |>  ensureSuccessCode
4750    } 
4851
4952    let  private  getAsync  ct  ( invoker  :  HttpMessageInvoker )  ( serverUrl  :  string )  =  task  { 
50-         use  requestMessage =  new  HttpRequestMessage( HttpMethod.Get,  serverUrl) 
51-         return !  invoker.SendAsync( requestMessage,  ct)  |>  ensureSuccessCode
53+         use  requestMessage =  new  HttpRequestMessage  ( HttpMethod.Get,  serverUrl) 
54+         return !  invoker.SendAsync  ( requestMessage,  ct)  |>  ensureSuccessCode
5255    } 
5356
5457    /// Sends a request to a GraphQL server asynchronously. 
@@ -63,108 +66,129 @@ module GraphQLClient =
6366            |  Some x ->  JsonValue.String x
6467            |  None ->  JsonValue.Null
6568        let  requestJson  = 
66-             [|  " operationName" ,  operationName
67-                " query" ,  JsonValue.String request.Query
68-                " variables" ,  variables |] 
69+             [| 
70+                 " operationName" ,  operationName
71+                 " query" ,  JsonValue.String request.Query
72+                 " variables" ,  variables
73+             |] 
6974            |>  JsonValue.Record
70-         let  content  =  new  StringContent( requestJson.ToString(),  Encoding.UTF8,  " application/json" ) 
75+         let  content  =  new  StringContent  ( requestJson.ToString  (),  Encoding.UTF8,  " application/json" ) 
7176        return !  postAsync ct invoker request.ServerUrl request.HttpHeaders content
7277    } 
7378
7479    /// Sends a request to a GraphQL server. 
75- let  sendRequest  client request  =  ( sendRequestAsync CancellationToken.None client request) .GetAwaiter() .GetResult() 
80+ let  sendRequest  client request  = 
81+         ( sendRequestAsync CancellationToken.None client request) .GetAwaiter() .GetResult () 
7682
7783    /// Executes an introspection schema request to a GraphQL server asynchronously. 
7884let  sendIntrospectionRequestAsync  ct  ( connection  :  GraphQLClientConnection )  ( serverUrl  :  string )  httpHeaders  = 
79-         let  sendGet ()  =  getAsync ct connection.Invoker serverUrl
85+         let  sendGet   ()  =  getAsync ct connection.Invoker serverUrl
8086        let  rethrow   ( exns  :  exn list )  = 
8187            let rec  mapper   ( acc  :  string )  ( exns  :  exn list )  = 
8288                let  aggregateMapper   ( ex  :  AggregateException )  =  mapper " " ( List.ofSeq ex.InnerExceptions) 
8389                match  exns with 
84-                 |  []  ->  acc.TrimEnd() 
90+                 |  []  ->  acc.TrimEnd  () 
8591                |  ex ::  tail -> 
8692                    match  ex with 
8793                    |  :?  AggregateException as  ex ->  mapper ( acc +  aggregateMapper ex +  "  " )  tail
8894                    |  ex ->  mapper ( acc +  ex.Message +  "  " )  tail
8995            failwith $""" Failure trying to recover introspection schema from server at "%s %s """ 
9096        task  { 
91-             try  return !  sendGet() 
97+             try 
98+                 return !  sendGet () 
9299            with  getex -> 
93-                 let  request  = 
94-                     {  ServerUrl =  serverUrl
95-                       HttpHeaders =  httpHeaders
96-                       OperationName =  None
97-                       Query =  IntrospectionQuery.Definition
98-                       Variables =  [||]  } 
99-                 try  return !  sendRequestAsync ct connection request
100-                 with  postex ->  return  rethrow [ getex;  postex] 
100+                 let  request  =  { 
101+                     ServerUrl =  serverUrl
102+                     HttpHeaders =  httpHeaders
103+                     OperationName =  None
104+                     Query =  IntrospectionQuery.Definition
105+                     Variables =  [||] 
106+                 } 
107+                 try 
108+                     return !  sendRequestAsync ct connection request
109+                 with  postex -> 
110+                     return  rethrow [  getex;  postex ] 
101111        } 
102112
103113    /// Executes an introspection schema request to a GraphQL server. 
104114let  sendIntrospectionRequest  client serverUrl httpHeaders  = 
105-         ( sendIntrospectionRequestAsync CancellationToken.None client serverUrl httpHeaders) .GetAwaiter() .GetResult() 
115+         ( sendIntrospectionRequestAsync CancellationToken.None client serverUrl httpHeaders) .GetAwaiter() .GetResult  () 
106116
107117    /// Executes a multipart request to a GraphQL server asynchronously. 
108118let  sendMultipartRequestAsync  ct  ( connection  :  GraphQLClientConnection )  ( request  :  GraphQLRequest )  =  task  { 
109119        let  invoker  =  connection.Invoker
110-         let  boundary  =  " ----GraphQLProviderBoundary" +  ( Guid.NewGuid() .ToString( " N" )) 
111-         let  content  =  new  MultipartContent( " form-data" ,  boundary) 
120+         let  boundary  = 
121+             " ----GraphQLProviderBoundary" 
122+             +  ( Guid.NewGuid() .ToString ( " N" )) 
123+         let  content  =  new  MultipartContent ( " form-data" ,  boundary) 
112124        let  files  = 
113-             let rec  tryMapFileVariable   ( name :  string ,  value  :  obj )  = 
125+             let rec  tryMapFileVariable   ( name   :  string ,  value  :  obj )  = 
114126                match  value with 
115-                 |  null   |   : ?  string  ->  None 
116-                 |  : ? Upload as x   ->  Some   [| name ,  x |] 
117-                 |  OptionValue  x -> 
118-                      x |>  Option.bind ( fun  x  ->  tryMapFileVariable ( name,  x)) 
127+                 |  null 
128+                 |  : ? string   ->  None  
129+                 |  : ?  Upload as  x ->  Some  [|  name ,  x  |] 
130+                 |  OptionValue x  ->  x |>  Option.bind ( fun  x  ->  tryMapFileVariable ( name,  x)) 
119131                |  : ? IDictionary < string ,  obj >  as x  -> 
120-                     x |>  Seq.collect ( fun  kvp  ->  tryMapFileVariable ( name +  " ." +  ( kvp.Key.FirstCharLower()),  kvp.Value)  |>  Option.defaultValue [||]) 
121-                       |>  Array.ofSeq
122-                       |>  Some
132+                     x
133+                     |>  Seq.collect ( fun  kvp  -> 
134+                         tryMapFileVariable ( name +  " ." +  ( kvp.Key.FirstCharLower ()),  kvp.Value) 
135+                         |>  Option.defaultValue [||]) 
136+                     |>  Array.ofSeq
137+                     |>  Some
123138                |  EnumerableValue x -> 
124-                     x |>  Array.mapi ( fun  ix x  ->  tryMapFileVariable ( $" %s %i " ,  x)) 
125-                       |>  Array.collect ( Option.defaultValue [||]) 
126-                       |>  Some
139+                     x
140+                     |>  Array.mapi ( fun  ix x  ->  tryMapFileVariable ( $" %s %i " ,  x)) 
141+                     |>  Array.collect ( Option.defaultValue [||]) 
142+                     |>  Some
127143                |  _  ->  None
128-             request.Variables |>  Array.collect ( tryMapFileVariable >>  ( Option.defaultValue [||])) 
144+             request.Variables
145+             |>  Array.collect ( tryMapFileVariable >>  ( Option.defaultValue [||])) 
146+ 
129147        let  operationContent  = 
130148            let  variables  = 
131149                match  request.Variables with 
132-                 |  null  |  [||]  ->  JsonValue.Null
133-                 |  _  ->  request.Variables |>  Map.ofArray |>  Serialization.toJsonValue
150+                 |  null 
151+                 |  [||]  ->  JsonValue.Null
152+                 |  _  -> 
153+                     request.Variables
154+                     |>  Map.ofArray
155+                     |>  Serialization.toJsonValue
134156            let  operationName  = 
135157                match  request.OperationName with 
136158                |  Some x ->  JsonValue.String x
137159                |  None ->  JsonValue.Null
138160            let  json  = 
139-                 [|  " operationName" ,  operationName
140-                    " query" ,  JsonValue.String request.Query
141-                    " variables" ,  variables |] 
161+                 [| 
162+                     " operationName" ,  operationName
163+                     " query" ,  JsonValue.String request.Query
164+                     " variables" ,  variables
165+                 |] 
142166                |>  JsonValue.Record
143-             let  content  =  new  StringContent( json.ToString( JsonSaveOptions.DisableFormatting)) 
144-             content.Headers.Add( " Content-Disposition" ,  " form-data; name=\" operations\" " ) 
167+             let  content  =  new  StringContent  ( json.ToString  ( JsonSaveOptions.DisableFormatting)) 
168+             content.Headers.Add  ( " Content-Disposition" ,  " form-data; name=\" operations\" " ) 
145169            content
146-         content.Add( operationContent) 
170+         content.Add  ( operationContent) 
147171        let  mapContent  = 
148172            let  files  = 
149173                files
150-                 |>  Array.mapi ( fun  ix  ( name ,  _ )  -> (),  JsonValue.Array [|  JsonValue.String ( " variables." +  name)  |]) 
174+                 |>  Array.mapi ( fun  ix  ( name ,  _ )  ->   (),  JsonValue.Array [|  JsonValue.String ( " variables." +  name)  |]) 
151175                |>  JsonValue.Record
152-             let  content  =  new  StringContent( files.ToString( JsonSaveOptions.DisableFormatting)) 
153-             content.Headers.Add( " Content-Disposition" ,  " form-data; name=\" map\" " ) 
176+             let  content  =  new  StringContent  ( files.ToString  ( JsonSaveOptions.DisableFormatting)) 
177+             content.Headers.Add  ( " Content-Disposition" ,  " form-data; name=\" map\" " ) 
154178            content
155-         content.Add( mapContent) 
179+         content.Add  ( mapContent) 
156180        let  fileContents  = 
157181            files
158-             |>  Array .mapi ( fun  ix   ( _ ,  value )  -> 
159-                 let  content  =  new  StreamContent( value.Stream) 
160-                 content.Headers.Add( " Content-Disposition" ,  $" form-data; name=\" %i  {ix }\" ; filename=\" %s \" " ) 
161-                 content.Headers.Add( " Content-Type" ,  value.ContentType) 
182+             |>  Seq .mapi ( fun  _   ( _ ,  value )  -> 
183+                 let  content  =  new  StreamContent  ( value.Stream) 
184+                 content.Headers.Add  ( " Content-Disposition" ,  $" form-data; name=\" %s  {value.Name }\" ; filename=\" %s \" " ) 
185+                 content.Headers.Add  ( " Content-Type" ,  value.ContentType) 
162186                content) 
163-         fileContents |>  Array .iter content.Add
187+         fileContents |>  Seq .iter content.Add
164188        let!  result  =  postAsync ct invoker request.ServerUrl request.HttpHeaders content
165189        return  result
166190    } 
167191
168192    /// Executes a multipart request to a GraphQL server. 
169193let  sendMultipartRequest  connection request  = 
170-         ( sendMultipartRequestAsync CancellationToken.None connection request) .GetAwaiter() .GetResult() 
194+         ( sendMultipartRequestAsync CancellationToken.None connection request) .GetAwaiter() .GetResult  () 
0 commit comments