UNPKG

courtbot-engine

Version:

An engine for courtbot-like functionality to be included in city/county services sites.

239 lines (182 loc) 9.03 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.getCaseParties = getCaseParties; exports.getCasePartyEvents = getCasePartyEvents; exports.sendNonReplyMessage = sendNonReplyMessage; exports.verifyContact = verifyContact; var _courtbotError = require('./courtbotError'); var _courtbotError2 = _interopRequireDefault(_courtbotError); var _log4js = require('log4js'); var _log4js2 = _interopRequireDefault(_log4js); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var EventEmitter = require('events'); var CourtbotEmitter = function (_EventEmitter) { _inherits(CourtbotEmitter, _EventEmitter); function CourtbotEmitter() { _classCallCheck(this, CourtbotEmitter); return _possibleConstructorReturn(this, (CourtbotEmitter.__proto__ || Object.getPrototypeOf(CourtbotEmitter)).apply(this, arguments)); } return CourtbotEmitter; }(EventEmitter); var emitter = new CourtbotEmitter(); var logger = _log4js2.default.getLogger(); exports.default = emitter; function wrapPromises(promises) { var wrappedPromises = promises.map(function (p) { return p.then(function (r) { return { result: r }; }).catch(function (e) { return { error: e }; }); }); //Now Promise.all will return all success/errors return Promise.all(wrappedPromises).then(function (resultObjects) { return resultObjects.reduce(function (aggregate, item) { item.error ? aggregate.errors.push(item.error) : aggregate.results.push(item.result); return aggregate; }, { errors: [], results: [] }); }); } /* casenumber: string holding the casenumber to look up * options: * emitErrorEvent - whether the retrieve-parties-error event is emitted with error information * returnErrorsWithData - whether the error information is also returned along with the parties found { parties: [], errors: [] } */ function getCaseParties(casenumber, options) { var result = { promises: [] }; var _Object$assign = Object.assign({ emitErrorEvent: true, returnErrorsWithData: false }, options), emitErrorEvent = _Object$assign.emitErrorEvent, returnErrorsWithData = _Object$assign.returnErrorsWithData; // emit runs synchronously because I/O is not involved, so result will always be populated // before further functions are called. emitter.emit('retrieve-parties', casenumber, result); return wrapPromises(result.promises).then(function (results) { // Use a set to screen out exact duplicates var resultSet = new Set(); var errors = results.errors; //flatten the result sets (change [[a, b], c, d] to [a, b, c, d]) var flattenedData = _lodash2.default.flattenDeep(results.results); flattenedData.forEach(function (party) { //each item can be a string or an object with a name //property if (!party || party === "") { errors.push({ message: "Party cannot be empty" }); } else if (party.hasOwnProperty("name") && typeof party !== "function") { resultSet.add(party.name.trim()); } else if (typeof party === "string") { resultSet.add(party.trim()); } else { errors.push({ message: "Error parsing party", object: party }); } }); var wrappedErrors = _lodash2.default.map(errors, function (err) { return new _courtbotError2.default({ type: _courtbotError.COURTBOT_ERROR_TYPES.API.GET, case: casenumber, timestamp: Date(), initialError: (typeof err === 'undefined' ? 'undefined' : _typeof(err)) === 'object' ? err : { data: err } }); }); if (errors.length) { logger.error(wrappedErrors); if (emitErrorEvent) emitter.emit("retrieve-parties-error", wrappedErrors); } if (returnErrorsWithData) { return { errors: wrappedErrors, parties: _lodash2.default.map([].concat(_toConsumableArray(resultSet)), function (r) { return { name: r }; }) }; } else { return _lodash2.default.map([].concat(_toConsumableArray(resultSet)), function (r) { return { name: r }; }); } }); } /* casenumber: string holding the casenumber to look up * party: string holding the party name to look up * errorMode: 2-bit integer that determines how errors are handled: * 1s bit - whether the retrieve-parties-error event is emitted with error information * 2s bit - whether the error information is also returned along with the parties found { parties: [], errors: [] } * ======================================== * results: an array of {name: `partyname`} * errors: an array of courtbotErrors */ function getCasePartyEvents(casenumber, party) { var errorMode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; var result = { promises: [] }; // emit runs synchronously because I/O is not involved, so result will always be populated // before further functions are called. emitter.emit("retrieve-party-events", casenumber, party, result); var results = []; var errors = []; // instead of Promise.all(), use reduce() to catch all errors, but still return valid values return result.promises.reduce(function (chain, dataPromise) { // First with glue all the promises together with error handling... return chain.then(function () { return dataPromise; }).then(function (foundParties) { results = results.concat(foundParties); }).catch(function (err) { logger.warn('events.js getCasePartyEvents() data retrieval raw error on ' + Date() + ':'); logger.warn(err); // Wrap the errors if necessary if (err.name !== _courtbotError.COURTBOT_ERROR_NAME) { var wrappedError = new _courtbotError2.default({ type: _courtbotError.COURTBOT_ERROR_TYPES.API.GENERAL, case: casenumber, timestamp: Date(), initialError: (typeof err === 'undefined' ? 'undefined' : _typeof(err)) === 'object' ? err : { data: err } }); errors = errors.concat(wrappedError); } else { errors = errors.concat(err); } return true; }); }, Promise.resolve()) // ... then we return the results .then(function () { // Emit the retrieve-parties-error first. Like retrieve-parties, it runs synchronously because there's no I/O if (errorMode % 2) emitter.emit('retrieve-party-events-error', errors); // Add the errors to the return value if dictated by errorMode if ((errorMode >> 1) % 2) { results = { events: results, errors: errors }; } return results; }); } function sendNonReplyMessage(to, msg, communicationType) { var result = { promises: [] }; logger.debug("Attempting to send message", { to: to, msg: msg, communicationType: communicationType }); emitter.emit("send-non-reply", { to: to, msg: msg, communicationType: communicationType, result: result }); if (result.promise) { return result.promise; } if (result.promises.length) { return Promise.all(result.promises); } return Promise.resolve(result); } function verifyContact(contact, communicationType) { var result = { promises: [] }; logger.debug("Attempting to verify contact", { contact: contact, communicationType: communicationType }); emitter.emit("verify-contact", { contact: contact, communicationType: communicationType, result: result }); if (result.promise) { return result.promise; } if (result.promises.length) { return Promise.all(result.promises).then(function (x) { return x[0]; }); } return Promise.resolve(result); }