UNPKG

@nodecg/json-schema-lib

Version:

Extensible JSON Schema library with support for multi-file schemas using $ref

74 lines (62 loc) 2.41 kB
'use strict'; var ono = require('ono'); var __internal = require('../../util/internal'); var filterByMethod = require('./filterByMethod'); module.exports = callSyncPlugin; /** * Calls a synchronous plugin method with the given arguments. * * @param {PluginHelper} pluginHelper - The {@link PluginHelper} whose plugins are called * @param {string} methodName - The name of the plugin method to call * @param {object} args - The arguments to pass to the method * * @returns {{ result: *, plugin: ?object }} * If the method was handled by a plugin (i.e. the plugin didn't call next()), then the returned * object will contain a reference to the plugin, and the result that was returned by the plugin. */ function callSyncPlugin (pluginHelper, methodName, args) { var plugins = pluginHelper.filter(filterByMethod(methodName)); args.schema = pluginHelper[__internal].schema; args.config = args.schema.config; return callNextPlugin(plugins, methodName, args); } /** * Calls the the next plugin from an array of plugins. * * @param {object[]} plugins - The array of plugins * @param {string} methodName - The name of the plugin method to call * @param {object} args - The arguments to pass to the method * @returns {{ plugin: ?object, result: * }} */ function callNextPlugin (plugins, methodName, args) { var result, error, nextCalled; var plugin = plugins.shift(); if (!plugin) { // We've reached the end of the plugin chain. No plugin returned a value. return { plugin: null, result: undefined }; } // Invoke the plugin method. It can return a value, throw an error, or call next() args.next = next; result = plugin[methodName].call(null, args); if (result !== undefined && nextCalled) { throw ono('Error in %s.%s: Cannot return a value and call next()', plugin.name, methodName); } if (error) { throw ono(error, 'Error in %s.%s:', plugin.name, methodName); } else if (nextCalled && result === undefined) { return callNextPlugin(plugins, methodName, args); } else { // next() was NOT called, so return the plugin's result (even if there was no return value) return { plugin: plugin, result: result }; } function next (err, value) { if (nextCalled) { error = ono('Error in %s.%s: next() was called multiple times', plugin.name, methodName); } nextCalled = true; error = err; result = value; } }