UNPKG

fume-fhir-converter

Version:

FHIR-Utilized Mapping Engine - Community

147 lines 9.45 kB
"use strict"; /** * © Copyright Outburn Ltd. 2022-2024 All Rights Reserved * Project name: FUME-COMMUNITY */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getElementDefinition = void 0; const tslib_1 = require("tslib"); /* eslint-disable @typescript-eslint/restrict-plus-operands */ const lodash_1 = tslib_1.__importDefault(require("lodash")); const config_1 = tslib_1.__importDefault(require("../../config")); const cache_1 = require("../cache"); const conformance_1 = require("../conformance"); const logger_1 = require("../logger"); const stringFunctions_1 = require("../stringFunctions"); const thrower_1 = tslib_1.__importDefault(require("../thrower")); const getCurrElement_1 = require("./getCurrElement"); const getSnapshot_1 = require("./getSnapshot"); const returnPathWithoutX_1 = require("./returnPathWithoutX"); const dev = process.env.NODE_ENV === 'dev'; ; const getElementDefinition = async (rootType, path) => { if (dev) console.log({ func: exports.getElementDefinition, rootType, path }); if (typeof path === 'string') { path = { originPath: path, newPath: path }; if (dev) console.log({ 'typeof path === \'string\'': true, path }); } const { elementDefinition } = (0, cache_1.getCache)(); // The current root type element determains the existing paths to look out path in. const currTypeStructureDefinition = await (0, getSnapshot_1.getSnapshot)(rootType, config_1.default.getFhirVersion(), (0, conformance_1.getFhirPackageIndex)(), (0, logger_1.getLogger)()); // Creating a list of all the current path nodes. const pathNodes = path.newPath.split('.'); if (dev) console.log({ pathNodes }); // Iterating the nodes, and for each node implementing the logic. The path is being built from the begining to the end // for the fact that a diversion in the main path can lead to a "leaf", if we're not jumping to another Base element. for (let nodes = 1; nodes <= pathNodes.length; nodes++) { // Getting the path up to the current node (to check if it exists and then we can move on) let currPath = path.newPath.split('.').slice(0, nodes).join('.'); let currElement; // First checking the definition cache const cachedElementDefinition = elementDefinition.get(rootType + '-' + currPath); if (dev) console.log({ 'fetching from elementDefinition cache': rootType + '-' + currPath, found: !!cachedElementDefinition }); if (cachedElementDefinition) { currElement = cachedElementDefinition; if (dev) console.log({ cachedElementDefinition }); } else { // Checking if the current element path exists in the current sd if (dev) console.log('(getElementDefinition): getCurrElement()', { currTypeStructureDefinition: currTypeStructureDefinition.id, currPath, nodes, 'path.newPath.split(\'.\')': path.newPath.split('.'), rootType }); currElement = (0, getCurrElement_1.getCurrElement)(currTypeStructureDefinition, currPath, nodes, path.newPath.split('.'), rootType); if (currElement) { // If an element has a contentReference field, ), it will not have a type or a profile, since those are defined in the referenced target element. // The value of the contentReference field will be the target element’s id prefixed by ‘#’. if (lodash_1.default.get(currElement, 'contentReference')) { path.newPath = currElement.contentReference.split('.').slice(1).concat(path.newPath.split('.').slice(nodes)).join('.'); return (0, exports.getElementDefinition)(currElement.contentReference.split('.')[0].slice(1), path); } else { elementDefinition.set(rootType + '-' + currPath, currElement); } } } let baseElem; // Checking if the current node includes [x], and thats why we didnt find the relevant element. // so we need to check for all the options. if (!currElement && pathNodes[nodes - 1].includes('[') && !(nodes >= 2 && pathNodes[nodes - 2].includes('['))) { baseElem = lodash_1.default.cloneDeep(currTypeStructureDefinition.snapshot.element.find(e => { return (0, stringFunctions_1.replaceColonsWithBrackets)(e.id) === String(currTypeStructureDefinition?.type) + '.' + String(currPath.split('[')[0]); })); if (baseElem) { // If there’s a type.profile, fetching its snapshot and adding the url to the type. if (lodash_1.default.get(baseElem, ['type', '0'])) { let baseElemSnapshot; try { baseElemSnapshot = await (0, getSnapshot_1.getSnapshot)(pathNodes[nodes - 1].split('[')[1].split(']')[0], config_1.default.getFhirVersion(), (0, conformance_1.getFhirPackageIndex)(), (0, logger_1.getLogger)()); if (baseElemSnapshot) { // Fixing the fsh to the element id standard if relevant. (bracets to colon) const preFixed = currPath; currPath = currPath.slice(0, -1).split('[').join(':'); path.newPath = path.newPath.replace(preFixed, currPath); // Making sure we are not referencing a pointer to the element we're changing, but a deepClone of it. currElement = lodash_1.default.cloneDeep(baseElem); currElement.type[0].profile = [baseElemSnapshot.url]; currElement.id = currElement.id + ':' + currPath.split(currElement.id.split('.')[currElement.id.split('.').length - 1] + ':')[1]; elementDefinition.set(rootType + '-' + currPath, currElement); elementDefinition.set(currTypeStructureDefinition.url + '-' + currPath, currElement); } } catch (e) { } } } } // Checking wether to move on to the next node, to a content reference or throw an error if (currElement) { // We found the wanted element - the whole path exists. if (currPath === path.newPath) { currElement.__fromDefinition = currTypeStructureDefinition.url; return currElement; } else if (lodash_1.default.get(currElement, ['type', '0', 'code'], '').includes('System')) { // The path is invalid return thrower_1.default.throwParseError(`The element '${currPath}' does not have child elements.`); } else { // Applying the changes we made in the current fshPath in order to find it in the elements ids, before moving on to the next node. path.newPath = currElement.id.split('.').length > 1 ? String(currElement.id.split('.').slice(1).join('.')) + '.' + String(pathNodes.slice(nodes).join('.')) : pathNodes.slice(nodes).join('.'); } } else { if (!baseElem && currPath.split('.').length === 1) { return thrower_1.default.throwParseError(`The element '${path.newPath}' was not found in '${rootType}'`); } else { const prevPath = path.newPath.split('.').slice(0, nodes - 1).join('.'); baseElem = (0, getCurrElement_1.getCurrElement)(currTypeStructureDefinition, prevPath, nodes - 1, path.newPath.split('.'), rootType); // Moving on to the different Root type - all paths in the current one are not relevant, but there might be in another one. if (lodash_1.default.get(baseElem, 'contentReference')) { path.newPath = baseElem.contentReference.split('.').slice(1).join('.'); return (0, exports.getElementDefinition)(baseElem.contentReference.split('.')[0].slice(1), path); } path.newPath = path.newPath.split('.').slice(nodes - 1).join('.'); // Going to the profile type if exists. if (lodash_1.default.get(baseElem, ['type', '0', 'profile'])) { return (0, exports.getElementDefinition)(baseElem.type[0].profile[0], path); } else { // Selecting the relevant type for polymorphic fields. if (baseElem?.type.length > 1) { const splittedOriginPath = path.originPath.split('.').slice(0, -1 * path.newPath.split('.').length); const specificType = baseElem.type.find(t => splittedOriginPath[splittedOriginPath.length - 1] === (0, returnPathWithoutX_1.returnPathWithoutX)(baseElem.id.split('.')[baseElem.id.split('.').length - 1]) + (0, stringFunctions_1.initCapOnce)(t.code)); return (0, exports.getElementDefinition)(specificType.code, path); } else { return (0, exports.getElementDefinition)(baseElem.type[0].code, path); } } } } } }; exports.getElementDefinition = getElementDefinition; //# sourceMappingURL=getElementDefinition.js.map