diff --git a/deps.edn b/deps.edn index e238d234..d224cefb 100644 --- a/deps.edn +++ b/deps.edn @@ -15,7 +15,6 @@ mount/mount {:mvn/version "0.1.16"} nrepl/nrepl {:mvn/version "0.5.3"} orchestra/orchestra {:mvn/version "2019.02.06-1"} - org.clojure/java.classpath {:mvn/version "1.0.0"} org.clojure/tools.namespace {:mvn/version "1.0.0"} org.immutant/web {:mvn/version "2.1.10"} org.postgresql/postgresql {:mvn/version "42.2.12.jre7"} diff --git a/example/config.edn b/example/config.edn index 69a29ba6..f1300852 100644 --- a/example/config.edn +++ b/example/config.edn @@ -6,8 +6,8 @@ :biff.crux.jdbc/port ... ; Uncomment to use filesystem storage in production instead of jdbc: ; :biff.crux/topology :standalone - :example.biff/host "example.com" ; change this - :example.mailgun/api-key "..."} + :biff/host "example.com" ; change this + :mailgun/api-key "..."} :dev {:inherit [:prod] :biff/dev true - :example.biff/host "localhost"}} + :biff/host "localhost"}} diff --git a/example/deps.edn b/example/deps.edn index 8b9cd7ff..950ac985 100644 --- a/example/deps.edn +++ b/example/deps.edn @@ -3,8 +3,9 @@ thheller/shadow-cljs {:mvn/version "2.8.40"} binaryage/devtools {:mvn/version "0.9.10"} binaryage/oops {:mvn/version "0.7.0"} - cljs-http {:mvn/version "0.1.46"}}}} + cljs-http/cljs-http {:mvn/version "0.1.46"}}}} :deps {github-jacobobryant/biff - {:git/url "https://github.com/jacobobryant/biff" + {:local/root ".." + ;:git/url "https://github.com/jacobobryant/biff" :tag "HEAD"}}} diff --git a/example/resources/www/example/js/ensure-signed-in.js b/example/resources/www/js/ensure-signed-in.js similarity index 100% rename from example/resources/www/example/js/ensure-signed-in.js rename to example/resources/www/js/ensure-signed-in.js diff --git a/example/resources/www/example/js/ensure-signed-out.js b/example/resources/www/js/ensure-signed-out.js similarity index 100% rename from example/resources/www/example/js/ensure-signed-out.js rename to example/resources/www/js/ensure-signed-out.js diff --git a/example/src/example/client/app/db.cljs b/example/src/example/client/app/db.cljs index 0b2912dc..9fdd4437 100644 --- a/example/src/example/client/app/db.cljs +++ b/example/src/example/client/app/db.cljs @@ -5,10 +5,7 @@ [rum.core])) (defonce db (atom {})) - -; same as (do (rum.core/cursor-in db [:sub-data]) ...) -(u/defcursors db - sub-data [:sub-data]) +(defonce sub-data (atom {})) ; same as (do ; (rum.core/derived-atom [sub-data] :example.client.app.db/data diff --git a/example/src/example/core.clj b/example/src/example/core.clj index 303fb55d..8f6c0a38 100644 --- a/example/src/example/core.clj +++ b/example/src/example/core.clj @@ -1,38 +1,36 @@ -(ns ^:biff example.core +(ns example.core (:require - [biff.system] + [biff.core :as biff] [clojure.tools.namespace.repl :as tn] - [example.handlers] - [example.routes] - [example.rules] - [example.static] - [example.triggers])) + [example.handlers :refer [api]] + [example.routes :refer [routes]] + [example.rules :refer [rules]] + [example.static :refer [pages]] + [example.triggers :refer [triggers]])) (defn send-email [opts] (clojure.pprint/pprint [:send-email (select-keys opts [:to :template :data])])) -(defn start-example [sys] - (tn/set-refresh-dirs "src" "../../src") - (-> sys - (merge #:example.biff.auth{:send-email send-email - :on-signup "/signin/sent/" - :on-signin-request "/signin/sent/" - :on-signin-fail "/signin/fail/" - :on-signin "/app/" - :on-signout "/"}) - (merge #:example.biff{:routes example.routes/routes - :static-pages example.static/pages - :event-handler #(example.handlers/api % (:?data %)) - :rules example.rules/rules - :triggers example.triggers/triggers}) - (biff.system/start-biff 'example))) +(defn start [opts] + (tn/set-refresh-dirs "src" "../../src") ; For hacking on Biff + (biff/start-spa + (merge opts + #:biff{:routes routes + :static-pages pages + :event-handler #(api % (:?data %)) + :rules #'rules + :triggers #'triggers + :send-email send-email + :after-refresh `after-refresh}))) -(def components - [{:name :example/core - :requires [:biff/init] - :required-by [:biff/web-server] - :start start-example}]) +(defn -main [] + (start {:biff/first-start true})) + +(defn after-refresh [] + (start nil)) (comment - (crux.api/submit-tx (:example.biff/node @biff.core/system) - [[:crux.tx/delete {:game/id "test"}]])) + ; Useful REPL commands: + (biff.core/refresh) + (->> @biff.core/system keys sorted (run! prn)) + ) diff --git a/example/src/example/static.clj b/example/src/example/static.clj index f859f6af..e6bf0b35 100644 --- a/example/src/example/static.clj +++ b/example/src/example/static.clj @@ -45,7 +45,7 @@ (def pages {"/" home - "/signin/sent/" signin-sent - "/signin/fail/" signin-fail + "/signin-sent/" signin-sent + "/signin-fail/" signin-fail "/app/" app "/404.html" not-found}) diff --git a/example/task b/example/task index 7b8fbccc..f05b9ee7 100755 --- a/example/task +++ b/example/task @@ -1,8 +1,6 @@ #!/bin/bash set -e -APP_NS="example" -CLJS_APPS="app" HOST="example.com" setup () { @@ -11,16 +9,14 @@ setup () { } dev () { - clj -Sresolve-tags - BIFF_ENV=dev clj -A:cljs "$@" -m biff.core + clj -X:deps git-resolve-tags + BIFF_ENV=dev clj -A:cljs "$@" -M -m example.core } compile-cljs () { npx shadow-cljs release $CLJS_APPS - for app in $CLJS_APPS; do - mkdir -p resources/www/$APP_NS/cljs/$app - cp {www-dev,resources/www/$APP_NS}/cljs/$app/main.js - done + mkdir -p resources/www/cljs/app + cp {www-dev,resources/www}/cljs/app/main.js } push-config () { diff --git a/slate/source/index.html.md b/slate/source/index.html.md index a3e1fb74..0fb3d982 100644 --- a/slate/source/index.html.md +++ b/slate/source/index.html.md @@ -61,6 +61,9 @@ For hacking on Biff, change the example project's dependency to `:local/root # Getting started +**Note:** As of 19 Oct, the `./task dev` command below is broken due to a bug +in tools.deps. I'll update these docs with a workaround soon. + The fastest way to get started with Biff is by cloning the Github repo and running the official example project (an implementation of Tic Tac Toe): diff --git a/src/biff/auth.clj b/src/biff/auth.clj index 72626041..9be1845b 100644 --- a/src/biff/auth.clj +++ b/src/biff/auth.clj @@ -1,20 +1,20 @@ (ns biff.auth (:require - [crux.api :as crux] - [ring.middleware.anti-forgery :as anti-forgery] [biff.crux :as bcrux] [byte-streams :as bs] + [byte-transforms :as bt] + [cemerick.url :as url] + [clojure.string :as str] + [crux.api :as crux] [crypto.random :as random] - [trident.util :as u] + [ring.middleware.anti-forgery :as anti-forgery] [trident.jwt :as tjwt] - [clojure.string :as str] - [cemerick.url :as url] - [byte-transforms :as bt])) + [trident.util :as u])) (defn get-key [{:keys [biff/node biff/db k] :as env}] (or (get (crux/entity db :biff.auth/keys) k) (doto (bs/to-string (bt/encode (random/bytes 16) :base64)) - (#(bcrux/submit-admin-tx + (#(bcrux/submit-tx env {[:biff/auth-keys :biff.auth/keys] {:db/merge true @@ -43,8 +43,11 @@ (defn email= [s1 s2] (.equalsIgnoreCase s1 s2)) -(defn send-signin-link [{:keys [params/email biff/base-url template location] - :biff.auth/keys [send-email] +(defn send-signin-link [{:keys [params/email + biff/base-url + biff/send-email + template + location] :as env}] (let [{:keys [params] :as env} (update env :params (fn [m] (u/map-vals @@ -118,7 +121,7 @@ ["/api" ["/signup" {:post #(send-signin-link (assoc % :template :biff.auth/signup - :location (or on-signup on-signin-request))) + :location on-signup)) :name ::signup}] ["/signin-request" {:post #(send-signin-link (assoc % :template :biff.auth/signin diff --git a/src/biff/system.clj b/src/biff/components.clj similarity index 68% rename from src/biff/system.clj rename to src/biff/components.clj index 9ccf7f12..f1ddbc74 100644 --- a/src/biff/system.clj +++ b/src/biff/components.clj @@ -1,25 +1,28 @@ -(ns biff.system +(ns biff.components (:require - [biff.http :as http] [biff.auth :as auth] + [biff.crux :as bcrux] + [biff.http :as http] [biff.rules :as rules] [byte-transforms :as bt] - [clojure.set :as set] - [clojure.string :as str] + [clojure.edn :as edn] [clojure.java.io :as io] + [clojure.set :as set] [clojure.spec.alpha :as s] + [clojure.string :as str] [crux.api :as crux] [expound.alpha :as expound] - [taoensso.sente :as sente] - [ring.middleware.session.cookie :as cookie] + [immutant.web :as imm] + [nrepl.server :as nrepl] + [orchestra.spec.test :as st] [ring.middleware.anti-forgery :as anti-forgery] + [ring.middleware.session.cookie :as cookie] [rum.core :as rum] + [taoensso.sente :as sente] [taoensso.sente.server-adapters.immutant :refer [get-sch-adapter]] - [biff.crux :as bcrux] - [taoensso.timbre :refer [log spy]] + [taoensso.timbre :as timbre] [trident.util :as u]) - (:import - [java.nio.file Paths])) + (:import [java.nio.file Paths])) (defn wrap-env [handler {:keys [biff/node] :as sys}] (comp handler @@ -30,31 +33,64 @@ (merge (u/prepend-keys "session" (get req :session))) (merge (u/prepend-keys "params" (get req :params)))))))) -(defn set-defaults [sys app-ns] - (let [sys (merge sys (u/select-ns-as sys (str app-ns ".biff") 'biff)) - {:biff/keys [dev host rules triggers using-proxy] - :keys [biff.auth/send-email - biff.web/port +(defn concrete [x] + (cond + (var? x) @x + (fn? x) (x) + :default x)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn init [sys] + (let [env (keyword (or (System/getenv "BIFF_ENV") :prod)) + config (some-> "config.edn" + u/maybe-slurp + edn/read-string + (u/merge-config env)) + {:biff/keys [first-start dev] + :biff.init/keys [start-nrepl nrepl-port instrument timbre start-shadow] + :or {start-nrepl true nrepl-port 7888 timbre true} + :as sys} (merge sys config)] + (when timbre + (timbre/merge-config! (u/select-ns-as sys 'timbre nil))) + (when instrument + (s/check-asserts true) + (st/instrument)) + (when (and first-start start-nrepl nrepl-port (not dev)) + (nrepl/start-server :port nrepl-port)) + (when (and first-start (or dev start-shadow)) + ((requiring-resolve 'shadow.cljs.devtools.server/start!))) + sys)) + +(defn set-defaults [sys] + (let [{:biff/keys [dev host rules triggers using-proxy] + :keys [biff.web/port biff.static/root biff.static/root-dev] :or {port 8080}} sys using-proxy (cond dev false (some? using-proxy) using-proxy - :default (not= host "localhost")) - root (or root (str "www/" host)) + :default (not (#{"localhost" nil} host))) + root (or root "www") root-dev (if dev "www-dev" root-dev)] (merge - {:biff.crux/topology :jdbc - :biff.crux/storage-dir (str "data/" app-ns "/crux-db") + {:biff/host "localhost" + :biff.auth/on-signup "/signin-sent/" + :biff.auth/on-signin-request "/signin-sent/" + :biff.auth/on-signin-fail "/signin-fail/" + :biff.auth/on-signin "/app/" + :biff.auth/on-signout "/" + :biff.crux/topology :jdbc + :biff.crux/storage-dir "data/crux-db" :biff.web/port 8080 :biff.static/root root - :biff.static/resource-root (str "www/" app-ns) + :biff.static/resource-root "www" :biff.handler/secure-defaults true :biff.handler/not-found-path (str root "/404.html")} sys - {:biff/rules (rules/expand-ops (merge rules rules/rules)) - :biff/triggers (rules/expand-ops triggers) + {:biff/rules #(rules/expand-ops (merge (concrete rules) rules/rules)) + :biff/triggers #(rules/expand-ops (concrete triggers)) :biff.handler/roots (if root-dev [root-dev root] [root]) @@ -65,11 +101,6 @@ {:biff.crux/topology :standalone :biff.handler/secure-defaults false})))) -(defn check-config [sys] - (when-not (contains? sys :biff/host) - (throw (ex-info ":biff/host not set. Do you need to add or update config.edn?" {}))) - sys) - (defn start-crux [sys] (let [opts (-> sys (u/select-ns-as 'biff.crux 'crux) @@ -78,7 +109,7 @@ node (bcrux/start-node opts)] (-> sys (assoc :biff/node node) - (update :sys/stop conj #(.close node))))) + (update :biff/stop conj #(.close node))))) (defn start-sente [sys] (let [{:keys [ch-recv send-fn connected-uids @@ -149,25 +180,26 @@ (defn set-auth-route [sys] (update sys :biff/routes conj (auth/route sys))) -(defn set-handler [{:biff/keys [routes host node] +(defn set-handler [{:biff/keys [routes node] :biff.handler/keys [roots secure-defaults spa-path not-found-path] :as sys}] - (let [cookie-key (bt/decode (auth/get-key (assoc sys - :k :cookie-key - :biff/db (crux/db node))) - :base64) - session-store (cookie/cookie-store {:key cookie-key}) - handler (http/make-handler - {:roots roots - :session-store session-store - :secure-defaults secure-defaults - :not-found-path not-found-path - :spa-path spa-path - :routes [(into ["" {:middleware [[wrap-env sys]]}] - routes)]})] - (update sys :biff.web/host->handler assoc host handler))) + (let [cookie-key (-> (assoc sys + :k :cookie-key + :biff/db (crux/db node)) + auth/get-key + (bt/decode :base64)) + session-store (cookie/cookie-store {:key cookie-key})] + (assoc sys :biff.web/handler + (http/make-handler + {:roots roots + :session-store session-store + :secure-defaults secure-defaults + :not-found-path not-found-path + :spa-path spa-path + :routes [(into ["" {:middleware [[wrap-env sys]]}] + routes)]})))) (defn copy-resources [src-root dest-root] (when-some [resource-root (io/resource src-root)] @@ -198,20 +230,15 @@ [{:biff.static/keys [root resource-root] :keys [biff/static-pages] :as sys}] (export-rum static-pages root) - (copy-resources resource-root root)) - -(defn start-biff [sys app-ns] - (binding [s/*explain-out* expound/printer] - (let [new-sys (-> sys - (set-defaults app-ns) - check-config - start-crux - start-sente - start-tx-listener - start-event-router - set-auth-route - set-handler)] - (write-static-resources new-sys) - (-> sys - (merge (select-keys new-sys [:sys/stop :biff.web/host->handler])) - (merge (u/select-ns-as new-sys 'biff (str app-ns ".biff"))))))) + (copy-resources resource-root root) + sys) + +(defn start-web-server [{:biff/keys [dev] + :biff.web/keys [handler host port] + :or {host "localhost" + port 8080} :as sys}] + (let [host (if dev + "0.0.0.0" + host) + server (imm/run handler {:host host :port port})] + (update sys :sys/stop conj #(imm/stop server)))) diff --git a/src/biff/core.clj b/src/biff/core.clj index e1dde35b..56c73b4e 100644 --- a/src/biff/core.clj +++ b/src/biff/core.clj @@ -1,128 +1,33 @@ -(ns ^:biff biff.core +(ns biff.core (:require - [clojure.edn :as edn] - [clojure.java.classpath :as cp] - [clojure.set :as set] - [clojure.spec.alpha :as s] - [clojure.string :as str] - [clojure.tools.namespace.find :as tn-find] - [clojure.tools.namespace.repl :as tn-repl] - [orchestra.spec.test :as st] - [nrepl.server :as nrepl] - [biff.system :refer [start-biff]] - [trident.util :as u] - [taoensso.timbre :as timbre :refer [log spy]] - [immutant.web :as imm])) + [biff.components :as c] + [clojure.tools.namespace.repl :as tn-repl])) (defonce system (atom nil)) -(defn try-requiring-resolve [sym] - (try - (requiring-resolve sym) - (catch Exception e - (println (str "Couldn't require " (namespace sym) ":")) - (.printStackTrace e) - nil))) - -(defn get-components [] - (->> (cp/classpath) - tn-find/find-ns-decls - (map second) - (filter (comp :biff meta)) - (mapcat #(some-> % - name - (symbol "components") - try-requiring-resolve - deref)))) - -(defn start - ([] - (start (get-components))) - ([components] - (apply println "Starting" (map :name components)) - (reset! system (u/start-system components)) - (println "System started.") - nil)) - -(defn stop [] - (u/stop-system @system)) - (defn refresh [] - (stop) - (tn-repl/refresh :after `start)) - -(def set-first-start - {:name ::set-first-start - :required-by [:biff/init] - :start #(merge {:biff/first-start true} %)}) - -(defn -main [] - (start (conj (get-components) set-first-start))) - -(defn get-config [env] - (some-> "config.edn" - u/maybe-slurp - edn/read-string - (u/merge-config env))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(def init - {:name :biff/init - :start (fn [sys] - (let [env (keyword (or (System/getenv "BIFF_ENV") :prod)) - {:biff/keys [first-start dev] - :biff.init/keys [start-nrepl nrepl-port instrument timbre start-shadow] - :or {start-nrepl true nrepl-port 7888 timbre true} - :as sys} (merge sys (get-config env))] - (when timbre - (timbre/merge-config! (u/select-ns-as sys 'timbre nil))) - (when instrument - (s/check-asserts true) - (st/instrument)) - (when (and first-start start-nrepl nrepl-port (not dev)) - (nrepl/start-server :port nrepl-port)) - (when (and first-start (or dev start-shadow)) - ((requiring-resolve 'shadow.cljs.devtools.server/start!))) - sys))}) - -(def console - {:name :biff/console - :requires [:biff/init] - :required-by [:biff/web-server] - :start (fn [{:keys [biff.console/enabled] :as sys}] - ; I'll enable this by default after we actually have a web console app. - (if enabled - (-> sys - (merge #:console.biff.auth{:on-signin "/" - :on-signin-request "/biff/signin-request" - :on-signin-fail "/biff/signin-fail" - :on-signout "/biff/signin"}) - (start-biff 'console)) - sys))}) - -(def web-server - {:name :biff/web-server - :requires [:biff/init] - :start (fn [{:biff/keys [dev] - :biff.web/keys [host->handler host port] - :or {host "localhost" - port 8080} :as sys}] - (let [host (if dev - "0.0.0.0" - host) - server (imm/run - #(if-some [handler (get host->handler (:server-name %))] - (handler %) - {:status 404 - :body "Not found." - :headers {"Content-Type" "text/plain"}}) - {:host host :port port})] - (update sys :sys/stop conj #(imm/stop server))))}) - -(def components [init console web-server]) - -(comment - (u/pprint (deref system)) - (refresh) - (u/stop-system @system)) + (let [{:keys [biff/after-refresh biff/stop]} @system] + (doseq [f stop] + (f)) + (tn-repl/refresh :after after-refresh))) + +(defn start-system [config components] + (reset! system + (reduce (fn [sys component] + (component sys)) + (merge {:biff/stop '()} config) + components)) + (println "System started.")) + +(defn start-spa [config] + (start-system config + [c/init + c/set-defaults + c/start-crux + c/start-sente + c/start-tx-listener + c/start-event-router + c/set-auth-route + c/set-handler + c/write-static-resources + c/start-web-server])) diff --git a/src/biff/crux.clj b/src/biff/crux.clj index d5b016ae..18d73b89 100644 --- a/src/biff/crux.clj +++ b/src/biff/crux.clj @@ -3,14 +3,20 @@ [biff.protocols :as proto] [clojure.core.async :refer [go m @@ -101,7 +107,8 @@ (try (doto (s/valid? x-spec x) #(when (and verbose (not %)) - (expound x-spec x))) + (binding [s/*explain-out* expound/printer] + (expound/expound x-spec x)))) (catch Exception e (println "Exception while checking spec:" (pr-str x-spec) (pr-str x)) @@ -113,6 +120,7 @@ (let [query-type (if (contains? query :id) :get :query) + rules (concrete rules) auth-fn (get-in rules [table query-type]) specs (get-in rules [table :spec]) anom-message (cond @@ -148,10 +156,11 @@ (into {}))) (defn run-triggers [{:keys [biff/db-client batch] :as env}] - (doseq [{:keys [table op triggers doc] :as env} (proto/get-trigger-data db-client env batch)] + (doseq [{:keys [trigger-fn] :as env} (proto/get-trigger-data db-client env batch)] (try - ((get-in triggers [table op]) env) + (trigger-fn env) (catch Exception e + (def env env) (.printStackTrace e) (log :error e "Couldn't run trigger"))))) @@ -272,9 +281,9 @@ (nil? doc) :delete (nil? doc-before) :create :default :update)] - [table op->fn] triggers + [table op->fn] (concrete triggers) [trigger-op f] op->fn - :let [specs (get-in rules [table :spec])] + :let [specs (get-in (concrete rules) [table :spec])] :when (and (= trigger-op doc-op) (some #(doc-valid? {:specs specs :db-client db-client @@ -282,6 +291,7 @@ (assoc env :table table :op trigger-op + :trigger-fn f :doc doc :doc-before doc-before :db db @@ -441,7 +451,7 @@ (and (some? doc'') (some not (map s/valid? - (get-in rules [table :spec]) + (get-in (concrete rules) [table :spec]) [id' doc'']))) (u/anom :incorrect "Document doesn't meet spec." :doc doc @@ -463,7 +473,7 @@ {:keys [table op] :as doc-tx-data}] (if admin doc-tx-data - (u/letdelay [auth-fn (get-in rules [table op]) + (u/letdelay [auth-fn (get-in (concrete rules) [table op]) result (auth-fn (merge env doc-tx-data)) anom-fn #(merge (u/anom :forbidden %) (select-keys doc-tx-data [:table :id]))] @@ -486,9 +496,8 @@ tx (into {} tx*) env (assoc env :tx tx :current-time current-time) auth-result (mapv #(authorize-write env (second %)) tx) - crux-tx (u/forv [{:keys [op cas old-doc doc id]} auth-result] + crux-tx (u/forv [{:keys [op old-doc doc id]} auth-result] (cond - cas [:crux.tx/cas old-doc doc] (= op :delete) [:crux.tx/delete id] :default [:crux.tx/put doc]))] (or @@ -507,24 +516,9 @@ ; ============================================================================== -; Deprecated, use submit-tx -(defn submit-admin-tx [{:biff/keys [node db rules]} tx] - (let [db (or db (crux/db node)) - tx (authorize-tx {:tx tx - :biff/db db - :biff/rules rules - :admin true}) - anom (u/anomaly? tx)] - (when anom - (u/pprint tx)) - (if anom - tx - (crux/submit-tx node tx)))) - (defn submit-tx [{:biff/keys [node db rules]} tx] - (let [db (or db (crux/db node)) - tx (authorize-tx {:tx tx - :biff/db db + (let [tx (authorize-tx {:tx tx + :biff/db (or db (crux/db node)) :biff/rules rules :admin true})] (when (u/anomaly? tx) diff --git a/src/biff/http.clj b/src/biff/http.clj index 30b8106a..167fd6c0 100644 --- a/src/biff/http.clj +++ b/src/biff/http.clj @@ -1,17 +1,17 @@ (ns biff.http (:require + [clojure.java.io :as io] + [clojure.string :as str] [muuntaja.middleware :as muuntaja] + [reitit.ring :as reitit] [ring.middleware.anti-forgery :as anti-forgery] + [ring.middleware.defaults :as rd] [ring.middleware.head :as head] - [trident.util :as u] - [ring.util.time :as rtime] - [ring.util.io :as rio] - [clojure.string :as str] [ring.util.codec :as codec] + [ring.util.io :as rio] [ring.util.request :as request] - [clojure.java.io :as io] - [ring.middleware.defaults :as rd] - [reitit.ring :as reitit])) + [ring.util.time :as rtime] + [trident.util :as u])) (defn wrap-authorize [handler] (anti-forgery/wrap-anti-forgery @@ -43,14 +43,13 @@ file (io/file path)] (file-response req file))))) -(defn nice-response [resp] - (when resp - (-> {:body "" :status 200} - (merge resp) - (u/nest-string-keys [:headers :cookies])))) - -(defn wrap-nice-response [handler] - (comp nice-response handler)) +(defn wrap-sugary-response [handler] + (fn [resp] + (let [resp (handler resp)] + (when resp + (-> {:body "" :status 200} + (merge resp) + (u/nest-string-keys [:headers :cookies])))))) (defn make-handler [{:keys [session-store secure-defaults roots not-found-path spa-path routes default-routes]}] @@ -82,7 +81,7 @@ (reitit/ring-handler (reitit/router routes) (apply reitit/routes default-handlers)) - wrap-nice-response + wrap-sugary-response muuntaja/wrap-params muuntaja/wrap-format (rd/wrap-defaults ring-defaults))))