@phema/cql-execution
Version:
An execution framework for the Clinical Quality Language (CQL)
818 lines (618 loc) • 21.1 kB
JavaScript
"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
};