mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-13 17:43:59 +00:00
68 lines
1.6 KiB
JavaScript
68 lines
1.6 KiB
JavaScript
|
|
||
|
import consola from 'consola'
|
||
|
|
||
|
import { sequence } from './utils'
|
||
|
|
||
|
export default class Hookable {
|
||
|
constructor() {
|
||
|
this._hooks = {}
|
||
|
this._deprecatedHooks = {}
|
||
|
|
||
|
this.hook = this.hook.bind(this)
|
||
|
this.callHook = this.callHook.bind(this)
|
||
|
}
|
||
|
|
||
|
hook(name, fn) {
|
||
|
if (!name || typeof fn !== 'function') {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if (this._deprecatedHooks[name]) {
|
||
|
consola.warn(`${name} hook has been deprecated, please use ${this._deprecatedHooks[name]}`)
|
||
|
name = this._deprecatedHooks[name]
|
||
|
}
|
||
|
|
||
|
this._hooks[name] = this._hooks[name] || []
|
||
|
this._hooks[name].push(fn)
|
||
|
}
|
||
|
|
||
|
async callHook(name, ...args) {
|
||
|
if (!this._hooks[name]) {
|
||
|
return
|
||
|
}
|
||
|
consola.debug(`Call ${name} hooks (${this._hooks[name].length})`)
|
||
|
try {
|
||
|
await sequence(this._hooks[name], fn => fn(...args))
|
||
|
} catch (err) {
|
||
|
consola.error(err)
|
||
|
this.callHook('error', err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
clearHook(name) {
|
||
|
if (name) {
|
||
|
delete this._hooks[name]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
flatHooks(configHooks, hooks = {}, parentName) {
|
||
|
Object.keys(configHooks).forEach((key) => {
|
||
|
const subHook = configHooks[key]
|
||
|
const name = parentName ? `${parentName}:${key}` : key
|
||
|
if (typeof subHook === 'object' && subHook !== null) {
|
||
|
this.flatHooks(subHook, hooks, name)
|
||
|
} else {
|
||
|
hooks[name] = subHook
|
||
|
}
|
||
|
})
|
||
|
return hooks
|
||
|
}
|
||
|
|
||
|
addHooks(configHooks) {
|
||
|
const hooks = this.flatHooks(configHooks)
|
||
|
Object.keys(hooks).filter(Boolean).forEach((key) => {
|
||
|
[].concat(hooks[key]).forEach(h => this.hook(key, h))
|
||
|
})
|
||
|
}
|
||
|
}
|