diff --git a/.gitignore b/.gitignore index f0353b6..b93d4f2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ pom.xml.asc .nrepl-port /.idea/* *.iml +/.cpcache/ +/.clj-kondo/.cache/ +/.lsp/.cache/ +/.calva/output-window/ diff --git a/src/kee_frame/router.cljc b/src/kee_frame/router.cljc index 410853d..19d3ca2 100644 --- a/src/kee_frame/router.cljc +++ b/src/kee_frame/router.cljc @@ -58,13 +58,21 @@ (let [[_ path-params] route {:keys [path] :as match} (apply reitit/match-by-name routes route)] (when (valid? match) - (str (when hash? (str base-path "/#")) path + (str base-path (when hash? "/#") path (when-some [q (:query-string path-params)] (str "?" q)) (when-some [h (:hash path-params)] (str "#" h)))))) +(defn- remove-base-path [url base-path] + ;; i don't want to think about how to quote the regex + ;; also we would pay for compilation on every check + (if (str/starts-with? url base-path) + (subs url (count base-path)) + url)) + (defn match-url [routes base-path url] (let [[path+query fragment] (-> url - (str/replace (re-pattern (str "^" base-path "/?#/")) "/") + (remove-base-path base-path) + (str/replace #"^/#/" "/") (str/split #"#" 2)) [path query] (str/split path+query #"\?" 2)] (some-> (reitit/match-by-path routes path) @@ -119,7 +127,7 @@ (defn start! [{:keys [routes initial-db router app-db-spec root-component chain-links screen scroll global-interceptors log-spec-error base-path] - :or {scroll true base-path "/"} + :or {scroll true base-path ""} :as config}] (deprecations config) (when app-db-spec diff --git a/test/kee_frame/router_test.cljc b/test/kee_frame/router_test.cljc index b4fa994..0642aaf 100644 --- a/test/kee_frame/router_test.cljc +++ b/test/kee_frame/router_test.cljc @@ -4,16 +4,17 @@ [kee-frame.api :as api] [reitit.core :as reitit])) -(defn router [routes hash?] (router/->ReititRouter (reitit/router routes) hash? nil)) +(defn router [routes hash? base-path] (router/->ReititRouter (reitit/router routes) hash? base-path nil)) -(deftest can-produce-hash-urls +(defn produce-urls-helper [hash? base-path] (let [r (router [["/" :root] - ["/item/:id" :item]] true)] + ["/item/:id" :item]] hash? base-path) + hash-path (if hash? "/#" "")] (testing "Root" - (is (= "/#/" (api/data->url r [:root])))) + (is (= (str base-path hash-path "/") (api/data->url r [:root])))) (testing "Item" - (is (= "/#/item/1" (api/data->url r [:item {:id 1}])))) + (is (= (str base-path hash-path "/item/1") (api/data->url r [:item {:id 1}])))) (testing "Item with missing id throws" (is (thrown? @@ -21,17 +22,29 @@ :cljs js/Error) (api/data->url r [:item])))))) -(deftest can-parse-hash-urls +(defn parse-urls-helper [hash? base-path] (let [r (router [["/" :root] - ["/item/:id" :item]] true)] + ["/item/:id" :item]] true base-path) + hash-path (if hash? "/#" "")] (testing "Root" - (is (= :root (-> (api/url->data r "/") + (is (= :root (-> (api/url->data r (str base-path hash-path "/")) :data :name)))) (testing "Item with path params and query string" - (let [{:keys [data path-params query-string]} (api/url->data r "/item/1?query=string")] + (let [{:keys [data path-params query-string]} + (api/url->data r (str base-path hash-path "/item/1?query=string"))] (is (= "query=string" query-string)) (is (= :item (:name data))) (is (= "1" (:id path-params))))))) + +(deftest can-produce-urls + (doseq [hash? [true false] + base-path ["" "/prefix"]] + (produce-urls-helper hash? base-path))) + +(deftest can-parse-urls + (doseq [hash? [true false] + base-path ["" "/prefix"]] + (parse-urls-helper hash? base-path)))