| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const { eq, remove, cloneDeep } = require('lodash/fp'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Create a default Strapi hook | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createHook = () => { | 
					
						
							|  |  |  |   const state = { | 
					
						
							|  |  |  |     handlers: [], | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							| 
									
										
										
										
											2022-05-09 20:55:21 +02:00
										 |  |  |     getHandlers() { | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |       return state.handlers; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |     register(handler) { | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |       state.handlers.push(handler); | 
					
						
							| 
									
										
										
										
											2022-05-09 20:55:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |       return this; | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |     delete(handler) { | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |       state.handlers = remove(eq(handler), state.handlers); | 
					
						
							| 
									
										
										
										
											2022-05-09 20:55:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |       return this; | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     call() { | 
					
						
							|  |  |  |       throw new Error('Method not implemented'); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Create an async series hook. | 
					
						
							|  |  |  |  * Upon execution, it will execute every handler in order with the same context | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createAsyncSeriesHook = () => ({ | 
					
						
							|  |  |  |   ...createHook(), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async call(context) { | 
					
						
							| 
									
										
										
										
											2022-05-09 20:55:21 +02:00
										 |  |  |     for (const handler of this.getHandlers()) { | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |       await handler(context); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Create an async series waterfall hook. | 
					
						
							|  |  |  |  * Upon execution, it will execute every handler in order and pass the return value of the last handler to the next one | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createAsyncSeriesWaterfallHook = () => ({ | 
					
						
							|  |  |  |   ...createHook(), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async call(param) { | 
					
						
							|  |  |  |     let res = param; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-09 20:55:21 +02:00
										 |  |  |     for (const handler of this.getHandlers()) { | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  |       res = await handler(res); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return res; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Create an async parallel hook. | 
					
						
							|  |  |  |  * Upon execution, it will execute every registered handler in band. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createAsyncParallelHook = () => ({ | 
					
						
							|  |  |  |   ...createHook(), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 13:06:40 +02:00
										 |  |  |   async call(context) { | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |     const promises = this.getHandlers().map((handler) => handler(cloneDeep(context))); | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Promise.all(promises); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-21 10:42:30 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Create an async parallel hook. | 
					
						
							|  |  |  |  * Upon execution, it will execute every registered handler in serie and return the first result found. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const createAsyncBailHook = () => ({ | 
					
						
							|  |  |  |   ...createHook(), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async call(context) { | 
					
						
							|  |  |  |     for (const handler of this.getHandlers()) { | 
					
						
							|  |  |  |       const result = await handler(context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (result !== undefined) { | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  | module.exports = { | 
					
						
							|  |  |  |   // Internal utils
 | 
					
						
							|  |  |  |   internals: { | 
					
						
							|  |  |  |     createHook, | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   // Hooks
 | 
					
						
							|  |  |  |   createAsyncSeriesHook, | 
					
						
							|  |  |  |   createAsyncSeriesWaterfallHook, | 
					
						
							|  |  |  |   createAsyncParallelHook, | 
					
						
							| 
									
										
										
										
											2022-07-21 10:42:30 +02:00
										 |  |  |   createAsyncBailHook, | 
					
						
							| 
									
										
										
										
											2021-03-25 14:59:44 +01:00
										 |  |  | }; |