@@ -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+
3742type AutomaticDependency = {
3843 packageId : string ;
3944 version : string ;
4045 fhirVersions ?: FHIRVersionName [ ] ;
46+ priority : AutomaticDependencyPriority ;
4147} ;
4248
4349type 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
390415export 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