UNPKG

endo-core

Version:
110 lines (88 loc) 3.06 kB
http = require 'http' _ = require 'lodash' path = require 'path' glob = require 'glob' {validate} = require 'jsonschema' NOT_FOUND_RESPONSE = {metadata: {code: 404, status: http.STATUS_CODES[404]}} class MessageHandler constructor: ({ @defaultJobType, @jobsPath }={})-> throw new Error 'MessageHandler requires jobsPath' unless @jobsPath? @jobs = @_getJobs() onMessage: ({data, encrypted, metadata}, callback) => job = @jobs[metadata?.jobType] job ?= @jobs[@defaultJobType] if @defaultJobType? return callback null, NOT_FOUND_RESPONSE unless job? schema = @_messageSchemaFromJob job, metadata?.jobType validation = validate {metadata, data}, schema return callback null, @_validationErrorsResponse(validation.errors) unless _.isEmpty validation.errors job.action {encrypted}, {data, metadata}, (error, response) => return callback error if error? return callback null, _.pick(response, 'data', 'metadata') formSchema: (callback) => callback null, @_formSchemaFromJobs @jobs messageSchema: (callback) => callback null, @_messageSchemaFromJobs @jobs responseSchema: (callback) => callback null, @_responseSchemaFromJobs @jobs _formSchemaFromJobs: (jobs) => return { message: _.mapValues jobs, 'form' } _generateMessageMetadata: (jobType) => return { type: 'object' required: ['jobType'] properties: jobType: type: 'string' enum: [jobType] default: jobType respondTo: {} } _generateResponseMetadata: => return { type: 'object' required: ['status', 'code'] properties: status: type: 'string' code: type: 'integer' } _getJobs: => dirnames = glob.sync path.join(@jobsPath, '/*/') jobs = {} _.each dirnames, (dir) => key = _.upperFirst _.camelCase path.basename dir try jobs[key] = require dir catch error console.error error.stack return jobs _messageSchemaFromJob: (job, key) => message = _.cloneDeep job.message message ?= {} _.set message, 'x-form-schema.angular', "message.#{key}.angular" _.set message, 'x-response-schema', "#{key}" _.set message, 'properties.metadata', @_generateMessageMetadata(key) message.required = _.union ['metadata'], message.required return message _messageSchemaFromJobs: (jobs) => _.mapValues jobs, @_messageSchemaFromJob _responseSchemaFromJob: (job) => response = _.cloneDeep job.response _.set response, 'properties.metadata', @_generateResponseMetadata() return response _responseSchemaFromJobs: (jobs) => _.mapValues jobs, @_responseSchemaFromJob _validationErrorsResponse: (errors) => return { metadata: code: 422 status: http.STATUS_CODES[422] data: errors: _.map(errors, @_formatValidationError) } _formatValidationError: (error) => return _.replace error.stack, /^instance\./, 'message.' module.exports = MessageHandler