@vara/custom-logic-sdk
Version:
Server Side JavaScript SDK for Custom Business Logic
99 lines (79 loc) • 3.23 kB
JavaScript
/**
* 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;