/
typenames.cljs
50 lines (40 loc) · 2.32 KB
/
typenames.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
(ns district.ui.graphql.middleware.typenames
(:require
[district.ui.graphql.utils :as utils]))
(def visit (aget js/GraphQL "visit"))
(def gql-sync (aget js/GraphQL "graphqlSync"))
(def print-str-graphql (aget js/GraphQL "print"))
(defn- field-resolver [root-value args context info]
(let [return-type (aget info "returnType")]
(cond
(and (instance? (aget js/GraphQL "GraphQLObjectType") return-type))
(js/Object.)
(and (instance? (aget js/GraphQL "GraphQLList") return-type)
(instance? (aget js/GraphQL "GraphQLObjectType") (aget return-type "ofType")))
;; TODO QUESTION How do I know here if I'll be resolving to empty or not
;; since we don't know what resolver will apply
(js/Array. (js/Object.))
:else nil)))
(defn typenames-middleware [{:keys [:query :schema :variables :kw->gql-name]}]
(let [typename-field (clj->js (utils/create-field-node "__typename"))
typenames-query (visit query
#js {:leave (fn [node key parent path ancestors]
(condp = (aget node "kind")
"Field"
(if (and (not (contains? #{"OperationDefinition" "FragmentDefinition"}
(aget parent "kind")))
(and (aget node "selectionSet")
(seq (aget node "selectionSet" "selections"))))
(do
(let [node (clj->js (js->clj node))] ;; deep clone ¯\_(ツ)_/¯
(.push (aget node "selectionSet" "selections") typename-field)
node))
js/undefined)
js/undefined))})]
{:response (-> (gql-sync schema
(print-str-graphql typenames-query)
nil
nil
(clj->js variables)
nil
field-resolver))}))