fume-fhir-converter
Version:
FHIR-Utilized Mapping Engine - Community
238 lines • 8.97 kB
JavaScript
;
/**
* © Copyright Outburn Ltd. 2022-2024 All Rights Reserved
* Project name: FUME-COMMUNITY
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.flashMerge = void 0;
const tslib_1 = require("tslib");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const objectFunctions_1 = require("../objectFunctions");
;
const deleteEntriesWithSamePath = async (obj, path) => {
const tempObj = Object.fromEntries(Object.entries(obj).filter(([key, value]) => value === path || (path.includes('[x]') && String(value).includes(path.slice(0, -3)))));
const empty = await (0, objectFunctions_1.isEmpty)(tempObj);
if (!empty) {
const keyName = lodash_1.default.keys(tempObj)[0].split('__path_')[1];
return Object.fromEntries(Object.entries(obj).filter(([key, value]) => !key.includes(keyName)));
}
else {
return obj;
}
};
const sliceByMax = (arr, max) => {
return arr.length ? arr.slice(-1 * Number(max))[0] : null;
};
const addToArr = (arr, value) => {
if (Array.isArray(value)) {
arr = arr.concat(value);
}
else {
arr.push(value);
}
return arr;
};
const flashMerge = async (options, baseObj, ruleObj) => {
// const empty: boolean = await isEmpty(ruleObj);
// if (options?.min === 0) {
// if (empty) return baseObj;
// } else {
// let amountOfElements = 1;
// if (empty) {
// amountOfElements = 0;
// } else {
// try {
// amountOfElements = JSON.parse(ruleObj[options.key]).length;
// } catch (e) {}
// }
// // if (amountOfElements < Number(options.min)) {
// // thrower.throwRuntimeError(`Element '${options.path ?? ''}' has a minimum cardinality of ${options.min ?? ''}, got ${amountOfElements} instead`);
// // }
// }
// this function merges key:value into an existing object
// taking into account cardinality and children of primitives
const isBaseArray = typeof options?.baseMax !== 'undefined' && (options?.baseMax > '1' || options?.baseMax === '*');
const isArray = typeof options?.max !== 'undefined' && (options?.max > '1' || options?.max === '*');
const key = options.key;
const primitive = options?.kind === 'primitive-type' || !(options?.kind);
const mandatoryObj = options?.mandatory;
const newBaseObj = { ...baseObj };
let prevKeyValue;
if (mandatoryObj) {
if (lodash_1.default.get(newBaseObj, key)) {
prevKeyValue = newBaseObj[key];
}
newBaseObj[key] = mandatoryObj;
}
;
let fullUrl;
if (Object.prototype.hasOwnProperty.call(ruleObj, 'fullUrl')) {
// logger.info({ fullUrl: ruleObj.fullUrl, options });
fullUrl = ruleObj.fullUrl;
newBaseObj.fullUrl = fullUrl;
}
;
if (isArray && !primitive) {
let arr = [];
if (prevKeyValue) {
arr = addToArr(arr, prevKeyValue);
}
if ((typeof newBaseObj === 'object') && newBaseObj[key] && !mandatoryObj) {
const baseValue = newBaseObj[key];
arr = addToArr(arr, baseValue);
}
;
if (ruleObj[key]) {
const addValue = ruleObj[key];
let finalObject = addValue;
if (mandatoryObj) {
if (Array.isArray(addValue)) {
finalObject = { ...mandatoryObj };
addValue.forEach(obj => {
const [key, value] = Object.entries(obj)[0];
if (finalObject[key] !== undefined) {
// The key exists in both objects, convert values to an array
if (Array.isArray(value)) {
value.forEach(e => finalObject[key].push(e));
}
else {
finalObject[key].push(value);
}
}
else {
// The key is unique to the array object, add it to the final object
finalObject[key] = value;
}
});
}
finalObject = { ...mandatoryObj, ...finalObject };
}
arr = addToArr(arr, finalObject);
}
;
const resObj = { ...newBaseObj };
if (arr.length > 0)
resObj[key] = arr;
return resObj;
}
else if (isArray && primitive) {
// primitives in fhir have children that are represented in a dedicated object
// when the element is repeating, the array of primitive values and the array of objects must be synced
let arr1 = [];
if ((typeof newBaseObj === 'object') && newBaseObj[key]) {
const baseValue = newBaseObj[key];
arr1 = addToArr(arr1, baseValue);
}
let arr2 = [];
if ((typeof newBaseObj === 'object') && newBaseObj['_' + key]) {
const baseValue = newBaseObj['_' + key];
arr2 = addToArr(arr2, baseValue);
}
;
if (arr1.length === arr2.length) {
if (ruleObj[key]) {
try {
const parsedVal = JSON.parse(ruleObj[key]);
ruleObj[key] = typeof parsedVal === 'number' ? ruleObj[key] : parsedVal;
}
catch (e) { }
if (Array.isArray(ruleObj[key]) && options.max !== '*') {
ruleObj[key] = ruleObj[key].slice(Number(options.max) * -1);
}
const newValue = ruleObj[key];
arr1 = addToArr(arr1, newValue);
}
;
if (ruleObj['_' + key]) {
const newValue = ruleObj['_' + key];
arr2 = addToArr(arr2, newValue);
}
;
}
else {
// fill in with nulls before push
const diff = arr1.length - arr2.length;
const absDiff = Math.abs(diff);
const fill = Array(absDiff).fill(null);
if (diff > 0) {
// positive number, so fill arr2
// but only if we have anything to add to it
if (ruleObj['_' + key])
arr2 = [...arr2, ...fill];
}
else {
// negative diff, so fill arr1
// but only if we have anything to add to it
if (ruleObj[key])
arr1 = [...arr1, ...fill];
}
;
if (ruleObj[key]) { // primitive array
const newValue = ruleObj[key];
arr1 = addToArr(arr1, newValue);
}
if (ruleObj['_' + key]) { // children object array
const newValue = ruleObj['_' + key];
arr2 = addToArr(arr2, newValue);
}
}
const resObj = { ...newBaseObj };
if (arr1.length > 0)
resObj[key] = arr1;
if (arr2.length > 0)
resObj['_' + key] = arr2;
return resObj;
}
else {
// not an array
let resObj = { ...newBaseObj };
resObj = await deleteEntriesWithSamePath(resObj, options.eDefPath);
if (primitive) {
try {
const parsedValue = JSON.parse(ruleObj[key]);
if (typeof parsedValue === 'object') {
// The parsed value is a non-array object
ruleObj[key] = parsedValue;
}
}
catch (e) { }
if (Array.isArray(ruleObj[key]) && options.max) {
ruleObj[key] = sliceByMax(ruleObj[key], options.max);
}
resObj[key] = ruleObj[key];
resObj['_' + key] = ruleObj['_' + key];
resObj['__path_' + key] = options?.path;
}
else {
if (ruleObj[key]) {
if (Array.isArray(ruleObj[key]) && options.max) {
ruleObj[key] = sliceByMax(ruleObj[key], options.max);
}
const newVal = ruleObj[key];
const baseVal = resObj[key];
const merged = { ...baseVal, ...newVal };
resObj[key] = merged;
}
}
if (isBaseArray) {
if (resObj[key]) {
let arr1 = [];
const val = resObj[key];
arr1 = addToArr(arr1, val);
resObj[key] = arr1;
}
if (resObj['_' + key]) {
let arr2 = [];
const val = resObj['_' + key];
arr2 = addToArr(arr2, val);
resObj['_' + key] = arr2;
}
return resObj;
}
else {
return resObj;
}
}
};
exports.flashMerge = flashMerge;
//# sourceMappingURL=flashMerge.js.map