Fork me on GitHub
#om
<
2018-04-20
>
souenzzo14:04:27

A name and a spec. I think I can write one.

danielstockton15:04:27

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))))

👍 4