-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support code caret rules in ValueSets (#249)
* Support code caret rules in ValueSets A ValueSet can use caret rules with a code path to set values on included or excluded concepts. The typical use of this is to set a designation, but other elements may also appear. Elements outside of a concept are still unsupported and require the creation of an Instance. * update jest-extended dependency to avoid downstream problems * ValueSet concept caret rules include system in path array The SUSHI dependency is updated to 3.6.0, which supports including the system in the path array. This is needed for rules on ValueSets. Add the system to the path array when extracting caret rules on ValueSet concept components. Caret rules on CodeSystem concepts don't need a system, but still need the leading # as a separator. Add optimizer that reorders rules on ValueSets so that concept rules are grouped with their corresponding caret rules. Update other tests for Invariants, ValueSets, and ConceptRules based on other changes included in SUSHI 3.6.0. * Resolve URLs in ValueSet caret rule concept paths Resolve URLs on caret rules after resolving URLs on ValueSet components so that the caret rules will be able to use aliases that were created when resolving the components. Create new arrays to assign to path array when extracting caret rules on concepts. This avoids the possibility of inadvertantly modifying multiple rules with a single operation that mutates the path array. * Add concepts without caret rules to optimizer test
- Loading branch information
1 parent
8668264
commit 225d702
Showing
22 changed files
with
592 additions
and
474 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
src/optimizer/plugins/ResolveValueSetCaretRuleURLsOptimizer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { utils } from 'fsh-sushi'; | ||
import { OptimizerPlugin } from '../OptimizerPlugin'; | ||
import { optimizeURL } from '../utils'; | ||
import { Package } from '../../processor'; | ||
import { MasterFisher, ProcessingOptions } from '../../utils'; | ||
import { ExportableCaretValueRule } from '../../exportable'; | ||
|
||
export default { | ||
name: 'resolve_value_set_caret_rule_urls', | ||
description: 'Replace URLs in value set caret rules with their names or aliases', | ||
runAfter: ['resolve_value_set_component_rule_urls'], | ||
optimize(pkg: Package, fisher: MasterFisher, options: ProcessingOptions = {}): void { | ||
pkg.valueSets.forEach(vs => { | ||
vs.rules.forEach(rule => { | ||
if (rule instanceof ExportableCaretValueRule && rule.pathArray.length > 0) { | ||
const [system, ...code] = rule.pathArray[0].split('#'); | ||
const resolvedSystem = optimizeURL( | ||
system, | ||
pkg.aliases, | ||
[utils.Type.CodeSystem], | ||
fisher, | ||
options.alias ?? true | ||
); | ||
rule.pathArray[0] = [resolvedSystem, code.join('#')].join('#'); | ||
} | ||
}); | ||
}); | ||
} | ||
} as OptimizerPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
src/optimizer/plugins/SeparateConceptsWithCaretRulesOptimizer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { isEmpty, isEqual } from 'lodash'; | ||
import { ExportableCaretValueRule, ExportableValueSetConceptComponentRule } from '../../exportable'; | ||
import { Package } from '../../processor'; | ||
import { OptimizerPlugin } from '../OptimizerPlugin'; | ||
|
||
// a ValueSetConceptComponentRule will print as multiple consecutive rules | ||
// if there is a system, but no valuesets. | ||
// normally, this is fine, but if more than one of those concepts has caret rules, | ||
// split them manually so that the caret rules appear immediately after the concept. for example: | ||
// * #BEAR from system http://example.org/zoo | ||
// * #BEAR ^designation.value = "ourse" | ||
// * #BEAR ^designation.language = #fr | ||
// * #PEL from system http://example.org/zoo | ||
// * #PEL ^designation.value = "pelícano" | ||
// * #PEL ^designation.language = #es | ||
export default { | ||
name: 'separate_concepts_with_caret_rules', | ||
description: 'Separate concepts in ValueSets from the same system if they also have caret rules.', | ||
runBefore: ['resolve_value_set_component_rule_urls'], | ||
optimize(pkg: Package): void { | ||
pkg.valueSets.forEach(vs => { | ||
const systemRulesToCheck = vs.rules.filter(rule => { | ||
return ( | ||
rule instanceof ExportableValueSetConceptComponentRule && | ||
rule.from.system != null && | ||
isEmpty(rule.from.valueSets) && | ||
rule.concepts.length > 1 | ||
); | ||
}) as ExportableValueSetConceptComponentRule[]; | ||
const allCodeCaretRules = vs.rules.filter(rule => { | ||
return rule instanceof ExportableCaretValueRule && rule.pathArray.length > 0; | ||
}) as ExportableCaretValueRule[]; | ||
if (allCodeCaretRules.length > 0) { | ||
systemRulesToCheck.forEach(conceptRule => { | ||
// for each concept in the rule, see if there are any caret value rules. | ||
const caretRulesForSystem = new Map<string, ExportableCaretValueRule[]>(); | ||
conceptRule.concepts.forEach(concept => { | ||
caretRulesForSystem.set( | ||
concept.code, | ||
allCodeCaretRules.filter(caretRule => | ||
isEqual(caretRule.pathArray, [`${conceptRule.from.system ?? ''}#${concept.code}`]) | ||
) | ||
); | ||
}); | ||
if (caretRulesForSystem.size > 1) { | ||
// split apart the codes so that the ones with caret rules can be next to their concept rule | ||
const reorganizedRules: ( | ||
| ExportableValueSetConceptComponentRule | ||
| ExportableCaretValueRule | ||
)[] = []; | ||
for (const concept of conceptRule.concepts) { | ||
const singleConceptRule = new ExportableValueSetConceptComponentRule( | ||
conceptRule.inclusion | ||
); | ||
singleConceptRule.from.system = conceptRule.from.system; | ||
singleConceptRule.concepts = [concept]; | ||
// don't need to copy indent since it will always be 0 | ||
reorganizedRules.push(singleConceptRule); | ||
for (const caretRule of caretRulesForSystem.get(concept.code)) { | ||
reorganizedRules.push(caretRule); | ||
vs.rules.splice(vs.rules.indexOf(caretRule), 1); | ||
} | ||
} | ||
const originalConceptRuleIndex = vs.rules.indexOf(conceptRule); | ||
vs.rules.splice(originalConceptRuleIndex, 1, ...reorganizedRules); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
} as OptimizerPlugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.