fume-fhir-converter
Version:
FHIR-Utilized Mapping Engine - Community
144 lines • 8.34 kB
JavaScript
;
/**
* © Copyright Outburn Ltd. 2022-2023 All Rights Reserved
* Project name: FUME
*/
/* eslint-disable */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMandatoriesOfElement = void 0;
const tslib_1 = require("tslib");
const getSnapshot_1 = require("../parser/getSnapshot");
const stringFunctions_1 = require("../stringFunctions");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const getElementDefinition_1 = require("../parser/getElementDefinition");
const jsonataFunctions_1 = require("../jsonataFunctions");
const getMandatoriesOfStructure_1 = require("./getMandatoriesOfStructure");
const config_1 = tslib_1.__importDefault(require("../../config"));
const conformance_1 = require("../conformance");
const logger_1 = require("../logger");
const dev = process.env.NODE_ENV === 'dev';
const getMandatoriesOfElement = async (structId, relativePath) => {
if (dev)
console.log({ func: exports.getMandatoriesOfElement, structId, relativePath });
/* for primitives, return the primitive if it has a fixed value */
/* for complex types, return an object containing all mandatory */
/* decendants that have fixed values down the chain */
/* the element is taken from the root structure definition 'snapshot.element' array */
const rootStruct = await (0, getSnapshot_1.getSnapshot)(structId, config_1.default.getFhirVersion(), (0, conformance_1.getFhirPackageIndex)(), (0, logger_1.getLogger)());
const rootStructSnapshot = rootStruct.snapshot?.element;
/* take the element definition of the requested (parent) element */
if (dev)
console.log('calling getElementDefinition', { structId, relativePath });
const parentElement = await (0, getElementDefinition_1.getElementDefinition)(structId, relativePath);
const fromDefinition = parentElement?.__fromDefinition;
if (dev)
console.log({ fromDefinition });
/* check if returned element is from the root definition */
if (rootStruct?.url === fromDefinition) {
/* get the fhirtype name(s) of the parent, for use in polymorphic keys */
const parentElementType = parentElement.type.map(t => {
if (t.code.startsWith('http://hl7.org/fhirpath/System.')) {
return t?.extension.find(e => e?.url === 'http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type')?.valueUrl;
}
else {
return t?.code;
}
});
/* get the profile, if set (e.g. slices on extension or il-core-patient.address) TODO */
const parentElementProfile = parentElement?.type[0]?.profile;
let fixed;
/* not poly - polies cannot have fixed */
if (parentElementType.length === 1) {
const fixedKeys = ['fixed', 'pattern'].map(key => key + parentElementType[0].split(' ').map(w => (0, stringFunctions_1.initCapOnce)(w)).join(' '));
/* get the fixed value if there is one TODO */
fixed = fixedKeys.map(k => lodash_1.default.get(parentElement, k)).filter(Boolean);
fixed = fixed.length ? fixed[0] : undefined;
}
const typeOfFixed = typeof fixed;
/* now if fixed is not object, no need to continue */
if (fixed && typeOfFixed !== 'object') {
return fixed;
}
else {
/* however if it is an object, it may also have fixed values from underneath */
/* this is obviously true also when there isn't a fixed value */
/* take all elements with min>0 that are "under" the requested element */
let childrenFromRootStruct = rootStructSnapshot.filter(e => {
/* There is a fixed[x] or pattern[x] or it's just mandatory */
return e.id.startsWith(parentElement.id + '.') &&
!(0, stringFunctions_1.substringAfter)(e.id, parentElement.id + '.')?.includes('.') && /* take only those that are a single step under */
(Object.keys(e).filter(k => (0, stringFunctions_1.startsWith)(k, 'fixed') || (0, stringFunctions_1.startsWith)(k, 'pattern')).length > 0 ||
e.min > 0);
});
/* add the correct json key name to each element */
childrenFromRootStruct = childrenFromRootStruct.map(child => {
const lastNode = child.id.split('.').slice(-1)[0];
child.__jsonKey = lastNode.endsWith('[x]') ? (0, stringFunctions_1.substringBefore)(lastNode, '[x]') + (0, stringFunctions_1.initCap)(child?.type[0].code) : lastNode;
return child;
});
let obj = [];
childrenFromRootStruct = childrenFromRootStruct.map(child => {
const code = child?.type[0]?.code;
if (code) {
if ((0, stringFunctions_1.startsWith)(code, 'http://hl7.org/fhirpath/System.')) {
child.__kind = 'primitive-type';
}
else {
child.__kind = (0, jsonataFunctions_1.getStructureDefinition)(code, config_1.default.getFhirVersion(), (0, conformance_1.getFhirPackageIndex)(), (0, logger_1.getLogger)()).kind;
}
}
return child;
});
childrenFromRootStruct = await Promise.all(childrenFromRootStruct.map(async (child) => {
const val = await (0, exports.getMandatoriesOfElement)(structId, (0, stringFunctions_1.substringAfter)(child.id, rootStructSnapshot[0].id + '.'));
return lodash_1.default.merge(child, { __val: val });
}));
childrenFromRootStruct = childrenFromRootStruct.map(child => {
if (typeof child.__val === 'object' && child.__kind === 'primitive-type') {
child[`_${child.__jsonKey}`] = child[child.__jsonKey];
delete child[child.__jsonKey];
}
return child;
});
childrenFromRootStruct = childrenFromRootStruct.map(child => {
const lastNode = child.id.split('.').slice(-1)[0];
const jsonKey = lastNode.endsWith('[x]')
? `${lastNode.split('[x]')[0]}${(0, stringFunctions_1.initCapOnce)(child.type[0].code)}`
: lastNode;
return { ...child, __jsonKey: jsonKey };
});
obj = await childrenFromRootStruct.reduce((acc, curr) => {
if (curr.__val) {
acc[curr.__jsonKey] = (curr.base.max > '1' || curr.base.max === '*' || curr.max > '1' || curr.max === '*') ? [curr.__val] : curr.__val;
}
return acc;
}, {});
let fromProfile;
if (parentElementProfile?.length === 1) {
fromProfile = await (0, getMandatoriesOfStructure_1.getMandatoriesOfStructure)(parentElementProfile[0]);
}
const res = lodash_1.default.merge(fixed, fromProfile, obj);
if (Object.keys(res).length !== 0 && Object.keys(res).length > 0) {
const kv = { ...res };
const kvWithBrackets = {};
for (const key of Object.keys(kv)) {
if (res[key]) {
kvWithBrackets[(0, stringFunctions_1.replaceColonsWithBrackets)(key)] = kv[key];
}
}
const mergedResult = Object.assign({}, kvWithBrackets);
return mergedResult;
}
}
}
else {
/* if returned element is from a different definition than the root, call this function again */
/* this time on the element's containing definition */
const fromDefinitionSnapshot = await (0, getSnapshot_1.getSnapshot)(fromDefinition, config_1.default.getFhirVersion(), (0, conformance_1.getFhirPackageIndex)(), (0, logger_1.getLogger)());
const baseType = fromDefinitionSnapshot.type;
const relativeElementId = (0, stringFunctions_1.substringAfter)(parentElement.id, baseType + '.');
return await (0, exports.getMandatoriesOfElement)(fromDefinition, relativeElementId ?? '');
}
};
exports.getMandatoriesOfElement = getMandatoriesOfElement;
//# sourceMappingURL=getMandatoriesOfElement.js.map