Skip to content

Commit

Permalink
fix: make filterPlugins work in saber-node.js (#221)
Browse files Browse the repository at this point in the history
* make filterPlugins work in saber-node.js

* tweaks

* tweaks

* beforePlugins hook is only available in saber-node.js
  • Loading branch information
egoist authored May 29, 2019
1 parent a7e2d08 commit f3ec588
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 42 deletions.
44 changes: 29 additions & 15 deletions packages/saber/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class Saber {
}

for (const plugin of userPlugins) {
this.applyPlugin(plugin, plugin.options, plugin.__path)
this.applyPlugin(plugin, plugin.options, plugin.location)
}

await this.hooks.afterPlugins.promise()
Expand Down Expand Up @@ -214,32 +214,46 @@ class Saber {

getUserPlugins() {
// Plugins that are specified in user config, a.k.a. saber-config.js etc
let plugins =
const plugins =
this.configDir && this.config.plugins
? this.config.plugins.map(p => {
if (typeof p === 'string') {
p = { resolve: p }
}

p.resolve = resolveFrom(this.configDir, p.resolve)
return p
const location = resolveFrom(this.configDir, p.resolve)

const plugin = require(location)
plugin.location = location
plugin.options = p.option

return plugin
})
: []

plugins = plugins.map(({ resolve, options }) => {
const plugin = require(resolve)
plugin.__path = resolve
plugin.options = options
if (plugin.filterPlugins) {
this.hooks.filterPlugins.tap(plugin.name, plugins =>
plugin.filterPlugins(plugins, options)
)
const applyFilterPlugins = plugins => {
const handlers = new Set()

for (const plugin of plugins) {
const { filterPlugins, options } = plugin
if (filterPlugins) {
delete plugin.filterPlugins
handlers.add(plugins => filterPlugins(plugins, options))
}
}

return plugin
})
if (handlers.size > 0) {
for (const handler of handlers) {
plugins = handler(plugins)
}

return applyFilterPlugins(plugins)
}

return plugins
}

return this.hooks.filterPlugins.call(plugins)
return applyFilterPlugins(this.hooks.filterPlugins.call(plugins))
}

resolveCache(...args) {
Expand Down
51 changes: 25 additions & 26 deletions packages/saber/lib/plugins/extend-node-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,39 @@ exports.apply = api => {
updateNodeApi()

const getHookHandler = hookName => nodeApi[hookName] || __noopHandler__

api.hooks.beforePlugins.tapPromise(nodeApiId, () => {
const hookHandler = getHookHandler('beforePlugins')
if (hookHandler.name !== '__noopHandler__') {
log.verbose(() => `beforePlugins ${colors.dim(`(${nodeApiId})`)}`)
const addHook = hookName => {
const hook = api.hooks[hookName]
if (hook) {
const tapType = hook.call ? 'tap' : 'tapPromise'
hook[tapType](nodeApiId, (...args) => {
const hookHandler = getHookHandler(hookName)
if (hookHandler.name !== '__noopHandler__') {
log.verbose(() => `${hookName} ${colors.dim(`(${nodeApiId})`)}`)
}

if (tapType === 'tap') {
return hookHandler.call(api, ...args)
}

return Promise.resolve(hookHandler.call(api, ...args))
})
}
}

return Promise.resolve(hookHandler.call(api))
})
// Hooks that should be added before `afterPlugins` hook
const preHooks = ['beforePlugins', 'filterPlugins']

for (const preHook of preHooks) {
addHook(preHook)
}

api.hooks.afterPlugins.tap(nodeApiId, () => {
for (const hookName of Object.keys(api.hooks)) {
if (hookName === 'beforePlugins') {
if (preHooks.includes(hookName)) {
continue
}

const hook = api.hooks[hookName]
if (hook) {
const tapType = hook.call ? 'tap' : 'tapPromise'
hook[tapType](nodeApiId, (...args) => {
const hookHandler = getHookHandler(hookName)
const result = hookHandler.call(api, ...args)

if (hookHandler.name !== '__noopHandler__') {
log.verbose(() => `${hookName} ${colors.dim(`(${nodeApiId})`)}`)
}

if (tapType === 'tapPromise') {
return Promise.resolve(result)
}

return result
})
}
addHook(hookName)
}
})

Expand Down
17 changes: 16 additions & 1 deletion website/pages/docs/plugin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,22 @@ A function to invoke.

### filterPlugins

- Type: `(plugins: Plugins[], options: any) => Plugins[]`
- Type: `FilterPlugins`
- Required: `false`

Filter the plugins, you can use it to add or remove plugins.

```ts
type FilterPlugins = (plugins: Plugin[], options: any) => Plugins[]

interface Plugin {
/* Plugin name */
name: string
apply: (api: SaberInstance, options?: any) => void
filterPlugins: FilterPlugins
/* Plugin options */
options?: any
/* The path to the plugin, only used in logs */
location?: string
}
```
9 changes: 9 additions & 0 deletions website/pages/docs/saber-instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,27 @@ Depending on the hook type, `tapAsync` and `tapPromise` may also be available. H

Called to filter plugins.

This hook is __only__ available `saber-node.js`.

```ts
interface Plugin {
/* Plugin name */
name: string
apply: (api: SaberInstance, options?: any) => void
/* Plugin options */
options?: any
/* The path to the plugin, only used in logs */
location?: string
}
```


### `beforePlugins`

- Hook Type: `AsyncSeriesHook`

This hook is __only__ available `saber-node.js`.

Called before loading user plugins.

### `afterPlugins`
Expand Down

0 comments on commit f3ec588

Please sign in to comment.