Skip to content

Commit

Permalink
extract validatePlugin and create isBundledOrTypescriptPlugin (#216)
Browse files Browse the repository at this point in the history
* extract validatePlugin and create isBundledOrTypescriptPlugin
more fine grained error message

* fix test label

* add jsdoc

* adapt metcoders suggestion
  • Loading branch information
Uzlopak authored Jun 25, 2023
1 parent 1a15d14 commit bcb7fb4
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 14 deletions.
20 changes: 6 additions & 14 deletions boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const inherits = require('util').inherits
const {
AVV_ERR_EXPOSE_ALREADY_DEFINED,
AVV_ERR_CALLBACK_NOT_FN,
AVV_ERR_PLUGIN_NOT_VALID,
AVV_ERR_ROOT_PLG_BOOTED,
AVV_ERR_READY_TIMEOUT
} = require('./lib/errors')
Expand All @@ -18,6 +17,8 @@ const {
const { TimeTree } = require('./lib/time-tree')
const { Plugin } = require('./plugin')
const { debug } = require('./lib/debug')
const { validatePlugin } = require('./lib/validate-plugin')
const { isBundledOrTypescriptPlugin } = require('./lib/is-bundled-or-typescript-plugin')
const { loadPlugin } = require('./lib/load-plugin')

function wrap (server, opts, instance) {
Expand Down Expand Up @@ -201,18 +202,6 @@ Boot.prototype.override = function (server, func, opts) {
return server
}

function assertPlugin (plugin) {
// Faux modules are modules built with TypeScript
// or Babel that they export a .default property.
if (plugin && typeof plugin === 'object' && typeof plugin.default === 'function') {
plugin = plugin.default
}
if (!(plugin && (typeof plugin === 'function' || typeof plugin.then === 'function'))) {
throw new AVV_ERR_PLUGIN_NOT_VALID(typeof plugin)
}
return plugin
}

Boot.prototype[kAvvio] = true

// load a plugin
Expand Down Expand Up @@ -241,7 +230,10 @@ Boot.prototype._loadRegistered = function () {
Object.defineProperty(Boot.prototype, 'then', { get: thenify })

Boot.prototype._addPlugin = function (plugin, opts, isAfter) {
plugin = assertPlugin(plugin)
if (isBundledOrTypescriptPlugin(plugin)) {
plugin = plugin.default
}
validatePlugin(plugin)
opts = opts || {}

if (this.booted) {
Expand Down
20 changes: 20 additions & 0 deletions lib/is-bundled-or-typescript-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

/**
* bundled or typescript plugin
* @typedef {object} BundledOrTypescriptPlugin
* @property {function} default
*/

/**
* @param {unknown} plugin
* @returns {plugin is BundledOrTypescriptPlugin}
*/

function isBundledOrTypescriptPlugin (plugin) {
return plugin !== null && typeof plugin === 'object' && typeof plugin.default === 'function'
}

module.exports = {
isBundledOrTypescriptPlugin
}
25 changes: 25 additions & 0 deletions lib/validate-plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict'

const { AVV_ERR_PLUGIN_NOT_VALID } = require('./errors')

/**
* @param {unknown} plugin
* @throws {AVV_ERR_PLUGIN_NOT_VALID}
* @returns {Function}
*/
function validatePlugin (plugin) {
// validate if plugin is a function or Promise
if (!(plugin && (typeof plugin === 'function' || typeof plugin.then === 'function'))) {
if (Array.isArray(plugin)) {
throw new AVV_ERR_PLUGIN_NOT_VALID('array')
} else if (plugin === null) {
throw new AVV_ERR_PLUGIN_NOT_VALID('null')
} else {
throw new AVV_ERR_PLUGIN_NOT_VALID(typeof plugin)
}
}
}

module.exports = {
validatePlugin
}
20 changes: 20 additions & 0 deletions test/lib/is-bundled-or-typescript-plugin.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

const { test } = require('tap')
const { isBundledOrTypescriptPlugin } = require('../../lib/is-bundled-or-typescript-plugin')

test('isBundledOrTypescriptPlugin', (t) => {
t.plan(9)

t.equal(isBundledOrTypescriptPlugin(1), false)
t.equal(isBundledOrTypescriptPlugin('function'), false)
t.equal(isBundledOrTypescriptPlugin({}), false)
t.equal(isBundledOrTypescriptPlugin([]), false)
t.equal(isBundledOrTypescriptPlugin(null), false)

t.equal(isBundledOrTypescriptPlugin(function () {}), false)
t.equal(isBundledOrTypescriptPlugin(new Promise((resolve) => resolve)), false)
t.equal(isBundledOrTypescriptPlugin(Promise.resolve()), false)

t.equal(isBundledOrTypescriptPlugin({ default: () => {} }), true)
})
19 changes: 19 additions & 0 deletions test/lib/validate-plugin.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict'

const { test } = require('tap')
const { validatePlugin } = require('../../lib/validate-plugin')
const { AVV_ERR_PLUGIN_NOT_VALID } = require('../../lib/errors')

test('validatePlugin', (t) => {
t.plan(8)

t.throws(() => validatePlugin(1), new AVV_ERR_PLUGIN_NOT_VALID('number'))
t.throws(() => validatePlugin('function'), new AVV_ERR_PLUGIN_NOT_VALID('string'))
t.throws(() => validatePlugin({}), new AVV_ERR_PLUGIN_NOT_VALID('object'))
t.throws(() => validatePlugin([]), new AVV_ERR_PLUGIN_NOT_VALID('array'))
t.throws(() => validatePlugin(null), new AVV_ERR_PLUGIN_NOT_VALID('null'))

t.doesNotThrow(() => validatePlugin(function () {}))
t.doesNotThrow(() => validatePlugin(new Promise((resolve) => resolve)))
t.doesNotThrow(() => validatePlugin(Promise.resolve()))
})

0 comments on commit bcb7fb4

Please sign in to comment.