/
frontend.cljs
75 lines (69 loc) · 2.54 KB
/
frontend.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
(ns reitit.frontend
(:require [clojure.set :as set]
[reitit.coercion :as coercion]
[reitit.core :as r])
(:import goog.Uri
goog.Uri.QueryData))
(defn- query-param [^QueryData q k]
(let [vs (.getValues q k)]
(if (< (alength vs) 2)
(aget vs 0)
(vec vs))))
(defn query-params
"Given goog.Uri, read query parameters into Clojure map."
[^Uri uri]
(let [q (.getQueryData uri)]
(->> q
(.getKeys)
(map (juxt keyword #(query-param q %)))
(into {}))))
(defn match-by-path
"Given routing tree and current path, return match with possibly
coerced parameters. Return nil if no match found."
[router path]
(let [uri (.parse Uri path)]
(if-let [match (r/match-by-path router (.getPath uri))]
(let [q (query-params uri)
match (assoc match :query-params q)
;; Return uncoerced values if coercion is not enabled - so
;; that tha parameters are always accessible from same property.
parameters (or (coercion/coerce! match)
{:path (:path-params match)
:query q})]
(assoc match :parameters parameters)))))
(defn match-by-name
"Given a router, route name and optionally path-parameters,
will return a Match (exact match), PartialMatch (missing path-parameters)
or `nil` (no match)."
([router name]
(match-by-name router name {}))
([router name path-params]
(r/match-by-name router name path-params)))
(defn router
"Create a `reitit.core.router` from raw route data and optionally an options map.
Enables request coercion. See [[reitit.core/router]] for details on options."
([raw-routes]
(router raw-routes {}))
([raw-routes opts]
(r/router raw-routes (merge {:compile coercion/compile-request-coercers} opts))))
(defn match-by-name!
"Logs problems using console.warn"
([router name]
(match-by-name! router name {}))
([router name path-params]
(if-let [match (match-by-name router name path-params)]
(if (r/partial-match? match)
(if (every? #(contains? path-params %) (:required match))
match
(let [defined (-> path-params keys set)
missing (set/difference (:required match) defined)]
(js/console.warn
"missing path-params for route" name
{:template (:template match)
:missing missing
:path-params path-params
:required (:required match)})
nil))
match)
(do (js/console.warn "missing route" name)
nil))))