UNPKG

@phema/cql-execution

Version:

An execution framework for the Clinical Quality Language (CQL)

818 lines (618 loc) 21.1 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var _require = require('./expression'), Expression = _require.Expression; var _require2 = require('./builder'), build = _require2.build; var MathUtil = require('../util/math'); var _require3 = require('../datatypes/quantity'), Quantity = _require3.Quantity, doAddition = _require3.doAddition, doSubtraction = _require3.doSubtraction, doMultiplication = _require3.doMultiplication, doDivision = _require3.doDivision; var _require4 = require('../datatypes/uncertainty'), Uncertainty = _require4.Uncertainty; var Add = /*#__PURE__*/function (_Expression) { _inherits(Add, _Expression); var _super = _createSuper(Add); function Add(json) { _classCallCheck(this, Add); return _super.call(this, json); } _createClass(Add, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var sum = args.reduce(function (x, y) { if (x.isUncertainty && !y.isUncertainty) { y = new Uncertainty(y, y); } else if (y.isUncertainty && !x.isUncertainty) { x = new Uncertainty(x, x); } if (x.isQuantity || x.isDateTime || x.isDate || x.isTime && x.isTime()) { return doAddition(x, y); } else if (x.isUncertainty && y.isUncertainty) { if (x.low.isQuantity || x.low.isDateTime || x.low.isDate || x.low.isTime && x.low.isTime()) { return new Uncertainty(doAddition(x.low, y.low), doAddition(x.high, y.high)); } else { return new Uncertainty(x.low + y.low, x.high + y.high); } } else { return x + y; } }); if (MathUtil.overflowsOrUnderflows(sum)) { return null; } return sum; } }]); return Add; }(Expression); var Subtract = /*#__PURE__*/function (_Expression2) { _inherits(Subtract, _Expression2); var _super2 = _createSuper(Subtract); function Subtract(json) { _classCallCheck(this, Subtract); return _super2.call(this, json); } _createClass(Subtract, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var difference = args.reduce(function (x, y) { if (x.isUncertainty && !y.isUncertainty) { y = new Uncertainty(y, y); } else if (y.isUncertainty && !x.isUncertainty) { x = new Uncertainty(x, x); } if (x.isQuantity || x.isDateTime || x.isDate) { return doSubtraction(x, y); } else if (x.isUncertainty && y.isUncertainty) { if (x.low.isQuantity || x.low.isDateTime || x.low.isDate) { return new Uncertainty(doSubtraction(x.low, y.high), doSubtraction(x.high, y.low)); } else { return new Uncertainty(x.low - y.high, x.high - y.low); } } else { return x - y; } }); if (MathUtil.overflowsOrUnderflows(difference)) { return null; } return difference; } }]); return Subtract; }(Expression); var Multiply = /*#__PURE__*/function (_Expression3) { _inherits(Multiply, _Expression3); var _super3 = _createSuper(Multiply); function Multiply(json) { _classCallCheck(this, Multiply); return _super3.call(this, json); } _createClass(Multiply, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var product = args.reduce(function (x, y) { if (x.isUncertainty && !y.isUncertainty) { y = new Uncertainty(y, y); } else if (y.isUncertainty && !x.isUncertainty) { x = new Uncertainty(x, x); } if (x.isQuantity || y.isQuantity) { return doMultiplication(x, y); } else if (x.isUncertainty && y.isUncertainty) { if (x.low.isQuantity) { return new Uncertainty(doMultiplication(x.low, y.low), doMultiplication(x.high, y.high)); } else { return new Uncertainty(x.low * y.low, x.high * y.high); } } else { return x * y; } }); if (MathUtil.overflowsOrUnderflows(product)) { return null; } return product; } }]); return Multiply; }(Expression); var Divide = /*#__PURE__*/function (_Expression4) { _inherits(Divide, _Expression4); var _super4 = _createSuper(Divide); function Divide(json) { _classCallCheck(this, Divide); return _super4.call(this, json); } _createClass(Divide, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var quotient = args.reduce(function (x, y) { if (x.isUncertainty && !y.isUncertainty) { y = new Uncertainty(y, y); } else if (y.isUncertainty && !x.isUncertainty) { x = new Uncertainty(x, x); } if (x.isQuantity) { return doDivision(x, y); } else if (x.isUncertainty && y.isUncertainty) { if (x.low.isQuantity) { return new Uncertainty(doDivision(x.low, y.high), doDivision(x.high, y.low)); } else { return new Uncertainty(x.low / y.high, x.high / y.low); } } else { return x / y; } }); // Note, anything divided by 0 is Infinity in Javascript, which will be // considered as overflow by this check. if (MathUtil.overflowsOrUnderflows(quotient)) { return null; } return quotient; } }]); return Divide; }(Expression); var TruncatedDivide = /*#__PURE__*/function (_Expression5) { _inherits(TruncatedDivide, _Expression5); var _super5 = _createSuper(TruncatedDivide); function TruncatedDivide(json) { _classCallCheck(this, TruncatedDivide); return _super5.call(this, json); } _createClass(TruncatedDivide, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var quotient = args.reduce(function (x, y) { return x / y; }); var truncatedQuotient = quotient >= 0 ? Math.floor(quotient) : Math.ceil(quotient); if (MathUtil.overflowsOrUnderflows(truncatedQuotient)) { return null; } return truncatedQuotient; } }]); return TruncatedDivide; }(Expression); var Modulo = /*#__PURE__*/function (_Expression6) { _inherits(Modulo, _Expression6); var _super6 = _createSuper(Modulo); function Modulo(json) { _classCallCheck(this, Modulo); return _super6.call(this, json); } _createClass(Modulo, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var modulo = args.reduce(function (x, y) { return x % y; }); return MathUtil.decimalOrNull(modulo); } }]); return Modulo; }(Expression); var Ceiling = /*#__PURE__*/function (_Expression7) { _inherits(Ceiling, _Expression7); var _super7 = _createSuper(Ceiling); function Ceiling(json) { _classCallCheck(this, Ceiling); return _super7.call(this, json); } _createClass(Ceiling, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } return Math.ceil(arg); } }]); return Ceiling; }(Expression); var Floor = /*#__PURE__*/function (_Expression8) { _inherits(Floor, _Expression8); var _super8 = _createSuper(Floor); function Floor(json) { _classCallCheck(this, Floor); return _super8.call(this, json); } _createClass(Floor, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } return Math.floor(arg); } }]); return Floor; }(Expression); var Truncate = /*#__PURE__*/function (_Expression9) { _inherits(Truncate, _Expression9); var _super9 = _createSuper(Truncate); function Truncate(json) { _classCallCheck(this, Truncate); return _super9.call(this, json); } _createClass(Truncate, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } return arg >= 0 ? Math.floor(arg) : Math.ceil(arg); } }]); return Truncate; }(Expression); var Abs = /*#__PURE__*/function (_Expression10) { _inherits(Abs, _Expression10); var _super10 = _createSuper(Abs); function Abs(json) { _classCallCheck(this, Abs); return _super10.call(this, json); } _createClass(Abs, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } else if (arg.isQuantity) { return new Quantity(Math.abs(arg.value), arg.unit); } else { return Math.abs(arg); } } }]); return Abs; }(Expression); var Negate = /*#__PURE__*/function (_Expression11) { _inherits(Negate, _Expression11); var _super11 = _createSuper(Negate); function Negate(json) { _classCallCheck(this, Negate); return _super11.call(this, json); } _createClass(Negate, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } else if (arg.isQuantity) { return new Quantity(arg.value * -1, arg.unit); } else { return arg * -1; } } }]); return Negate; }(Expression); var Round = /*#__PURE__*/function (_Expression12) { _inherits(Round, _Expression12); var _super12 = _createSuper(Round); function Round(json) { var _this; _classCallCheck(this, Round); _this = _super12.call(this, json); _this.precision = build(json.precision); return _this; } _createClass(Round, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } var dec = this.precision != null ? this.precision.execute(ctx) : 0; return Math.round(arg * Math.pow(10, dec)) / Math.pow(10, dec); } }]); return Round; }(Expression); var Ln = /*#__PURE__*/function (_Expression13) { _inherits(Ln, _Expression13); var _super13 = _createSuper(Ln); function Ln(json) { _classCallCheck(this, Ln); return _super13.call(this, json); } _createClass(Ln, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } var ln = Math.log(arg); return MathUtil.decimalOrNull(ln); } }]); return Ln; }(Expression); var Exp = /*#__PURE__*/function (_Expression14) { _inherits(Exp, _Expression14); var _super14 = _createSuper(Exp); function Exp(json) { _classCallCheck(this, Exp); return _super14.call(this, json); } _createClass(Exp, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { return null; } var power = Math.exp(arg); if (MathUtil.overflowsOrUnderflows(power)) { return null; } return power; } }]); return Exp; }(Expression); var Log = /*#__PURE__*/function (_Expression15) { _inherits(Log, _Expression15); var _super15 = _createSuper(Log); function Log(json) { _classCallCheck(this, Log); return _super15.call(this, json); } _createClass(Log, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var log = args.reduce(function (x, y) { return Math.log(x) / Math.log(y); }); return MathUtil.decimalOrNull(log); } }]); return Log; }(Expression); var Power = /*#__PURE__*/function (_Expression16) { _inherits(Power, _Expression16); var _super16 = _createSuper(Power); function Power(json) { _classCallCheck(this, Power); return _super16.call(this, json); } _createClass(Power, [{ key: "exec", value: function exec(ctx) { var args = this.execArgs(ctx); if (args == null || args.some(function (x) { return x == null; })) { return null; } var power = args.reduce(function (x, y) { return Math.pow(x, y); }); if (MathUtil.overflowsOrUnderflows(power)) { return null; } return power; } }]); return Power; }(Expression); var MinValue = /*#__PURE__*/function (_Expression17) { _inherits(MinValue, _Expression17); var _super17 = _createSuper(MinValue); function MinValue(json) { var _this2; _classCallCheck(this, MinValue); _this2 = _super17.call(this, json); _this2.valueType = json.valueType; return _this2; } _createClass(MinValue, [{ key: "exec", value: function exec(ctx) { if (MinValue.MIN_VALUES[this.valueType]) { if (this.valueType === '{urn:hl7-org:elm-types:r1}DateTime') { var minDateTime = MinValue.MIN_VALUES[this.valueType].copy(); minDateTime.timezoneOffset = ctx.getTimezoneOffset(); return minDateTime; } else { return MinValue.MIN_VALUES[this.valueType]; } } else { throw new Error("Minimum not supported for ".concat(this.valueType)); } } }]); return MinValue; }(Expression); MinValue.MIN_VALUES = {}; MinValue.MIN_VALUES['{urn:hl7-org:elm-types:r1}Integer'] = MathUtil.MIN_INT_VALUE; MinValue.MIN_VALUES['{urn:hl7-org:elm-types:r1}Decimal'] = MathUtil.MIN_FLOAT_VALUE; MinValue.MIN_VALUES['{urn:hl7-org:elm-types:r1}DateTime'] = MathUtil.MIN_DATETIME_VALUE; MinValue.MIN_VALUES['{urn:hl7-org:elm-types:r1}Date'] = MathUtil.MIN_DATE_VALUE; MinValue.MIN_VALUES['{urn:hl7-org:elm-types:r1}Time'] = MathUtil.MIN_TIME_VALUE; var MaxValue = /*#__PURE__*/function (_Expression18) { _inherits(MaxValue, _Expression18); var _super18 = _createSuper(MaxValue); function MaxValue(json) { var _this3; _classCallCheck(this, MaxValue); _this3 = _super18.call(this, json); _this3.valueType = json.valueType; return _this3; } _createClass(MaxValue, [{ key: "exec", value: function exec(ctx) { if (MaxValue.MAX_VALUES[this.valueType] != null) { if (this.valueType === '{urn:hl7-org:elm-types:r1}DateTime') { var maxDateTime = MaxValue.MAX_VALUES[this.valueType].copy(); maxDateTime.timezoneOffset = ctx.getTimezoneOffset(); return maxDateTime; } else { return MaxValue.MAX_VALUES[this.valueType]; } } else { throw new Error("Maximum not supported for ".concat(this.valueType)); } } }]); return MaxValue; }(Expression); MaxValue.MAX_VALUES = {}; MaxValue.MAX_VALUES['{urn:hl7-org:elm-types:r1}Integer'] = MathUtil.MAX_INT_VALUE; MaxValue.MAX_VALUES['{urn:hl7-org:elm-types:r1}Decimal'] = MathUtil.MAX_FLOAT_VALUE; MaxValue.MAX_VALUES['{urn:hl7-org:elm-types:r1}DateTime'] = MathUtil.MAX_DATETIME_VALUE; MaxValue.MAX_VALUES['{urn:hl7-org:elm-types:r1}Date'] = MathUtil.MAX_DATE_VALUE; MaxValue.MAX_VALUES['{urn:hl7-org:elm-types:r1}Time'] = MathUtil.MAX_TIME_VALUE; var Successor = /*#__PURE__*/function (_Expression19) { _inherits(Successor, _Expression19); var _super19 = _createSuper(Successor); function Successor(json) { _classCallCheck(this, Successor); return _super19.call(this, json); } _createClass(Successor, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { null; } var successor = null; try { // MathUtil.successor throws on overflow, and the exception is used in // the logic for evaluating `meets`, so it can't be changed to just return null successor = MathUtil.successor(arg); } catch (e) { if (e instanceof MathUtil.OverFlowException) { return null; } } if (MathUtil.overflowsOrUnderflows(successor)) { return null; } return successor; } }]); return Successor; }(Expression); var Predecessor = /*#__PURE__*/function (_Expression20) { _inherits(Predecessor, _Expression20); var _super20 = _createSuper(Predecessor); function Predecessor(json) { _classCallCheck(this, Predecessor); return _super20.call(this, json); } _createClass(Predecessor, [{ key: "exec", value: function exec(ctx) { var arg = this.execArgs(ctx); if (arg == null) { null; } var predecessor = null; try { // MathUtil.predecessor throws on underflow, and the exception is used in // the logic for evaluating `meets`, so it can't be changed to just return null predecessor = MathUtil.predecessor(arg); } catch (e) { if (e instanceof MathUtil.OverFlowException) { return null; } } if (MathUtil.overflowsOrUnderflows(predecessor)) { return null; } return predecessor; } }]); return Predecessor; }(Expression); module.exports = { Abs: Abs, Add: Add, Ceiling: Ceiling, Divide: Divide, Exp: Exp, Floor: Floor, Ln: Ln, Log: Log, MaxValue: MaxValue, MinValue: MinValue, Modulo: Modulo, Multiply: Multiply, Negate: Negate, Power: Power, Predecessor: Predecessor, Round: Round, Subtract: Subtract, Successor: Successor, Truncate: Truncate, TruncatedDivide: TruncatedDivide };