Skip to content

Commit

Permalink
Treat Instance type as wildcard when fishing FHIR dependencies
Browse files Browse the repository at this point in the history
If the FHIRDefinitions fish functions are called specifying Type.Instance as a requested type, treat it like no types were passed in at all (i.e. wildcard type search) in order to search all types.
  • Loading branch information
cmoesel committed Dec 21, 2024
1 parent 853a04e commit b5cff59
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 34 deletions.
13 changes: 9 additions & 4 deletions src/fhirdefs/FHIRDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,15 @@ export class FHIRDefinitions extends BasePackageLoader implements Fishable {

fishForPredefinedResource(item: string, ...types: Type[]): any | undefined {
return this.findResourceJSON(item, {
type: types,
type: normalizeTypes(types),
scope: PREDEFINED_PACKAGE_NAME,
sort: DEFAULT_SORT
});
}

fishForPredefinedResourceMetadata(item: string, ...types: Type[]): Metadata | undefined {
const info = this.findResourceInfo(item, {
type: types,
type: normalizeTypes(types),
scope: PREDEFINED_PACKAGE_NAME,
sort: DEFAULT_SORT
});
Expand All @@ -175,7 +175,7 @@ export class FHIRDefinitions extends BasePackageLoader implements Fishable {

fishForFHIR(item: string, ...types: Type[]): any | undefined {
const def = this.findResourceJSON(item, {
type: types,
type: normalizeTypes(types),
sort: DEFAULT_SORT
});
if (def) {
Expand All @@ -189,7 +189,7 @@ export class FHIRDefinitions extends BasePackageLoader implements Fishable {

fishForMetadata(item: string, ...types: Type[]): Metadata | undefined {
const info = this.findResourceInfo(item, {
type: types,
type: normalizeTypes(types),
sort: DEFAULT_SORT
});
if (info) {
Expand Down Expand Up @@ -223,6 +223,11 @@ export async function createFHIRDefinitions(
return fhirDefinitions;
}

function normalizeTypes(types?: Type[]): undefined | string[] {
// Instance is like a wildcard, allowing anything -- so treat it like no types are passed in at all
return types?.some(t => t === Type.Instance) ? undefined : types;
}

function convertInfoToMetadata(info: ResourceInfo): Metadata {
if (info) {
// Note: explicitly return undefined instead of null to keep tests happy
Expand Down
127 changes: 97 additions & 30 deletions test/fhirdefs/FHIRDefinitions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@ describe('FHIRDefinitions', () => {
).toEqual(allergyStatusCodeSystemByID);
});

it('should find other types when the fished type is Type.Instance', () => {
const individualGenderSearchParamByID = defs.fishForFHIR('individual-gender', Type.Instance);
expect(individualGenderSearchParamByID.url).toBe(
'http://hl7.org/fhir/SearchParameter/individual-gender'
);
expect(individualGenderSearchParamByID.version).toBe('4.0.1');
expect(defs.fishForFHIR('gender', Type.Instance)).toEqual(individualGenderSearchParamByID);
expect(
defs.fishForFHIR('http://hl7.org/fhir/SearchParameter/individual-gender', Type.Instance)
).toEqual(individualGenderSearchParamByID);
});

it('should find the time-traveling R5 FHIR resources when R4 is loaded', () => {
['ActorDefinition', 'Requirements', 'SubscriptionTopic', 'TestPlan'].forEach(r => {
const resourceById = defs.fishForFHIR(r, Type.Resource);
Expand Down Expand Up @@ -335,8 +347,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(conditionByID).toBeUndefined();

Expand All @@ -347,8 +358,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(booleanByID).toBeUndefined();

Expand All @@ -359,8 +369,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(addressByID).toBeUndefined();

Expand All @@ -371,8 +380,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(vitalSignsProfileByID).toBeUndefined();

Expand All @@ -383,8 +391,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Profile,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(maidenNameExtensionByID).toBeUndefined();

Expand All @@ -395,8 +402,7 @@ describe('FHIRDefinitions', () => {
Type.Logical,
Type.Type,
Type.Profile,
Type.Extension,
Type.Instance
Type.Extension
);
expect(allergyStatusValueSetByID).toBeUndefined();

Expand All @@ -407,8 +413,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.Instance
Type.ValueSet
);
expect(w3cProvenanceCodeSystemByID).toBeUndefined();

Expand All @@ -419,9 +424,21 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.Instance
Type.CodeSystem
);
expect(eLTSSServiceModelByID).toBeUndefined();

const individualGenderSearchParamByID = defs.fishForFHIR(
'individual-gender',
Type.Resource,
Type.Logical,
Type.Type,
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem
);
expect(individualGenderSearchParamByID).toBeUndefined();
});

it('should globally find any definition', () => {
Expand Down Expand Up @@ -494,6 +511,16 @@ describe('FHIRDefinitions', () => {
expect(
defs.fishForFHIR('http://hl7.org/fhir/us/eltss/StructureDefinition/eLTSSServiceModel')
).toEqual(eLTSSServiceModelByID);

const individualGenderSearchParamByID = defs.fishForFHIR('individual-gender');
expect(individualGenderSearchParamByID.url).toBe(
'http://hl7.org/fhir/SearchParameter/individual-gender'
);
expect(individualGenderSearchParamByID.version).toBe('4.0.1');
expect(defs.fishForFHIR('gender')).toEqual(individualGenderSearchParamByID);
expect(defs.fishForFHIR('http://hl7.org/fhir/SearchParameter/individual-gender')).toEqual(
individualGenderSearchParamByID
);
});
});

Expand Down Expand Up @@ -700,6 +727,27 @@ describe('FHIRDefinitions', () => {
).toEqual(allergyStatusCodeSystemByID);
});

it('should find other types when the fished type is Type.Instance', () => {
const individualGenderSearchParamByID = defs.fishForMetadata(
'individual-gender',
Type.Instance
);
expect(individualGenderSearchParamByID).toEqual({
id: 'individual-gender',
name: 'gender',
resourcePath: `virtual:hl7.fhir.r4.core#4.0.1:${testDefsPath('r4-definitions', 'package', 'SearchParameter-individual-gender.json')}`,
resourceType: 'SearchParameter',
url: 'http://hl7.org/fhir/SearchParameter/individual-gender',
version: '4.0.1'
});
expect(defs.fishForMetadata('gender', Type.Instance)).toEqual(
individualGenderSearchParamByID
);
expect(
defs.fishForMetadata('http://hl7.org/fhir/SearchParameter/individual-gender', Type.Instance)
).toEqual(individualGenderSearchParamByID);
});

it('should find the time-traveling R5 FHIR resources when R4 is loaded', () => {
['ActorDefinition', 'Requirements', 'SubscriptionTopic', 'TestPlan'].forEach(r => {
const resourceById = defs.fishForMetadata(r, Type.Resource);
Expand Down Expand Up @@ -865,8 +913,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(conditionByID).toBeUndefined();

Expand All @@ -877,8 +924,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(booleanByID).toBeUndefined();

Expand All @@ -889,8 +935,7 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(addressByID).toBeUndefined();

Expand All @@ -901,8 +946,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Extension,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(vitalSignsProfileByID).toBeUndefined();

Expand All @@ -913,8 +957,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Profile,
Type.ValueSet,
Type.CodeSystem,
Type.Instance
Type.CodeSystem
);
expect(maidenNameExtensionByID).toBeUndefined();

Expand All @@ -925,8 +968,7 @@ describe('FHIRDefinitions', () => {
Type.Logical,
Type.Type,
Type.Profile,
Type.Extension,
Type.Instance
Type.Extension
);
expect(allergyStatusValueSetByID).toBeUndefined();

Expand All @@ -937,8 +979,7 @@ describe('FHIRDefinitions', () => {
Type.Type,
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.Instance
Type.ValueSet
);
expect(w3cProvenanceCodeSystemByID).toBeUndefined();

Expand All @@ -949,9 +990,21 @@ describe('FHIRDefinitions', () => {
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.Instance
Type.CodeSystem
);
expect(eLTSSServiceModelByID).toBeUndefined();

const individualGenderSearchParamByID = defs.fishForFHIR(
'individual-gender',
Type.Resource,
Type.Logical,
Type.Type,
Type.Profile,
Type.Extension,
Type.ValueSet,
Type.CodeSystem
);
expect(individualGenderSearchParamByID).toBeUndefined();
});

it('should globally find any definition', () => {
Expand Down Expand Up @@ -1089,6 +1142,20 @@ describe('FHIRDefinitions', () => {
expect(
defs.fishForMetadata('http://hl7.org/fhir/us/eltss/StructureDefinition/eLTSSServiceModel')
).toEqual(eLTSSServiceModelByID);

const individualGenderSearchParamByID = defs.fishForMetadata('individual-gender');
expect(individualGenderSearchParamByID).toEqual({
id: 'individual-gender',
name: 'gender',
resourcePath: `virtual:hl7.fhir.r4.core#4.0.1:${testDefsPath('r4-definitions', 'package', 'SearchParameter-individual-gender.json')}`,
resourceType: 'SearchParameter',
url: 'http://hl7.org/fhir/SearchParameter/individual-gender',
version: '4.0.1'
});
expect(defs.fishForMetadata('gender')).toEqual(individualGenderSearchParamByID);
expect(defs.fishForMetadata('http://hl7.org/fhir/SearchParameter/individual-gender')).toEqual(
individualGenderSearchParamByID
);
});

it('should find logical models with the can-bind type characteristic extension', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"resourceType": "SearchParameter",
"id": "individual-gender",
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status",
"valueCode": "trial-use"
}
],
"url": "http://hl7.org/fhir/SearchParameter/individual-gender",
"version": "4.0.1",
"name": "gender",
"status": "draft",
"experimental": false,
"date": "2019-11-01T09:29:23+11:00",
"publisher": "Health Level Seven International (Patient Administration)",
"contact": [
{ "telecom": [{ "system": "url", "value": "http://hl7.org/fhir" }] },
{
"telecom": [
{ "system": "url", "value": "http://www.hl7.org/Special/committees/pafm/index.cfm" }
]
}
],
"description": "Multiple Resources: \r\n\r\n* [Patient](patient.html): Gender of the patient\r\n* [Person](person.html): The gender of the person\r\n* [Practitioner](practitioner.html): Gender of the practitioner\r\n* [RelatedPerson](relatedperson.html): Gender of the related person\r\n",
"code": "gender",
"base": ["Patient", "Person", "Practitioner", "RelatedPerson"],
"type": "token",
"expression": "Patient.gender | Person.gender | Practitioner.gender | RelatedPerson.gender",
"xpath": "f:Patient/f:gender | f:Person/f:gender | f:Practitioner/f:gender | f:RelatedPerson/f:gender",
"xpathUsage": "normal"
}

0 comments on commit b5cff59

Please sign in to comment.