fume-fhir-converter
Version:
FHIR-Utilized Mapping Engine - Community
226 lines • 8.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FumeServer = void 0;
const tslib_1 = require("tslib");
/**
* © Copyright Outburn Ltd. 2022-2024 All Rights Reserved
* Project name: FUME-COMMUNITY
*/
const cors_1 = tslib_1.__importDefault(require("cors"));
const express_1 = tslib_1.__importDefault(require("express"));
const config_1 = tslib_1.__importDefault(require("./config"));
const constants_1 = require("./constants");
const cache_1 = require("./helpers/cache");
const conformance = tslib_1.__importStar(require("./helpers/conformance"));
const fhirServer_1 = require("./helpers/fhirServer");
const jsonataFunctions_1 = require("./helpers/jsonataFunctions");
const logger_1 = require("./helpers/logger");
const routes_1 = require("./routes");
const serverConfig_1 = tslib_1.__importDefault(require("./serverConfig"));
class FumeServer {
app;
server;
/**
* FHIR client instance
* Used to communicate with FHIR server
* Can be overriden by calling
*/
fhirClient;
/**
* Cache configuration
* Allows to register custom cache classes and options
*/
cacheConfig = {};
logger = (0, logger_1.getLogger)();
// default app middleware does nothing - just calls next
appMiddleware = (req, res, next) => {
next();
};
constructor() {
this.app = (0, express_1.default)();
this.app.use(express_1.default.urlencoded({ extended: true, limit: '400mb' }));
this.app.use(express_1.default.json({ limit: '400mb', type: ['application/json', 'application/fhir+json'] }));
this.app.use(express_1.default.text({ limit: '400mb', type: ['text/plain', 'application/vnd.outburn.fume', 'x-application/hl7-v2+er7', 'text/csv', 'application/xml'] }));
this.app.use((0, cors_1.default)());
}
async shutDown() {
if (this.server) {
this.server.close(() => {
console.log('server closed');
process.exit(0);
});
}
}
/**
* Start the server
* Any extensions to the server should be done before calling this method
* i.e. registering alternative logger, cache class, fhir client and express routes.
* @param serverOptions
*/
async warmUp(serverOptions) {
const options = serverOptions ?? serverConfig_1.default;
this.logger.info('FUME initializing...');
config_1.default.setServerConfig(options);
const serverConfig = config_1.default.getServerConfig();
const { SERVER_PORT, FHIR_SERVER_BASE, FHIR_VERSION, FHIR_PACKAGES, SEARCH_BUNDLE_PAGE_SIZE, FHIR_SERVER_TIMEOUT, SERVER_STATELESS } = serverConfig;
this.logger.info(serverConfig);
// initialize caches
(0, cache_1.initCache)(this.cacheConfig);
this.logger.info('Caches initialized');
this.logger.info(`Default FHIR version is set to ${FHIR_VERSION}`);
// translate fhir version to package id
const fhirVersionCorePackageId = config_1.default.getFhirCorePackage();
// download package or throw error
if (fhirVersionCorePackageId) {
const loadRes = await conformance.downloadPackages([fhirVersionCorePackageId]);
if (!loadRes) {
throw new Error(`Errors loading package for FHIR version ${FHIR_VERSION}`);
}
}
else {
throw new Error(`FHIR version ${FHIR_VERSION} is unsupported/invalid!`);
}
;
// load packages
const packageList = [fhirVersionCorePackageId, constants_1.fumeFhirPackageId].concat(FHIR_PACKAGES.split(','));
await conformance.downloadPackages(packageList);
// load index of all packages found in global fhir cache (on disk)
await conformance.loadFhirPackageIndex();
// if fhir server defined, load mappings and aliases from it
if (SERVER_STATELESS) {
this.logger.info('Running in stateless mode');
}
else {
this.logger.info(`Bundle search size: ${SEARCH_BUNDLE_PAGE_SIZE}`);
this.logger.info(`FHIR Server Timeout: ${FHIR_SERVER_TIMEOUT}`);
this.logger.info(`Loading FUME resources from FHIR server ${FHIR_SERVER_BASE} into cache...`);
if (!this.fhirClient) {
this.registerFhirClient(new fhirServer_1.FhirClient());
}
const recacheResult = await conformance.recacheFromServer();
if (recacheResult) {
this.logger.info('Successfully loaded cache');
}
}
;
// mount middleware on application level
// all requests will pass through this function
this.app.use(this.appMiddleware);
// mount routes handler
// if the middleware calls next(), the request handling will proceed here
this.app.use('/', routes_1.routes);
// catch any routes that are not found
// This allows consumers to extend the server with their own routes
// and still have a default 404 handler
this.app.use(routes_1.notFound);
this.server = this.app.listen(SERVER_PORT);
this.logger.info(`FUME server is running on port ${SERVER_PORT}`);
}
/**
* @returns express application
*/
getExpressApp() {
return this.app;
}
/**
* Register application level middleware to intercept all requests
* @param middleware
*/
registerAppMiddleware(middleware) {
this.appMiddleware = middleware;
this.logger.info('Registered application middleware...');
}
;
/**
* Register a logger to replace the default logger
* @param logger
*/
registerLogger(logger) {
this.logger = logger;
(0, logger_1.setLogger)(logger);
}
;
/**
* Register a class to replace the default cache class
* Cache itself is initialized during warm up
* @param CacheClass
* @param options
*/
registerCacheClass(CacheClass, cacheClassOptions, applyToCaches) {
if (applyToCaches.length > 0) {
applyToCaches.forEach(cacheKey => {
this.cacheConfig[cacheKey] = { cacheClass: CacheClass, cacheClassOptions };
});
}
else {
this.logger.warn('No cache keys provided to apply cache class to');
}
}
;
/**
* Pass a FHIR client instance to be used by the server
* @param fhirClient
*/
registerFhirClient(fhirClient) {
this.fhirClient = fhirClient;
(0, fhirServer_1.setFhirClient)(fhirClient);
}
/**
* @returns fhir client
*/
getFhirClient() {
if (!this.fhirClient) {
throw new Error('FHIR client not registered');
}
return this.fhirClient;
}
/**
*
* @returns cache
*/
getCache() {
return (0, cache_1.getCache)();
}
/**
*
* @returns config
*/
getConfig() {
return config_1.default.getServerConfig();
}
/**
* Register additional bindings for `transform` function
* @param key
* @param binding
*/
registerBinding(key, binding) {
config_1.default.setBinding(key, binding);
}
/**
*
* @returns fhir package index
*/
getFhirPackageIndex() {
return conformance.getFhirPackageIndex();
}
/**
*
* @returns fhir packages for the version set in config
*/
getFhirPackages() {
const fhirVersionMinor = config_1.default.getFhirVersionMinor();
const packages = conformance.getFhirPackageIndex();
return packages[fhirVersionMinor];
}
/**
* Calls transform with any additional bindings passed using `registerBinding`
* @param input
* @param expression
* @returns
*/
async transform(input, expression, bindings = {}) {
return await (0, jsonataFunctions_1.transform)(input, expression, { ...config_1.default.getBindings(), ...bindings });
}
}
exports.FumeServer = FumeServer;
//# sourceMappingURL=server.js.map