File tree Expand file tree Collapse file tree 5 files changed +51
-15
lines changed Expand file tree Collapse file tree 5 files changed +51
-15
lines changed Original file line number Diff line number Diff line change @@ -34,7 +34,7 @@ export function validateApiPath(path: string = '/') {
34
34
) ;
35
35
}
36
36
37
- const regexpPath = path . replace ( POSSIBLE_VARNAME_PATTERN , ':$1' ) ;
37
+ const regexpPath = toExpressPath ( path ) ;
38
38
tokens = pathToRegExp . parse ( regexpPath ) ;
39
39
for ( const token of tokens ) {
40
40
if ( typeof token === 'string' ) continue ;
@@ -62,5 +62,7 @@ export function getPathVariables(path: string) {
62
62
* @param path OpenAPI path with optional variables as `{var}`
63
63
*/
64
64
export function toExpressPath ( path : string ) {
65
- return path . replace ( POSSIBLE_VARNAME_PATTERN , ':$1' ) ;
65
+ // Convert `.` to `\\.` so that path-to-regexp will treat it as the plain
66
+ // `.` character
67
+ return path . replace ( POSSIBLE_VARNAME_PATTERN , ':$1' ) . replace ( '.' , '\\.' ) ;
66
68
}
Original file line number Diff line number Diff line change 4
4
// License text available at https://opensource.org/licenses/MIT
5
5
6
6
import { PathParameterValues } from '../types' ;
7
+ import { toExpressPath } from './openapi-path' ;
8
+ import pathToRegexp = require( 'path-to-regexp' ) ;
7
9
8
10
/**
9
11
* A Node in the trie
@@ -215,17 +217,13 @@ function createNode<T>(
215
217
}
216
218
217
219
// Check if the key has variables such as `{var}`
218
- const pattern = / \{ ( [ ^ \{ ] * ) \} / g;
219
- const names : string [ ] = [ ] ;
220
- let match ;
221
- while ( ( match = pattern . exec ( key ) ) ) {
222
- names . push ( match [ 1 ] ) ;
223
- }
220
+ const path = toExpressPath ( key ) ;
221
+ const params : pathToRegexp . Key [ ] = [ ] ;
222
+ const re = pathToRegexp ( path , params ) ;
224
223
225
- if ( names . length ) {
226
- child . names = names ;
227
- const re = '^' + key . replace ( / \{ ( [ ^ \} ] + ) \} / g, '(.+)' ) + '$' ;
228
- child . regexp = new RegExp ( re ) ;
224
+ if ( params . length ) {
225
+ child . names = params . map ( p => `${ p . name } ` ) ;
226
+ child . regexp = re ;
229
227
}
230
228
231
229
// Add the node to the parent
Original file line number Diff line number Diff line change @@ -22,6 +22,16 @@ describe('validateApiPath', () => {
22
22
expect ( path ) . to . eql ( '/{foo}/{bar}' ) ;
23
23
} ) ;
24
24
25
+ it ( 'allows /{foo}.{bar}' , ( ) => {
26
+ const path = validateApiPath ( '/{foo}.{bar}' ) ;
27
+ expect ( path ) . to . eql ( '/{foo}.{bar}' ) ;
28
+ } ) ;
29
+
30
+ it ( 'allows /{foo}@{bar}' , ( ) => {
31
+ const path = validateApiPath ( '/{foo}@{bar}' ) ;
32
+ expect ( path ) . to . eql ( '/{foo}@{bar}' ) ;
33
+ } ) ;
34
+
25
35
it ( 'allows /{_foo}/{bar}' , ( ) => {
26
36
const path = validateApiPath ( '/{_foo}/{bar}' ) ;
27
37
expect ( path ) . to . eql ( '/{_foo}/{bar}' ) ;
Original file line number Diff line number Diff line change @@ -188,6 +188,32 @@ function runTestsWithRouter(router: RestRouter) {
188
188
expect ( route . pathParams ) . to . containEql ( { arg1 : '3' , arg2 : '2' } ) ;
189
189
} ) ;
190
190
191
+ it ( 'finds "GET /getProfile/{userId}.{format}" endpoint' , ( ) => {
192
+ const spec = anOpenApiSpec ( )
193
+ . withOperationReturningString (
194
+ 'get' ,
195
+ '/getProfile/{userId}.{format}' ,
196
+ 'getProfile' ,
197
+ )
198
+ . build ( ) ;
199
+
200
+ spec . basePath = '/my' ;
201
+
202
+ class TestController { }
203
+
204
+ const table = givenRoutingTable ( ) ;
205
+ table . registerController ( spec , TestController ) ;
206
+
207
+ let request = givenRequest ( {
208
+ method : 'get' ,
209
+ url : '/my/getProfile/1.json' ,
210
+ } ) ;
211
+
212
+ let route = table . find ( request ) ;
213
+ expect ( route . path ) . to . eql ( '/my/getProfile/{userId}.{format}' ) ;
214
+ expect ( route . pathParams ) . to . containEql ( { userId : '1' , format : 'json' } ) ;
215
+ } ) ;
216
+
191
217
it ( 'throws if router is not found' , ( ) => {
192
218
const table = givenRoutingTable ( ) ;
193
219
Original file line number Diff line number Diff line change @@ -53,7 +53,7 @@ describe('Trie', () => {
53
53
key : '{id}' ,
54
54
value : getOrderById ,
55
55
names : [ 'id' ] ,
56
- regexp : / ^ ( . + ) $ / ,
56
+ regexp : / ^ ( [ ^ \/ ] + ? ) (?: \/ ) ? $ / i ,
57
57
children : { } ,
58
58
} ,
59
59
} ,
@@ -89,7 +89,7 @@ describe('Trie', () => {
89
89
key : '{id}' ,
90
90
value : { verb : 'get' , path : '/orders/{id}' } ,
91
91
names : [ 'id' ] ,
92
- regexp : / ^ ( . + ) $ / ,
92
+ regexp : / ^ ( [ ^ \/ ] + ? ) (?: \/ ) ? $ / i ,
93
93
} ,
94
94
] ) ;
95
95
} ) ;
@@ -104,7 +104,7 @@ describe('Trie', () => {
104
104
key : '{id}' ,
105
105
value : { verb : 'get' , path : '/orders/{id}' } ,
106
106
names : [ 'id' ] ,
107
- regexp : / ^ ( . + ) $ / ,
107
+ regexp : / ^ ( [ ^ \/ ] + ? ) (?: \/ ) ? $ / i ,
108
108
children : { } ,
109
109
} ,
110
110
] ) ;
You can’t perform that action at this time.
0 commit comments