UNPKG

2.77 kBJavaScriptView Raw
1'use strict'
2
3const supportedHooks = [
4 'onRequest',
5 'preParsing',
6 'preValidation',
7 'preSerialization',
8 'preHandler',
9 'onResponse',
10 'onSend',
11 'onError',
12 // executed at start/close time
13 'onRoute',
14 'onRegister',
15 'onClose'
16]
17const {
18 codes: {
19 FST_ERR_HOOK_INVALID_TYPE,
20 FST_ERR_HOOK_INVALID_HANDLER
21 }
22} = require('./errors')
23
24function Hooks () {
25 this.onRequest = []
26 this.preParsing = []
27 this.preValidation = []
28 this.preSerialization = []
29 this.preHandler = []
30 this.onResponse = []
31 this.onSend = []
32 this.onError = []
33}
34
35Hooks.prototype.validate = function (hook, fn) {
36 if (typeof hook !== 'string') throw new FST_ERR_HOOK_INVALID_TYPE()
37 if (typeof fn !== 'function') throw new FST_ERR_HOOK_INVALID_HANDLER()
38 if (supportedHooks.indexOf(hook) === -1) {
39 throw new Error(`${hook} hook not supported!`)
40 }
41}
42
43Hooks.prototype.add = function (hook, fn) {
44 this.validate(hook, fn)
45 this[hook].push(fn)
46}
47
48function buildHooks (h) {
49 const hooks = new Hooks()
50 hooks.onRequest = h.onRequest.slice()
51 hooks.preParsing = h.preParsing.slice()
52 hooks.preValidation = h.preValidation.slice()
53 hooks.preSerialization = h.preSerialization.slice()
54 hooks.preHandler = h.preHandler.slice()
55 hooks.onSend = h.onSend.slice()
56 hooks.onResponse = h.onResponse.slice()
57 hooks.onError = h.onError.slice()
58 return hooks
59}
60
61function hookRunner (functions, runner, request, reply, cb) {
62 var i = 0
63
64 function next (err) {
65 if (err || i === functions.length) {
66 cb(err, request, reply)
67 return
68 }
69
70 const result = runner(functions[i++], request, reply, next)
71 if (result && typeof result.then === 'function') {
72 result.then(handleResolve, handleReject)
73 }
74 }
75
76 function handleResolve () {
77 next()
78 }
79
80 function handleReject (err) {
81 cb(err, request, reply)
82 }
83
84 next()
85}
86
87function onSendHookRunner (functions, request, reply, payload, cb) {
88 var i = 0
89
90 function next (err, newPayload) {
91 if (err) {
92 cb(err, request, reply, payload)
93 return
94 }
95
96 if (newPayload !== undefined) {
97 payload = newPayload
98 }
99
100 if (i === functions.length) {
101 cb(null, request, reply, payload)
102 return
103 }
104
105 const result = functions[i++](request, reply, payload, next)
106 if (result && typeof result.then === 'function') {
107 result.then(handleResolve, handleReject)
108 }
109 }
110
111 function handleResolve (newPayload) {
112 next(null, newPayload)
113 }
114
115 function handleReject (err) {
116 cb(err, request, reply, payload)
117 }
118
119 next()
120}
121
122function hookIterator (fn, request, reply, next) {
123 if (reply.sent === true) return undefined
124 return fn(request, reply, next)
125}
126
127module.exports = {
128 Hooks,
129 buildHooks,
130 hookRunner,
131 onSendHookRunner,
132 hookIterator
133}