UNPKG

fume-fhir-converter

Version:

FHIR-Utilized Mapping Engine - Community

147 lines (132 loc) 6.02 kB
/** * © Copyright Outburn Ltd. 2022-2024 All Rights Reserved * Project name: FUME-COMMUNITY */ /* eslint-disable no-trailing-spaces */ /** * © Copyright Outburn Ltd. 2022-2023 All Rights Reserved * Project name: FUME */ import HL7Dictionary from 'hl7-dictionary'; import jsonata from 'jsonata'; import config from '../../config'; import { IAppBinding } from '../../types'; import { getCache } from '../cache'; import * as conformance from '../conformance'; import { codeSystemDictionary, valueSetExpandDictionary } from '../conformance/conformance'; import fhirFuncs from '../fhirFunctions'; import { parseCsv } from '../inputConverters'; import * as v2 from '../inputConverters/hl7v2'; import { getLogger } from '../logger'; import * as objectFuncs from '../objectFunctions'; import compiler from '../parser'; import { removeComments } from '../parser/removeComments'; import runtime from '../runtime'; import * as stringFuncs from '../stringFunctions'; import { getStructureDefinition } from './getStructureDefinition'; import { logInfo, logWarn } from './log'; import { registerTable } from './registerTable'; const dev = process.env.NODE_ENV === 'dev'; const compiledExpression = async (expression: string): Promise<jsonata.Expression> => { const { compiledExpressions } = getCache(); // takes a fume expression string and compiles it into a jsonata expression // or returns the already compiled expression from cache const key = stringFuncs.hashKey(expression); // turn expression string to a key let compiled: any = compiledExpressions.get(key); // get from cache if (compiled === undefined) { // not cached getLogger().info('expression not cached, compiling it...'); const parsedAsJsonataStr = await compiler.toJsonataString(expression); compiled = jsonata(parsedAsJsonataStr!); compiledExpressions.set(key, compiled); }; return compiled; }; export const transform = async (input: any, expression: string, extraBindings: Record<string, IAppBinding> = {}) => { try { getLogger().info('Running transformation...'); const expr = await compiledExpression(expression); let bindings: Record<string, Function | Record<string, any> | string> = {}; // bind all mappings from cache const { compiledMappings } = getCache(); const mappingIds: any[] = Array.from(compiledMappings.keys()); if (mappingIds) { mappingIds.forEach((mappingId) => { const mapping: any = compiledMappings.get(mappingId); expr.registerFunction(mappingId, mapping?.function, '<x-o?:x>'); }); } // bind functions bindings.__checkResourceId = runtime.checkResourceId; bindings.__finalize = runtime.finalize; bindings.__castToFhir = runtime.castToFhir; bindings.__flashMerge = runtime.flashMerge; bindings.wait = runtime.wait; bindings.resourceId = fhirFuncs.resourceId; bindings.initCap = stringFuncs.initCap; bindings.isEmpty = objectFuncs.isEmpty; bindings.matches = stringFuncs.matches; bindings.stringify = JSON.stringify; bindings.selectKeys = objectFuncs.selectKeys; bindings.omitKeys = objectFuncs.omitKeys; bindings.uuid = stringFuncs.uuid; bindings.registerTable = registerTable; bindings.translateCode = fhirFuncs.translateCode; bindings.translate = fhirFuncs.translateCode; bindings.translateCoding = fhirFuncs.translateCoding; bindings.search = fhirFuncs.search; bindings.searchSingle = fhirFuncs.searchSingle; bindings.literal = fhirFuncs.literal; bindings.resolve = fhirFuncs.resolve; bindings.warning = logWarn; bindings.info = logInfo; bindings.parseCsv = parseCsv; bindings.v2parse = v2.v2parse; bindings.v2json = v2.v2json; bindings.capabilities = fhirFuncs.capabilities; const { aliases } = getCache(); // these are debug functions, should be removed in production versions bindings.fhirCacheIndex = conformance.getFhirPackageIndex(); bindings.getTable = conformance.getTable; bindings.v2dictionary = HL7Dictionary.definitions; bindings.v2codeLookup = v2.v2codeLookup; bindings.v2tableUrl = v2.v2tableUrl; bindings.toJsonataString = compiler.toJsonataString; if (dev) bindings.getMandatoriesOfElement = compiler.getMandatoriesOfElement; if (dev) bindings.getMandatoriesOfStructure = compiler.getMandatoriesOfStructure; if (dev) bindings.getElementDefinition = compiler.getElementDefinition; if (dev) bindings.replaceColonsWithBrackets = compiler.replaceColonsWithBrackets; if (dev) bindings.removeComments = removeComments; if (dev) bindings.valueSetExpandDictionary = valueSetExpandDictionary; if (dev) bindings.codeSystemDictionary = codeSystemDictionary; bindings.getCodeSystem = conformance.getCodeSystem; bindings.getValueSet = conformance.getValueSet; // end of debug functions // bind all aliases from cache bindings = { ...aliases.getDict(), ...bindings, ...extraBindings }; expr.registerFunction('base64encode', stringFuncs.base64encode, '<s-:s>'); expr.registerFunction('base64decode', stringFuncs.base64decode, '<s-:s>'); expr.registerFunction('startsWith', stringFuncs.startsWith, '<s-s:b>'); expr.registerFunction('endsWith', stringFuncs.endsWith, '<s-s:b>'); expr.registerFunction('isNumeric', stringFuncs.isNumeric, '<j-:b>'); expr.registerFunction('reference', fhirFuncs.reference, '<o-:s>'); expr.registerFunction( 'getStructureDefinition', (defId: string) => getStructureDefinition(defId, config.getFhirVersion(), conformance.getFhirPackageIndex(), getLogger()), '<s-:o>' ); expr.registerFunction( 'getSnapshot', async (defId: string) => await compiler.getSnapshot(defId, config.getFhirVersion(), conformance.getFhirPackageIndex(), getLogger()), '<s-:o>' ); const res = await expr.evaluate(input, bindings); return res; } catch (error) { getLogger().error(error); throw error; } };