UNPKG

@vara/custom-logic-sdk

Version:

Server Side JavaScript SDK for Custom Business Logic

171 lines (144 loc) 7.63 kB
/** * Created by stevenchin on 1/31/17. */ const _ = require('lodash'); const logSvc = require('../services/log-svc'); const fnRegistry = require('../services/fn-registry'); const customError = require('../services/custom-error'); const configGenerator = require('../services/platform-config-generator'); const ApplicationErrors = require('../constants/application-errors.json'); const { InvalidAPIResponderError, InvalidClActionError } = ApplicationErrors; const { CUSTOM_LOGIC } = require('../constants/constants'); const { TYPES: CL_FN_TYPES } = CUSTOM_LOGIC.FUNCTIONS; const { EXECUTION_MODES } = CUSTOM_LOGIC.FUNCTIONS; const { VERSIONS: CL_PROTOCOL_VERSIONS } = CUSTOM_LOGIC.PROTOCOL; const { TYPES: CL_ACTION_TYPES } = CUSTOM_LOGIC.ACTIONS; function initializeSdk(app, options = {}) { const sdk = { app, server: null }; /** * @throws InvalidAPIResponderError - thrown when the config object is invalid or the fn param is not a function * @throws InvalidClActionError - thrown when the config object is invalid or the fn param is not a function * Adds a function to the internal registry with the configurations specified * @param config {Object} - configurations for function to be added to the internal registry * @param fn {Function} - function to add to registry * @param opts {Object} - options to use when adding the fn to the registry */ function addFnToRegistry(config, fn, { isAction } = {}) { const logPrefix = 'Sdk#addFnToRegistry'; try { // prevent validation failures for lowercased request methods for developer convenience // note: httpMethods is only required for pre-hooks if (Array.isArray(config.httpMethods)) { config.httpMethods = config.httpMethods.map((method) => method.toUpperCase()); } fnRegistry.add(config, fn, { isAction }); } catch (validationError) { let error; if (isAction) { error = customError(InvalidClActionError.name, null, { innerError: validationError }); } else { error = customError(InvalidAPIResponderError.name, null, { innerError: validationError }); } logSvc.logError(error, {}, logPrefix); throw error; } } /** * Defaults the config for the custom logic protocol version to the latest version * @param config {Object} - config to update */ function setDefaultProtocolVersion(config) { config.clProtocolVersion = config.clProtocolVersion || CL_PROTOCOL_VERSIONS.LATEST; } /** * Adds the relevant configurations for API responders * @param config {Object} - config to update */ function updateConfigForAPIResponders(config) { config.executionMode = EXECUTION_MODES.SYNC; setDefaultProtocolVersion(config); } /** * Start custom logic web server */ sdk.run = function run() { logSvc.info('generating registration configs...'); const regConfig = configGenerator.generateRegistrationConfigForPlatform(); logSvc.info('registration configs generated: ', JSON.stringify(regConfig)); sdk.server = app.listen(options.PORT, () => { logSvc.info('server started on port: %d', options.PORT); }); }; /** * @throws InvalidAPIResponderError - thrown when the config object is invalid or the responder property is not a function * Stores the configurations for a standalone custom logic responder so that it can be executed when matching requests are made to the custom logic web service. * @param config {Object} - configurations for standalone custom logic responder * @param config.name {String} - name of standalone function * @param [config.httpMethods] {Array} - list of http methods (i.e GET, PUT, POST, DELETE) that the standalone function should be invoked for when a matching request is made to the Etx Platform. * @param [config.supportAllMethods] {Array} - support all http request methods made to the Etx Platform. * @param [config.clProtocolVersion] {String} - the custom logic protocol version to use for the standalone function * @param responder {Function} - standalone function to execute */ sdk.registerStandaloneAPIResponder = function registerStandaloneAPIResponder(config = {}, responder) { const updatedConfig = Object.assign({}, config); updatedConfig.type = CL_FN_TYPES.STANDALONE; updateConfigForAPIResponders(updatedConfig); addFnToRegistry(updatedConfig, responder); }; /** * @throws InvalidAPIResponderError - thrown when the config object is invalid or the responder property is not a function * Stores the configurations for a post hook responder so that it can be executed when matching requests are made to the custom logic web service. * @param config {Object} - configurations for post hook responder * @param config.name {String} - name of post hook * @param config.modelName {String} - model the post hook should be executed on * @param config.modelMethod {String} - name of the model method the post hook should be executed on * @param [config.clProtocolVersion] {String} - the custom logic protocol version to use for the post hook * @param responder {Function} - post hook to execute */ sdk.registerPostHookAPIResponder = function registerPostHookAPIResponder(config = {}, responder) { const updatedConfig = Object.assign({}, config); updatedConfig.type = CL_FN_TYPES.POST_HOOK; updateConfigForAPIResponders(updatedConfig); addFnToRegistry(updatedConfig, responder); }; /** * @throws InvalidAPIResponderError - thrown when the config object is invalid or the responder property is not a function * Stores the configurations for a pre hook responder so that it can be executed when matching requests are made to the custom logic web service. * @param config {Object} - configurations for pre hook responder * @param config.name {String} - name of hook * @param config.urlPath {String} - url path the hook should be executed on * @param config.httpMethods {Array} - HTTP method(s) that the hook should be triggered on. Supported values are GET, POST, PUT, DELETE and *. * @param [config.clProtocolVersion] {String} - the custom logic protocol version to use for the post hook * @param responder {Function} - post hook to execute */ sdk.registerPreHookAPIResponder = function registerPreHookAPIResponder(config = {}, responder) { const updatedConfig = Object.assign({}, config); updatedConfig.type = CL_FN_TYPES.PRE_HOOK; updateConfigForAPIResponders(updatedConfig); addFnToRegistry(updatedConfig, responder); }; /** * @throws InvalidClActionError - thrown when the config object is invalid or the fn param is not a function * Stores the configurations for a custom logic action so that it can be executed when matching requests are made to the custom logic web service. * @param config {Object} - configurations for custom logic action * @param config.name {String} - name of action * @param action {Function} - action to execute */ sdk.registerAction = function registerAction(config = {}, action) { const updatedConfig = Object.assign({}, config); updatedConfig.type = CL_ACTION_TYPES.CL_ACTION; addFnToRegistry(updatedConfig, action, { isAction: true }); }; // allows developers to use logger while bootstrapping their application or in other contexts outside of their handlers sdk.log = logSvc; function stopServer() { if (sdk.server && _.isFunction(sdk.server.close)) { sdk.server.close(); } } if (options.NODE_ENV === 'test') { sdk.stop = stopServer; } return sdk; } module.exports = initializeSdk;