fhirsmith 0.5.6 → 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 +38 -0
- package/README.md +2 -0
- package/configurations/projector.json +21 -0
- package/configurations/readme.md +5 -0
- package/library/html-server.js +2 -1
- package/library/package-manager.js +37 -34
- package/library/utilities.js +10 -1
- package/library/version-utilities.js +85 -0
- package/package.json +1 -1
- package/packages/package-crawler.js +144 -52
- package/packages/packages.js +15 -7
- package/publisher/publisher.js +15 -3
- package/registry/api.js +173 -191
- package/registry/crawler.js +100 -65
- package/registry/model.js +14 -8
- package/registry/registry.js +5 -0
- package/root-template.html +1 -0
- package/server.js +113 -45
- package/tx/README.md +4 -4
- package/tx/cs/cs-api.js +18 -1
- package/tx/cs/cs-base.js +1 -0
- 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/cs/cs-rxnorm.js +9 -2
- package/tx/cs/cs-snomed.js +17 -2
- package/tx/html/codesystem-operations.liquid +17 -24
- package/tx/html/valueset-operations.liquid +46 -52
- package/tx/library/canonical-resource.js +6 -1
- package/tx/library/codesystem.js +6 -1
- package/tx/library/renderer.js +81 -7
- package/tx/library.js +145 -13
- 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 +51 -2
- package/tx/sct/expressions.js +20 -9
- package/tx/tx-html.js +144 -51
- package/tx/tx.js +10 -2
- 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 +125 -18
- 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 +6 -8
- 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/xversion/xv-terminologyCapabilities.js +1 -1
package/tx/cs/cs-api.js
CHANGED
|
@@ -774,12 +774,19 @@ class CodeSystemFactoryProvider {
|
|
|
774
774
|
}
|
|
775
775
|
|
|
776
776
|
/**
|
|
777
|
-
* @returns {string}
|
|
777
|
+
* @returns {string} name for the code system
|
|
778
778
|
*/
|
|
779
779
|
name() {
|
|
780
780
|
throw new Error("Must override");
|
|
781
781
|
}
|
|
782
782
|
|
|
783
|
+
/**
|
|
784
|
+
* @returns {string} name for the code system, without version information
|
|
785
|
+
*/
|
|
786
|
+
nameBase() {
|
|
787
|
+
return this.name();
|
|
788
|
+
}
|
|
789
|
+
|
|
783
790
|
/**
|
|
784
791
|
* @returns {string} version for the code system
|
|
785
792
|
*/
|
|
@@ -796,6 +803,16 @@ class CodeSystemFactoryProvider {
|
|
|
796
803
|
}
|
|
797
804
|
return ver;
|
|
798
805
|
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* the version parameter might not be the same as version() once
|
|
809
|
+
* all matching rules are done
|
|
810
|
+
* @param version
|
|
811
|
+
*/
|
|
812
|
+
describeVersion(version) {
|
|
813
|
+
return "v"+version;
|
|
814
|
+
}
|
|
815
|
+
|
|
799
816
|
/**
|
|
800
817
|
* @returns {number} how many times the factory has been asked to construct a provider
|
|
801
818
|
*/
|
package/tx/cs/cs-base.js
CHANGED
package/tx/cs/cs-loinc.js
CHANGED
|
@@ -203,9 +203,12 @@ class LoincServices extends BaseCSServices {
|
|
|
203
203
|
// Use language-aware display logic
|
|
204
204
|
if (this.opContext.langs && !this.opContext.langs.isEnglishOrNothing()) {
|
|
205
205
|
const displays = await this.#getDisplaysForContext(ctxt, this.opContext.langs);
|
|
206
|
+
const requestedLanguages = Array.isArray(this.opContext.langs.languages)
|
|
207
|
+
? this.opContext.langs.languages
|
|
208
|
+
: (Array.isArray(this.opContext.langs.langs) ? this.opContext.langs.langs : []);
|
|
206
209
|
|
|
207
210
|
// Try to find exact language match
|
|
208
|
-
for (const lang of
|
|
211
|
+
for (const lang of requestedLanguages) {
|
|
209
212
|
for (const display of displays) {
|
|
210
213
|
if (lang.matches(display.language, true)) {
|
|
211
214
|
return display.value;
|
|
@@ -214,7 +217,7 @@ class LoincServices extends BaseCSServices {
|
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
// Try partial language match
|
|
217
|
-
for (const lang of
|
|
220
|
+
for (const lang of requestedLanguages) {
|
|
218
221
|
for (const display of displays) {
|
|
219
222
|
if (lang.matches(display.language, false)) {
|
|
220
223
|
return display.value;
|
package/tx/cs/cs-provider-api.js
CHANGED
|
@@ -20,7 +20,13 @@ class AbstractCodeSystemProvider {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
|
|
23
|
+
* Returns the list of CodeSystems this provider provides. This is called once at start up.
|
|
24
|
+
* The code systems should be fully loaded; lazy loading code systems is not considered good
|
|
25
|
+
* for engineering.
|
|
26
|
+
*
|
|
27
|
+
*
|
|
28
|
+
* Note that unlike value sets, which are accessed from the provider on the fly, code systems
|
|
29
|
+
* are all preloaded into the kernel (e.g. provider) at start up
|
|
24
30
|
*
|
|
25
31
|
* @param {string} fhirVersion - The FHIRVersion in scope - if relevant (there's always a stated version, though R5 is always used)
|
|
26
32
|
* @param {string} context - The client's stated context - if provided.
|
|
@@ -32,6 +38,24 @@ class AbstractCodeSystemProvider {
|
|
|
32
38
|
throw new Error('listCodeSystems must be implemented by AbstractCodeSystemProvider subclass');
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
/**
|
|
42
|
+
* This is called once a minute to update the code system list that the provider maintains.
|
|
43
|
+
*
|
|
44
|
+
* return an object that has three Map<String, CodeSystem>: {added, changed, deleted}
|
|
45
|
+
*
|
|
46
|
+
* these use the same key as the
|
|
47
|
+
*
|
|
48
|
+
* code systems are identified by url and version
|
|
49
|
+
*
|
|
50
|
+
* @param fhirVersion
|
|
51
|
+
* @param context
|
|
52
|
+
* @returns {Promise<null>}
|
|
53
|
+
*/
|
|
54
|
+
// eslint-disable-next-line no-unused-vars
|
|
55
|
+
async getCodeSystemChanges(fhirVersion, context){
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
35
59
|
async close() {
|
|
36
60
|
|
|
37
61
|
}
|
|
@@ -7,7 +7,7 @@ class ListCodeSystemProvider extends AbstractCodeSystemProvider {
|
|
|
7
7
|
/**
|
|
8
8
|
* {Map<String, CodeSystem>} A list of code system factories that contains all the preloaded native code systems
|
|
9
9
|
*/
|
|
10
|
-
codeSystems =
|
|
10
|
+
codeSystems = [];
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* ensure that the ids on the code systems are unique, if they are
|
|
@@ -17,7 +17,7 @@ class ListCodeSystemProvider extends AbstractCodeSystemProvider {
|
|
|
17
17
|
*/
|
|
18
18
|
// eslint-disable-next-line no-unused-vars
|
|
19
19
|
assignIds(ids) {
|
|
20
|
-
for (const cs of this.codeSystems
|
|
20
|
+
for (const cs of this.codeSystems) {
|
|
21
21
|
if (!cs.id || ids.has("CodeSystem/"+cs.id)) {
|
|
22
22
|
cs.id = ""+ids.size;
|
|
23
23
|
}
|
package/tx/cs/cs-rxnorm.js
CHANGED
|
@@ -3,7 +3,7 @@ const assert = require('assert');
|
|
|
3
3
|
const { CodeSystem } = require('../library/codesystem');
|
|
4
4
|
const { CodeSystemProvider, CodeSystemFactoryProvider } = require('./cs-api');
|
|
5
5
|
const {Designations} = require("../library/designations");
|
|
6
|
-
const {validateArrayParameter} = require("../../library/utilities");
|
|
6
|
+
const {validateArrayParameter, formatDateMMDDYYYY} = require("../../library/utilities");
|
|
7
7
|
|
|
8
8
|
// Context for RxNorm concepts
|
|
9
9
|
class RxNormConcept {
|
|
@@ -806,9 +806,16 @@ class RxNormTypeServicesFactory extends CodeSystemFactoryProvider {
|
|
|
806
806
|
}
|
|
807
807
|
|
|
808
808
|
id() {
|
|
809
|
-
return this.name();
|
|
809
|
+
return this.name()+"-"+this.version();
|
|
810
810
|
}
|
|
811
811
|
|
|
812
|
+
describeVersion(version) {
|
|
813
|
+
try {
|
|
814
|
+
return formatDateMMDDYYYY(version);
|
|
815
|
+
} catch (error) {
|
|
816
|
+
return "v" + version;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
812
819
|
}
|
|
813
820
|
|
|
814
821
|
// Specific RxNorm implementation
|
package/tx/cs/cs-snomed.js
CHANGED
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
} = require('../sct/expressions');
|
|
12
12
|
const {DesignationUse} = require("../library/designations");
|
|
13
13
|
const {BaseCSServices} = require("./cs-base");
|
|
14
|
+
const {formatDateMMDDYYYY} = require("../../library/utilities");
|
|
14
15
|
|
|
15
16
|
// Context kinds matching Pascal enum
|
|
16
17
|
const SnomedProviderContextKind = {
|
|
@@ -1262,11 +1263,25 @@ class SnomedServicesFactory extends CodeSystemFactoryProvider {
|
|
|
1262
1263
|
return `SCT ${getEditionCode(this._sharedData.edition)}`;
|
|
1263
1264
|
}
|
|
1264
1265
|
|
|
1266
|
+
nameBase() {
|
|
1267
|
+
return `SCT`;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1265
1270
|
id() {
|
|
1266
|
-
|
|
1271
|
+
const match = this.version().match(/^http:\/\/snomed\.info\/sct\/(\d+)(?:\/version\/(\d{8}))?$/);
|
|
1272
|
+
return "SCT-"+match[1]+"-"+match[2];
|
|
1267
1273
|
}
|
|
1268
|
-
}
|
|
1269
1274
|
|
|
1275
|
+
describeVersion(version) {
|
|
1276
|
+
const match = version.match(/^http:\/\/snomed\.info\/sct\/(\d+)(?:\/version\/(\d{8}))?$/);
|
|
1277
|
+
if (!match) return version;
|
|
1278
|
+
|
|
1279
|
+
const edition = getEditionName(match[1]);
|
|
1280
|
+
if (!match[2]) return edition;
|
|
1281
|
+
|
|
1282
|
+
return edition + ' ' + formatDateMMDDYYYY(match[2].substring(4, 6) + match[2].substring(6, 8) + match[2].substring(0, 4));
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1270
1285
|
|
|
1271
1286
|
function getEditionName(edition) {
|
|
1272
1287
|
const editionMap = {
|
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
<div class="
|
|
2
|
-
<
|
|
3
|
-
<
|
|
1
|
+
<div class="operation-form" style="margin-bottom: 15px;">
|
|
2
|
+
<strong>Lookup</strong>
|
|
3
|
+
<form method="get" action="$lookup" style="display: inline-block; margin-left: 10px;">
|
|
4
|
+
<input type="hidden" name="system" value="{{ url }}"/>
|
|
5
|
+
<input type="text" name="code" placeholder="Code" required size="20"/>
|
|
6
|
+
<button type="submit" class="btn btn-sm btn-primary">Lookup</button>
|
|
7
|
+
</form>
|
|
8
|
+
</div>
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<div class="operation-form" style="margin-bottom: 15px;">
|
|
15
|
-
<strong>Subsumes</strong>
|
|
16
|
-
<form method="get" action="$subsumes" style="display: inline-block; margin-left: 10px;">
|
|
17
|
-
<input type="hidden" name="system" value="{{ url }}"/>
|
|
18
|
-
<input type="text" name="codeA" placeholder="Code A" required size="15"/>
|
|
19
|
-
<input type="text" name="codeB" placeholder="Code B" required size="15"/>
|
|
20
|
-
<button type="submit" class="btn btn-sm btn-primary">Subsumes</button>
|
|
21
|
-
</form>
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
10
|
+
<div class="operation-form" style="margin-bottom: 15px;">
|
|
11
|
+
<strong>Subsumes</strong>
|
|
12
|
+
<form method="get" action="$subsumes" style="display: inline-block; margin-left: 10px;">
|
|
13
|
+
<input type="hidden" name="system" value="{{ url }}"/>
|
|
14
|
+
<input type="text" name="codeA" placeholder="Code A" required size="15"/>
|
|
15
|
+
<input type="text" name="codeB" placeholder="Code B" required size="15"/>
|
|
16
|
+
<button type="submit" class="btn btn-sm btn-primary">Subsumes</button>
|
|
17
|
+
</form>
|
|
18
|
+
</div>
|
|
@@ -1,54 +1,48 @@
|
|
|
1
|
-
<div class="operations" style="margin-top: 20px;">
|
|
2
|
-
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleOperations('{{ opsId }}')">Show Operations</button>
|
|
3
|
-
<div id="{{ opsId }}" style="display: none; margin-top: 10px;">
|
|
4
1
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
2
|
+
<div class="operation-form" style="margin-bottom: 15px;">
|
|
3
|
+
<strong>Expand</strong>
|
|
4
|
+
<form method="get" action="$expand" style="margin-left: 10px; margin-top: 5px;">
|
|
5
|
+
<input type="hidden" name="url" value="{{ url }}"/>
|
|
6
|
+
<table class="grid" cellpadding="0" cellspacing="0">
|
|
7
|
+
<tr>
|
|
8
|
+
<td>Filter: <input type="text" name="filter" size="20"/></td>
|
|
9
|
+
<td>Language: <input type="text" name="displayLanguage" size="10"/></td>
|
|
10
|
+
</tr>
|
|
11
|
+
<tr>
|
|
12
|
+
<td colspan="2">
|
|
13
|
+
<input type="checkbox" name="includeDesignations" id="expand_desig" value="true"/>
|
|
14
|
+
<label for="expand_desig">Include Designations</label>
|
|
15
|
+
<input type="checkbox" name="activeOnly" id="expand_active" value="true"/>
|
|
16
|
+
<label for="expand_active">Active Only</label>
|
|
17
|
+
</td>
|
|
18
|
+
</tr>
|
|
19
|
+
</table>
|
|
20
|
+
<button type="submit" class="btn btn-sm btn-primary">Expand</button>
|
|
21
|
+
</form>
|
|
22
|
+
</div>
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
24
|
+
<div class="operation-form" style="margin-bottom: 15px;">
|
|
25
|
+
<strong>Validate Code (ValueSet)</strong>
|
|
26
|
+
<form method="get" action="$validate-code" style="margin-left: 10px; margin-top: 5px;">
|
|
27
|
+
<input type="hidden" name="url" value="{{ url }}"/>
|
|
28
|
+
<input type="hidden" name="inferSystem" id="{{ inferSystemId }}" value="true"/>
|
|
29
|
+
<table class="grid" cellpadding="0" cellspacing="0">
|
|
30
|
+
<tr>
|
|
31
|
+
<td>System: <input type="text" name="system" id="{{ vcSystemId }}" size="30" onchange="updateInferSystem('{{ vcSystemId }}', '{{ inferSystemId }}')"/></td>
|
|
32
|
+
<td>Version: <input type="text" name="version" size="10"/></td>
|
|
33
|
+
</tr>
|
|
34
|
+
<tr>
|
|
35
|
+
<td>Code: <input type="text" name="code" size="20" required/></td>
|
|
36
|
+
<td>Display: <input type="text" name="display" size="20"/></td>
|
|
37
|
+
</tr>
|
|
38
|
+
<tr>
|
|
39
|
+
<td>Language: <input type="text" name="displayLanguage" size="10"/></td>
|
|
40
|
+
<td>
|
|
41
|
+
<input type="checkbox" name="abstract" value="true"/>
|
|
42
|
+
<label>Abstract</label>
|
|
43
|
+
</td>
|
|
44
|
+
</tr>
|
|
45
|
+
</table>
|
|
46
|
+
<button type="submit" class="btn btn-sm btn-primary">Validate Code</button>
|
|
47
|
+
</form>
|
|
48
|
+
</div>
|
|
@@ -111,7 +111,12 @@ class CanonicalResource {
|
|
|
111
111
|
const fmt = this.versionAlgorithm() || other.versionAlgorithm() || this.guessVersionAlgorithmFromVersion(this.version);
|
|
112
112
|
switch (fmt) {
|
|
113
113
|
case 'semver':
|
|
114
|
-
|
|
114
|
+
try {
|
|
115
|
+
return VersionUtilities.isThisOrLater(other.version, this.version, VersionPrecision.PATCH);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
// other is not semver. Not much we can do
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
115
120
|
case 'date':
|
|
116
121
|
return this.dateIsMoreRecent(this.version, other.version);
|
|
117
122
|
case 'integer':
|
package/tx/library/codesystem.js
CHANGED
|
@@ -33,7 +33,12 @@ class CodeSystem extends CanonicalResource {
|
|
|
33
33
|
// Convert to R5 format internally (modifies input for performance)
|
|
34
34
|
this.jsonObj = codeSystemToR5(this.jsonObj, fhirVersion);
|
|
35
35
|
if (!noMaps) {
|
|
36
|
-
|
|
36
|
+
try {
|
|
37
|
+
this.validate();
|
|
38
|
+
} catch (e) {
|
|
39
|
+
const id = this.jsonObj?.url ? `${this.jsonObj.url}|${this.jsonObj.version || ''}` : this.jsonObj?.name || 'unknown';
|
|
40
|
+
throw new Error(`${e.message} (in ${id})`);
|
|
41
|
+
}
|
|
37
42
|
this.buildMaps();
|
|
38
43
|
}
|
|
39
44
|
}
|
package/tx/library/renderer.js
CHANGED
|
@@ -147,6 +147,7 @@ class Renderer {
|
|
|
147
147
|
this.renderProperty(tbl, 'GENERAL_TITLE', res.title);
|
|
148
148
|
this.renderProperty(tbl, 'GENERAL_STATUS', res.status);
|
|
149
149
|
this.renderPropertyMD(tbl, 'GENERAL_DEFINITION', res.description);
|
|
150
|
+
this.renderPropertyMD(tbl, 'GENERAL_PURPOSE', res.purpose);
|
|
150
151
|
this.renderProperty(tbl, 'CANON_REND_PUBLISHER', res.publisher);
|
|
151
152
|
this.renderProperty(tbl, 'CANON_REND_COMMITTEE', Extensions.readString(res, 'http://hl7.org/fhir/StructureDefinition/structuredefinition-wg'));
|
|
152
153
|
this.renderProperty(tbl, 'GENERAL_COPYRIGHT', res.copyright);
|
|
@@ -339,7 +340,7 @@ class Renderer {
|
|
|
339
340
|
}
|
|
340
341
|
if (vs.expansion) {
|
|
341
342
|
div_.h2().tx("Expansion");
|
|
342
|
-
await this.renderExpansion(div_
|
|
343
|
+
await this.renderExpansion(div_, vs, tbl);
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
return div_.toString();
|
|
@@ -419,7 +420,7 @@ class Renderer {
|
|
|
419
420
|
li.tx(this.translate('VALUE_SET_ALL_CODES_DEF')+" ");
|
|
420
421
|
await this.renderLink(li,inc.system+(inc.version ? "|"+inc.version : ""));
|
|
421
422
|
} else if (inc.concept) {
|
|
422
|
-
li.tx(this.translate('VALUE_SET_THESE_CODES_DEF'));
|
|
423
|
+
li.tx(this.translate('VALUE_SET_THESE_CODES_DEF')+" ");
|
|
423
424
|
await this.renderLink(li,inc.system+(inc.version ? "|"+inc.version : ""));
|
|
424
425
|
li.tx(":");
|
|
425
426
|
const ul = li.ul();
|
|
@@ -898,18 +899,45 @@ class Renderer {
|
|
|
898
899
|
return count;
|
|
899
900
|
}
|
|
900
901
|
|
|
902
|
+
async renderVSExpansion(vs, showProps) {
|
|
903
|
+
let div_ = div();
|
|
904
|
+
let tbl;
|
|
905
|
+
if (showProps) {
|
|
906
|
+
div_.h2().tx("Expansion Properties");
|
|
907
|
+
tbl = div_.table("grid");
|
|
908
|
+
} else {
|
|
909
|
+
tbl = div(); // dummy
|
|
910
|
+
}
|
|
911
|
+
await this.renderExpansion(div_.table("grid"), vs, tbl);
|
|
912
|
+
return div_.toString();
|
|
913
|
+
}
|
|
914
|
+
|
|
901
915
|
async renderExpansion(x, vs, tbl) {
|
|
902
916
|
this.renderProperty(tbl, 'Expansion Identifier', vs.expansion.identifier);
|
|
903
917
|
this.renderProperty(tbl, 'Expansion Timestamp', vs.expansion.timestamp);
|
|
904
918
|
this.renderProperty(tbl, 'Expansion Total', vs.expansion.total);
|
|
905
919
|
this.renderProperty(tbl, 'Expansion Offset', vs.expansion.offset);
|
|
920
|
+
const warnings = [];
|
|
921
|
+
const warningNames = new Set(['deprecated', 'withdrawn', 'retired', 'experimental', 'draft']);
|
|
922
|
+
const useds = [];
|
|
923
|
+
const usedNames = new Set(['codesystem', 'valueset', 'supplement']);
|
|
906
924
|
for (let p of vs.expansion.parameter || []) {
|
|
907
|
-
if
|
|
925
|
+
if (p.name.startsWith('warning-') && warningNames.has(p.name.substring(8))) {
|
|
926
|
+
warnings.push(p);
|
|
927
|
+
} else if (p.name.startsWith('used-') && usedNames.has(p.name.substring(5))) {
|
|
928
|
+
useds.push(p);
|
|
929
|
+
} else if( getValueName(p) === 'valueUri' || getValueName(p) === 'valueCanonical') {
|
|
908
930
|
await this.renderPropertyLink(tbl, "Parameter: " + p.name, getValuePrimitive(p));
|
|
909
931
|
} else {
|
|
910
932
|
this.renderProperty(tbl, "Parameter: " + p.name, getValuePrimitive(p));
|
|
911
933
|
}
|
|
912
934
|
}
|
|
935
|
+
if (useds.length > 0) {
|
|
936
|
+
await this.renderUsed(x, useds);
|
|
937
|
+
}
|
|
938
|
+
if (warnings.length > 0) {
|
|
939
|
+
await this.renderWarnings(x, warnings);
|
|
940
|
+
}
|
|
913
941
|
|
|
914
942
|
if (!vs.expansion.contains || vs.expansion.contains.length === 0) {
|
|
915
943
|
x.para().i().tx('No concepts in expansion');
|
|
@@ -935,10 +963,10 @@ class Renderer {
|
|
|
935
963
|
}
|
|
936
964
|
headerRow.th().tx(this.translate('TX_DISPLAY'));
|
|
937
965
|
if (columnInfo.hasAbstract) {
|
|
938
|
-
headerRow.th().tx('Abstract');
|
|
966
|
+
headerRow.th().tx(this.translate('Abstract'));
|
|
939
967
|
}
|
|
940
968
|
if (columnInfo.hasInactive) {
|
|
941
|
-
headerRow.th().tx('
|
|
969
|
+
headerRow.th().tx(this.translate('VALUE_SET_INACTIVE'));
|
|
942
970
|
}
|
|
943
971
|
|
|
944
972
|
// Property columns (from expansion.property definitions)
|
|
@@ -1117,12 +1145,12 @@ class Renderer {
|
|
|
1117
1145
|
|
|
1118
1146
|
// Abstract column
|
|
1119
1147
|
if (columnInfo.hasAbstract) {
|
|
1120
|
-
tr.td().tx(contains.abstract === true ? '
|
|
1148
|
+
tr.td().tx(contains.abstract === true ? 'abstract' : '');
|
|
1121
1149
|
}
|
|
1122
1150
|
|
|
1123
1151
|
// Inactive column
|
|
1124
1152
|
if (columnInfo.hasInactive) {
|
|
1125
|
-
tr.td().tx(contains.inactive === true ? '
|
|
1153
|
+
tr.td().tx(contains.inactive === true ? this.translate('VALUE_SET_INACT') : '');
|
|
1126
1154
|
}
|
|
1127
1155
|
|
|
1128
1156
|
// Property columns
|
|
@@ -1566,6 +1594,52 @@ class Renderer {
|
|
|
1566
1594
|
|
|
1567
1595
|
return div_.toString();
|
|
1568
1596
|
}
|
|
1597
|
+
|
|
1598
|
+
async renderWarnings(x, warnings) {
|
|
1599
|
+
await this.renderWarningsForStatus(x, 'deprecated', warnings);
|
|
1600
|
+
await this.renderWarningsForStatus(x, 'withdrawn', warnings);
|
|
1601
|
+
await this.renderWarningsForStatus(x, 'retired', warnings);
|
|
1602
|
+
await this.renderWarningsForStatus(x, 'experimental', warnings);
|
|
1603
|
+
await this.renderWarningsForStatus(x, 'draft', warnings);
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
async renderWarningsForStatus(x, name, warnings) {
|
|
1607
|
+
const wl = warnings.filter(item => item.name == 'warning-'+name);
|
|
1608
|
+
if (wl && wl.length > 0) {
|
|
1609
|
+
x.para().tx(`This ValueSet depends on the following ${name} ValueSets: `);
|
|
1610
|
+
let ul = x.ul();
|
|
1611
|
+
for (const w of wl) {
|
|
1612
|
+
const linkinfo = await this.linkResolver.resolveURL(this.opContext, getValuePrimitive(w));
|
|
1613
|
+
if (linkinfo) {
|
|
1614
|
+
ul.li().ah(linkinfo.link).tx(linkinfo.description);
|
|
1615
|
+
} else {
|
|
1616
|
+
ul.li().code().tx(getValuePrimitive(w));
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
async renderUsed(x, list) {
|
|
1623
|
+
x.para().tx(`This ValueSet depends on the following items:`);
|
|
1624
|
+
let ul = x.ul();
|
|
1625
|
+
await this.renderUsedForType(ul, 'codesystem', 'CodeSystem', list);
|
|
1626
|
+
await this.renderUsedForType(ul, 'valueset', 'ValueSet', list);
|
|
1627
|
+
await this.renderUsedForType(ul, 'supplement', 'Supplement', list);
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
async renderUsedForType(ul, name, title, list) {
|
|
1631
|
+
const wl = list.filter(item => item.name == 'used-' + name);
|
|
1632
|
+
for (const w of wl) {
|
|
1633
|
+
const li = ul.li();
|
|
1634
|
+
li.tx(title+": ");
|
|
1635
|
+
const linkinfo = await this.linkResolver.resolveURL(this.opContext, getValuePrimitive(w));
|
|
1636
|
+
if (linkinfo) {
|
|
1637
|
+
li.ah(linkinfo.link).tx(linkinfo.description);
|
|
1638
|
+
} else {
|
|
1639
|
+
li.code().tx(getValuePrimitive(w));
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1569
1643
|
}
|
|
1570
1644
|
|
|
1571
1645
|
module.exports = { Renderer };
|