Skip to content

Commit 305ab57

Browse files
committed
Introduce Automatic Extension Priorities
Specify automatic dependencies as having low or high priority. Low priority auto dependencies are loaded first (before everything else). High priority auto dependencies are loaded last (after everything else). Currently, the terminology and tools packages are low priority; the extensions package is high priority.
1 parent b4840db commit 305ab57

File tree

2 files changed

+241
-123
lines changed

2 files changed

+241
-123
lines changed

src/utils/Processing.ts

Lines changed: 58 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,16 @@ const EXT_PKG_TO_FHIR_PKG_MAP: { [key: string]: string } = {
3434
'hl7.fhir.extensions.r5': 'hl7.fhir.r5.core#5.0.0'
3535
};
3636

37+
export enum AutomaticDependencyPriority {
38+
Low = 'Low', // load before configured dependencies / FHIR core (lowest resolution priority)
39+
High = 'High' // load after configured dependencies / FHIR core (highest resolution priority)
40+
}
41+
3742
type AutomaticDependency = {
3843
packageId: string;
3944
version: string;
4045
fhirVersions?: FHIRVersionName[];
46+
priority: AutomaticDependencyPriority;
4147
};
4248

4349
type FshFhirMapping = {
@@ -54,32 +60,38 @@ export const AUTOMATIC_DEPENDENCIES: AutomaticDependency[] = [
5460
{
5561
packageId: 'hl7.fhir.uv.tools.r4',
5662
version: 'latest',
57-
fhirVersions: ['R4', 'R4B']
63+
fhirVersions: ['R4', 'R4B'],
64+
priority: AutomaticDependencyPriority.Low
5865
},
5966
{
6067
packageId: 'hl7.fhir.uv.tools.r5',
6168
version: 'latest',
62-
fhirVersions: ['R5', 'R6']
69+
fhirVersions: ['R5', 'R6'],
70+
priority: AutomaticDependencyPriority.Low
6371
},
6472
{
6573
packageId: 'hl7.terminology.r4',
6674
version: 'latest',
67-
fhirVersions: ['R4', 'R4B']
75+
fhirVersions: ['R4', 'R4B'],
76+
priority: AutomaticDependencyPriority.Low
6877
},
6978
{
7079
packageId: 'hl7.terminology.r5',
7180
version: 'latest',
72-
fhirVersions: ['R5', 'R6']
81+
fhirVersions: ['R5', 'R6'],
82+
priority: AutomaticDependencyPriority.Low
7383
},
7484
{
7585
packageId: 'hl7.fhir.uv.extensions.r4',
7686
version: 'latest',
77-
fhirVersions: ['R4', 'R4B']
87+
fhirVersions: ['R4', 'R4B'],
88+
priority: AutomaticDependencyPriority.High
7889
},
7990
{
8091
packageId: 'hl7.fhir.uv.extensions.r5',
8192
version: 'latest',
82-
fhirVersions: ['R5', 'R6']
93+
fhirVersions: ['R5', 'R6'],
94+
priority: AutomaticDependencyPriority.High
8395
}
8496
];
8597

@@ -379,24 +391,42 @@ export async function loadExternalDependencies(
379391
}
380392
dependencies.push({ packageId: fhirVersionInfo.packageId, version: fhirVersionInfo.version });
381393

382-
// Load configured dependencies, with FHIR core last so it has higher priority in resolution
394+
// First load automatic dependencies with the lowest priority (before configured dependencies and FHIR core)
395+
await loadAutomaticDependencies(
396+
fhirVersionInfo.version,
397+
dependencies,
398+
defs,
399+
AutomaticDependencyPriority.Low
400+
);
401+
402+
// Then load configured dependencies and FHIR core (FHIR core is last so it has higher priority in resolution)
383403
await loadConfiguredDependencies(dependencies, fhirVersionInfo.version, config.filePath, defs);
384404

385-
// Then load automatic dependencies since they have priority over the core dependencies
405+
// Then load automatic dependencies with highest priority (taking precedence over even FHIR core)
386406
// See: https://chat.fhir.org/#narrow/channel/179239-tooling/topic/New.20Implicit.20Package/near/562477575
387-
await loadAutomaticDependencies(fhirVersionInfo.version, dependencies, defs);
407+
await loadAutomaticDependencies(
408+
fhirVersionInfo.version,
409+
dependencies,
410+
defs,
411+
AutomaticDependencyPriority.High
412+
);
388413
}
389414

390415
export async function loadAutomaticDependencies(
391416
fhirVersion: string,
392417
configuredDependencies: ImplementationGuideDependsOn[],
393-
defs: FHIRDefinitions
418+
defs: FHIRDefinitions,
419+
priority: AutomaticDependencyPriority
394420
): Promise<void> {
395421
const fhirVersionName = getFHIRVersionInfo(fhirVersion).name;
396422

397-
if (fhirVersionName === 'R4' || fhirVersionName === 'R4B') {
423+
if (
424+
priority === AutomaticDependencyPriority.Low &&
425+
(fhirVersionName === 'R4' || fhirVersionName === 'R4B')
426+
) {
398427
// There are several R5 resources that are allowed for use in R4 and R4B.
399-
// Add them first so they're always available.
428+
// Add them first so they're always available (but are lower priority than
429+
// any other version loaded from an official package).
400430
const R5forR4Map = new Map<string, any>();
401431
R5_DEFINITIONS_NEEDED_IN_R4.forEach(def => R5forR4Map.set(def.id, def));
402432
const virtualR5forR4Package = new InMemoryVirtualPackage(
@@ -411,20 +441,22 @@ export async function loadAutomaticDependencies(
411441
await defs.loadVirtualPackage(virtualR5forR4Package);
412442
}
413443

414-
// Gather all automatic dependencies, substituting matching configured dependencies where applicable
415-
const automaticDependencies = AUTOMATIC_DEPENDENCIES.map(autoDep => {
416-
const configuredDeps = configuredDependencies.filter(configuredDep =>
417-
configuredDependencyMatchesAutomaticDependency(configuredDep, autoDep)
418-
);
419-
if (configuredDeps.length) {
420-
// Prefer configured dependencies over automatic dependencies
421-
return configuredDeps;
422-
} else if (autoDep.fhirVersions && !autoDep.fhirVersions.includes(fhirVersionName)) {
423-
// Skip automatic dependencies not intended for this version of FHIR
424-
return [];
425-
}
426-
return autoDep;
427-
}).flat();
444+
// Gather all automatic dependencies matching this priority, substituting matching configured dependencies where applicable
445+
const automaticDependencies = AUTOMATIC_DEPENDENCIES.filter(ad => ad.priority === priority)
446+
.map(autoDep => {
447+
const configuredDeps = configuredDependencies.filter(configuredDep =>
448+
configuredDependencyMatchesAutomaticDependency(configuredDep, autoDep)
449+
);
450+
if (configuredDeps.length) {
451+
// Prefer configured dependencies over automatic dependencies
452+
return configuredDeps;
453+
} else if (autoDep.fhirVersions && !autoDep.fhirVersions.includes(fhirVersionName)) {
454+
// Skip automatic dependencies not intended for this version of FHIR
455+
return [];
456+
}
457+
return autoDep;
458+
})
459+
.flat();
428460
// Load automatic dependencies serially so dependency loading order is predictable and repeatable
429461
for (const dep of automaticDependencies) {
430462
const isUserConfigured = !AUTOMATIC_DEPENDENCIES.some(

0 commit comments

Comments
 (0)