55// themselves use our routing information, without disturbing express
66// components that external developers may be modifying.
77
8- function PromiseRouter ( ) {
8+ export default class PromiseRouter {
99 // Each entry should be an object with:
1010 // path: the path to route, in express format
1111 // method: the HTTP method that this route handles.
@@ -15,73 +15,102 @@ function PromiseRouter() {
1515 // status: optional. the http status code. defaults to 200
1616 // response: a json object with the content of the response
1717 // location: optional. a location header
18- this . routes = [ ] ;
19- }
20-
21- // Global flag. Set this to true to log every request and response.
22- PromiseRouter . verbose = process . env . VERBOSE || false ;
23-
24- // Merge the routes into this one
25- PromiseRouter . prototype . merge = function ( router ) {
26- for ( var route of router . routes ) {
27- this . routes . push ( route ) ;
28- }
29- } ;
30-
31- PromiseRouter . prototype . route = function ( method , path , handler ) {
32- switch ( method ) {
33- case 'POST' :
34- case 'GET' :
35- case 'PUT' :
36- case 'DELETE' :
37- break ;
38- default :
39- throw 'cannot route method: ' + method ;
18+ constructor ( ) {
19+ this . routes = [ ] ;
20+ this . mountRoutes ( ) ;
4021 }
22+
23+ // Leave the opportunity to
24+ // subclasses to mount their routes by overriding
25+ mountRoutes ( ) { }
26+
27+ // Merge the routes into this one
28+ merge ( router ) {
29+ for ( var route of router . routes ) {
30+ this . routes . push ( route ) ;
31+ }
32+ } ;
33+
34+ route ( method , path , handler ) {
35+ switch ( method ) {
36+ case 'POST' :
37+ case 'GET' :
38+ case 'PUT' :
39+ case 'DELETE' :
40+ break ;
41+ default :
42+ throw 'cannot route method: ' + method ;
43+ }
4144
42- this . routes . push ( {
43- path : path ,
44- method : method ,
45- handler : handler
46- } ) ;
47- } ;
45+ this . routes . push ( {
46+ path : path ,
47+ method : method ,
48+ handler : handler
49+ } ) ;
50+ } ;
51+
52+ // Returns an object with:
53+ // handler: the handler that should deal with this request
54+ // params: any :-params that got parsed from the path
55+ // Returns undefined if there is no match.
56+ match ( method , path ) {
57+ for ( var route of this . routes ) {
58+ if ( route . method != method ) {
59+ continue ;
60+ }
4861
49- // Returns an object with:
50- // handler: the handler that should deal with this request
51- // params: any :-params that got parsed from the path
52- // Returns undefined if there is no match.
53- PromiseRouter . prototype . match = function ( method , path ) {
54- for ( var route of this . routes ) {
55- if ( route . method != method ) {
56- continue ;
57- }
62+ // NOTE: we can only route the specific wildcards :className and
63+ // :objectId, and in that order.
64+ // This is pretty hacky but I don't want to rebuild the entire
65+ // express route matcher. Maybe there's a way to reuse its logic.
66+ var pattern = '^' + route . path + '$' ;
5867
59- // NOTE: we can only route the specific wildcards :className and
60- // :objectId, and in that order.
61- // This is pretty hacky but I don't want to rebuild the entire
62- // express route matcher. Maybe there's a way to reuse its logic.
63- var pattern = '^' + route . path + '$' ;
68+ pattern = pattern . replace ( ':className' ,
69+ '(_?[A-Za-z][A-Za-z_0-9]*)' ) ;
70+ pattern = pattern . replace ( ':objectId' ,
71+ '([A-Za-z0-9]+)' ) ;
72+ var re = new RegExp ( pattern ) ;
73+ var m = path . match ( re ) ;
74+ if ( ! m ) {
75+ continue ;
76+ }
77+ var params = { } ;
78+ if ( m [ 1 ] ) {
79+ params . className = m [ 1 ] ;
80+ }
81+ if ( m [ 2 ] ) {
82+ params . objectId = m [ 2 ] ;
83+ }
6484
65- pattern = pattern . replace ( ':className' ,
66- '(_?[A-Za-z][A-Za-z_0-9]*)' ) ;
67- pattern = pattern . replace ( ':objectId' ,
68- '([A-Za-z0-9]+)' ) ;
69- var re = new RegExp ( pattern ) ;
70- var m = path . match ( re ) ;
71- if ( ! m ) {
72- continue ;
85+ return { params : params , handler : route . handler } ;
7386 }
74- var params = { } ;
75- if ( m [ 1 ] ) {
76- params . className = m [ 1 ] ;
77- }
78- if ( m [ 2 ] ) {
79- params . objectId = m [ 2 ] ;
87+ } ;
88+
89+ // Mount the routes on this router onto an express app (or express router)
90+ mountOnto ( expressApp ) {
91+ for ( var route of this . routes ) {
92+ switch ( route . method ) {
93+ case 'POST' :
94+ expressApp . post ( route . path , makeExpressHandler ( route . handler ) ) ;
95+ break ;
96+ case 'GET' :
97+ expressApp . get ( route . path , makeExpressHandler ( route . handler ) ) ;
98+ break ;
99+ case 'PUT' :
100+ expressApp . put ( route . path , makeExpressHandler ( route . handler ) ) ;
101+ break ;
102+ case 'DELETE' :
103+ expressApp . delete ( route . path , makeExpressHandler ( route . handler ) ) ;
104+ break ;
105+ default :
106+ throw 'unexpected code branch' ;
107+ }
80108 }
109+ } ;
110+ }
81111
82- return { params : params , handler : route . handler } ;
83- }
84- } ;
112+ // Global flag. Set this to true to log every request and response.
113+ PromiseRouter . verbose = process . env . VERBOSE || false ;
85114
86115// A helper function to make an express handler out of a a promise
87116// handler.
@@ -122,27 +151,3 @@ function makeExpressHandler(promiseHandler) {
122151 }
123152 }
124153}
125-
126- // Mount the routes on this router onto an express app (or express router)
127- PromiseRouter . prototype . mountOnto = function ( expressApp ) {
128- for ( var route of this . routes ) {
129- switch ( route . method ) {
130- case 'POST' :
131- expressApp . post ( route . path , makeExpressHandler ( route . handler ) ) ;
132- break ;
133- case 'GET' :
134- expressApp . get ( route . path , makeExpressHandler ( route . handler ) ) ;
135- break ;
136- case 'PUT' :
137- expressApp . put ( route . path , makeExpressHandler ( route . handler ) ) ;
138- break ;
139- case 'DELETE' :
140- expressApp . delete ( route . path , makeExpressHandler ( route . handler ) ) ;
141- break ;
142- default :
143- throw 'unexpected code branch' ;
144- }
145- }
146- } ;
147-
148- module . exports = PromiseRouter ;
0 commit comments