fhirsmith 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +2 -0
- package/configurations/projector.json +21 -0
- package/configurations/readme.md +5 -0
- package/library/package-manager.js +0 -2
- package/library/version-utilities.js +85 -0
- package/package.json +1 -1
- package/packages/package-crawler.js +44 -9
- package/packages/packages.js +1 -0
- package/registry/crawler.js +35 -14
- package/registry/registry.js +3 -0
- package/server.js +4 -0
- package/tx/README.md +4 -4
- package/tx/cs/cs-loinc.js +5 -2
- package/tx/cs/cs-provider-api.js +25 -1
- package/tx/cs/cs-provider-list.js +2 -2
- package/tx/library/canonical-resource.js +6 -1
- package/tx/library.js +127 -10
- package/tx/ocl/README.md +236 -0
- package/tx/ocl/cache/cache-paths.cjs +32 -0
- package/tx/ocl/cache/cache-paths.js +2 -0
- package/tx/ocl/cache/cache-utils.cjs +43 -0
- package/tx/ocl/cache/cache-utils.js +2 -0
- package/tx/ocl/cm-ocl.cjs +531 -0
- package/tx/ocl/cm-ocl.js +1 -105
- package/tx/ocl/cs-ocl.cjs +1779 -0
- package/tx/ocl/cs-ocl.js +1 -38
- package/tx/ocl/fingerprint/fingerprint.cjs +67 -0
- package/tx/ocl/fingerprint/fingerprint.js +2 -0
- package/tx/ocl/http/client.cjs +31 -0
- package/tx/ocl/http/client.js +2 -0
- package/tx/ocl/http/pagination.cjs +98 -0
- package/tx/ocl/http/pagination.js +2 -0
- package/tx/ocl/jobs/background-queue.cjs +200 -0
- package/tx/ocl/jobs/background-queue.js +2 -0
- package/tx/ocl/mappers/concept-mapper.cjs +66 -0
- package/tx/ocl/mappers/concept-mapper.js +2 -0
- package/tx/ocl/model/concept-filter-context.cjs +51 -0
- package/tx/ocl/model/concept-filter-context.js +2 -0
- package/tx/ocl/shared/constants.cjs +15 -0
- package/tx/ocl/shared/constants.js +2 -0
- package/tx/ocl/shared/patches.cjs +224 -0
- package/tx/ocl/shared/patches.js +2 -0
- package/tx/ocl/vs-ocl.cjs +1848 -0
- package/tx/ocl/vs-ocl.js +1 -104
- package/tx/operation-context.js +8 -1
- package/tx/params.js +24 -3
- package/tx/provider.js +47 -0
- package/tx/tx-html.js +1 -1
- package/tx/tx.js +8 -0
- package/tx/vs/vs-vsac.js +4 -3
- package/tx/workers/batch-validate.js +3 -2
- package/tx/workers/batch.js +3 -2
- package/tx/workers/expand.js +64 -9
- package/tx/workers/lookup.js +5 -4
- package/tx/workers/read.js +2 -1
- package/tx/workers/related.js +3 -2
- package/tx/workers/search.js +4 -9
- package/tx/workers/subsumes.js +3 -2
- package/tx/workers/translate.js +4 -3
- package/tx/workers/validate.js +132 -40
- package/tx/workers/worker.js +1 -7
package/tx/workers/search.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const { TerminologyWorker } = require('./worker');
|
|
9
9
|
const {Utilities} = require("../../library/utilities");
|
|
10
|
+
const {debugLog} = require("../operation-context");
|
|
10
11
|
|
|
11
12
|
class SearchWorker extends TerminologyWorker {
|
|
12
13
|
/**
|
|
@@ -114,7 +115,7 @@ class SearchWorker extends TerminologyWorker {
|
|
|
114
115
|
|
|
115
116
|
} catch (error) {
|
|
116
117
|
this.log.error(error);
|
|
117
|
-
|
|
118
|
+
debugLog(error);
|
|
118
119
|
req.logInfo = "error "+(error.msgId || error.className);
|
|
119
120
|
return res.status(500).json({
|
|
120
121
|
resourceType: 'OperationOutcome',
|
|
@@ -146,9 +147,7 @@ class SearchWorker extends TerminologyWorker {
|
|
|
146
147
|
|
|
147
148
|
for (const [key, cs] of this.provider.codeSystems) {
|
|
148
149
|
this.deadCheck('searchCodeSystems');
|
|
149
|
-
|
|
150
|
-
console.log("debug");
|
|
151
|
-
}
|
|
150
|
+
|
|
152
151
|
if (key == cs.vurl) {
|
|
153
152
|
const json = cs.jsonObj;
|
|
154
153
|
|
|
@@ -160,10 +159,6 @@ class SearchWorker extends TerminologyWorker {
|
|
|
160
159
|
// Check each search parameter for partial match
|
|
161
160
|
let isMatch = true;
|
|
162
161
|
for (const [param, searchValue] of Object.entries(searchParams)) {
|
|
163
|
-
// 'system' doesn't do anything for CodeSystem search
|
|
164
|
-
if (param === 'system') {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
162
|
|
|
168
163
|
// Map content-mode to content property
|
|
169
164
|
const jsonProp = param === 'content-mode' ? 'content' : param;
|
|
@@ -180,7 +175,7 @@ class SearchWorker extends TerminologyWorker {
|
|
|
180
175
|
isMatch = false;
|
|
181
176
|
break;
|
|
182
177
|
}
|
|
183
|
-
} else if (param === 'url') { // exact match
|
|
178
|
+
} else if (param === 'url' || param === 'system') { // exact match
|
|
184
179
|
const propValue = json.url;
|
|
185
180
|
if (propValue !== searchValue) {
|
|
186
181
|
isMatch = false;
|
package/tx/workers/subsumes.js
CHANGED
|
@@ -12,6 +12,7 @@ const { FhirCodeSystemProvider } = require('../cs/cs-cs');
|
|
|
12
12
|
const {TxParameters} = require("../params");
|
|
13
13
|
const {Parameters} = require("../library/parameters");
|
|
14
14
|
const {Issue, OperationOutcome} = require("../library/operation-outcome");
|
|
15
|
+
const {debugLog} = require("../operation-context");
|
|
15
16
|
class SubsumesWorker extends TerminologyWorker {
|
|
16
17
|
/**
|
|
17
18
|
* @param {OperationContext} opContext - Operation context
|
|
@@ -43,7 +44,7 @@ class SubsumesWorker extends TerminologyWorker {
|
|
|
43
44
|
await this.handleTypeLevelSubsumes(req, res);
|
|
44
45
|
} catch (error) {
|
|
45
46
|
this.log.error(error);
|
|
46
|
-
|
|
47
|
+
debugLog(error);
|
|
47
48
|
req.logInfo = "error "+(error.msgId || error.className);
|
|
48
49
|
if (error instanceof Issue) {
|
|
49
50
|
let oo = new OperationOutcome();
|
|
@@ -67,7 +68,7 @@ class SubsumesWorker extends TerminologyWorker {
|
|
|
67
68
|
await this.handleInstanceLevelSubsumes(req, res);
|
|
68
69
|
} catch (error) {
|
|
69
70
|
this.log.error(error);
|
|
70
|
-
|
|
71
|
+
debugLog(error);
|
|
71
72
|
if (error instanceof Issue) {
|
|
72
73
|
let oo = new OperationOutcome();
|
|
73
74
|
oo.addIssue(error);
|
package/tx/workers/translate.js
CHANGED
|
@@ -12,6 +12,7 @@ const { TxParameters } = require('../params');
|
|
|
12
12
|
const { Parameters } = require('../library/parameters');
|
|
13
13
|
const { Issue, OperationOutcome } = require('../library/operation-outcome');
|
|
14
14
|
const {ConceptMap} = require("../library/conceptmap");
|
|
15
|
+
const {debugLog} = require("../operation-context");
|
|
15
16
|
|
|
16
17
|
class TranslateWorker extends TerminologyWorker {
|
|
17
18
|
/**
|
|
@@ -44,7 +45,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
44
45
|
await this.handleTypeLevelTranslate(req, res);
|
|
45
46
|
} catch (error) {
|
|
46
47
|
this.log.error(error);
|
|
47
|
-
|
|
48
|
+
debugLog(error);
|
|
48
49
|
if (error instanceof Issue) {
|
|
49
50
|
const oo = new OperationOutcome();
|
|
50
51
|
oo.addIssue(error);
|
|
@@ -67,7 +68,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
67
68
|
await this.handleInstanceLevelTranslate(req, res);
|
|
68
69
|
} catch (error) {
|
|
69
70
|
this.log.error(error);
|
|
70
|
-
|
|
71
|
+
debugLog(error);
|
|
71
72
|
if (error instanceof Issue) {
|
|
72
73
|
const oo = new OperationOutcome();
|
|
73
74
|
oo.addIssue(error);
|
|
@@ -410,7 +411,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
410
411
|
}
|
|
411
412
|
} catch (error) {
|
|
412
413
|
this.log.error(error);
|
|
413
|
-
|
|
414
|
+
debugLog(error);
|
|
414
415
|
result.push({
|
|
415
416
|
name: 'result',
|
|
416
417
|
valueBoolean: false
|
package/tx/workers/validate.js
CHANGED
|
@@ -23,6 +23,8 @@ const ValueSet = require("../library/valueset");
|
|
|
23
23
|
const {ValueSetExpander} = require("./expand");
|
|
24
24
|
const {FhirCodeSystemProvider} = require("../cs/cs-cs");
|
|
25
25
|
const {CodeSystem} = require("../library/codesystem");
|
|
26
|
+
const {VersionUtilities} = require("../../library/version-utilities");
|
|
27
|
+
const {debugLog} = require("../operation-context");
|
|
26
28
|
|
|
27
29
|
const DEV_IGNORE_VALUESET = false; // todo: what's going on with this (ported from pascal)
|
|
28
30
|
|
|
@@ -123,7 +125,7 @@ class ValueSetChecker {
|
|
|
123
125
|
}
|
|
124
126
|
} catch (error) {
|
|
125
127
|
this.log.error(error);
|
|
126
|
-
|
|
128
|
+
debugLog(error);
|
|
127
129
|
throw new Error('Exception expanding value set in order to infer system: ' + error.message);
|
|
128
130
|
}
|
|
129
131
|
return result;
|
|
@@ -444,7 +446,7 @@ class ValueSetChecker {
|
|
|
444
446
|
return await this.check(issuePath, system, version, code, null, unknownSystems, ver, inactive, normalForm, vstatus, it, op, null, null, contentMode, impliedSystem, ts, msgs, defLang);
|
|
445
447
|
}
|
|
446
448
|
|
|
447
|
-
async check(path, system, version, code, displays, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, vcc, params, contentMode, impliedSystem, unkCodes, messages, defLang) {
|
|
449
|
+
async check(path, system, version, code, displays, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, vcc, params, contentMode, impliedSystem, unkCodes, messages, defLang, display) {
|
|
448
450
|
defLang.value = new Language('en');
|
|
449
451
|
this.worker.opContext.addNote(this.valueSet, 'Check "' + this.worker.renderer.displayCoded(system, version, code) + '"', this.indentCount);
|
|
450
452
|
|
|
@@ -677,11 +679,28 @@ class ValueSetChecker {
|
|
|
677
679
|
|
|
678
680
|
if (Extensions.checkNoModifiers(this.valueSet.jsonObj.compose, 'ValueSetChecker.prepare', 'ValueSet.compose')) {
|
|
679
681
|
result = false;
|
|
680
|
-
|
|
682
|
+
let determinedVersion = undefined;
|
|
683
|
+
if (!version) {
|
|
684
|
+
// if we don't have a fixed version, and we have more than one possible version, we have to pick the version
|
|
685
|
+
// now, by looking to see which version we can find the value in, starting from the most revent.
|
|
686
|
+
let includes = (this.valueSet.jsonObj.compose.include || []).filter(inc => inc.system == system);
|
|
687
|
+
let vset = new Set(includes.map(inc => inc.version).filter(Boolean));
|
|
688
|
+
if (vset.size > 1) {
|
|
689
|
+
determinedVersion = await this.pickApplicableVersion(vset, system, code, display);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
const includes = [...(this.valueSet.jsonObj.compose.include || [])];
|
|
693
|
+
includes.sort((a, b) => {
|
|
694
|
+
if (a.system === b.system && a.version && b.version) {
|
|
695
|
+
return -VersionUtilities.compareVersionsGeneral(a.version, b.version);
|
|
696
|
+
}
|
|
697
|
+
return 0;
|
|
698
|
+
});
|
|
699
|
+
for (let cc of includes) {
|
|
681
700
|
this.worker.deadCheck('check#2');
|
|
682
701
|
if (!cc.system) {
|
|
683
702
|
result = true;
|
|
684
|
-
} else if (cc.system === system || system === '%%null%%') {
|
|
703
|
+
} else if ((cc.system === system || system === '%%null%%') && (!determinedVersion || cc.version == determinedVersion) && this.useThisVersion(cc, version)) {
|
|
685
704
|
let v = await this.determineVersion(path, cc.system, cc.version, version, op, unknownSystems, messages);
|
|
686
705
|
let cs = await this.worker.findCodeSystem(system, v, this.params, ["complete", "fragment"], op,true, true, false, this.worker.requiredSupplements);
|
|
687
706
|
if (cs === null) {
|
|
@@ -720,12 +739,12 @@ class ValueSetChecker {
|
|
|
720
739
|
defLang.value = new Language(cs.defLang());
|
|
721
740
|
this.worker.opContext.addNote(this.valueSet, 'CodeSystem found: ' + this.worker.renderer.displayCoded(cs) + ' for ' + this.worker.renderer.displayCoded(cc.system, v), this.indentCount);
|
|
722
741
|
await this.checkCanonicalStatusCS(path, op, cs, this.valueSet);
|
|
723
|
-
ver.value = cs.version();
|
|
724
742
|
this.worker.checkSupplements(cs, cc, this.worker.requiredSupplements, this.worker.usedSupplements);
|
|
725
743
|
contentMode.value = cs.contentMode();
|
|
726
744
|
|
|
727
745
|
let msg = '';
|
|
728
746
|
if ((system === '%%null%%' || cs.system() === system) && await this.checkConceptSet(path, 'in', cs, cc, code, displays, this.valueSet, msg, inactive, normalForm, vstatus, op, vcc, messages)) {
|
|
747
|
+
ver.value = cs.version();
|
|
729
748
|
result = true;
|
|
730
749
|
} else {
|
|
731
750
|
result = false;
|
|
@@ -766,7 +785,6 @@ class ValueSetChecker {
|
|
|
766
785
|
}
|
|
767
786
|
await this.checkCanonicalStatus(path, op, cs, this.valueSet);
|
|
768
787
|
this.worker.checkSupplements(cs, cc, this.worker.requiredSupplements, this.worker.usedSupplements);
|
|
769
|
-
ver.value = cs.version();
|
|
770
788
|
contentMode.value = cs.contentMode();
|
|
771
789
|
let msg = '';
|
|
772
790
|
excluded = (system === '%%null%%' || cs.system() === system) && await this.checkConceptSet(path, 'not in', cs, cc, code, displays, this.valueSet, msg, inactive, normalForm, vstatus, op, vcc);
|
|
@@ -1037,7 +1055,8 @@ class ValueSetChecker {
|
|
|
1037
1055
|
if (this.worker.opContext.usageTracker) {
|
|
1038
1056
|
this.worker.opContext.usageTracker.seeConcept(c.system, c.code);
|
|
1039
1057
|
}
|
|
1040
|
-
|
|
1058
|
+
let vsImpliedVersion = this.findVSVersionForSystem(c.system);
|
|
1059
|
+
const csd = await this.worker.findCodeSystem(c.system, vsImpliedVersion, this.params, ['complete', 'fragment'], false, true, false, false, this.worker.requiredSupplements);
|
|
1041
1060
|
this.worker.seeSourceProvider(csd, c.system);
|
|
1042
1061
|
this.worker.deadCheck('check-b#1');
|
|
1043
1062
|
let path;
|
|
@@ -1055,7 +1074,7 @@ class ValueSetChecker {
|
|
|
1055
1074
|
let ver = { value: '' };
|
|
1056
1075
|
let contentMode = { value: null };
|
|
1057
1076
|
let defLang = { value: null };
|
|
1058
|
-
let v = await this.check(path, c.system, c.version, c.code, list, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, vcc, result, contentMode, impliedSystem, ts, mt, defLang);
|
|
1077
|
+
let v = await this.check(path, c.system, c.version, c.code, list, unknownSystems, ver, inactive, normalForm, vstatus, cause, op, vcc, result, contentMode, impliedSystem, ts, mt, defLang, c.display);
|
|
1059
1078
|
if (v === false) {
|
|
1060
1079
|
cause.value = 'code-invalid';
|
|
1061
1080
|
}
|
|
@@ -1509,14 +1528,16 @@ class ValueSetChecker {
|
|
|
1509
1528
|
|
|
1510
1529
|
async checkConceptSet(path, role, cs, cset, code, displays, vs, message, inactive, normalForm, vstatus, op, vcc, messages) {
|
|
1511
1530
|
this.worker.opContext.addNote(vs, 'check code ' + role + ' ' + this.worker.renderer.displayValueSetInclude(cset) + ' at ' + path, this.indentCount);
|
|
1512
|
-
|
|
1531
|
+
if (role !== 'not in') {
|
|
1532
|
+
inactive.value = false;
|
|
1533
|
+
}
|
|
1513
1534
|
let result = false;
|
|
1514
1535
|
if (!cset.concept && !cset.filter) {
|
|
1515
1536
|
let loc = await cs.locate(code);
|
|
1516
1537
|
result = false;
|
|
1517
1538
|
if (loc.context == null) {
|
|
1518
1539
|
this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" not found in ' + this.worker.renderer.displayCoded(cs)+": "+loc.mesage, this.indentCount);
|
|
1519
|
-
if (!this.params.membershipOnly) {
|
|
1540
|
+
if (!this.params.membershipOnly && role !== 'not in') {
|
|
1520
1541
|
if (cs.contentMode() !== 'complete') {
|
|
1521
1542
|
op.addIssue(new Issue('warning', 'code-invalid', addToPath(path, 'code'), 'UNKNOWN_CODE_IN_FRAGMENT', this.worker.i18n.translate('UNKNOWN_CODE_IN_FRAGMENT', this.params.HTTPLanguages, [code, cs.system(), cs.version()]), 'invalid-code'));
|
|
1522
1543
|
result = true;
|
|
@@ -1548,16 +1569,18 @@ class ValueSetChecker {
|
|
|
1548
1569
|
|
|
1549
1570
|
if (!(this.params.abstractOk || !(await cs.isAbstract(loc.context)))) {
|
|
1550
1571
|
this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" found in ' + this.worker.renderer.displayCoded(cs) + ' but is abstract', this.indentCount);
|
|
1551
|
-
if (!this.params.membershipOnly) {
|
|
1572
|
+
if (!this.params.membershipOnly && role !== 'not in') {
|
|
1552
1573
|
op.addIssue(new Issue('error', 'business-rule', addToPath(path, 'code'), 'ABSTRACT_CODE_NOT_ALLOWED', this.worker.i18n.translate('ABSTRACT_CODE_NOT_ALLOWED', this.params.HTTPLanguages, [cs.system(), code]), 'code-rule'));
|
|
1553
1574
|
}
|
|
1554
1575
|
} else if (this.excludeInactives() && await cs.isInactive(loc.context)) {
|
|
1555
1576
|
this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" found in ' + this.worker.renderer.displayCoded(cs) + ' but is inactive', this.indentCount);
|
|
1556
|
-
|
|
1557
|
-
|
|
1577
|
+
if (role !== 'not in') {
|
|
1578
|
+
let msg = this.worker.i18n.translate('STATUS_CODE_WARNING_CODE', this.params.HTTPLanguages, ['not active', code]);
|
|
1579
|
+
op.addIssue(new Issue('error', 'business-rule', addToPath(path, 'code'), 'STATUS_CODE_WARNING_CODE', msg, 'code-rule'));
|
|
1580
|
+
messages.push(msg);
|
|
1581
|
+
}
|
|
1558
1582
|
result = false;
|
|
1559
|
-
|
|
1560
|
-
if (!this.params.membershipOnly) {
|
|
1583
|
+
if (!this.params.membershipOnly && role !== 'not in') {
|
|
1561
1584
|
inactive.value = true;
|
|
1562
1585
|
inactive.path = path;
|
|
1563
1586
|
if (inactive.value) {
|
|
@@ -1567,28 +1590,31 @@ class ValueSetChecker {
|
|
|
1567
1590
|
} else if (this.params.activeOnly && await cs.isInactive(loc.context)) {
|
|
1568
1591
|
this.worker.opContext.addNote(this.valueSet, 'Code "' + code + '" found in ' + this.worker.renderer.displayCoded(cs) + ' but is inactive', this.indentCount);
|
|
1569
1592
|
result = false;
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1593
|
+
if (role !== 'not in') {
|
|
1594
|
+
inactive.value = true;
|
|
1595
|
+
inactive.path = path;
|
|
1596
|
+
vstatus.value = await cs.getStatus(loc.context);
|
|
1597
|
+
let msg = this.worker.i18n.translate('STATUS_CODE_WARNING_CODE', this.params.HTTPLanguages, ['not active', code]);
|
|
1598
|
+
messages.push(msg);
|
|
1599
|
+
op.addIssue(new Issue('error', 'business-rule', addToPath(path, 'code'), 'STATUS_CODE_WARNING_CODE', msg, 'code-rule'));
|
|
1600
|
+
}
|
|
1576
1601
|
} else {
|
|
1577
1602
|
result = true;
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1603
|
+
if (role !== 'not in') {
|
|
1604
|
+
inactive.value = await cs.isInactive(loc.context);
|
|
1605
|
+
inactive.path = path;
|
|
1606
|
+
vstatus.value = await cs.getStatus(loc.context);
|
|
1607
|
+
if (vcc !== null) {
|
|
1608
|
+
if (!vcc.coding) {
|
|
1609
|
+
vcc.coding = [];
|
|
1610
|
+
}
|
|
1611
|
+
vcc.coding.push({
|
|
1612
|
+
system: cs.system(),
|
|
1613
|
+
version: cs.version(),
|
|
1614
|
+
code: await cs.code(loc.context),
|
|
1615
|
+
display: displays.preferredDisplay(this.params.workingLanguages())
|
|
1616
|
+
});
|
|
1585
1617
|
}
|
|
1586
|
-
vcc.coding.push({
|
|
1587
|
-
system: cs.system(),
|
|
1588
|
-
version: cs.version(),
|
|
1589
|
-
code: await cs.code(loc.context),
|
|
1590
|
-
display: displays.preferredDisplay(this.params.workingLanguages())
|
|
1591
|
-
});
|
|
1592
1618
|
}
|
|
1593
1619
|
return result;
|
|
1594
1620
|
}
|
|
@@ -1739,6 +1765,72 @@ class ValueSetChecker {
|
|
|
1739
1765
|
return list.join(",");
|
|
1740
1766
|
}
|
|
1741
1767
|
|
|
1768
|
+
findVSVersionForSystem(system) {
|
|
1769
|
+
let set = new Set();
|
|
1770
|
+
for (let inc of this.valueSet.jsonObj.compose?.include || []) {
|
|
1771
|
+
if (inc.system == system && inc.version) {
|
|
1772
|
+
set.add(inc.version);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
let v = null;
|
|
1776
|
+
for (let t of set) {
|
|
1777
|
+
if (!v || VersionUtilities.compareVersionsGeneral(t, v) > 0) {
|
|
1778
|
+
v = t;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return v;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
async pickApplicableVersion(vset, system, code, display) {
|
|
1785
|
+
let found = [];
|
|
1786
|
+
for (let v of vset) {
|
|
1787
|
+
let cs = await this.worker.findCodeSystem(system, v, this.params, ["complete", "fragment"], null, true, true, false, this.worker.requiredSupplements);
|
|
1788
|
+
if (cs != null) {
|
|
1789
|
+
let loc = await cs.locate(code);
|
|
1790
|
+
if (loc.context) {
|
|
1791
|
+
if (!display || await this.displayIsOk(cs, loc.context, display)) {
|
|
1792
|
+
found.push(v);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
// if it was found in none or all of them, we don't do anything
|
|
1798
|
+
if (found.length == vset.size) {
|
|
1799
|
+
return undefined;
|
|
1800
|
+
}
|
|
1801
|
+
if (found.length > 0) {
|
|
1802
|
+
let sorted = found.sort((a, b) => -VersionUtilities.compareVersionsGeneral(a, b));
|
|
1803
|
+
return sorted[0];
|
|
1804
|
+
} else { // well, none of them, we'll go with the latest
|
|
1805
|
+
let sorted = [...vset].sort((a, b) => -VersionUtilities.compareVersionsGeneral(a, b));
|
|
1806
|
+
return sorted[0];
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
async displayIsOk(cs, context, display) {
|
|
1811
|
+
if (display == await cs.display(context)) {
|
|
1812
|
+
return true;
|
|
1813
|
+
}
|
|
1814
|
+
const cds = new Designations(this.worker.i18n.languageDefinitions);
|
|
1815
|
+
await cs.designations(context, cds);
|
|
1816
|
+
return cds.designations.find(cd => cd.value == display);
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
hasMatchForVersion(includes, version) {
|
|
1820
|
+
for (let inc of includes) {
|
|
1821
|
+
if (inc.version == version) {
|
|
1822
|
+
return true;
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
return false;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
useThisVersion(cc, version) {
|
|
1829
|
+
if (!version || cc.version == version) {
|
|
1830
|
+
return true;
|
|
1831
|
+
}
|
|
1832
|
+
return !this.hasMatchForVersion(this.valueSet.jsonObj.compose.include || [], version);
|
|
1833
|
+
}
|
|
1742
1834
|
}
|
|
1743
1835
|
|
|
1744
1836
|
function addToPath(path, name) {
|
|
@@ -1855,7 +1947,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
1855
1947
|
|
|
1856
1948
|
} catch (error) {
|
|
1857
1949
|
this.log.error(error);
|
|
1858
|
-
|
|
1950
|
+
debugLog(error);
|
|
1859
1951
|
if (error instanceof Issue) {
|
|
1860
1952
|
if (error.isHandleAsOO()) {
|
|
1861
1953
|
let oo = new OperationOutcome();
|
|
@@ -1914,7 +2006,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
1914
2006
|
return result;
|
|
1915
2007
|
} catch (error) {
|
|
1916
2008
|
this.log.error(error);
|
|
1917
|
-
|
|
2009
|
+
debugLog(error);
|
|
1918
2010
|
if (error instanceof Issue && !error.isHandleAsOO()) {
|
|
1919
2011
|
return await this.handlePrepareError(error, coded, mode.mode, txp);
|
|
1920
2012
|
} else {
|
|
@@ -1973,7 +2065,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
1973
2065
|
|
|
1974
2066
|
} catch (error) {
|
|
1975
2067
|
this.log.error(error);
|
|
1976
|
-
|
|
2068
|
+
debugLog(error);
|
|
1977
2069
|
return res.status(error.statusCode || 500).json(this.operationOutcome(
|
|
1978
2070
|
'error', error.issueCode || 'exception', error.message));
|
|
1979
2071
|
}
|
|
@@ -1994,7 +2086,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
1994
2086
|
|
|
1995
2087
|
} catch (error) {
|
|
1996
2088
|
this.log.error(error);
|
|
1997
|
-
|
|
2089
|
+
debugLog(error);
|
|
1998
2090
|
if (error instanceof Issue) {
|
|
1999
2091
|
let op = new OperationOutcome();
|
|
2000
2092
|
op.addIssue(error);
|
|
@@ -2074,7 +2166,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
2074
2166
|
|
|
2075
2167
|
} catch (error) {
|
|
2076
2168
|
this.log.error(error);
|
|
2077
|
-
|
|
2169
|
+
debugLog(error);
|
|
2078
2170
|
return res.status(error.statusCode || 500).json(this.operationOutcome(
|
|
2079
2171
|
'error', error.issueCode || 'exception', error.message));
|
|
2080
2172
|
}
|
|
@@ -2314,7 +2406,7 @@ class ValidateWorker extends TerminologyWorker {
|
|
|
2314
2406
|
await checker.prepare();
|
|
2315
2407
|
} catch (error) {
|
|
2316
2408
|
this.log.error(error);
|
|
2317
|
-
|
|
2409
|
+
debugLog(error);
|
|
2318
2410
|
if (!(error instanceof Issue) || error.isHandleAsOO()) {
|
|
2319
2411
|
throw error;
|
|
2320
2412
|
} else {
|
package/tx/workers/worker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { TerminologyError
|
|
1
|
+
const { TerminologyError} = require('../operation-context');
|
|
2
2
|
const { CodeSystem } = require('../library/codesystem');
|
|
3
3
|
const ValueSet = require('../library/valueset');
|
|
4
4
|
const {VersionUtilities} = require("../../library/version-utilities");
|
|
@@ -900,12 +900,6 @@ class TerminologyWorker {
|
|
|
900
900
|
return true;
|
|
901
901
|
}
|
|
902
902
|
|
|
903
|
-
debugLog(error) {
|
|
904
|
-
if (isDebugging()) {
|
|
905
|
-
console.log(error);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
903
|
hasSupplement(cs, supplements) {
|
|
910
904
|
for (let t of supplements) {
|
|
911
905
|
if (t.vurl == cs.vurl) {
|