11import * as t from "tap" ;
2- import { buildRouteFromURL } from "./buildRouteFromURL" ;
2+ import { buildRouteFromURL , compileCustomPattern } from "./buildRouteFromURL" ;
33import * as ObjectID from "bson-objectid" ;
44import { createHash } from "crypto" ;
55
66t . test ( "it returns undefined for invalid URLs" , async ( ) => {
7- t . same ( buildRouteFromURL ( "" ) , undefined ) ;
8- t . same ( buildRouteFromURL ( "http" ) , undefined ) ;
7+ t . same ( buildRouteFromURL ( "" , [ ] ) , undefined ) ;
8+ t . same ( buildRouteFromURL ( "http" , [ ] ) , undefined ) ;
99} ) ;
1010
1111t . test ( "it returns / for root URLs" , async ( ) => {
12- t . same ( buildRouteFromURL ( "/" ) , "/" ) ;
13- t . same ( buildRouteFromURL ( "http://localhost/" ) , "/" ) ;
12+ t . same ( buildRouteFromURL ( "/" , [ ] ) , "/" ) ;
13+ t . same ( buildRouteFromURL ( "http://localhost/" , [ ] ) , "/" ) ;
1414} ) ;
1515
1616t . test ( "it replaces numbers" , async ( ) => {
17- t . same ( buildRouteFromURL ( "/posts/3" ) , "/posts/:number" ) ;
18- t . same ( buildRouteFromURL ( "http://localhost/posts/3" ) , "/posts/:number" ) ;
19- t . same ( buildRouteFromURL ( "http://localhost/posts/3/" ) , "/posts/:number" ) ;
17+ t . same ( buildRouteFromURL ( "/posts/3" , [ ] ) , "/posts/:number" ) ;
18+ t . same ( buildRouteFromURL ( "http://localhost/posts/3" , [ ] ) , "/posts/:number" ) ;
19+ t . same ( buildRouteFromURL ( "http://localhost/posts/3/" , [ ] ) , "/posts/:number" ) ;
2020 t . same (
21- buildRouteFromURL ( "http://localhost/posts/3/comments/10" ) ,
21+ buildRouteFromURL ( "http://localhost/posts/3/comments/10" , [ ] ) ,
2222 "/posts/:number/comments/:number"
2323 ) ;
2424 t . same (
25- buildRouteFromURL ( "/blog/2023/05/great-article" ) ,
25+ buildRouteFromURL ( "/blog/2023/05/great-article" , [ ] ) ,
2626 "/blog/:number/:number/great-article"
2727 ) ;
2828} ) ;
2929
3030t . test ( "it replaces dates" , async ( ) => {
31- t . same ( buildRouteFromURL ( "/posts/2023-05-01" ) , "/posts/:date" ) ;
32- t . same ( buildRouteFromURL ( "/posts/2023-05-01/" ) , "/posts/:date" ) ;
31+ t . same ( buildRouteFromURL ( "/posts/2023-05-01" , [ ] ) , "/posts/:date" ) ;
32+ t . same ( buildRouteFromURL ( "/posts/2023-05-01/" , [ ] ) , "/posts/:date" ) ;
3333 t . same (
34- buildRouteFromURL ( "/posts/2023-05-01/comments/2023-05-01" ) ,
34+ buildRouteFromURL ( "/posts/2023-05-01/comments/2023-05-01" , [ ] ) ,
3535 "/posts/:date/comments/:date"
3636 ) ;
37- t . same ( buildRouteFromURL ( "/posts/01-05-2023" ) , "/posts/:date" ) ;
37+ t . same ( buildRouteFromURL ( "/posts/01-05-2023" , [ ] ) , "/posts/:date" ) ;
3838} ) ;
3939
4040t . test ( "it ignores API version numbers" , async ( ) => {
41- t . same ( buildRouteFromURL ( "/v1/posts/3" ) , "/v1/posts/:number" ) ;
41+ t . same ( buildRouteFromURL ( "/v1/posts/3" , [ ] ) , "/v1/posts/:number" ) ;
4242} ) ;
4343
4444t . test ( "it replaces UUIDs v1" , async ( ) => {
4545 t . same (
46- buildRouteFromURL ( "/posts/d9428888-122b-11e1-b85c-61cd3cbb3210" ) ,
46+ buildRouteFromURL ( "/posts/d9428888-122b-11e1-b85c-61cd3cbb3210" , [ ] ) ,
4747 "/posts/:uuid"
4848 ) ;
4949} ) ;
5050
5151t . test ( "it replaces UUIDs v2" , async ( ) => {
5252 t . same (
53- buildRouteFromURL ( "/posts/000003e8-2363-21ef-b200-325096b39f47" ) ,
53+ buildRouteFromURL ( "/posts/000003e8-2363-21ef-b200-325096b39f47" , [ ] ) ,
5454 "/posts/:uuid"
5555 ) ;
5656} ) ;
5757
5858t . test ( "it replaces UUIDs v3" , async ( ) => {
5959 t . same (
60- buildRouteFromURL ( "/posts/a981a0c2-68b1-35dc-bcfc-296e52ab01ec" ) ,
60+ buildRouteFromURL ( "/posts/a981a0c2-68b1-35dc-bcfc-296e52ab01ec" , [ ] ) ,
6161 "/posts/:uuid"
6262 ) ;
6363} ) ;
6464
6565t . test ( "it replaces UUIDs v4" , async ( ) => {
6666 t . same (
67- buildRouteFromURL ( "/posts/109156be-c4fb-41ea-b1b4-efe1671c5836" ) ,
67+ buildRouteFromURL ( "/posts/109156be-c4fb-41ea-b1b4-efe1671c5836" , [ ] ) ,
6868 "/posts/:uuid"
6969 ) ;
7070} ) ;
7171
7272t . test ( "it replaces UUIDs v5" , async ( ) => {
7373 t . same (
74- buildRouteFromURL ( "/posts/90123e1c-7512-523e-bb28-76fab9f2f73d" ) ,
74+ buildRouteFromURL ( "/posts/90123e1c-7512-523e-bb28-76fab9f2f73d" , [ ] ) ,
7575 "/posts/:uuid"
7676 ) ;
7777} ) ;
7878
7979t . test ( "it replaces UUIDs v6" , async ( ) => {
8080 t . same (
81- buildRouteFromURL ( "/posts/1ef21d2f-1207-6660-8c4f-419efbd44d48" ) ,
81+ buildRouteFromURL ( "/posts/1ef21d2f-1207-6660-8c4f-419efbd44d48" , [ ] ) ,
8282 "/posts/:uuid"
8383 ) ;
8484} ) ;
8585
8686t . test ( "it replaces UUIDs v7" , async ( ) => {
8787 t . same (
88- buildRouteFromURL ( "/posts/017f22e2-79b0-7cc3-98c4-dc0c0c07398f" ) ,
88+ buildRouteFromURL ( "/posts/017f22e2-79b0-7cc3-98c4-dc0c0c07398f" , [ ] ) ,
8989 "/posts/:uuid"
9090 ) ;
9191} ) ;
9292
9393t . test ( "it replaces UUIDs v8" , async ( ) => {
9494 t . same (
95- buildRouteFromURL ( "/posts/0d8f23a0-697f-83ae-802e-48f3756dd581" ) ,
95+ buildRouteFromURL ( "/posts/0d8f23a0-697f-83ae-802e-48f3756dd581" , [ ] ) ,
9696 "/posts/:uuid"
9797 ) ;
9898} ) ;
9999
100100t . test ( "it ignores invalid UUIDs" , async ( ) => {
101101 t . same (
102- buildRouteFromURL ( "/posts/00000000-0000-1000-6000-000000000000" ) ,
102+ buildRouteFromURL ( "/posts/00000000-0000-1000-6000-000000000000" , [ ] ) ,
103103 "/posts/00000000-0000-1000-6000-000000000000"
104104 ) ;
105105} ) ;
106106
107107t . test ( "it ignores strings" , async ( ) => {
108- t . same ( buildRouteFromURL ( "/posts/abc" ) , "/posts/abc" ) ;
108+ t . same ( buildRouteFromURL ( "/posts/abc" , [ ] ) , "/posts/abc" ) ;
109109} ) ;
110110
111111t . test ( "it replaces email addresses" , async ( ) => {
112- t . same ( buildRouteFromURL ( "/login/john.doe@acme.com" ) , "/login/:email" ) ;
113- t . same ( buildRouteFromURL ( "/login/john.doe+alias@acme.com" ) , "/login/:email" ) ;
112+ t . same ( buildRouteFromURL ( "/login/john.doe@acme.com" , [ ] ) , "/login/:email" ) ;
113+ t . same (
114+ buildRouteFromURL ( "/login/john.doe+alias@acme.com" , [ ] ) ,
115+ "/login/:email"
116+ ) ;
114117} ) ;
115118
116119t . test ( "it replaces IP addresses" , async ( ) => {
117- t . same ( buildRouteFromURL ( "/block/1.2.3.4" ) , "/block/:ip" ) ;
120+ t . same ( buildRouteFromURL ( "/block/1.2.3.4" , [ ] ) , "/block/:ip" ) ;
118121 t . same (
119- buildRouteFromURL ( "/block/2001:2:ffff:ffff:ffff:ffff:ffff:ffff" ) ,
122+ buildRouteFromURL ( "/block/2001:2:ffff:ffff:ffff:ffff:ffff:ffff" , [ ] ) ,
120123 "/block/:ip"
121124 ) ;
122- t . same ( buildRouteFromURL ( "/block/64:ff9a::255.255.255.255" ) , "/block/:ip" ) ;
123- t . same ( buildRouteFromURL ( "/block/100::" ) , "/block/:ip" ) ;
124- t . same ( buildRouteFromURL ( "/block/fec0::" ) , "/block/:ip" ) ;
125- t . same ( buildRouteFromURL ( "/block/227.202.96.196" ) , "/block/:ip" ) ;
125+ t . same (
126+ buildRouteFromURL ( "/block/64:ff9a::255.255.255.255" , [ ] ) ,
127+ "/block/:ip"
128+ ) ;
129+ t . same ( buildRouteFromURL ( "/block/100::" , [ ] ) , "/block/:ip" ) ;
130+ t . same ( buildRouteFromURL ( "/block/fec0::" , [ ] ) , "/block/:ip" ) ;
131+ t . same ( buildRouteFromURL ( "/block/227.202.96.196" , [ ] ) , "/block/:ip" ) ;
126132} ) ;
127133
128134function generateHash ( type : string ) {
129135 return createHash ( type ) . update ( "test" ) . digest ( "hex" ) ;
130136}
131137
132138t . test ( "it replaces hashes" , async ( ) => {
133- t . same ( buildRouteFromURL ( `/files/${ generateHash ( "md5" ) } ` ) , "/files/:hash" ) ;
134- t . same ( buildRouteFromURL ( `/files/${ generateHash ( "sha1" ) } ` ) , "/files/:hash" ) ;
135- t . same ( buildRouteFromURL ( `/files/${ generateHash ( "sha256" ) } ` ) , "/files/:hash" ) ;
136- t . same ( buildRouteFromURL ( `/files/${ generateHash ( "sha512" ) } ` ) , "/files/:hash" ) ;
139+ t . same (
140+ buildRouteFromURL ( `/files/${ generateHash ( "md5" ) } ` , [ ] ) ,
141+ "/files/:hash"
142+ ) ;
143+ t . same (
144+ buildRouteFromURL ( `/files/${ generateHash ( "sha1" ) } ` , [ ] ) ,
145+ "/files/:hash"
146+ ) ;
147+ t . same (
148+ buildRouteFromURL ( `/files/${ generateHash ( "sha256" ) } ` , [ ] ) ,
149+ "/files/:hash"
150+ ) ;
151+ t . same (
152+ buildRouteFromURL ( `/files/${ generateHash ( "sha512" ) } ` , [ ] ) ,
153+ "/files/:hash"
154+ ) ;
137155} ) ;
138156
139157t . test ( "it replaces secrets" , async ( ) => {
140158 t . same (
141- buildRouteFromURL ( "/confirm/CnJ4DunhYfv2db6T1FRfciRBHtlNKOYrjoz" ) ,
159+ buildRouteFromURL ( "/confirm/CnJ4DunhYfv2db6T1FRfciRBHtlNKOYrjoz" , [ ] ) ,
142160 "/confirm/:secret"
143161 ) ;
144162} ) ;
@@ -150,24 +168,24 @@ t.test("it replaces BSON ObjectIDs", async () => {
150168 "/posts/:objectId"
151169 ) ;
152170 t . same (
153- buildRouteFromURL ( `/posts/66ec29159d00113616fc7184` ) ,
171+ buildRouteFromURL ( `/posts/66ec29159d00113616fc7184` , [ ] ) ,
154172 "/posts/:objectId"
155173 ) ;
156174} ) ;
157175
158176t . test ( "it replaces ULID strings" , async ( ) => {
159177 t . same (
160- buildRouteFromURL ( "/posts/01ARZ3NDEKTSV4RRFFQ69G5FAV" ) ,
178+ buildRouteFromURL ( "/posts/01ARZ3NDEKTSV4RRFFQ69G5FAV" , [ ] ) ,
161179 "/posts/:ulid"
162180 ) ;
163181 t . same (
164- buildRouteFromURL ( "/posts/01arz3ndektsv4rrffq69g5fav" ) ,
182+ buildRouteFromURL ( "/posts/01arz3ndektsv4rrffq69g5fav" , [ ] ) ,
165183 "/posts/:ulid"
166184 ) ;
167185} ) ;
168186
169187t . test ( "test_ratelimiting_1 is not a secret" , async ( ) => {
170- t . same ( buildRouteFromURL ( "/test_ratelimiting_1" ) , "/test_ratelimiting_1" ) ;
188+ t . same ( buildRouteFromURL ( "/test_ratelimiting_1" , [ ] ) , "/test_ratelimiting_1" ) ;
171189} ) ;
172190
173191t . test ( "it does not detect static files as secrets" , async ( ) => {
@@ -180,33 +198,37 @@ t.test("it does not detect static files as secrets", async () => {
180198 ] ;
181199
182200 for ( const file of files ) {
183- t . same ( buildRouteFromURL ( `/assets/${ file } ` ) , `/assets/${ file } ` ) ;
201+ t . same ( buildRouteFromURL ( `/assets/${ file } ` , [ ] ) , `/assets/${ file } ` ) ;
184202 }
185203} ) ;
186204
187205t . test ( "it detects numeric comma separated arrays" , async ( t ) => {
188- t . same ( buildRouteFromURL ( "/users/1,2" ) , "/users/:array(number)" ) ;
189- t . same ( buildRouteFromURL ( "/users/1,2,3,4,5" ) , "/users/:array(number)" ) ;
206+ t . same ( buildRouteFromURL ( "/users/1,2" , [ ] ) , "/users/:array(number)" ) ;
207+ t . same ( buildRouteFromURL ( "/users/1,2,3,4,5" , [ ] ) , "/users/:array(number)" ) ;
190208 t . same (
191- buildRouteFromURL ( "/users/100,200,3000000,40000000,500000000" ) ,
209+ buildRouteFromURL ( "/users/100,200,3000000,40000000,500000000" , [ ] ) ,
192210 "/users/:array(number)"
193211 ) ;
194212
195- t . same ( buildRouteFromURL ( "/users/1,2,3,4," ) , "/users/1,2,3,4," ) ;
196- t . same ( buildRouteFromURL ( "/users/1," ) , "/users/1," ) ;
197- t . same ( buildRouteFromURL ( "/users/,1,2" ) , "/users/,1,2" ) ;
198- t . same ( buildRouteFromURL ( "/users/1,2,3_" ) , "/users/1,2,3_" ) ;
199- t . same ( buildRouteFromURL ( "/users/1,2,3a" ) , "/users/1,2,3a" ) ;
213+ t . same ( buildRouteFromURL ( "/users/1,2,3,4," , [ ] ) , "/users/1,2,3,4," ) ;
214+ t . same ( buildRouteFromURL ( "/users/1," , [ ] ) , "/users/1," ) ;
215+ t . same ( buildRouteFromURL ( "/users/,1,2" , [ ] ) , "/users/,1,2" ) ;
216+ t . same ( buildRouteFromURL ( "/users/1,2,3_" , [ ] ) , "/users/1,2,3_" ) ;
217+ t . same ( buildRouteFromURL ( "/users/1,2,3a" , [ ] ) , "/users/1,2,3a" ) ;
200218} ) ;
201219
202220t . test ( "it supports custom patterns" , async ( ) => {
203221 t . same (
204- buildRouteFromURL ( "/prefix-103799/api/dashboard" , [ "prefix-{digits}" ] ) ,
222+ buildRouteFromURL ( "/prefix-103799/api/dashboard" , [
223+ compileCustomPattern ( "prefix-{digits}" ) ! ,
224+ ] ) ,
205225 "/:custom/api/dashboard"
206226 ) ;
207227
208228 t . same (
209- buildRouteFromURL ( "/blog/01-31513/slug" , [ "{digits}-{digits}" ] ) ,
229+ buildRouteFromURL ( "/blog/01-31513/slug" , [
230+ compileCustomPattern ( "{digits}-{digits}" ) ! ,
231+ ] ) ,
210232 "/blog/:custom/slug"
211233 ) ;
212234} ) ;
0 commit comments