fume-fhir-converter
Version:
FHIR-Utilized Mapping Engine - Community
175 lines • 7.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.recacheFromServer = exports.getAliasResource = exports.cacheMapping = void 0;
const tslib_1 = require("tslib");
/**
* © Copyright Outburn Ltd. 2022-2024 All Rights Reserved
* Project name: FUME-COMMUNITY
*/
const config_1 = tslib_1.__importDefault(require("../../config"));
const cache_1 = require("../cache");
const fhirServer_1 = require("../fhirServer");
const jsonataExpression_1 = tslib_1.__importDefault(require("../jsonataExpression"));
const jsonataFunctions_1 = require("../jsonataFunctions");
const logger_1 = require("../logger");
const serverConfig = config_1.default.getServerConfig();
// Returns the mapping as a function, ready to be called directly from JSONata expressions
const toFunction = (mapping) => {
return async (input, bindings) => {
const extraBindings = config_1.default.getBindings();
const res = await (0, jsonataFunctions_1.transform)(input, mapping, { ...extraBindings, ...bindings });
return res;
};
};
// Saves a mapping's expression and function in cache
const cacheMapping = (mappingId, mappingExpr) => {
const mappingFunc = toFunction(mappingExpr);
const cacheEntry = {
expression: mappingExpr,
function: mappingFunc
};
(0, cache_1.getCache)().compiledMappings.set(mappingId, cacheEntry);
};
exports.cacheMapping = cacheMapping;
// Returns the next page in a series of searchset Bundles
const getNextBundle = async (bundle) => {
if (serverConfig.SERVER_STATELESS) {
throw new Error('FUME running in stateless mode. Cannot get next page of search results bundle.');
}
;
let nextBundle;
const nextLink = await jsonataExpression_1.default.extractNextLink.evaluate(bundle);
if (typeof nextLink === 'string' && nextLink > '') {
nextBundle = await (0, fhirServer_1.getFhirClient)().read(nextLink);
}
return nextBundle;
};
// Scan for all resources in all pages of a FHIR search
const fullSearch = async (query, params) => {
if (serverConfig.SERVER_STATELESS) {
throw new Error('FUME running in stateless mode. Cannot perform search.');
}
;
const bundleArray = [];
let page = await (0, fhirServer_1.getFhirClient)().search(query, params);
while (typeof page === 'object' && page?.resourceType === 'Bundle') {
bundleArray.push(page);
page = await getNextBundle(page);
}
;
const resourceArray = await jsonataExpression_1.default.bundleToArrayOfResources.evaluate({}, { bundleArray });
return resourceArray;
};
// Searches for the alias ConceptMap resource on the server and returns it
const getAliasResource = async () => {
const logger = (0, logger_1.getLogger)();
if (serverConfig.SERVER_STATELESS) {
logger.error('FUME running in stateless mode. Cannot fetch aliases from server.');
return undefined;
}
;
let resource;
try {
const aliasResourceSearch = await (0, fhirServer_1.getFhirClient)().search('ConceptMap', { context: 'http://codes.fume.health|fume', name: 'FumeAliases' });
if (typeof aliasResourceSearch === 'object' && aliasResourceSearch.resourceType === 'Bundle' && typeof aliasResourceSearch.total === 'number') {
if (aliasResourceSearch.total === 1) {
logger.info(`Alias resource found: ${aliasResourceSearch.entry[0].fullUrl}`);
resource = aliasResourceSearch.entry[0].resource;
}
else {
if (aliasResourceSearch.total === 0) {
logger.info('Alias resource not found');
resource = {};
}
else {
logger.error('Multiple alias resources found on server!');
}
}
}
else {
logger.error('Error fetching alias resource!');
}
;
}
catch (e) {
resource = {};
}
return resource;
};
exports.getAliasResource = getAliasResource;
// Fetches the alias resource and returns it in an alias object structure
const getAliases = async (createFunc) => {
const logger = (0, logger_1.getLogger)();
if (serverConfig.SERVER_STATELESS) {
logger.error('FUME running in stateless mode. Cannot fetch mappings from server.');
return undefined;
}
;
let aliasObject;
let aliasResource = await (0, exports.getAliasResource)();
if (typeof aliasResource === 'object') {
if (typeof aliasResource.resourceType === 'string' && aliasResource.resourceType === 'ConceptMap') {
aliasObject = await jsonataExpression_1.default.aliasResourceToObject.evaluate(aliasResource);
}
else {
if (createFunc !== undefined) {
logger.info('Creating new alias resource...');
aliasResource = await createFunc();
aliasObject = await jsonataExpression_1.default.aliasResourceToObject.evaluate(aliasResource);
}
}
}
;
return aliasObject;
};
// Searches the server for all saved mappings and returns their expressions in a single dictionary
const getAllMappings = async () => {
const logger = (0, logger_1.getLogger)();
if (serverConfig.SERVER_STATELESS) {
logger.error('FUME running in stateless mode. Cannot fetch mappings from server.');
return {};
}
;
const allStructureMaps = await fullSearch('StructureMap/', { context: 'http://codes.fume.health|fume' });
const mappingDict = await jsonataExpression_1.default.structureMapsToMappingObject.evaluate(allStructureMaps);
if (Object.keys(mappingDict).length > 0) {
logger.info('Loaded the following mappings from server: ' + Object.keys(mappingDict).join(', '));
}
;
return mappingDict;
};
// Resets the cache and reloads it from the FHIR server
const recacheFromServer = async () => {
const logger = (0, logger_1.getLogger)();
if (serverConfig.SERVER_STATELESS) {
logger.error('FUME running in stateless mode. Cannot recache from server.');
return false;
}
;
try {
const { aliases, compiledMappings } = (0, cache_1.getCache)();
aliases.reset();
aliases.populate(await getAliases());
if (aliases.keys().length > 0) {
logger.info(`Updated cache with aliases: ${aliases.keys().join(', ')}.`);
}
;
const mappingDict = await getAllMappings();
compiledMappings.reset();
Object.keys(mappingDict).forEach((key) => {
(0, exports.cacheMapping)(key, mappingDict[key]);
});
if (Object.keys(mappingDict).length > 0) {
logger.info(`Updated cache with mappings: ${Object.keys(mappingDict).join(', ')}.`);
}
;
}
catch (e) {
logger.error(e);
return false;
}
;
return true;
};
exports.recacheFromServer = recacheFromServer;
//# sourceMappingURL=recacheFromServer.js.map