Files
integreat/src/cljs/auto_ap/effects.cljs
2018-05-11 17:23:17 -07:00

148 lines
4.3 KiB
Clojure

(ns auto-ap.effects
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [re-frame.core :as re-frame]
[cljs-http.client :as http]
[cljs-time.coerce :as c]
[cljs-time.core :as time]
[cljs-time.format :as format]
[cljs.core.async :refer [<! ] :as async]
[clojure.string :as str]
[clojure.walk :as walk]
[venia.core :as v]
[auto-ap.history :as p]
[pushy.core :as pushy]))
(re-frame/reg-fx
:redirect
(fn [uri]
(pushy/set-token! p/history uri)))
(re-frame/reg-fx
:new-window
(fn [url]
(.open js/window url)))
(re-frame/reg-fx
:set-local-storage
(fn [[name value]]
(if value
(.setItem js/localStorage name value)
(.removeItem js/localStorage name ))))
;; 2017-09-19T07:00:00.000Z
(def is-8601 #"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$")
(defn dates->date-times [x]
(walk/postwalk
(fn [node]
(cond
(and (string? node)
(re-matches is-8601 node))
(format/parse (format/formatters :date-time) node)
(instance? js/Date node)
(time/to-default-time-zone (c/from-date node))
:else
node))
x))
(re-frame/reg-fx
:http
(fn [{:keys [method uri on-success on-error body headers token]}]
(go
(let [headers (if token
(assoc headers "Authorization" (str "Token " token))
headers)
response (<! (http/request {:method method
:body body
:headers headers
:url uri}))]
(if (>= (:status response) 400)
(when on-error
(->> response
:body
(dates->date-times)
(conj on-error)
(re-frame/dispatch)))
(->> response
:body
(dates->date-times)
(conj on-success)
(re-frame/dispatch)))))))
(re-frame/reg-fx
:https
(fn [{:keys [requests on-success on-failure]}]
(go
(let [results (->>
(for [{:keys [method body headers uri token]} requests]
(go
(let [headers (if token
(assoc headers "Authorization" (str "Token " token))
headers)
response (<! (http/request {:method method
:body body
:headers headers
:url uri}))]
(if (>= (:status response) 400)
:error
:success))))
(async/merge)
(async/reduce conj [])
(async/<!))]
(if (some #{:error} results)
(re-frame/dispatch on-failure)
(re-frame/dispatch on-success))))))
(defn kebab->snake [s]
(str/replace s #"-" "_"))
(defn snake [x]
(if (namespace x)
(keyword (namespace x) (kebab->snake (name x)))
(keyword (kebab->snake (name x)))))
(defn ->graphql [m]
(walk/postwalk
(fn [node]
(cond
(keyword? node)
(snake node)
:else
node))
m))
(re-frame/reg-fx
:graphql
(fn [{:keys [query on-success on-error token variables query-obj]}]
(go
(let [headers (if token
{"Authorization" (str "Token " token)}
{})
query (or query (v/graphql-query (->graphql query-obj)))
response (<! (http/request {:method :get
:headers headers
:url (str "/api/graphql?query=" (js/encodeURIComponent query)
"&variables=" (pr-str (or variables {})))}))]
(if (>= (:status response) 400)
(when on-error
(->> response
:body
:data
(dates->date-times)
(conj on-error)
(re-frame/dispatch)))
(->> response
:body
:data
(dates->date-times)
(conj on-success)
(re-frame/dispatch)))))))