Fhirx is a library to generate typescript classes from HL7 FHIR structure definition JSON file.
- Install Node.js which includes Node Package Manager
Install Fhirx:
npm install --save-dev fhirx
Create fhirx.config.js
file in the root of the project:
module.exports = {}
Supported config properties:
Property | Required | Type | Default | Description |
---|---|---|---|---|
structureDefinition.path |
true | string | You must provide a path to the folder where structure definition JSON file is stored. | |
structureDefinition.filename |
false | string | structure-definition.json | Allows you to change the default name of the structure definition JSON file. |
outputPath |
true | string | You must provide a path to the folder where FHIR classes will be generated. | |
namespace |
false | string | Fhir | Allows you to change the default name of the exported namespace. |
load |
false | Promise | This field is optional, but required if you want to use CLI to fetch structure definition file. The load function should return a valid Structure Definition JSON object. |
fhirx.config.js
example:
module.exports = {
structureDefinition: {
path: 'src/fhirx'
},
outputPath: 'src/fhirx/generated';
}
To generate Fhir classes use the following command:
fhirx --compile
To patch Fhir classes use the following command:
fhirx --patch-resources
To load structure definition JSON file use the following command:
fhirx --load-structure-definition
Considering that outputPath: 'src/fhirx/generated'
and namespace: 'Fhir'
:
import {Fhir} from 'src/fhirx/generated/fhir';
export class Main {
constructor() {
const appointment = new Fhir.Appointment()
.setStatus('pending')
.setComment('comment')
.setAppointmentType(
new Fhir.CodeableConcept()
.addCoding(
new Fhir.Coding()
.setCode('code')
.setDisplay('display')
)
.addCoding(
new Fhir.Coding()
.setCode('code2')
.setDisplay('display2')
)
)
console.log(appointment.toPlainObject());
}
}
Every model supports .toPlainObject()
method that converts class instance to JavaScript Object.
In addition, every model supports .toJSON()
method, thus you can pass a class instance to request and it will be converted to the JSON automatically
Every model accepts an object as the first argument in the constructor and recursively deserialize all the properties to class instances.
Example:
const appointment = new Fhir.Appointment({
appointmentType: {
coding: [
{
code: 'code',
display: 'display'
},
{
code: 'code2',
display: 'display2'
},
]
}
});
console.log(appointment.getAppointmentType().getCodings()[1].getCode()); // code2
You can extend generated classes to put more logic there.
In order to do that you need to create extensions
folder inside outputPath
folder provided in the config.
Put your extensions in extensions
folder.
File name should match the class you want to extend and have a suffix .extension.ts
.
For example: bundle.extension.ts
, appointment.extension.ts
, codeable-concept.extension.ts
etc.
Extension class name should match the class name you want to extend and have a suffix Extension
.
For example: BundleExtension
, AppointmentExtension
, CodeableConceptExtension
etc.
Class extension example:
/* File path: [<outputPath>/extensions/bundle.extension.ts] */
import { Bundle } from '../resources/bundle';
import { Resource } from '../resources/resource';
export class BundleExtension extends Bundle {
public findResources<T extends Resource>(resourceType: string): T[] {
return this.getEntries()
.filter(entry => entry.getResource()?.resourceType === resourceType)
.map(entry => entry.getResource()) as T[];
}
public findResource<T extends Resource>(resourceType: string): T | null {
const resources = this.findResources<T>(resourceType);
return resources[0] || null;
}
}
If a new extension(s) was added you need to run fhirx --patch-resources
command, otherwise your changes won't be applied.
Note: you DO NOT need to run fhirx --patch-resources
if you're making changes to already existing extension. Although it won't break anything, but just useless.
Although, this is not a commonly used feature, but might be required in some cases :)
module.exports = {
load: async () => {
const response = await fetch('YOUR_URL');
return response.json();
},
structureDefinition: {
path: 'src/fhirx'
},
...
}
fhirx --load-structure-definition
Like Fhirx? Give the repo a star ⭐