33module  FSharp.Data.GraphQL.Server.Middleware.SchemaDefinitions 
44
55open  System 
6- open  System.Collections .Generic  
7- open  System.Collections .Immutable  
8- open  System.Text .Json  
96open  FSharp.Data .GraphQL  
107open  FSharp.Data .GraphQL .Types  
118open  FSharp.Data .GraphQL .Ast  
@@ -22,7 +19,7 @@ type private ComparisonOperator =
2219    |  LessThanOrEqual of  string 
2320    |  In of  string 
2421
25- let rec  private  coerceObjectListFilterInput  x   :  Result < ObjectListFilter  voption ,  IGQLError  list >  = 
22+ let rec  private  coerceObjectListFilterInput   ( variables  :   Variables )   inputValue  :  Result < ObjectListFilter  voption ,  IGQLError  list >  = 
2623
2724    let  parseFieldCondition   ( s  :  string )  = 
2825        let  s  =  s.ToLowerInvariant () 
@@ -81,17 +78,17 @@ let rec private coerceObjectListFilterInput x : Result<ObjectListFilter voption,
8178                |  ValueSome acc ->  build ( ValueSome ( Or ( acc,  x)))  xs
8279        build ValueNone x
8380
84-     let rec  mapFilter   ( name  :  string ,   value  :  InputValue )  = 
81+     let rec  mapFilter   ( condition  :  ComparisonOperator )   ( value  :  InputValue )  = 
8582        let  mapFilters  fields  = 
8683            let  coerceResults  = 
8784                fields
88-                 |>  Seq.map coerceObjectListFilterInput
85+                 |>  Seq.map ( coerceObjectListFilterInput variables ) 
8986                |>  Seq.toList
9087                |>  splitSeqErrorsList
9188            match  coerceResults with 
9289            |  Error errs ->  Error errs
9390            |  Ok coerced ->  coerced |>  Seq.vchoose id |>  Seq.toList |>  Ok
94-         match  parseFieldCondition name ,  value with 
91+         match  condition ,  value with 
9592        |  Equals " and" ,  ListValue fields ->  fields |>  mapFilters |>  Result.map buildAnd
9693        |  Equals " or" ,  ListValue fields ->  fields |>  mapFilters |>  Result.map buildOr
9794        |  Equals " not" ,  ObjectValue value -> 
@@ -126,76 +123,58 @@ let rec private coerceObjectListFilterInput x : Result<ObjectListFilter voption,
126123                |>  splitSeqErrors
127124            return  ValueSome ( ObjectListFilter.In {  FieldName =  fname;  Value =  parsedValues |>  Array.toList }) 
128125          } 
126+         |  condition,  VariableName variableName -> 
127+             match  variables.TryGetValue variableName with 
128+             |  true ,  value ->  mapFilter condition ( value |>  InputValue.OfObject) 
129+             |  false ,  _  ->  Errors.Variables.getVariableNotFoundError variableName
129130        |  _  ->  Ok ValueNone
130131
131132    and  mapInput  value  = 
132133        let  filterResults  = 
133134            value
134-             |>  Map.toSeq
135-             |>  Seq.map mapFilter
135+             |>  Seq.map ( fun  kvp  ->  mapFilter ( parseFieldCondition kvp.Key)  kvp.Value) 
136136            |>  Seq.toList
137137            |>  splitSeqErrorsList
138138        match  filterResults with 
139139        |  Error errs ->  Error errs
140140        |  Ok filters ->  filters |>  Seq.vchoose id |>  List.ofSeq |>  buildAnd |>  Ok
141141
142-     match  x with 
143-     |  ObjectValue x ->  mapInput x
144-     |  NullValue ->  ValueNone |>  Ok
145-     // TODO: Get union case 
146-     |  _  -> 
147-         Error [ 
148-             {  new  IGQLError with 
149-                 member  _.Message  =  $" 'ObjectListFilter' must be defined as object but got '{x.GetType ()}'" 
150-             } 
151-         ] 
142+     let rec  parse  inputValue  = 
143+         match  inputValue with 
144+         |  ObjectValue x ->  mapInput x
145+         |  NullValue ->  ValueNone |>  Ok
146+         |  VariableName variableName -> 
147+             match  variables.TryGetValue variableName with 
148+             |  true ,  (:?  ObjectListFilter as  filter)  ->  ValueSome filter |>  Ok
149+             |  true ,  value -> 
150+                 System.Diagnostics.Debug.Fail " We expect the root value is parsed into ObjectListFilter" 
151+                 value |>  InputValue.OfObject |>  parse
152+             |  false ,  _  ->  Errors.Variables.getVariableNotFoundError variableName
153+         // TODO: Get union case 
154+         |  _  -> 
155+             Error [ 
156+                 {  new  IGQLError with 
157+                     member  _.Message  =  $" 'ObjectListFilter' must be defined as object but got '{inputValue.GetType ()}'" 
158+                 } 
159+             ] 
160+     parse inputValue
152161
153- let  private  coerceObjectListFilterValue   ( x  :  obj )  :  ObjectListFilter option  = 
154-     match  x with 
155-     |  :?  ObjectListFilter as  x ->  Some x
156-     |  _  ->  None
157- //let private coerceObjectListFilterValue (x : obj) = 
158- //    match x with 
159- //    | :? ObjectListFilter as x -> Ok x 
160- //    | _ -> Error [{ new IGQLError with member _.Message = $"Cannot coerce ObjectListFilter output. '%s{x.GetType().FullName}' is not 'ObjectListFilter'" }] 
161- 
162- // TODO: Move to shared and make public 
163- let rec  private  jsonElementToInputValue   ( element  :  JsonElement )  = 
164-     match  element.ValueKind with 
165-     |  JsonValueKind.Null ->  NullValue
166-     |  JsonValueKind.True ->  BooleanValue true 
167-     |  JsonValueKind.False ->  BooleanValue false 
168-     |  JsonValueKind.String ->  StringValue ( element.GetString ()) 
169-     |  JsonValueKind.Number ->  FloatValue ( element.GetDouble ()) 
170-     |  JsonValueKind.Array -> 
171-         ListValue ( 
172-             element.EnumerateArray () 
173-             |>  Seq.map jsonElementToInputValue
174-             |>  List.ofSeq
175-         ) 
176-     |  JsonValueKind.Object -> 
177-         ObjectValue ( 
178-             element.EnumerateObject () 
179-             |>  Seq.map ( fun  p  ->  p.Name,  jsonElementToInputValue p.Value) 
180-             |>  Map.ofSeq
181-         ) 
182-     |  _  ->  raise ( NotSupportedException " Unsupported JSON element type" ) 
183162
184163/// Defines an object list filter for use as an argument for filter list of object fields. 
185- let  ObjectListFilterType   :  ScalarDefinition < ObjectListFilter >  =  { 
164+ let  ObjectListFilterType   :  InputCustomDefinition < ObjectListFilter >  =  { 
186165    Name =  " ObjectListFilter" 
187166    Description = 
188167        Some
189168            " The `Filter` scalar type represents a filter on one or more fields of an object in an object list. The filter is represented by a JSON object where the fields are the complemented by specific suffixes to represent a query." 
190169    CoerceInput = 
191-         ( function 
192-         |  InlineConstant c  -> 
193-             coerceObjectListFilterInput c 
194-             |>  Result.map ValueOption.toObj 
195-         |  Variable json  -> 
196-             json
197-             |>  jsonElementToInputValue 
198-             |>  coerceObjectListFilterInput 
199-             |>  Result.map ValueOption.toObj ) 
200-     CoerceOutput  =  coerceObjectListFilterValue 
170+         ( fun  input variables  -> 
171+              match  input  with 
172+             |  InlineConstant c  -> 
173+                  ( coerceObjectListFilterInput variables c ) 
174+                  |>  Result.map ValueOption.toObj 
175+             |  Variable  json  -> 
176+                 json 
177+                  |>  InputValue.OfJsonElement 
178+                  |>  ( coerceObjectListFilterInput variables ) 
179+                  |>  Result.map ValueOption.toObj ) 
201180} 
0 commit comments