A name and a spec. I think I can write one.
I came up with this spec. Might be a start.
(s/def ::ident (s/and vector? (s/tuple keyword? #(not (coll? %)))))
(s/def ::join-key (s/or :prop keyword? :ident ::ident))
(s/def ::join (s/map-of ::join-key ::query :conform-keys true))
(s/def ::union (s/map-of keyword? (s/map-of keyword? ::query)))
(s/def ::param-expr
(s/cat :query-expr ::query-expr
:params map?))
(s/def ::mutation-expr
(s/or :no-params (s/cat :mutate-key symbol?)
:with-params (s/cat :mutate-key symbol?
:params map?)))
(s/def ::query-expr
(s/or :prop keyword?
:ident ::ident
:mutation-expr ::mutation-expr
:union ::union
:join ::join
:param-expr ::param-expr))
(defn query-conform [x]
(if (vector? x) x :clojure.spec/invalid))
(s/def ::query
(s/or :recursion (s/or :depth number?
:unbounded #(= % '...))
:query (s/and (s/conformer query-conform vec)
(s/+ ::query-expr))))
@danielstockton @souenzzo there is a fully working spec and generators available in pathom: https://github.com/wilkerlucio/pathom/blob/master/src/com/wsscode/pathom/specs/query.cljc