Revert "Revert "Merge pull request #554 from just-sultanov/add-support-for-fragment-parameters""

This reverts commit 4d1b00edfa.
This commit is contained in:
Juho Teperi 2023-01-18 20:28:26 +02:00
parent b6c046318b
commit 83c31e35bc
3 changed files with 54 additions and 12 deletions

View file

@ -39,7 +39,8 @@
:body (->ParameterCoercion :body-params :body false false) :body (->ParameterCoercion :body-params :body false false)
:form (->ParameterCoercion :form-params :string true true) :form (->ParameterCoercion :form-params :string true true)
:header (->ParameterCoercion :headers :string true true) :header (->ParameterCoercion :headers :string true true)
:path (->ParameterCoercion :path-params :string true true)}) :path (->ParameterCoercion :path-params :string true true)
:fragment (->ParameterCoercion :fragment-params :string true true)})
(defn ^:no-doc request-coercion-failed! [result coercion value in request serialize-failed-result] (defn ^:no-doc request-coercion-failed! [result coercion value in request serialize-failed-result]
(throw (throw

View file

@ -1,5 +1,6 @@
(ns reitit.frontend (ns reitit.frontend
(:require [clojure.set :as set] (:require [clojure.set :as set]
[clojure.string :as str]
[reitit.coercion :as coercion] [reitit.coercion :as coercion]
[reitit.core :as r]) [reitit.core :as r])
(:import goog.Uri (:import goog.Uri
@ -20,6 +21,19 @@
(map (juxt keyword #(query-param q %))) (map (juxt keyword #(query-param q %)))
(into {})))) (into {}))))
(defn fragment-params
"Given goog.Uri, read fragment parameters into Clojure map."
[^Uri uri]
(let [fp (.getFragment uri)]
(if-not (seq fp)
{}
(into {}
(comp
(map #(str/split % #"="))
(map (fn [[k v]]
[(keyword k) v])))
(str/split fp #"&")))))
(defn match-by-path (defn match-by-path
"Given routing tree and current path, return match with possibly "Given routing tree and current path, return match with possibly
coerced parameters. Return nil if no match found. coerced parameters. Return nil if no match found.
@ -37,12 +51,14 @@
coercion/coerce!)] coercion/coerce!)]
(if-let [match (r/match-by-path router (.getPath uri))] (if-let [match (r/match-by-path router (.getPath uri))]
(let [q (query-params uri) (let [q (query-params uri)
match (assoc match :query-params q) fp (fragment-params uri)
match (assoc match :query-params q :fragment-params fp)
;; Return uncoerced values if coercion is not enabled - so ;; Return uncoerced values if coercion is not enabled - so
;; that tha parameters are always accessible from same property. ;; that tha parameters are always accessible from same property.
parameters (or (coerce! match) parameters (or (coerce! match)
{:path (:path-params match) {:path (:path-params match)
:query q})] :query q
:fragment fp})]
(assoc match :parameters parameters)))))) (assoc match :parameters parameters))))))
(defn match-by-name (defn match-by-name

View file

@ -21,9 +21,11 @@
:data {:name ::frontpage} :data {:name ::frontpage}
:path-params {} :path-params {}
:query-params {} :query-params {}
:fragment-params {}
:path "/" :path "/"
:parameters {:query {} :parameters {:query {}
:path {}}}) :path {}
:fragment {}}})
(rf/match-by-path router "/"))) (rf/match-by-path router "/")))
(is (= "/" (is (= "/"
@ -34,9 +36,11 @@
:data {:name ::foo} :data {:name ::foo}
:path-params {} :path-params {}
:query-params {} :query-params {}
:fragment-params {}
:path "/foo" :path "/foo"
:parameters {:query {} :parameters {:query {}
:path {}}}) :path {}
:fragment {}}})
(rf/match-by-path router "/foo"))) (rf/match-by-path router "/foo")))
(is (= (r/map->Match (is (= (r/map->Match
@ -44,9 +48,11 @@
:data {:name ::foo} :data {:name ::foo}
:path-params {} :path-params {}
:query-params {:mode ["foo", "bar"]} :query-params {:mode ["foo", "bar"]}
:fragment-params {}
:path "/foo" :path "/foo"
:parameters {:query {:mode ["foo", "bar"]} :parameters {:query {:mode ["foo", "bar"]}
:path {}}}) :path {}
:fragment {}}})
(rf/match-by-path router "/foo?mode=foo&mode=bar"))) (rf/match-by-path router "/foo?mode=foo&mode=bar")))
(is (= "/foo" (is (= "/foo"
@ -64,7 +70,12 @@
(let [router (r/router ["/" (let [router (r/router ["/"
[":id" {:name ::foo [":id" {:name ::foo
:parameters {:path {:id s/Int} :parameters {:path {:id s/Int}
:query {(s/optional-key :mode) s/Keyword}}}]] :query {(s/optional-key :mode) s/Keyword}
:fragment {(s/optional-key :access_token) s/Str
(s/optional-key :refresh_token) s/Str
(s/optional-key :expires_in) s/Int
(s/optional-key :provider_token) s/Str
(s/optional-key :token_type) s/Str}}}]]
{:compile rc/compile-request-coercers {:compile rc/compile-request-coercers
:data {:coercion rsc/coercion}})] :data {:coercion rsc/coercion}})]
@ -72,9 +83,11 @@
{:template "/:id" {:template "/:id"
:path-params {:id "5"} :path-params {:id "5"}
:query-params {} :query-params {}
:fragment-params {}
:path "/5" :path "/5"
:parameters {:query {} :parameters {:query {}
:path {:id 5}}}) :path {:id 5}
:fragment {}}})
(m (rf/match-by-path router "/5")))) (m (rf/match-by-path router "/5"))))
(is (= "/5" (is (= "/5"
@ -98,23 +111,35 @@
{:template "/:id" {:template "/:id"
:path-params {:id "5"} :path-params {:id "5"}
:query-params {:mode "foo"} :query-params {:mode "foo"}
:fragment-params {}
:path "/5" :path "/5"
:parameters {:path {:id 5} :parameters {:path {:id 5}
:query {:mode :foo}}}) :query {:mode :foo}
:fragment {}}})
(m (rf/match-by-path router "/5?mode=foo")))) (m (rf/match-by-path router "/5?mode=foo"))))
(is (= "/5?mode=foo" (is (= "/5?mode=foo"
(r/match->path (rf/match-by-name router ::foo {:id 5}) {:mode :foo})))) (r/match->path (rf/match-by-name router ::foo {:id 5}) {:mode :foo}))))
(testing "fragment is ignored" (testing "fragment is read"
(is (= (r/map->Match (is (= (r/map->Match
{:template "/:id" {:template "/:id"
:path-params {:id "5"} :path-params {:id "5"}
:query-params {:mode "foo"} :query-params {:mode "foo"}
:fragment-params {:access_token "foo"
:refresh_token "bar"
:provider_token "baz"
:token_type "bearer"
:expires_in "3600"}
:path "/5" :path "/5"
:parameters {:path {:id 5} :parameters {:path {:id 5}
:query {:mode :foo}}}) :query {:mode :foo}
(m (rf/match-by-path router "/5?mode=foo#fragment"))))) :fragment {:access_token "foo"
:refresh_token "bar"
:provider_token "baz"
:token_type "bearer"
:expires_in 3600}}})
(m (rf/match-by-path router "/5?mode=foo#access_token=foo&refresh_token=bar&provider_token=baz&token_type=bearer&expires_in=3600")))))
(testing "console warning about missing params" (testing "console warning about missing params"
(is (= [{:type :warn (is (= [{:type :warn