fhirsmith 0.5.6 → 0.6.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 +18 -0
- package/library/html-server.js +2 -1
- package/library/package-manager.js +37 -32
- package/library/utilities.js +10 -1
- package/package.json +1 -1
- package/packages/package-crawler.js +103 -46
- package/packages/packages.js +14 -7
- package/publisher/publisher.js +15 -3
- package/registry/api.js +173 -191
- package/registry/crawler.js +72 -58
- package/registry/model.js +14 -8
- package/registry/registry.js +2 -0
- package/root-template.html +1 -0
- package/server.js +109 -45
- package/tx/cs/cs-api.js +18 -1
- package/tx/cs/cs-base.js +1 -0
- 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/codesystem.js +6 -1
- package/tx/library/renderer.js +81 -7
- package/tx/library.js +18 -3
- package/tx/provider.js +4 -2
- package/tx/sct/expressions.js +20 -9
- package/tx/tx-html.js +143 -50
- package/tx/tx.js +2 -2
- package/tx/workers/expand.js +61 -9
- package/tx/workers/search.js +5 -2
- package/tx/xversion/xv-terminologyCapabilities.js +1 -1
package/tx/tx-html.js
CHANGED
|
@@ -9,6 +9,15 @@ const htmlServer = require('../library/html-server');
|
|
|
9
9
|
const Logger = require('../library/logger');
|
|
10
10
|
const packageJson = require("../package.json");
|
|
11
11
|
const escape = require('escape-html');
|
|
12
|
+
const {ExpandWorker} = require("./workers/expand");
|
|
13
|
+
const ValueSet = require("./library/valueset");
|
|
14
|
+
const {CodeSystemXML} = require("./xml/codesystem-xml");
|
|
15
|
+
const {ValueSetXML} = require("./xml/valueset-xml");
|
|
16
|
+
const {BundleXML} = require("./xml/bundle-xml");
|
|
17
|
+
const {CapabilityStatementXML} = require("./xml/capabilitystatement-xml");
|
|
18
|
+
const {TerminologyCapabilitiesXML} = require("./xml/terminologycapabilities-xml");
|
|
19
|
+
const {ParametersXML} = require("./xml/parameters-xml");
|
|
20
|
+
const {OperationOutcomeXML} = require("./xml/operationoutcome-xml");
|
|
12
21
|
|
|
13
22
|
const txHtmlLog = Logger.getInstance().child({ module: 'tx-html' });
|
|
14
23
|
|
|
@@ -57,10 +66,16 @@ function loadTemplate() {
|
|
|
57
66
|
class TxHtmlRenderer {
|
|
58
67
|
renderer;
|
|
59
68
|
liquid;
|
|
69
|
+
languages;
|
|
70
|
+
i18n;
|
|
71
|
+
path;
|
|
60
72
|
|
|
61
|
-
constructor(renderer, liquid) {
|
|
73
|
+
constructor(renderer, liquid, languages, i18n, path) {
|
|
62
74
|
this.renderer = renderer;
|
|
63
75
|
this.liquid = liquid;
|
|
76
|
+
this.languages = languages;
|
|
77
|
+
this.i18n = i18n;
|
|
78
|
+
this.path = path;
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
/**
|
|
@@ -85,7 +100,7 @@ class TxHtmlRenderer {
|
|
|
85
100
|
if (_fmt && typeof _fmt !== 'string') {
|
|
86
101
|
_fmt = null;
|
|
87
102
|
}
|
|
88
|
-
if (_fmt && _fmt == 'html') {
|
|
103
|
+
if (_fmt && (_fmt == 'html' || _fmt.startsWith('html/'))) {
|
|
89
104
|
return true;
|
|
90
105
|
}
|
|
91
106
|
if (!_fmt) {
|
|
@@ -106,6 +121,14 @@ class TxHtmlRenderer {
|
|
|
106
121
|
} else {
|
|
107
122
|
const resourceType = json.resourceType || 'Response';
|
|
108
123
|
|
|
124
|
+
let pfx = resourceType;
|
|
125
|
+
if (req.path.includes('$')) {
|
|
126
|
+
let s = req.path.substring(req.path.indexOf('$') + 1).replace(/[^a-zA-Z].*$/, '');
|
|
127
|
+
switch (s) {
|
|
128
|
+
case 'expand': pfx = "Expansion for "+resourceType;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
109
132
|
if (resourceType === 'Bundle' && json.type === 'searchset') {
|
|
110
133
|
// Extract the resource type being searched from self link or entries
|
|
111
134
|
const selfLink = json.link?.find(l => l.relation === 'self')?.url || '';
|
|
@@ -124,11 +147,11 @@ class TxHtmlRenderer {
|
|
|
124
147
|
}
|
|
125
148
|
|
|
126
149
|
if (json.id) {
|
|
127
|
-
return `${
|
|
150
|
+
return `${pfx} ${json.id}`;
|
|
128
151
|
}
|
|
129
152
|
|
|
130
153
|
if (json.name) {
|
|
131
|
-
return `${
|
|
154
|
+
return `${pfx} ${json.name}`;
|
|
132
155
|
}
|
|
133
156
|
|
|
134
157
|
return resourceType;
|
|
@@ -267,15 +290,27 @@ class TxHtmlRenderer {
|
|
|
267
290
|
return await this.buildHomePage(req);
|
|
268
291
|
} else {
|
|
269
292
|
try {
|
|
293
|
+
const _fmt = req?.query?._format || req?.query?.format || req?.body?._format;
|
|
294
|
+
const op = req ? req.path.includes("$") : false;
|
|
270
295
|
const resourceType = json.resourceType;
|
|
271
296
|
|
|
272
297
|
switch (resourceType) {
|
|
273
298
|
case 'Parameters':
|
|
274
299
|
return await this.renderParameters(json);
|
|
275
300
|
case 'CodeSystem':
|
|
276
|
-
return await this.renderCodeSystem(json, inBundle);
|
|
277
|
-
case 'ValueSet':
|
|
278
|
-
|
|
301
|
+
return await this.renderCodeSystem(json, inBundle, _fmt, op);
|
|
302
|
+
case 'ValueSet': {
|
|
303
|
+
let exp = undefined;
|
|
304
|
+
if (!inBundle && !op && (!_fmt || _fmt == 'html')) {
|
|
305
|
+
try {
|
|
306
|
+
let worker = new ExpandWorker(req.txOpContext, this.log, req.txProvider, this.languages, this.i18n);
|
|
307
|
+
exp = new ValueSet(await worker.handleInternalExpand(json, req));
|
|
308
|
+
} catch (error) {
|
|
309
|
+
exp = error;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return await this.renderValueSet(json, inBundle, _fmt, op, exp);
|
|
313
|
+
}
|
|
279
314
|
case 'ConceptMap':
|
|
280
315
|
return await this.renderConceptMap(json, inBundle);
|
|
281
316
|
case 'CapabilityStatement':
|
|
@@ -575,35 +610,88 @@ class TxHtmlRenderer {
|
|
|
575
610
|
/**
|
|
576
611
|
* Render CodeSystem resource
|
|
577
612
|
*/
|
|
578
|
-
async renderCodeSystem(json, inBundle) {
|
|
579
|
-
|
|
613
|
+
async renderCodeSystem(json, inBundle, _fmt) {
|
|
614
|
+
if (inBundle) {
|
|
615
|
+
return await this.renderResourceWithNarrative(json, await this.renderer.renderCodeSystem(json));
|
|
616
|
+
} else {
|
|
617
|
+
let html = `<ul class="nav nav-tabs">`;
|
|
618
|
+
html += this.tab(!_fmt || _fmt == 'html', json.resourceType, json.resourceType, 'html', json.id);
|
|
619
|
+
html += this.tab(_fmt && _fmt == 'html/json', 'JSON', json.resourceType, 'html/json', json.id);
|
|
620
|
+
html += this.tab(_fmt && _fmt == 'html/xml', 'XML', json.resourceType, 'html/xml', json.id);
|
|
621
|
+
html += this.tab(_fmt && _fmt == 'html/narrative', 'Original Narrative', json.resourceType, 'html/narrative', json.id);
|
|
622
|
+
html += this.tab(_fmt && _fmt == 'html/ops', 'LookUp / Subsumes', json.resourceType, 'html/ops', json.id);
|
|
623
|
+
html += `</ul>`;
|
|
624
|
+
|
|
625
|
+
if (!_fmt || _fmt == 'html') {
|
|
626
|
+
html += await this.renderResourceWithNarrative(json, await this.renderer.renderCodeSystem(json));
|
|
627
|
+
} else if (_fmt == "html/json") {
|
|
628
|
+
html += await this.renderResourceJson(json);
|
|
629
|
+
} else if (_fmt == "html/xml") {
|
|
630
|
+
html += await this.renderResourceXml(json);
|
|
631
|
+
} else if (_fmt == "html/narrative") {
|
|
632
|
+
html += await this.renderResourceWithNarrative(json, json.text?.div);
|
|
633
|
+
} else if (_fmt == "html/ops") {
|
|
634
|
+
html += await this.liquid.renderFile('codesystem-operations', {
|
|
635
|
+
opsId: this.generateResourceId(),
|
|
636
|
+
vcSystemId: this.generateResourceId(),
|
|
637
|
+
inferSystemId: this.generateResourceId(),
|
|
638
|
+
url: escape(json.url || '')
|
|
639
|
+
});
|
|
640
|
+
}
|
|
580
641
|
|
|
581
|
-
if (!inBundle) {
|
|
582
|
-
html += await this.liquid.renderFile('codesystem-operations', {
|
|
583
|
-
opsId: this.generateResourceId(),
|
|
584
|
-
url: escape(json.url || '')
|
|
585
|
-
});
|
|
586
|
-
}
|
|
587
642
|
|
|
588
|
-
|
|
643
|
+
return html;
|
|
644
|
+
}
|
|
589
645
|
}
|
|
590
646
|
|
|
647
|
+
tab(b, name, rtype, type, id) {
|
|
648
|
+
if (b) {
|
|
649
|
+
return `<li class="active"><a href="#">${name}</a></li>`;
|
|
650
|
+
} else {
|
|
651
|
+
return `<li><a href="${this.path}/${rtype}/${id}?_format=${type}">${name}</a></li>`;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
591
654
|
/**
|
|
592
655
|
* Render ValueSet resource
|
|
593
656
|
*/
|
|
594
|
-
async renderValueSet(json, inBundle) {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
html
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
657
|
+
async renderValueSet(json, inBundle, _fmt, op, exp) {
|
|
658
|
+
if (inBundle || op) {
|
|
659
|
+
return await this.renderResourceWithNarrative(json, await this.renderer.renderValueSet(json));
|
|
660
|
+
} else {
|
|
661
|
+
let html = `<ul class="nav nav-tabs">`;
|
|
662
|
+
html += this.tab(!_fmt || _fmt == 'html', json.resourceType, json.resourceType, 'html', json.id);
|
|
663
|
+
html += this.tab(_fmt && _fmt == 'html/json', 'JSON', json.resourceType, 'html/json', json.id);
|
|
664
|
+
html += this.tab(_fmt && _fmt == 'html/xml', 'XML', json.resourceType, 'html/xml', json.id);
|
|
665
|
+
html += this.tab(_fmt && _fmt == 'html/narrative', 'Original Narrative', json.resourceType, 'html/narrative', json.id);
|
|
666
|
+
html += this.tab(_fmt && _fmt == 'html/ops', 'Expand / Validate', json.resourceType, 'html/ops', json.id);
|
|
667
|
+
html += `</ul>`;
|
|
668
|
+
|
|
669
|
+
if (!_fmt || _fmt == 'html') {
|
|
670
|
+
html += await this.renderResourceWithNarrative(json, await this.renderer.renderValueSet(json));
|
|
671
|
+
if (exp) {
|
|
672
|
+
html += "<h2>Expansion</h2>";
|
|
673
|
+
if (exp instanceof ValueSet) {
|
|
674
|
+
html += await this.renderer.renderVSExpansion(exp.jsonObj, false)
|
|
675
|
+
} else {
|
|
676
|
+
html += `<p>Error: `+exp.message+`</p>`;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
} else if (_fmt == "html/json") {
|
|
680
|
+
html += await this.renderResourceJson(json);
|
|
681
|
+
} else if (_fmt == "html/xml") {
|
|
682
|
+
html += await this.renderResourceXml(json);
|
|
683
|
+
} else if (_fmt == "html/narrative") {
|
|
684
|
+
html += await this.renderResourceWithNarrative(json, json.text?.div);
|
|
685
|
+
} else if (_fmt == "html/ops") {
|
|
686
|
+
html += await this.liquid.renderFile('valueset-operations', {
|
|
687
|
+
opsId: this.generateResourceId(),
|
|
688
|
+
vcSystemId: this.generateResourceId(),
|
|
689
|
+
inferSystemId: this.generateResourceId(),
|
|
690
|
+
url: escape(json.url || '')
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
return html;
|
|
604
694
|
}
|
|
605
|
-
|
|
606
|
-
return html;
|
|
607
695
|
}
|
|
608
696
|
|
|
609
697
|
/**
|
|
@@ -1101,9 +1189,7 @@ class TxHtmlRenderer {
|
|
|
1101
1189
|
* Render resource with text/div narrative and collapsible JSON source
|
|
1102
1190
|
*/
|
|
1103
1191
|
async renderResourceWithNarrative(json, rendered) {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
let html = "";
|
|
1192
|
+
let html = '';
|
|
1107
1193
|
|
|
1108
1194
|
// Show text/div narrative if present
|
|
1109
1195
|
if (rendered) {
|
|
@@ -1113,30 +1199,37 @@ class TxHtmlRenderer {
|
|
|
1113
1199
|
} else {
|
|
1114
1200
|
html += '<div class="narrative">(No Narrative)</div>';
|
|
1115
1201
|
}
|
|
1116
|
-
if (json.text && json.text.div) {
|
|
1117
|
-
// Collapsible JSON source
|
|
1118
|
-
html += '<div class="xhtml">';
|
|
1119
|
-
html += `<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleOriginalNarrative('${resourceId}x')">`;
|
|
1120
|
-
html += 'Show Original Narrative</button>';
|
|
1121
|
-
html += `<div id="${resourceId}x" class="original-narrative" style="display: none; margin-top: 10px;">`;
|
|
1122
|
-
|
|
1123
|
-
html += '<div class="narrative">';
|
|
1124
|
-
html += json.text.div; // Already HTML, render as-is
|
|
1125
|
-
html += '</div>';
|
|
1126
|
-
}
|
|
1127
|
-
html += '</div>';
|
|
1128
|
-
html += '</div>';
|
|
1129
1202
|
|
|
1203
|
+
return html;
|
|
1204
|
+
}
|
|
1130
1205
|
|
|
1131
|
-
|
|
1132
|
-
html
|
|
1133
|
-
html += `<
|
|
1134
|
-
html += 'Show JSON Source</button>';
|
|
1135
|
-
html += `<div id="${resourceId}" class="json-content" style="display: none; margin-top: 10px;">`;
|
|
1206
|
+
async renderResourceJson(json) {
|
|
1207
|
+
let html = "";
|
|
1208
|
+
html += `<div class="json-content" style="margin-top: 10px;">`;
|
|
1136
1209
|
html += `<pre>${escape(JSON.stringify(json, null, 2))}</pre>`;
|
|
1137
1210
|
html += '</div>';
|
|
1138
|
-
html
|
|
1211
|
+
return html;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
convertResourceToXml(res) {
|
|
1215
|
+
switch (res.resourceType) {
|
|
1216
|
+
case "CodeSystem" : return CodeSystemXML.toXml(res);
|
|
1217
|
+
case "ValueSet" : return ValueSetXML.toXml(res);
|
|
1218
|
+
case "Bundle" : return BundleXML.toXml(res, this.fhirVersion);
|
|
1219
|
+
case "CapabilityStatement" : return CapabilityStatementXML.toXml(res, "R5");
|
|
1220
|
+
case "TerminologyCapabilities" : return TerminologyCapabilitiesXML.toXml(res, "R5");
|
|
1221
|
+
case "Parameters": return ParametersXML.toXml(res, this.fhirVersion);
|
|
1222
|
+
case "OperationOutcome": return OperationOutcomeXML.toXml(res, this.fhirVersion);
|
|
1223
|
+
}
|
|
1224
|
+
throw new Error(`Resource type ${res.resourceType} not supported in XML`);
|
|
1225
|
+
}
|
|
1139
1226
|
|
|
1227
|
+
async renderResourceXml(json) {
|
|
1228
|
+
let xml = this.convertResourceToXml(json);
|
|
1229
|
+
let html = "";
|
|
1230
|
+
html += `<div class="xml-content" style="margin-top: 10px;">`;
|
|
1231
|
+
html += `<pre>${escape(xml)}</pre>`;
|
|
1232
|
+
html += '</div>';
|
|
1140
1233
|
return html;
|
|
1141
1234
|
}
|
|
1142
1235
|
|
package/tx/tx.js
CHANGED
|
@@ -300,7 +300,7 @@ class TXModule {
|
|
|
300
300
|
// Wrap res.json to intercept and convert to HTML if browser requests it, and log the request
|
|
301
301
|
const originalJson = res.json.bind(res);
|
|
302
302
|
|
|
303
|
-
let txhtml = new TxHtmlRenderer(new Renderer(opContext, endpointInfo.provider), this.liquid);
|
|
303
|
+
let txhtml = new TxHtmlRenderer(new Renderer(opContext, endpointInfo.provider), this.liquid, this.languages, this.i18n, endpointInfo.path);
|
|
304
304
|
res.json = async (data) => {
|
|
305
305
|
try {
|
|
306
306
|
const duration = Date.now() - req.txStartTime;
|
|
@@ -897,7 +897,7 @@ class TXModule {
|
|
|
897
897
|
router.get('/problems.html', async (req, res) => {
|
|
898
898
|
const start = Date.now();
|
|
899
899
|
try {
|
|
900
|
-
let txhtml = new TxHtmlRenderer(new Renderer(req.txOpContext, req.txProvider), this.liquid);
|
|
900
|
+
let txhtml = new TxHtmlRenderer(new Renderer(req.txOpContext, req.txProvider), this.liquid, this.languages, this.i18n, req.txEndpoint.path);
|
|
901
901
|
const problemFinder = new ProblemFinder();
|
|
902
902
|
const content = await problemFinder.scanValueSets(req.txProvider);
|
|
903
903
|
const html = await txhtml.renderPage('Problems', '<h3>ValueSet dependencies on unknown CodeSystem/Versions</h3>'+content, req.txEndpoint, req.txStartTime);
|
package/tx/workers/expand.js
CHANGED
|
@@ -1388,17 +1388,28 @@ class ValueSetExpander {
|
|
|
1388
1388
|
}
|
|
1389
1389
|
|
|
1390
1390
|
checkCanonicalStatus(exp, vurl, status, standardsStatus, experimental, source) {
|
|
1391
|
+
let sourceStatus = source ? source.status : undefined;
|
|
1392
|
+
let sourceStandardsStatus= source ? Extensions.readString(source, 'http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status') : undefined;
|
|
1391
1393
|
if (standardsStatus == 'deprecated') {
|
|
1392
|
-
|
|
1394
|
+
if (sourceStandardsStatus != 'deprecated') {
|
|
1395
|
+
this.addParamUri(exp, 'warning-deprecated', vurl);
|
|
1396
|
+
}
|
|
1393
1397
|
} else if (standardsStatus == 'withdrawn') {
|
|
1394
|
-
|
|
1398
|
+
if (sourceStandardsStatus != 'withdrawn') {
|
|
1399
|
+
this.addParamUri(exp, 'warning-withdrawn', vurl);
|
|
1400
|
+
}
|
|
1395
1401
|
} else if (status == 'retired') {
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
} else if (
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
+
if (sourceStatus != 'retired') {
|
|
1403
|
+
this.addParamUri(exp, 'warning-retired', vurl);
|
|
1404
|
+
}
|
|
1405
|
+
} else if (experimental) {
|
|
1406
|
+
if (!source.experimental) {
|
|
1407
|
+
this.addParamUri(exp, 'warning-experimental', vurl);
|
|
1408
|
+
}
|
|
1409
|
+
} else if (((status == 'draft') || (standardsStatus == 'draft'))) {
|
|
1410
|
+
if (!((source.status == 'draft') || (Extensions.readString(source, 'http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status') == 'draft'))) {
|
|
1411
|
+
this.addParamUri(exp, 'warning-draft', vurl)
|
|
1412
|
+
}
|
|
1402
1413
|
}
|
|
1403
1414
|
}
|
|
1404
1415
|
|
|
@@ -1797,7 +1808,48 @@ class ExpandWorker extends TerminologyWorker {
|
|
|
1797
1808
|
req.logInfo = this.usedSources.join("|")+txp.logInfo();
|
|
1798
1809
|
return res.json(result);
|
|
1799
1810
|
}
|
|
1800
|
-
|
|
1811
|
+
|
|
1812
|
+
/**
|
|
1813
|
+
* Handle type-level expand: /ValueSet/$expand
|
|
1814
|
+
* ValueSet identified by url, or provided directly in body
|
|
1815
|
+
*/
|
|
1816
|
+
async handleInternalExpand(valueSet, req) {
|
|
1817
|
+
this.deadCheck('expand-internal');
|
|
1818
|
+
|
|
1819
|
+
if (!valueSet.jsonObj) {
|
|
1820
|
+
valueSet = new ValueSet(valueSet);
|
|
1821
|
+
}
|
|
1822
|
+
// Determine how the request is structured
|
|
1823
|
+
let params = null;
|
|
1824
|
+
this.seeSourceVS(valueSet);
|
|
1825
|
+
|
|
1826
|
+
if (req.method === 'POST' && req.body) {
|
|
1827
|
+
if (req.body.resourceType === 'ValueSet') {
|
|
1828
|
+
params = this.queryToParameters(req.query);
|
|
1829
|
+
} else if (req.body.resourceType === 'Parameters') {
|
|
1830
|
+
// Body is a Parameters resource
|
|
1831
|
+
params = req.body;
|
|
1832
|
+
} else {
|
|
1833
|
+
// Assume form body - convert to Parameters
|
|
1834
|
+
params = this.formToParameters(req.body, req.query);
|
|
1835
|
+
}
|
|
1836
|
+
} else {
|
|
1837
|
+
// GET request - convert query to Parameters
|
|
1838
|
+
params = this.queryToParameters(req.query);
|
|
1839
|
+
}
|
|
1840
|
+
this.addHttpParams(req, params);
|
|
1841
|
+
|
|
1842
|
+
// Handle tx-resource and cache-id parameters
|
|
1843
|
+
this.setupAdditionalResources(params);
|
|
1844
|
+
const logExtraOutput = this.findParameter(params, 'logExtraOutput');
|
|
1845
|
+
|
|
1846
|
+
let txp = new TxParameters(this.opContext.i18n.languageDefinitions, this.opContext.i18n, false);
|
|
1847
|
+
txp.readParams(params);
|
|
1848
|
+
|
|
1849
|
+
// Perform the expansion
|
|
1850
|
+
return await this.doExpand(valueSet, txp, logExtraOutput);
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1801
1853
|
/**
|
|
1802
1854
|
* Handle instance-level expand: /ValueSet/{id}/$expand
|
|
1803
1855
|
* ValueSet identified by resource ID
|
package/tx/workers/search.js
CHANGED
|
@@ -137,7 +137,7 @@ class SearchWorker extends TerminologyWorker {
|
|
|
137
137
|
const searchParams = {};
|
|
138
138
|
for (const [key, value] of Object.entries(params)) {
|
|
139
139
|
if (!key.startsWith('_') && value && SearchWorker.ALLOWED_PARAMS.includes(key)) {
|
|
140
|
-
searchParams[key] = value.toLowerCase();
|
|
140
|
+
searchParams[key] = key == 'url' ? value : value.toLowerCase();
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -146,6 +146,9 @@ class SearchWorker extends TerminologyWorker {
|
|
|
146
146
|
|
|
147
147
|
for (const [key, cs] of this.provider.codeSystems) {
|
|
148
148
|
this.deadCheck('searchCodeSystems');
|
|
149
|
+
if (cs.url == 'http://www.cms.gov/Medicare/Coding/HCPCSReleaseCodeSets') {
|
|
150
|
+
console.log("debug");
|
|
151
|
+
}
|
|
149
152
|
if (key == cs.vurl) {
|
|
150
153
|
const json = cs.jsonObj;
|
|
151
154
|
|
|
@@ -179,7 +182,7 @@ class SearchWorker extends TerminologyWorker {
|
|
|
179
182
|
}
|
|
180
183
|
} else if (param === 'url') { // exact match
|
|
181
184
|
const propValue = json.url;
|
|
182
|
-
if (propValue
|
|
185
|
+
if (propValue !== searchValue) {
|
|
183
186
|
isMatch = false;
|
|
184
187
|
break;
|
|
185
188
|
}
|
|
@@ -17,7 +17,7 @@ function terminologyCapabilitiesToR5(jsonObj, sourceVersion) {
|
|
|
17
17
|
if (VersionUtilities.isR4Ver(sourceVersion)) {
|
|
18
18
|
for (const cs of jsonObj.codeSystem || []) {
|
|
19
19
|
if (cs.content) {
|
|
20
|
-
let cnt = Extensions.readString("http://hl7.org/fhir/5.0/StructureDefinition/extension-TerminologyCapabilities.codeSystem.content");
|
|
20
|
+
let cnt = Extensions.readString(cs, "http://hl7.org/fhir/5.0/StructureDefinition/extension-TerminologyCapabilities.codeSystem.content");
|
|
21
21
|
if (cnt) {
|
|
22
22
|
delete cs.extensions;
|
|
23
23
|
cs.content = cnt;
|