diff --git a/CHANGELOG.md b/CHANGELOG.md index d758611d..5c64d8d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ * should only concern you if you are not using [Muuntaja](https://github.com/metosin/muuntaja). * the `r/routes` returns just the path + data tuples as documented, not the compiled route results. To get the compiled results, use `r/compiled-routes` instead. * welcome route name conflict resolution! If router has routes with same names, router can't be created. fix 'em. +* sequential child routes are allowed, enabling this: + +```clj +(-> ["/api" + (for [i (range 4)] + [(str "/" i)])] + (r/router) + (r/routes)) +;[["/api/0" {}] +; ["/api/1" {}] +; ["/api/2" {}] +; ["/api/3" {}]] +``` ## `reitit-swagger` diff --git a/modules/reitit-core/src/reitit/core.cljc b/modules/reitit-core/src/reitit/core.cljc index 62a77c6d..ab6dc4fd 100644 --- a/modules/reitit-core/src/reitit/core.cljc +++ b/modules/reitit-core/src/reitit/core.cljc @@ -41,7 +41,10 @@ (walk-many pacc macc routes) (when (string? (first routes)) (let [[path & [maybe-arg :as args]] routes - [data childs] (if (or (vector? maybe-arg) (nil? maybe-arg)) + [data childs] (if (or (vector? maybe-arg) + (and (sequential? maybe-arg) + (sequential? (first maybe-arg))) + (nil? maybe-arg)) [{} args] [maybe-arg (rest args)]) macc (into macc (expand data opts)) diff --git a/modules/reitit-core/src/reitit/spec.cljc b/modules/reitit-core/src/reitit/spec.cljc index 1c0800f6..cc0dee44 100644 --- a/modules/reitit-core/src/reitit/spec.cljc +++ b/modules/reitit-core/src/reitit/spec.cljc @@ -9,7 +9,7 @@ (s/def ::path (s/with-gen string? #(gen/fmap (fn [s] (str "/" s)) (s/gen string?)))) -(s/def ::arg (s/and some? (complement vector?))) +(s/def ::arg (s/and some? (complement sequential?))) (s/def ::data (s/map-of keyword? any?)) (s/def ::result any?) diff --git a/test/cljc/reitit/core_test.cljc b/test/cljc/reitit/core_test.cljc index 19091509..cc1cfdb2 100644 --- a/test/cljc/reitit/core_test.cljc +++ b/test/cljc/reitit/core_test.cljc @@ -268,3 +268,19 @@ (-> router (r/match-by-name! ::route {:a "olipa", :b "kerran"}) (r/match->path {:iso "pöriläinen"})))))) + +(deftest sequential-routes + (testing "sequential child routes work" + (is (= [["/api/0" {}] + ["/api/1" {}]] + (-> ["/api" + (for [i (range 2)] + [(str "/" i)])] + (r/router) + (r/routes))))) + (testing "sequential route definition fails" + (is (thrown? + #?(:clj Exception, :cljs js/Error) + (-> ["/api" + (list "/ipa")] + (r/router))))))