@phema/cql-execution
Version:
An execution framework for the Clinical Quality Language (CQL)
541 lines (396 loc) • 15.7 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 _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
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,
UnimplementedExpression = _require.UnimplementedExpression;
var _require2 = require('./builder'),
build = _require2.build;
var _require3 = require('../util/util'),
typeIsArray = _require3.typeIsArray;
var _require4 = require('../util/comparison'),
equals = _require4.equals;
var List = /*#__PURE__*/function (_Expression) {
_inherits(List, _Expression);
var _super = _createSuper(List);
function List(json) {
var _this;
_classCallCheck(this, List);
_this = _super.call(this, json);
_this.elements = build(json.element) || [];
return _this;
}
_createClass(List, [{
key: "isList",
get: function get() {
return true;
}
}, {
key: "exec",
value: function exec(ctx) {
return this.elements.map(function (item) {
return item.execute(ctx);
});
}
}]);
return List;
}(Expression);
var Exists = /*#__PURE__*/function (_Expression2) {
_inherits(Exists, _Expression2);
var _super2 = _createSuper(Exists);
function Exists(json) {
_classCallCheck(this, Exists);
return _super2.call(this, json);
}
_createClass(Exists, [{
key: "exec",
value: function exec(ctx) {
var list = this.execArgs(ctx); // if list exists and has non empty length we need to make sure it isnt just full of nulls
if (list) {
return list.some(function (item) {
return item != null;
});
}
return false;
}
}]);
return Exists;
}(Expression); // Equal is completely handled by overloaded#Equal
// NotEqual is completely handled by overloaded#Equal
// Delegated to by overloaded#Union
function doUnion(a, b) {
var distinct = doDistinct(a.concat(b));
return removeDuplicateNulls(distinct);
} // Delegated to by overloaded#Except
function doExcept(a, b) {
var distinct = doDistinct(a);
var setList = removeDuplicateNulls(distinct);
return setList.filter(function (item) {
return !doContains(b, item, true);
});
} // Delegated to by overloaded#Intersect
function doIntersect(a, b) {
var distinct = doDistinct(a);
var setList = removeDuplicateNulls(distinct);
return setList.filter(function (item) {
return doContains(b, item, true);
});
} // ELM-only, not a product of CQL
var Times = /*#__PURE__*/function (_UnimplementedExpress) {
_inherits(Times, _UnimplementedExpress);
var _super3 = _createSuper(Times);
function Times() {
_classCallCheck(this, Times);
return _super3.apply(this, arguments);
}
return Times;
}(UnimplementedExpression); // ELM-only, not a product of CQL
var Filter = /*#__PURE__*/function (_UnimplementedExpress2) {
_inherits(Filter, _UnimplementedExpress2);
var _super4 = _createSuper(Filter);
function Filter() {
_classCallCheck(this, Filter);
return _super4.apply(this, arguments);
}
return Filter;
}(UnimplementedExpression);
var SingletonFrom = /*#__PURE__*/function (_Expression3) {
_inherits(SingletonFrom, _Expression3);
var _super5 = _createSuper(SingletonFrom);
function SingletonFrom(json) {
_classCallCheck(this, SingletonFrom);
return _super5.call(this, json);
}
_createClass(SingletonFrom, [{
key: "exec",
value: function exec(ctx) {
var arg = this.execArgs(ctx);
if (arg != null && arg.length > 1) {
throw new Error("IllegalArgument: 'SingletonFrom' requires a 0 or 1 arg array");
} else if (arg != null && arg.length === 1) {
return arg[0];
} else {
return null;
}
}
}]);
return SingletonFrom;
}(Expression);
var ToList = /*#__PURE__*/function (_Expression4) {
_inherits(ToList, _Expression4);
var _super6 = _createSuper(ToList);
function ToList(json) {
_classCallCheck(this, ToList);
return _super6.call(this, json);
}
_createClass(ToList, [{
key: "exec",
value: function exec(ctx) {
var arg = this.execArgs(ctx);
if (arg != null) {
return [arg];
} else {
return [];
}
}
}]);
return ToList;
}(Expression);
var IndexOf = /*#__PURE__*/function (_Expression5) {
_inherits(IndexOf, _Expression5);
var _super7 = _createSuper(IndexOf);
function IndexOf(json) {
var _this2;
_classCallCheck(this, IndexOf);
_this2 = _super7.call(this, json);
_this2.source = build(json.source);
_this2.element = build(json.element);
return _this2;
}
_createClass(IndexOf, [{
key: "exec",
value: function exec(ctx) {
var index;
var src = this.source.execute(ctx);
var el = this.element.execute(ctx);
if (src == null || el == null) {
return null;
}
for (var i = 0; i < src.length; i++) {
var itm = src[i];
if (equals(itm, el)) {
index = i;
break;
}
}
if (index != null) {
return index;
} else {
return -1;
}
}
}]);
return IndexOf;
}(Expression); // Indexer is completely handled by overloaded#Indexer
// Delegated to by overloaded#Contains and overloaded#In
function doContains(container, item) {
var nullEquivalence = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
return container.some(function (element) {
return equals(element, item) || nullEquivalence && element == null && item == null;
});
} // Delegated to by overloaded#Includes and overloaded@IncludedIn
function doIncludes(list, sublist) {
return sublist.every(function (x) {
return doContains(list, x);
});
} // Delegated to by overloaded#ProperIncludes and overloaded@ProperIncludedIn
function doProperIncludes(list, sublist) {
return list.length > sublist.length && doIncludes(list, sublist);
} // ELM-only, not a product of CQL
var ForEach = /*#__PURE__*/function (_UnimplementedExpress3) {
_inherits(ForEach, _UnimplementedExpress3);
var _super8 = _createSuper(ForEach);
function ForEach() {
_classCallCheck(this, ForEach);
return _super8.apply(this, arguments);
}
return ForEach;
}(UnimplementedExpression);
var Flatten = /*#__PURE__*/function (_Expression6) {
_inherits(Flatten, _Expression6);
var _super9 = _createSuper(Flatten);
function Flatten(json) {
_classCallCheck(this, Flatten);
return _super9.call(this, json);
}
_createClass(Flatten, [{
key: "exec",
value: function exec(ctx) {
var arg = this.execArgs(ctx);
if (typeIsArray(arg) && arg.every(function (x) {
return typeIsArray(x);
})) {
return arg.reduce(function (x, y) {
return x.concat(y);
}, []);
} else {
return arg;
}
}
}]);
return Flatten;
}(Expression);
var Distinct = /*#__PURE__*/function (_Expression7) {
_inherits(Distinct, _Expression7);
var _super10 = _createSuper(Distinct);
function Distinct(json) {
_classCallCheck(this, Distinct);
return _super10.call(this, json);
}
_createClass(Distinct, [{
key: "exec",
value: function exec(ctx) {
var result = this.execArgs(ctx);
if (result == null) {
return null;
}
return doDistinct(result);
}
}]);
return Distinct;
}(Expression);
function doDistinct(list) {
var distinct = [];
list.forEach(function (item) {
var isNew = distinct.every(function (seenItem) {
return !equals(item, seenItem);
});
if (isNew) {
distinct.push(item);
}
});
return removeDuplicateNulls(distinct);
}
function removeDuplicateNulls(list) {
// Remove duplicate null elements
var firstNullFound = false;
var setList = [];
var _iterator = _createForOfIteratorHelper(list),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var item = _step.value;
if (item !== null) {
setList.push(item);
} else if (item === null && !firstNullFound) {
setList.push(item);
firstNullFound = true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return setList;
} // ELM-only, not a product of CQL
var Current = /*#__PURE__*/function (_UnimplementedExpress4) {
_inherits(Current, _UnimplementedExpress4);
var _super11 = _createSuper(Current);
function Current() {
_classCallCheck(this, Current);
return _super11.apply(this, arguments);
}
return Current;
}(UnimplementedExpression);
var First = /*#__PURE__*/function (_Expression8) {
_inherits(First, _Expression8);
var _super12 = _createSuper(First);
function First(json) {
var _this3;
_classCallCheck(this, First);
_this3 = _super12.call(this, json);
_this3.source = build(json.source);
return _this3;
}
_createClass(First, [{
key: "exec",
value: function exec(ctx) {
var src = this.source.exec(ctx);
if (src != null && typeIsArray(src) && src.length > 0) {
return src[0];
} else {
return null;
}
}
}]);
return First;
}(Expression);
var Last = /*#__PURE__*/function (_Expression9) {
_inherits(Last, _Expression9);
var _super13 = _createSuper(Last);
function Last(json) {
var _this4;
_classCallCheck(this, Last);
_this4 = _super13.call(this, json);
_this4.source = build(json.source);
return _this4;
}
_createClass(Last, [{
key: "exec",
value: function exec(ctx) {
var src = this.source.exec(ctx);
if (src != null && typeIsArray(src) && src.length > 0) {
return src[src.length - 1];
} else {
return null;
}
}
}]);
return Last;
}(Expression);
var Slice = /*#__PURE__*/function (_Expression10) {
_inherits(Slice, _Expression10);
var _super14 = _createSuper(Slice);
function Slice(json) {
var _this5;
_classCallCheck(this, Slice);
_this5 = _super14.call(this, json);
_this5.source = build(json.source);
_this5.startIndex = build(json.startIndex);
_this5.endIndex = build(json.endIndex);
return _this5;
}
_createClass(Slice, [{
key: "exec",
value: function exec(ctx) {
var src = this.source.exec(ctx);
if (src != null && typeIsArray(src)) {
var startIndex = this.startIndex.exec(ctx);
var endIndex = this.endIndex.exec(ctx);
var start = startIndex != null ? startIndex : 0;
var end = endIndex != null ? endIndex : src.length;
if (src.length === 0 || start < 0 || end < 0 || end < start) {
return [];
}
return src.slice(start, end);
}
return null;
}
}]);
return Slice;
}(Expression); // Length is completely handled by overloaded#Length
module.exports = {
Current: Current,
Distinct: Distinct,
Exists: Exists,
Filter: Filter,
First: First,
Flatten: Flatten,
ForEach: ForEach,
IndexOf: IndexOf,
Last: Last,
List: List,
SingletonFrom: SingletonFrom,
Slice: Slice,
Times: Times,
ToList: ToList,
doContains: doContains,
doIncludes: doIncludes,
doProperIncludes: doProperIncludes,
doUnion: doUnion,
doExcept: doExcept,
doIntersect: doIntersect
};