-
Notifications
You must be signed in to change notification settings - Fork 393
Expand file tree
/
Copy pathfilterService.ts
More file actions
118 lines (106 loc) · 3.79 KB
/
filterService.ts
File metadata and controls
118 lines (106 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { getLogger } from 'pinus-logger';import { RouteRecord } from '../../util/constants';
import { HandlerCallback } from './handlerService';
import { BeforeHandlerFilter, AfterHandlerFilter } from '../../interfaces/IHandlerFilter';
import { FrontendOrBackendSession } from '../../server/server';
let logger = getLogger('pinus', __filename);
/**
* Filter service.
* Register and fire before and after filters.
*/
export class FilterService
{
befores : BeforeHandlerFilter[] = []; // before filters
afters : AfterHandlerFilter[] = []; // after filters
name = 'filter';
/**
* Add before filter into the filter chain.
*
* @param filter {Object|Function} filter instance or filter function.
*/
before(filter : BeforeHandlerFilter)
{
this.befores.push(filter);
};
/**
* Add after filter into the filter chain.
*
* @param filter {Object|Function} filter instance or filter function.
*/
after(filter : AfterHandlerFilter)
{
this.afters.unshift(filter);
};
/**
* TODO: other insert method for filter? such as unshift
*/
/**
* Do the before filter.
* Fail over if any filter pass err parameter to the next function.
*
* @param msg {Object} clienet request msg
* @param session {Object} a session object for current request
* @param cb {Function} cb(err) callback function to invoke next chain node
*/
beforeFilter(routeRecord : RouteRecord ,msg : any, session : FrontendOrBackendSession, cb : HandlerCallback)
{
let index = 0, self = this;
let next = function (err?: any, resp?: any)
{
if (err || index >= self.befores.length)
{
cb(err, resp);
return;
}
let handler = self.befores[index++];
if (typeof handler === 'function')
{
handler(routeRecord , msg, session, next);
} else if (typeof handler.before === 'function')
{
handler.before(routeRecord , msg, session, next);
} else
{
logger.error('meet invalid before filter, handler or handler.before should be function.');
next(new Error('invalid before filter.'));
}
}; //end of next
next();
};
/**
* Do after filter chain.
* Give server a chance to do clean up jobs after request responsed.
* After filter can not change the request flow before.
* After filter should call the next callback to let the request pass to next after filter.
*
* @param err {Object} error object
* @param session {Object} session object for current request
* @param {Object} resp response object send to client
* @param cb {Function} cb(err) callback function to invoke next chain node
*/
afterFilter(err : Error, routeRecord : RouteRecord ,msg : any, session : FrontendOrBackendSession, resp : any, cb : HandlerCallback)
{
let index = 0, self = this;
function next(err : Error)
{
//if done
if (index >= self.afters.length)
{
cb(err);
return;
}
let handler = self.afters[index++];
if (typeof handler === 'function')
{
handler(err, routeRecord , msg, session, resp, next);
} else if (typeof handler.after === 'function')
{
handler.after(err, routeRecord , msg, session, resp, next);
} else
{
logger.error('meet invalid after filter, handler or handler.after should be function.');
next(new Error('invalid after filter.'));
}
} //end of next
next(err);
};
}