UNPKG

cql-execution

Version:

An execution framework for the Clinical Quality Language (CQL)

175 lines 5.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValueSet = exports.CQLValueSet = exports.CodeSystem = exports.Vocabulary = exports.Concept = exports.Code = void 0; const util_1 = require("../util/util"); class Code { constructor(code, system, version, display) { this.code = code; this.system = system; this.version = version; this.display = display; } get isCode() { return true; } hasMatch(code) { if (typeof code === 'string') { // the specific behavior for this is not in the specification. Matching codesystem behavior. return code === this.code; } else { return codesInList(toCodeList(code), [this]); } } } exports.Code = Code; class Concept { constructor(codes, display) { this.codes = codes; this.display = display; this.codes || (this.codes = []); } get isConcept() { return true; } hasMatch(code) { return codesInList(toCodeList(code), this.codes); } } exports.Concept = Concept; class Vocabulary { constructor(id, version, name) { this.id = id; this.version = version; this.name = name; } } exports.Vocabulary = Vocabulary; class CodeSystem extends Vocabulary { constructor(id, version, name) { super(id, version, name); this.id = id; this.version = version; this.name = name; } } exports.CodeSystem = CodeSystem; class CQLValueSet extends Vocabulary { constructor(id, version, name, codesystems) { super(id, version, name); this.id = id; this.version = version; this.name = name; this.codesystems = codesystems; } get isValueSet() { return true; } } exports.CQLValueSet = CQLValueSet; class ValueSet { constructor(oid, version, codes = []) { this.oid = oid; this.version = version; this.codes = codes; } /** * Determines if the provided code matches any code in the current set. * If the input is a single string, it checks for a direct match with the * codes in the set, ensuring all code systems are consistent. Throws an * error if multiple code systems exist and a match is found, indicating * ambiguity. For other inputs, it checks for any matching codes using * the `codesInList` function. Used for the `code in valueset` operation. * * @param code - The code to be checked for a match, which can be a string * or an object containing codes. * @returns {boolean} True if a match is found, otherwise false. * @throws {Error} If a match is found with multiple code systems present. */ hasMatch(code) { const codesList = toCodeList(code); // InValueSet String Overload if (codesList.length === 1 && typeof codesList[0] === 'string') { let matchFound = false; let multipleCodeSystemsExist = false; for (const codeItem of this.codes) { // Confirm all code systems match if (codeItem.system !== this.codes[0].system) { multipleCodeSystemsExist = true; } if (codeItem.code === codesList[0]) { matchFound = true; } if (multipleCodeSystemsExist && matchFound) { throw new Error('In (valueset) is ambiguous -- multiple codes with multiple code systems exist in value set.'); } } return matchFound; } else { return codesInList(codesList, this.codes); } } /** * Expands the current set of codes by returning a list of unique `Code` objects. * This method filters out duplicate codes from the `codes` array, ensuring each * code appears only once in the returned list. Use for the ExpandValueset operator * * @returns {Code[]} An array of unique `Code` objects. */ expand() { const expanded = []; this.codes.forEach(code => { const foundUniqueCode = expanded.find(uniqueCode => { if (uniqueCode == null || code == null) { return true; } return (uniqueCode.code === code.code && uniqueCode.system == code.system && uniqueCode.version == code.version && uniqueCode.display == code.display); }); if (!foundUniqueCode) { expanded.push(code); } }); return expanded; } } exports.ValueSet = ValueSet; function toCodeList(c) { if (c == null) { return []; } else if ((0, util_1.typeIsArray)(c)) { let list = []; for (const c2 of c) { list = list.concat(toCodeList(c2)); } return list; } else if ((0, util_1.typeIsArray)(c.codes)) { return c.codes; } else { return [c]; } } function codesInList(cl1, cl2) { // test each code in c1 against each code in c2 looking for a match return cl1.some((c1) => cl2.some((c2) => { // only the left argument (cl1) can contain strings. cl2 will only contain codes. if (typeof c1 === 'string') { // for "string in codesystem" this should compare the string to // the code's "code" field according to the specification. return c1 === c2.code; } else { return codesMatch(c1, c2); } })); } function codesMatch(code1, code2) { return code1.code === code2.code && code1.system === code2.system; } //# sourceMappingURL=clinical.js.map