Skip to content

Commit

Permalink
plugin.needs to assert dependencies (#89)
Browse files Browse the repository at this point in the history
* plugin.needs to assert dependencies

* tweak error msg

* support async needs check

* update documentation on plugins regarding `needs`
  • Loading branch information
staltz authored Jan 6, 2024
1 parent 33d1dae commit 6f1c104
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 0 deletions.
10 changes: 10 additions & 0 deletions PLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Plugins are simply NodeJS modules that export an `object` of form `{ name, versi

module.exports = {
name: 'bluetooth',
needs: ['conn'],
version: '5.0.1',
manifest: {
localPeers: 'async',
Expand Down Expand Up @@ -87,6 +88,15 @@ will be available at `node.fooBar`.
A `plugin.name` can also be an `'object`. This object will be merged
directly with the

### `plugin.needs` (Array) _optional_

An array of strings which are the names of other plugins that this plugin
depends on. If those plugins are not present, then secret-stack will throw
an error indicating that the dependency is missing.

Use this field to declare dependencies on other plugins, and this should
facilitate the correct usage of your plugin.

### `plugin.version` (String) _optional_

NOTE - not currently used anywhere functionally
Expand Down
12 changes: 12 additions & 0 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ function Api (plugins, defaultConfig) {
}

const name = plugin.name

if (plugin.needs) {
queueMicrotask(() => {
for (const needed of plugin.needs) {
const found = create.plugins.some((p) => p.name === needed)
if (!found) {
throw new Error(`secret-stack plugin "${name ?? '?'}" needs plugin "${needed}" but not found`)
}
}
})
}

if (plugin.manifest) {
create.manifest = u.merge.manifest(
create.manifest,
Expand Down
41 changes: 41 additions & 0 deletions test/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,47 @@ tape('plugin cannot be named global', function (t) {
t.end()
})

tape('plugin needs another plugin', function (t) {
// core, not a plugin.
var Create = Api([{
manifest: {},
init: function (api) {
return {}
}
}])

function uncaughtExceptionListener(err) {
t.equals(err.message, 'secret-stack plugin "x" needs plugin "y" but not found')

// Wait for potentially other errors
setTimeout(() => {
process.off('uncaughtException', uncaughtExceptionListener)
t.end()
}, 100)
}

process.on('uncaughtException', uncaughtExceptionListener)

// Should throw
Create.use({
name: 'x',
needs: ['y'],
init: function () { }
})

// Should NOT throw, even though 'foo' is loaded after 'bar'
Create.use({
name: 'bar',
needs: ['foo'],
init: function () { }
})

Create.use({
name: 'foo',
init: function () { }
})
})

tape('compound (array) plugins', function (t) {
// core, not a plugin.
var Create = Api([{
Expand Down

0 comments on commit 6f1c104

Please sign in to comment.