UNPKG

@vara/custom-logic-sdk

Version:

Server Side JavaScript SDK for Custom Business Logic

99 lines (79 loc) 3.23 kB
/** * Created by stevenchin on 2/1/17. */ const _ = require('lodash'); const Joi = require('joi'); const logSvc = require('./log-svc'); const customError = require('./custom-error'); const clFunctionConfigSchema = require('../validation-schemas/function-config'); const ApplicationErrors = require('../constants/application-errors.json'); const validationOpts = require('../constants/validation-opts'); const { ValidationError } = ApplicationErrors; const { CUSTOM_LOGIC } = require('../constants/constants'); const { TYPES: CL_FN_TYPES } = CUSTOM_LOGIC.FUNCTIONS; const { TYPES: CL_ACTION_TYPES } = CUSTOM_LOGIC.ACTIONS; const registry = { apiResponders: {}, actions: {}, }; const clFnRegistry = {}; /** * @throws ValidationError - thrown when the config param is invalid or the fn param is not a function * Adds a function along with its configurations to the registry. * @param config {Object} - configurations for custom logic function * @param fn {Function} - function to add to registry * @param opts {Object} - options to use when adding the fn to the registry */ clFnRegistry.add = function add(config = {}, fn, { isAction } = {}) { const errData = { typeofRegistryFn: typeof fn, config, }; if (!_.isFunction(fn)) { throw customError(ValidationError.name, 'Only functions can be added to custom logic registry', errData); } if (!config || !_.isString(config.type)) { const validTypes = [CL_FN_TYPES.POST_HOOK, CL_FN_TYPES.PRE_HOOK, CL_FN_TYPES.STANDALONE, CL_ACTION_TYPES.CL_ACTION]; throw customError(ValidationError.name, `Custom logic function config must contain a type property; Valid types are: ${validTypes}`, errData); } const fnTypeConfigValidationRes = Joi.validate(config, clFunctionConfigSchema[config.type], validationOpts.ALLOW_ADDITIONAL_PROPERTIES); if (fnTypeConfigValidationRes.error) { errData.details = fnTypeConfigValidationRes.error.details; throw customError(ValidationError.name, fnTypeConfigValidationRes.error.message, errData); } const registryPath = isAction ? 'actions' : 'apiResponders'; if (registry[registryPath][config.name]) { logSvc.warn(`Function: ${config.name} already exists in registry, it will be replaced`); } registry[registryPath][config.name] = { config, handler: fn }; }; /** * Returns the api responder specified by name or null if the function was not found * @param name {String} - name of api responder to retrieve * @returns {Function|Null} */ clFnRegistry.getAPIResponder = function getAPIResponder(name) { return registry['apiResponders'][name] || null; }; /** * Returns the custom logic action specified by name or null if the function was not found * @param name {String} - name of cl action to retrieve * @returns {Function|Null} */ clFnRegistry.getClAction = function getClAction(name) { return registry['actions'][name] || null; }; /** * Returns a list of all registered custom logic functions * @returns {Array} */ clFnRegistry.getAll = function getAll() { const handlers = []; _.forOwn(registry, (fnType) => { _.forOwn(fnType, (handlerConfig) => { handlers.push(handlerConfig); }); }); return handlers; }; module.exports = clFnRegistry;