@@ -138,6 +138,84 @@ describe('mount()', () => {
138138 } )
139139 } )
140140
141+ describe ( 'With dynamic prefixes' , ( ) => {
142+ const anotherApp = ( req : Request ) => new Response ( getPath ( req ) )
143+
144+ it . each ( [
145+ [ '/api/:version/*' , '/api/v1/hello' , '/hello' ] ,
146+ [ '/api/:version/*' , '/api/long-version/hello' , '/hello' ] ,
147+ [ '/api/:version/*' , '/api/v1' , '/' ] ,
148+ [ '/api/:version/*' , '/api/v1/' , '/' ] ,
149+ [ '/api/:version/*' , '/api/v1//hello' , '//hello' ] ,
150+ [ '/user/:id{[^/]+}/*' , '/user/123/hello' , '/hello' ] ,
151+ [ '/api/:id{[0-9]{2}}/*' , '/api/12/hello' , '/hello' ] ,
152+ [ '/x/:prefix{.+}/x/*' , '/x/a/b/x/c/d' , '/c/d' ] ,
153+ [ '/x/:prefix{.+}/x/*' , '/x/a%2Fb/c/x/d%2Fe' , '/d%2Fe' ] ,
154+ [ '/api/:id{[^/]+}/*' , '/api/ad%2Fmin/x%252Fy' , '/x%252Fy' ] ,
155+ [ '/api/:id{[^/]+}/*' , '/api/foo%252Fbar/hello' , '/hello' ] ,
156+ [ '/api/:id{[^/]+}/*' , '/api/%C3%A9/admin%2Fsecret' , '/admin%2Fsecret' ] ,
157+ ] ) ( 'Should strip %s from %s' , async ( route , path , expected ) => {
158+ const app = new Hono ( )
159+ app . all ( route , mount ( anotherApp ) )
160+
161+ const res = await app . request ( path )
162+
163+ expect ( res . status ) . toBe ( 200 )
164+ expect ( await res . text ( ) ) . toBe ( expected )
165+ } )
166+
167+ it ( 'Should use the current route captures with a merged basePath' , async ( ) => {
168+ const app = new Hono ( )
169+ app . use ( '*' , async ( _c , next ) => {
170+ await next ( )
171+ } )
172+ const subApp = new Hono ( ) . basePath ( '/:tenant' )
173+ subApp . all ( '/app/:id{[^/]+}/*' , mount ( anotherApp ) )
174+ app . route ( '/api' , subApp )
175+
176+ const res = await app . request ( '/api/acme/app/ad%2Fmin/hello' )
177+
178+ expect ( res . status ) . toBe ( 200 )
179+ expect ( await res . text ( ) ) . toBe ( '/hello' )
180+ } )
181+
182+ it . each ( [
183+ [ '/a/*/b/*' , '/a/one/b/two/three' , '/two/three' ] ,
184+ [ '/a/*/b/*' , '/a/one/b' , '/' ] ,
185+ [ '/foo/*/*' , '/foo/x/y/z' , '/y/z' ] ,
186+ [ '/x*/y/*' , '/xabc/y/hello' , '/hello' ] ,
187+ [ '/x*/y/*' , '/x/y/hello' , '/hello' ] ,
188+ [ '/x*/*' , '/x/y' , '/y' ] ,
189+ [ '/x*/*' , '/x/hello%2Fworld' , '/hello%2Fworld' ] ,
190+ [ '/x*/y/*' , '/x%25/y/foo%252Fbar' , '/foo%252Fbar' ] ,
191+ [ '/assets*' , '/assets/hello' , '/hello' ] ,
192+ [ '/assets*' , '/assets-v2/hello' , '/-v2/hello' ] ,
193+ [ '/x*/y*' , '/xyz/yellow/hello' , '/ellow/hello' ] ,
194+ ] ) ( 'Should strip %s up to the final wildcard from %s' , async ( route , path , expected ) => {
195+ const app = new Hono ( )
196+ app . all ( route , mount ( anotherApp ) )
197+
198+ const res = await app . request ( path )
199+
200+ expect ( res . status ) . toBe ( 200 )
201+ expect ( await res . text ( ) ) . toBe ( expected )
202+ } )
203+
204+ it . each ( [
205+ [ '/x*/:id/*' , '/xabc/123/hello' , '/hello' ] ,
206+ [ '/x*/:id/*' , '/x/123/hello' , '/hello' ] ,
207+ [ '/a/*/b/:prefix{.+}/c/*' , '/a/one/b/two/three/c/four/five' , '/four/five' ] ,
208+ ] ) ( 'Should resolve wildcards and parameters in %s for %s' , async ( route , path , expected ) => {
209+ const app = new Hono ( )
210+ app . all ( route , mount ( anotherApp ) )
211+
212+ const res = await app . request ( path )
213+
214+ expect ( res . status ) . toBe ( 200 )
215+ expect ( await res . text ( ) ) . toBe ( expected )
216+ } )
217+ } )
218+
141219 describe ( 'With encoded paths' , ( ) => {
142220 const anotherApp = ( req : Request ) => new Response ( getPath ( req ) )
143221
@@ -226,7 +304,7 @@ describe('mount()', () => {
226304 } )
227305 } )
228306
229- describe ( ' Mount on `/ `', ( ) => {
307+ describe . each ( [ '*' , '/*' ] ) ( ' Mount on `%s `', ( route ) => {
230308 const anotherApp = ( req : Request , _params : unknown ) => {
231309 const path = getPath ( req )
232310 if ( path === '/' ) {
@@ -244,7 +322,7 @@ describe('mount()', () => {
244322 }
245323
246324 const app = new Hono ( )
247- app . all ( '/*' , mount ( anotherApp ) )
325+ app . all ( route , mount ( anotherApp ) )
248326
249327 it ( 'Should return responses from AnotherApp - mount on `/`' , async ( ) => {
250328 let res = await app . request ( '/' )
0 commit comments