fhirsmith 0.9.6 → 0.10.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 +51 -0
- package/library/folder-content-loader.js +91 -0
- package/npmprojector/npmprojector.js +2 -6
- package/package.json +1 -1
- package/packages/package-crawler.js +123 -6
- package/packages/packages.js +104 -0
- package/publisher/publisher.js +290 -12
- package/registry/crawler.js +85 -6
- package/registry/registry.js +24 -7
- package/server.js +11 -2
- package/stats.js +26 -18
- package/translations/Messages.properties +2 -1
- package/tx/cs/cs-cs.js +8 -0
- package/tx/cs/cs-loinc.js +1 -0
- package/tx/cs/cs-provider-list.js +2 -1
- package/tx/cs/cs-snomed.js +142 -59
- package/tx/data/snomed-testing.cache +0 -0
- package/tx/html/home-metrics.liquid +10 -10
- package/tx/library/canonical-resource.js +4 -2
- package/tx/library/codesystem.js +31 -0
- package/tx/library/conceptmap.js +24 -0
- package/tx/library/designations.js +27 -20
- package/tx/library/renderer.js +303 -22
- package/tx/library/ucum-types.js +4 -1
- package/tx/library/valueset.js +46 -0
- package/tx/library.js +65 -21
- package/tx/operation-context.js +122 -27
- package/tx/params.js +36 -8
- package/tx/provider.js +6 -3
- package/tx/tx-html.js +34 -0
- package/tx/tx.js +92 -30
- package/tx/vs/vs-vsac.js +157 -9
- package/tx/workers/cache-control.js +186 -0
- package/tx/workers/{related.js → compare.js} +27 -27
- package/tx/workers/expand.js +100 -96
- package/tx/workers/lookup.js +6 -0
- package/tx/workers/metadata.js +11 -6
- package/tx/workers/read.js +1 -1
- package/tx/workers/translate.js +20 -29
- package/tx/workers/validate.js +18 -10
- package/tx/workers/worker.js +134 -47
- package/tx/xversion/xv-bundle.js +1 -2
- package/tx/xversion/xv-codesystem.js +5 -2
- package/tx/xversion/xv-parameters.js +4 -4
- package/tx/xversion/xv-resource.js +2 -2
- package/tx/xversion/xv-terminologyCapabilities.js +11 -6
- package/tx/xversion/xv-valueset.js +7 -7
- package/publisher/task-draft.js +0 -463
- package/tx/data/OperationDefinition-ValueSet-related.json +0 -133
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//
|
|
2
|
-
//
|
|
2
|
+
// Compare Worker - Handles ValueSet $compare operation
|
|
3
3
|
//
|
|
4
|
-
// GET /ValueSet/{id}/$
|
|
5
|
-
// GET /ValueSet/$
|
|
6
|
-
// POST /ValueSet/$
|
|
7
|
-
// POST /ValueSet/$
|
|
8
|
-
// POST /ValueSet/$
|
|
4
|
+
// GET /ValueSet/{id}/$compare
|
|
5
|
+
// GET /ValueSet/$compare?url=...&version=...
|
|
6
|
+
// POST /ValueSet/$compare (form body or Parameters with url)
|
|
7
|
+
// POST /ValueSet/$compare (body is ValueSet resource)
|
|
8
|
+
// POST /ValueSet/$compare (body is Parameters with valueSet parameter)
|
|
9
9
|
//
|
|
10
10
|
|
|
11
11
|
const { TerminologyWorker } = require('./worker');
|
|
@@ -18,7 +18,7 @@ const {SearchFilterText} = require("../library/designations");
|
|
|
18
18
|
const {ArrayMatcher} = require("../../library/utilities");
|
|
19
19
|
const {debugLog} = require("../operation-context");
|
|
20
20
|
|
|
21
|
-
class
|
|
21
|
+
class CompareWorker extends TerminologyWorker {
|
|
22
22
|
showLogic = false;
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -37,18 +37,18 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
37
37
|
* @returns {string}
|
|
38
38
|
*/
|
|
39
39
|
opName() {
|
|
40
|
-
return '
|
|
40
|
+
return 'compare';
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Handle a type-level $
|
|
45
|
-
* GET/POST /ValueSet/$
|
|
44
|
+
* Handle a type-level $compare request
|
|
45
|
+
* GET/POST /ValueSet/$compare
|
|
46
46
|
* @param {express.Request} req - Express request
|
|
47
47
|
* @param {express.Response} res - Express response
|
|
48
48
|
*/
|
|
49
49
|
async handle(req, res) {
|
|
50
50
|
try {
|
|
51
|
-
await this.
|
|
51
|
+
await this.handleTypeLevelCompare(req, res);
|
|
52
52
|
} catch (error) {
|
|
53
53
|
this.log.error(error);
|
|
54
54
|
debugLog(error);
|
|
@@ -76,14 +76,14 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* Handle an instance-level $
|
|
80
|
-
* GET/POST /ValueSet/{id}/$
|
|
79
|
+
* Handle an instance-level $compare request
|
|
80
|
+
* GET/POST /ValueSet/{id}/$compare
|
|
81
81
|
* @param {express.Request} req - Express request
|
|
82
82
|
* @param {express.Response} res - Express response
|
|
83
83
|
*/
|
|
84
84
|
async handleInstance(req, res) {
|
|
85
85
|
try {
|
|
86
|
-
await this.
|
|
86
|
+
await this.handleInstanceLevelCompare(req, res);
|
|
87
87
|
} catch (error) {
|
|
88
88
|
this.log.error(error);
|
|
89
89
|
debugLog(error);
|
|
@@ -105,11 +105,11 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
|
-
* Handle type-level $
|
|
108
|
+
* Handle type-level $compare: /ValueSet/$compare
|
|
109
109
|
* ValueSet identified by url, or provided directly in body
|
|
110
110
|
*/
|
|
111
|
-
async
|
|
112
|
-
this.deadCheck('
|
|
111
|
+
async handleTypeLevelCompare(req, res) {
|
|
112
|
+
this.deadCheck('compare-type-level');
|
|
113
113
|
|
|
114
114
|
let params = req.body;
|
|
115
115
|
this.addHttpParams(req, params);
|
|
@@ -121,16 +121,16 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
121
121
|
let thisVS = await this.readValueSet(res, "this", params, txp);
|
|
122
122
|
let otherVS = await this.readValueSet(res, "other", params, txp);
|
|
123
123
|
|
|
124
|
-
const result = await this.
|
|
124
|
+
const result = await this.doCompare(txp, thisVS, otherVS);
|
|
125
125
|
return res.json(result);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
|
-
* Handle instance-level
|
|
129
|
+
* Handle instance-level compare: /ValueSet/{id}/$compare
|
|
130
130
|
* ValueSet identified by resource ID
|
|
131
131
|
*/
|
|
132
|
-
async
|
|
133
|
-
this.deadCheck('
|
|
132
|
+
async handleInstanceLevelCompare(req, res) {
|
|
133
|
+
this.deadCheck('compare-instance-level');
|
|
134
134
|
|
|
135
135
|
let params = req.body;
|
|
136
136
|
this.addHttpParams(req, params);
|
|
@@ -147,7 +147,7 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
147
147
|
}
|
|
148
148
|
let otherVS = await this.readValueSet(res, "other", params, txp);
|
|
149
149
|
|
|
150
|
-
const result = await this.
|
|
150
|
+
const result = await this.doCompare(txp, thisVS, otherVS);
|
|
151
151
|
return res.json(result);
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -198,7 +198,7 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
async
|
|
201
|
+
async doCompare(txp, thisVS, otherVS) {
|
|
202
202
|
|
|
203
203
|
// ok, we have to compare the composes. we don't care about anything else
|
|
204
204
|
const thisC = thisVS.jsonObj.compose;
|
|
@@ -206,12 +206,12 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
206
206
|
if (!thisC) {
|
|
207
207
|
return this.makeOutcome("indeterminate", `The ValueSet ${thisVS.vurl} has no compose`);
|
|
208
208
|
}
|
|
209
|
-
Extensions.checkNoModifiers(thisC, '
|
|
209
|
+
Extensions.checkNoModifiers(thisC, 'CompareWorker.doCompare', 'compose', thisVS.vurl)
|
|
210
210
|
this.checkNoLockedDate(thisVS.vurl, thisC);
|
|
211
211
|
if (!otherC) {
|
|
212
212
|
return this.makeOutcome("indeterminate", `The ValueSet ${otherVS.vurl} has no compose`);
|
|
213
213
|
}
|
|
214
|
-
Extensions.checkNoModifiers(otherC, '
|
|
214
|
+
Extensions.checkNoModifiers(otherC, 'CompareWorker.doCompare', 'compose', otherVS.vurl)
|
|
215
215
|
this.checkNoLockedDate(otherVS.vurl, otherC);
|
|
216
216
|
|
|
217
217
|
let systems = new Map(); // tracks whether the comparison is version dependent or not
|
|
@@ -268,7 +268,7 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
268
268
|
} else if (status.left) {
|
|
269
269
|
outcome = this.makeOutcome("superset", `The valueSet ${thisVS.vurl} is a super-set of the valueSet ${otherVS.vurl}`);
|
|
270
270
|
} else {
|
|
271
|
-
outcome = this.makeOutcome("subset", `The valueSet ${thisVS.vurl} is a
|
|
271
|
+
outcome = this.makeOutcome("subset", `The valueSet ${thisVS.vurl} is a sub-set of the valueSet ${otherVS.vurl}`);
|
|
272
272
|
}
|
|
273
273
|
if (txp.diagnostics) {
|
|
274
274
|
outcome.parameter.push({name: 'performed-expansion', valueBoolean: exp ? true : false})
|
|
@@ -712,5 +712,5 @@ class RelatedWorker extends TerminologyWorker {
|
|
|
712
712
|
}
|
|
713
713
|
|
|
714
714
|
module.exports = {
|
|
715
|
-
|
|
715
|
+
CompareWorker
|
|
716
716
|
};
|
package/tx/workers/expand.js
CHANGED
|
@@ -647,11 +647,11 @@ class ValueSetExpander {
|
|
|
647
647
|
} else if (cs.contentMode() === 'supplement') {
|
|
648
648
|
throw new Issue('error', 'business-rule', null, null, 'The code system definition for ' + cset.system + ' defines a supplement, so this expansion cannot be performed', 'invalid');
|
|
649
649
|
} else if (cs.contentMode() === 'fragment') {
|
|
650
|
-
this.addParamUri(exp, 'used-fragment', cs.system()
|
|
650
|
+
this.addParamUri(exp, 'used-fragment', cs.system()+ (cs.version() ? '|' + cs.version(): ""));
|
|
651
651
|
Extensions.addBoolean(exp, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed", true);
|
|
652
652
|
Extensions.addString(exp, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed-reason","This extension is based on a fragment of the code system " + cset.system);
|
|
653
653
|
} else {
|
|
654
|
-
this.addParamUri(exp, cs.contentMode(), cs.system() + '|' + cs.version());
|
|
654
|
+
this.addParamUri(exp, cs.contentMode(), cs.system() + cs.system()+ (cs.version() ? '|' + cs.version(): ""));
|
|
655
655
|
Extensions.addBoolean(exp, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed", true);
|
|
656
656
|
Extensions.addString(exp, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed-reason","This extension is based on a fragment of the code system " + cset.system);
|
|
657
657
|
}
|
|
@@ -948,7 +948,7 @@ class ValueSetExpander {
|
|
|
948
948
|
let vs = await this.worker.findValueSet(s, '', vsSrc);
|
|
949
949
|
const ivs = new ImportedValueSet(await this.expandValueSet(s, '', vs, filter, notClosed));
|
|
950
950
|
this.checkResourceCanonicalStatus(expansion, ivs.valueSet, this.valueSet);
|
|
951
|
-
if (!vs.isContained) {
|
|
951
|
+
if (!vs.isContained && ivs.valueSet.vurl) {
|
|
952
952
|
this.addParamUri(expansion, 'used-valueset', ivs.valueSet.vurl);
|
|
953
953
|
}
|
|
954
954
|
valueSets.push(ivs);
|
|
@@ -961,124 +961,128 @@ class ValueSetExpander {
|
|
|
961
961
|
const cs = await this.worker.findCodeSystem(cset.system, cset.version, this.params, ['complete', 'fragment'], false,
|
|
962
962
|
true, true, null, this.requiredSupplements);
|
|
963
963
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
964
|
+
if (cs == null) {
|
|
965
|
+
// nothing?
|
|
966
|
+
} else {
|
|
967
|
+
this.worker.checkSupplements(cs, cset, this.requiredSupplements, this.usedSupplements);
|
|
968
|
+
this.checkResourceCanonicalStatus(expansion, cs, this.valueSet);
|
|
969
|
+
const sv = this.canonical(await cs.system(), await cs.version());
|
|
970
|
+
this.addParamUri(expansion, 'used-codesystem', sv);
|
|
968
971
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
972
|
+
for (const u of cset.valueSet || []) {
|
|
973
|
+
this.worker.deadCheck('processCodes#3');
|
|
974
|
+
const s = this.worker.pinValueSet(u);
|
|
975
|
+
this.worker.opContext.log('import value set ' + s);
|
|
976
|
+
let vs = await this.worker.findValueSet(s, '', vsSrc);
|
|
977
|
+
const ivs = new ImportedValueSet(await this.expandValueSet(s, '', vs, filter, notClosed));
|
|
978
|
+
this.checkResourceCanonicalStatus(expansion, ivs.valueSet, this.valueSet);
|
|
979
|
+
if (!vs.isContained) {
|
|
980
|
+
this.addParamUri(expansion, 'used-valueset', this.worker.makeVurl(ivs.valueSet));
|
|
981
|
+
}
|
|
982
|
+
valueSets.push(ivs);
|
|
978
983
|
}
|
|
979
|
-
valueSets.push(ivs);
|
|
980
|
-
}
|
|
981
984
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
985
|
+
if (!cset.concept && !cset.filter) {
|
|
986
|
+
this.worker.opContext.log('handle system');
|
|
987
|
+
if (!cset.valueSet) {
|
|
988
|
+
if (!this.excludeSpecialCase) {
|
|
989
|
+
// excluding a whole system - we don't list the codes in this case
|
|
990
|
+
this.excludedSystems.add(cset.system + (this.doingVersion && cset.version ? '|' + cset.version : ''));
|
|
991
|
+
} else {
|
|
992
|
+
const iter = await cs.iteratorAll();
|
|
993
|
+
if (iter) {
|
|
994
|
+
let c = await cs.nextContext(iter);
|
|
995
|
+
while (c) {
|
|
996
|
+
this.worker.deadCheck('processCodes#3aa');
|
|
997
|
+
this.excludeCode(cs, cs.system(), cs.version(), await cs.code(c), expansion, valueSets, vsSrc.url);
|
|
998
|
+
c = await cs.nextContext(iter);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
988
1002
|
} else {
|
|
1003
|
+
if (cs.isNotClosed(filter)) {
|
|
1004
|
+
if (cs.specialEnumeration()) {
|
|
1005
|
+
Extensions.addBoolean(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed", true);
|
|
1006
|
+
Extensions.addString(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed-reason", 'The code System "' + cs.system() + " has a grammar and so has infinite members. This extension is based on " + cs.specialEnumeration());
|
|
1007
|
+
} else {
|
|
1008
|
+
throw new Issue("error", "too-costly", null, null, 'The code System "' + cs.system() + '" has a grammar, and cannot be enumerated directly', null, 422).withDiagnostics(this.worker.opContext.diagnostics());
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
989
1012
|
const iter = await cs.iteratorAll();
|
|
990
1013
|
if (iter) {
|
|
991
1014
|
let c = await cs.nextContext(iter);
|
|
992
1015
|
while (c) {
|
|
993
|
-
this.worker.deadCheck('processCodes#
|
|
994
|
-
|
|
1016
|
+
this.worker.deadCheck('processCodes#3a');
|
|
1017
|
+
if (await this.passesFilters(cs, c, prep, filters, 0)) {
|
|
1018
|
+
this.excludeCode(cs, cs.system(), cs.version(), await cs.code(c), expansion, valueSets, vsSrc.url);
|
|
1019
|
+
}
|
|
995
1020
|
c = await cs.nextContext(iter);
|
|
996
1021
|
}
|
|
997
1022
|
}
|
|
998
1023
|
}
|
|
999
|
-
} else {
|
|
1000
|
-
if (cs.isNotClosed(filter)) {
|
|
1001
|
-
if (cs.specialEnumeration()) {
|
|
1002
|
-
Extensions.addBoolean(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed", true);
|
|
1003
|
-
Extensions.addString(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed-reason", 'The code System "' + cs.system() + " has a grammar and so has infinite members. This extension is based on " + cs.specialEnumeration());
|
|
1004
|
-
} else {
|
|
1005
|
-
throw new Issue("error", "too-costly", null, null, 'The code System "' + cs.system() + '" has a grammar, and cannot be enumerated directly', null, 422).withDiagnostics(this.worker.opContext.diagnostics());
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
const iter = await cs.iteratorAll();
|
|
1010
|
-
if (iter) {
|
|
1011
|
-
let c = await cs.nextContext(iter);
|
|
1012
|
-
while (c) {
|
|
1013
|
-
this.worker.deadCheck('processCodes#3a');
|
|
1014
|
-
if (await this.passesFilters(cs, c, prep, filters, 0)) {
|
|
1015
|
-
this.excludeCode(cs, cs.system(), cs.version(), await cs.code(c), expansion, valueSets, vsSrc.url);
|
|
1016
|
-
}
|
|
1017
|
-
c = await cs.nextContext(iter);
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
1024
|
}
|
|
1021
|
-
}
|
|
1022
1025
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1026
|
+
if (cset.concept) {
|
|
1027
|
+
this.worker.opContext.log('iterate concepts');
|
|
1028
|
+
const cds = new Designations(this.worker.i18n.languageDefinitions);
|
|
1029
|
+
for (const cc of cset.concept) {
|
|
1030
|
+
this.worker.deadCheck('processCodes#3');
|
|
1031
|
+
cds.clear();
|
|
1032
|
+
Extensions.checkNoModifiers(cc, 'ValueSetExpander.processCodes', 'set concept reference', vsSrc.vurl);
|
|
1033
|
+
const cctxt = await cs.locate(cc.code, this.allAltCodes);
|
|
1034
|
+
if (cctxt && cctxt.context && (!this.params.activeOnly || !await cs.isInactive(cctxt.context)) && await this.passesFilters(cs, cctxt.context, prep, filters, 0)) {
|
|
1035
|
+
if (filter.passesDesignations(cds) || filter.passes(cc.code)) {
|
|
1036
|
+
let ov = Extensions.readString(cc, 'http://hl7.org/fhir/StructureDefinition/itemWeight');
|
|
1037
|
+
if (!ov) {
|
|
1038
|
+
ov = await cs.itemWeight(cctxt.context);
|
|
1039
|
+
}
|
|
1040
|
+
this.excludeCode(cs, await cs.system(), await cs.version(), cc.code, expansion, valueSets, vsSrc.url);
|
|
1036
1041
|
}
|
|
1037
|
-
this.excludeCode(cs, await cs.system(), await cs.version(), cc.code, expansion, valueSets, vsSrc.url);
|
|
1038
1042
|
}
|
|
1039
1043
|
}
|
|
1040
1044
|
}
|
|
1041
|
-
}
|
|
1042
1045
|
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1046
|
+
if (cset.filter) {
|
|
1047
|
+
this.worker.opContext.log('prep filters');
|
|
1048
|
+
const prep = await cs.getPrepContext(true);
|
|
1049
|
+
if (!filter.isNull) {
|
|
1050
|
+
await cs.searchFilter(filter, prep, true);
|
|
1051
|
+
}
|
|
1049
1052
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1053
|
+
if (cs.specialEnumeration()) {
|
|
1054
|
+
await cs.specialFilter(prep, true);
|
|
1055
|
+
Extensions.addBoolean(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed", true);
|
|
1056
|
+
Extensions.addString(expansion, "http://hl7.org/fhir/StructureDefinition/valueset-unclosed-reason", 'The code System "' + cs.system() + " has a grammar and so has infinite members. This extension is based on " + cs.specialEnumeration());
|
|
1057
|
+
}
|
|
1055
1058
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1059
|
+
let first = true;
|
|
1060
|
+
for (let fc of cset.filter) {
|
|
1061
|
+
this.worker.deadCheck('processCodes#4a');
|
|
1062
|
+
Extensions.checkNoModifiers(fc, 'ValueSetExpander.processCodes', 'filter', vsSrc.vurl);
|
|
1063
|
+
await cs.filter(prep, first, fc.property, fc.op, fc.value);
|
|
1064
|
+
first = false;
|
|
1065
|
+
}
|
|
1063
1066
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1067
|
+
this.worker.opContext.log('iterate filters');
|
|
1068
|
+
const fset = await cs.executeFilters(prep);
|
|
1069
|
+
if (await cs.filtersNotClosed(prep)) {
|
|
1070
|
+
notClosed.value = true;
|
|
1071
|
+
}
|
|
1072
|
+
//let count = 0;
|
|
1073
|
+
while (await cs.filterMore(prep, fset[0])) {
|
|
1074
|
+
this.worker.deadCheck('processCodes#5');
|
|
1075
|
+
const c = await cs.filterConcept(prep, fset[0]);
|
|
1076
|
+
const ok = (!this.params.activeOnly || !await cs.isInactive(c)) && (await this.passesFilters(cs, c, prep, fset, 1));
|
|
1077
|
+
if (ok) {
|
|
1078
|
+
//count++;
|
|
1079
|
+
if (this.passesImports(valueSets, await cs.system(), await cs.code(c), 0)) {
|
|
1080
|
+
this.excludeCode(cs, await cs.system(), await cs.version(), await cs.code(c), expansion, null, vsSrc.url);
|
|
1081
|
+
}
|
|
1078
1082
|
}
|
|
1079
1083
|
}
|
|
1084
|
+
this.worker.opContext.log('iterate filters finished');
|
|
1080
1085
|
}
|
|
1081
|
-
this.worker.opContext.log('iterate filters finished');
|
|
1082
1086
|
}
|
|
1083
1087
|
}
|
|
1084
1088
|
}
|
package/tx/workers/lookup.js
CHANGED
|
@@ -374,6 +374,12 @@ class LookupWorker extends TerminologyWorker {
|
|
|
374
374
|
});
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
if (designation.status && designation.status !== 'active') {
|
|
378
|
+
designationParts.push({
|
|
379
|
+
name: 'status',
|
|
380
|
+
valueCode: designation.status
|
|
381
|
+
});
|
|
382
|
+
}
|
|
377
383
|
designationParts.push({
|
|
378
384
|
name: 'value',
|
|
379
385
|
valueString: designation.value
|
package/tx/workers/metadata.js
CHANGED
|
@@ -233,7 +233,7 @@ class MetadataHandler {
|
|
|
233
233
|
operation: [
|
|
234
234
|
{ name: 'expand', definition: 'http://hl7.org/fhir/OperationDefinition/ValueSet-expand' },
|
|
235
235
|
{ name: 'validate-code', definition: 'http://hl7.org/fhir/OperationDefinition/ValueSet-validate-code' },
|
|
236
|
-
{ name: '
|
|
236
|
+
{ name: 'compare', definition: 'http://hl7.org/fhir/tools/OperationDefinition/ValueSet-compare' }
|
|
237
237
|
]
|
|
238
238
|
},
|
|
239
239
|
{
|
|
@@ -266,7 +266,8 @@ class MetadataHandler {
|
|
|
266
266
|
{ name: 'validate-code', definition: 'http://hl7.org/fhir/OperationDefinition/Resource-validate-code' },
|
|
267
267
|
{ name: 'translate', definition: 'http://hl7.org/fhir/OperationDefinition/ConceptMap-translate' },
|
|
268
268
|
{ name: 'closure', definition: 'http://hl7.org/fhir/OperationDefinition/ConceptMap-closure' },
|
|
269
|
-
{ name: '
|
|
269
|
+
{ name: 'compare', definition: 'http://hl7.org/fhir/tools/OperationDefinition/ValueSet-compare' },
|
|
270
|
+
{ name: 'cache-control', definition: 'http://hl7.org/fhir/tools/OperationDefinition/cache-control' },
|
|
270
271
|
{ name: 'versions', definition: 'http://hl7.org/fhir/OperationDefinition/fhir-versions' }
|
|
271
272
|
]
|
|
272
273
|
}
|
|
@@ -395,10 +396,14 @@ class MetadataHandler {
|
|
|
395
396
|
buildExpansionCapabilities() {
|
|
396
397
|
return {
|
|
397
398
|
parameter: [
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
399
|
+
// NOTE: `cache-id` is deliberately not advertised as an expansion parameter.
|
|
400
|
+
// Caching is now discovered via the $cache-control operation in the
|
|
401
|
+
// CapabilityStatement, not by advertising a cache-id parameter here. The old
|
|
402
|
+
// advertisement implied the implicit "auto-create on first sight" protocol,
|
|
403
|
+
// which has been replaced: a cache must be created explicitly with
|
|
404
|
+
// $cache-control?mode=start before its cache-id can be used. Clients that
|
|
405
|
+
// only know the old mechanism will see no cache-id parameter and simply not
|
|
406
|
+
// cache (inlining each request), which is correct, just not optimised.
|
|
402
407
|
{
|
|
403
408
|
name: 'tx-resource',
|
|
404
409
|
documentation: 'Additional valuesets needed for evaluation e.g. value sets referred to from the import statement of the value set being expanded'
|
package/tx/workers/read.js
CHANGED
package/tx/workers/translate.js
CHANGED
|
@@ -205,10 +205,8 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
205
205
|
targetSystem = params.get('targetSystem');
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
let explicit = true;
|
|
209
208
|
// If no explicit concept map, we need to find one based on source/target
|
|
210
209
|
if (conceptMaps.length == 0) {
|
|
211
|
-
explicit = false;
|
|
212
210
|
if (reverse) {
|
|
213
211
|
await this.findConceptMapsInAdditionalResources(conceptMaps,targetSystem, targetScope, sourceScope, coding.system);
|
|
214
212
|
await this.provider.findConceptMapForTranslation(this.opContext, conceptMaps, targetSystem, targetScope, sourceScope, coding.system, coding.code);
|
|
@@ -222,7 +220,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
222
220
|
}
|
|
223
221
|
|
|
224
222
|
// Perform the translation
|
|
225
|
-
const result = await this.doTranslate(conceptMaps, coding, targetScope, targetSystem, txp, reverse
|
|
223
|
+
const result = await this.doTranslate(conceptMaps, coding, targetScope, targetSystem, txp, reverse);
|
|
226
224
|
return res.status(200).json(result);
|
|
227
225
|
}
|
|
228
226
|
|
|
@@ -322,7 +320,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
322
320
|
return result;
|
|
323
321
|
}
|
|
324
322
|
|
|
325
|
-
translateUsingGroupsForwards(cm, coding, targetScope, targetSystem, params, output
|
|
323
|
+
translateUsingGroupsForwards(cm, coding, targetScope, targetSystem, params, output) {
|
|
326
324
|
let result = false;
|
|
327
325
|
const matches = cm.listTranslations(coding, targetScope, targetSystem);
|
|
328
326
|
if (matches.length > 0) {
|
|
@@ -385,12 +383,10 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
385
383
|
part: productParts
|
|
386
384
|
});
|
|
387
385
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
});
|
|
393
|
-
}
|
|
386
|
+
matchParts.push({
|
|
387
|
+
name: 'originMap',
|
|
388
|
+
valueCanonical: cm.vurl
|
|
389
|
+
});
|
|
394
390
|
output.push({
|
|
395
391
|
name: 'match',
|
|
396
392
|
part: matchParts
|
|
@@ -403,7 +399,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
403
399
|
return result;
|
|
404
400
|
}
|
|
405
401
|
|
|
406
|
-
translateUsingGroupsReverse(cm, coding, targetScope, targetSystem, params, output
|
|
402
|
+
translateUsingGroupsReverse(cm, coding, targetScope, targetSystem, params, output) {
|
|
407
403
|
let result = false;
|
|
408
404
|
const matches = cm.listTranslationsReverse(coding, targetScope, targetSystem);
|
|
409
405
|
if (matches.length > 0) {
|
|
@@ -474,12 +470,10 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
474
470
|
part: productParts
|
|
475
471
|
});
|
|
476
472
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
});
|
|
482
|
-
}
|
|
473
|
+
matchParts.push({
|
|
474
|
+
name: 'originMap',
|
|
475
|
+
valueCanonical: cm.vurl
|
|
476
|
+
});
|
|
483
477
|
output.push({
|
|
484
478
|
name: 'match',
|
|
485
479
|
part: matchParts
|
|
@@ -491,7 +485,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
491
485
|
return result;
|
|
492
486
|
}
|
|
493
487
|
|
|
494
|
-
async translateUsingCodeSystem(cm, coding, target, params, output, reverse
|
|
488
|
+
async translateUsingCodeSystem(cm, coding, target, params, output, reverse) {
|
|
495
489
|
let result = false;
|
|
496
490
|
const factory = cm.jsonObj.internalSource;
|
|
497
491
|
let prov = await factory.build(this.opContext, []);
|
|
@@ -537,12 +531,10 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
537
531
|
valueString: t.message
|
|
538
532
|
});
|
|
539
533
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
});
|
|
545
|
-
}
|
|
534
|
+
matchParts.push({
|
|
535
|
+
name: 'originMap',
|
|
536
|
+
valueCanonical: cm.vurl
|
|
537
|
+
});
|
|
546
538
|
output.push({
|
|
547
539
|
name: 'match',
|
|
548
540
|
part: matchParts
|
|
@@ -560,10 +552,9 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
560
552
|
* @param {string} targetSystem - Target code system (optional)
|
|
561
553
|
* @param {Parameters} params - Full parameters object
|
|
562
554
|
* @param {boolean} reverse - Full parameters object*
|
|
563
|
-
* @param {boolean} explicit - If the concept map was named explicitly
|
|
564
555
|
* @returns {Object} Parameters resource with translate result
|
|
565
556
|
*/
|
|
566
|
-
async doTranslate(conceptMaps, coding, targetScope, targetSystem, params, reverse
|
|
557
|
+
async doTranslate(conceptMaps, coding, targetScope, targetSystem, params, reverse) {
|
|
567
558
|
this.deadCheck('doTranslate');
|
|
568
559
|
|
|
569
560
|
const result = [];
|
|
@@ -572,11 +563,11 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
572
563
|
let added = false;
|
|
573
564
|
for (const cm of conceptMaps) {
|
|
574
565
|
if (cm.jsonObj.internalSource) {
|
|
575
|
-
added = await this.translateUsingCodeSystem(cm, coding, targetSystem, params, result, reverse
|
|
566
|
+
added = await this.translateUsingCodeSystem(cm, coding, targetSystem, params, result, reverse) || added;
|
|
576
567
|
} else if (reverse) {
|
|
577
|
-
added = this.translateUsingGroupsReverse(cm, coding, targetScope, targetSystem, params, result
|
|
568
|
+
added = this.translateUsingGroupsReverse(cm, coding, targetScope, targetSystem, params, result) || added;
|
|
578
569
|
} else{
|
|
579
|
-
added = this.translateUsingGroupsForwards(cm, coding, targetScope, targetSystem, params, result
|
|
570
|
+
added = this.translateUsingGroupsForwards(cm, coding, targetScope, targetSystem, params, result) || added;
|
|
580
571
|
}
|
|
581
572
|
}
|
|
582
573
|
result.push({
|