fhirsmith 0.8.3 → 0.8.5
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 +43 -3
- package/package.json +5 -2
- package/static/assets/js/clipboard-btn.js +31 -0
- package/static/assets/js/clipboard.min.js +7 -0
- package/static/fhir.css +20 -1
- package/static/images/noun_copy to clipboard_1669410.png +0 -0
- package/translations/rendering-phrases.properties +144 -55
- package/tx/cs/cs-api.js +27 -4
- package/tx/cs/cs-base.js +13 -0
- package/tx/cs/cs-snomed.js +91 -10
- package/tx/html/tx-template.html +5 -2
- package/tx/library/codesystem.js +20 -0
- package/tx/library/designations.js +37 -1
- package/tx/library/renderer.js +26 -8
- package/tx/provider.js +30 -0
- package/tx/tx.fhir.org.yml +1 -1
- package/tx/workers/expand.js +19 -12
- package/tx/workers/lookup.js +19 -3
- package/tx/workers/read.js +4 -0
- package/tx/workers/search.js +126 -51
- package/tx/workers/translate.js +3 -3
- package/tx/workers/worker.js +8 -2
- package/tx/xversion/xv-codesystem.js +3 -3
- package/tx/xversion/xv-parameters.js +2 -2
- package/tx/xversion/xv-valueset.js +1 -2
package/tx/workers/search.js
CHANGED
|
@@ -149,57 +149,8 @@ class SearchWorker extends TerminologyWorker {
|
|
|
149
149
|
// If no search params, return all
|
|
150
150
|
const hasSearchParams = Object.keys(searchParams).length > 0;
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (key == cs.vurl) {
|
|
156
|
-
const json = cs.jsonObj;
|
|
157
|
-
|
|
158
|
-
if (!hasSearchParams) {
|
|
159
|
-
matches.push(json);
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Check each search parameter for partial match
|
|
164
|
-
let isMatch = true;
|
|
165
|
-
for (const [param, searchValue] of Object.entries(searchParams)) {
|
|
166
|
-
|
|
167
|
-
// Map content-mode to content property
|
|
168
|
-
const jsonProp = param === 'content-mode' ? 'content' : param;
|
|
169
|
-
|
|
170
|
-
if (param === 'jurisdiction') {
|
|
171
|
-
// Special handling for jurisdiction - array of CodeableConcept
|
|
172
|
-
if (!this.matchJurisdiction(json.jurisdiction, searchValue)) {
|
|
173
|
-
isMatch = false;
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
} else if (param === 'text') {
|
|
177
|
-
const propValue = json.title + json.description;
|
|
178
|
-
if (!this.matchValue(propValue, searchValue)) {
|
|
179
|
-
isMatch = false;
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
182
|
-
} else if (param === 'url' || param === 'system') { // exact match
|
|
183
|
-
const propValue = json.url;
|
|
184
|
-
if (propValue !== searchValue) {
|
|
185
|
-
isMatch = false;
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
// Standard partial text match
|
|
190
|
-
const propValue = json[jsonProp];
|
|
191
|
-
if (!this.matchValue(propValue, searchValue)) {
|
|
192
|
-
isMatch = false;
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (isMatch) {
|
|
199
|
-
matches.push(json);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
152
|
+
this.searchCodeSystemResources(searchParams, hasSearchParams, matches);
|
|
153
|
+
this.searchCodeSystemProviders(searchParams, hasSearchParams, matches);
|
|
203
154
|
|
|
204
155
|
return matches;
|
|
205
156
|
}
|
|
@@ -473,6 +424,130 @@ class SearchWorker extends TerminologyWorker {
|
|
|
473
424
|
|
|
474
425
|
return filtered;
|
|
475
426
|
}
|
|
427
|
+
|
|
428
|
+
searchCodeSystemResources(searchParams, hasSearchParams, matches) {
|
|
429
|
+
for (const [key, cs] of this.provider.codeSystems) {
|
|
430
|
+
this.deadCheck('searchCodeSystems');
|
|
431
|
+
|
|
432
|
+
if (key == cs.vurl) {
|
|
433
|
+
const json = cs.jsonObj;
|
|
434
|
+
|
|
435
|
+
if (!hasSearchParams) {
|
|
436
|
+
matches.push(json);
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Check each search parameter for partial match
|
|
441
|
+
let isMatch = true;
|
|
442
|
+
for (const [param, searchValue] of Object.entries(searchParams)) {
|
|
443
|
+
|
|
444
|
+
// Map content-mode to content property
|
|
445
|
+
const jsonProp = param === 'content-mode' ? 'content' : param;
|
|
446
|
+
|
|
447
|
+
if (param === 'jurisdiction') {
|
|
448
|
+
// Special handling for jurisdiction - array of CodeableConcept
|
|
449
|
+
if (!this.matchJurisdiction(json.jurisdiction, searchValue)) {
|
|
450
|
+
isMatch = false;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
} else if (param === 'text') {
|
|
454
|
+
const propValue = json.title + json.description;
|
|
455
|
+
if (!this.matchValue(propValue, searchValue)) {
|
|
456
|
+
isMatch = false;
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
} else if (param === 'url' || param === 'system') { // exact match
|
|
460
|
+
const propValue = json.url;
|
|
461
|
+
if (propValue !== searchValue) {
|
|
462
|
+
isMatch = false;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
} else {
|
|
466
|
+
// Standard partial text match
|
|
467
|
+
const propValue = json[jsonProp];
|
|
468
|
+
if (!this.matchValue(propValue, searchValue)) {
|
|
469
|
+
isMatch = false;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (isMatch) {
|
|
476
|
+
matches.push(json);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
searchCodeSystemProviders(searchParams, hasSearchParams, matches) {
|
|
483
|
+
let seen = new Set();
|
|
484
|
+
for (const csp of this.provider.codeSystemFactories.values()) {
|
|
485
|
+
this.deadCheck('searchCodeSystems');
|
|
486
|
+
|
|
487
|
+
if (seen.has(csp.id())) {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
seen.add(csp.id());
|
|
491
|
+
|
|
492
|
+
let json = {
|
|
493
|
+
resourceType: "CodeSystem",
|
|
494
|
+
id: "x-" + csp.id(),
|
|
495
|
+
url: csp.system(),
|
|
496
|
+
version: csp.version(),
|
|
497
|
+
name: csp.name(),
|
|
498
|
+
status: "active",
|
|
499
|
+
description: "This is a place holder for the code system which is fully supported through internal means (not by this code system)",
|
|
500
|
+
content: "not-present"
|
|
501
|
+
}
|
|
502
|
+
if (csp.webSource()) {
|
|
503
|
+
json.extension = [{ url: "http://hl7.org/fhir/StructureDefinition/web-source", valueUrl : csp.webSource()}];
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (!hasSearchParams) {
|
|
507
|
+
matches.push(json);
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Check each search parameter for partial match
|
|
512
|
+
let isMatch = true;
|
|
513
|
+
for (const [param, searchValue] of Object.entries(searchParams)) {
|
|
514
|
+
|
|
515
|
+
// Map content-mode to content property
|
|
516
|
+
const jsonProp = param === 'content-mode' ? 'content' : param;
|
|
517
|
+
|
|
518
|
+
if (param === 'jurisdiction') {
|
|
519
|
+
// Special handling for jurisdiction - array of CodeableConcept
|
|
520
|
+
if (!this.matchJurisdiction(json.jurisdiction, searchValue)) {
|
|
521
|
+
isMatch = false;
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
} else if (param === 'text') {
|
|
525
|
+
const propValue = json.title + json.description;
|
|
526
|
+
if (!this.matchValue(propValue, searchValue)) {
|
|
527
|
+
isMatch = false;
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
} else if (param === 'url' || param === 'system') { // exact match
|
|
531
|
+
const propValue = json.url;
|
|
532
|
+
if (propValue !== searchValue) {
|
|
533
|
+
isMatch = false;
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
} else {
|
|
537
|
+
// Standard partial text match
|
|
538
|
+
const propValue = json[jsonProp];
|
|
539
|
+
if (!this.matchValue(propValue, searchValue)) {
|
|
540
|
+
isMatch = false;
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (isMatch) {
|
|
547
|
+
matches.push(json);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
476
551
|
}
|
|
477
552
|
|
|
478
553
|
module.exports = SearchWorker;
|
package/tx/workers/translate.js
CHANGED
|
@@ -387,7 +387,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
387
387
|
}
|
|
388
388
|
if (!explicit) {
|
|
389
389
|
matchParts.push({
|
|
390
|
-
name: '
|
|
390
|
+
name: 'originMap',
|
|
391
391
|
valueCanonical: cm.vurl
|
|
392
392
|
});
|
|
393
393
|
}
|
|
@@ -476,7 +476,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
476
476
|
}
|
|
477
477
|
if (!explicit) {
|
|
478
478
|
matchParts.push({
|
|
479
|
-
name: '
|
|
479
|
+
name: 'originMap',
|
|
480
480
|
valueCanonical: cm.vurl
|
|
481
481
|
});
|
|
482
482
|
}
|
|
@@ -538,7 +538,7 @@ class TranslateWorker extends TerminologyWorker {
|
|
|
538
538
|
}
|
|
539
539
|
if (!explicit) {
|
|
540
540
|
matchParts.push({
|
|
541
|
-
name: '
|
|
541
|
+
name: 'originMap',
|
|
542
542
|
valueCanonical: cm.vurl
|
|
543
543
|
});
|
|
544
544
|
}
|
package/tx/workers/worker.js
CHANGED
|
@@ -252,6 +252,7 @@ class TerminologyWorker {
|
|
|
252
252
|
loadSupplements(url, version = '', statedSupplements) {
|
|
253
253
|
const supplements = [];
|
|
254
254
|
|
|
255
|
+
supplements.push(...this.provider.loadSupplements(url, version, statedSupplements));
|
|
255
256
|
// todo: look in provider for supplements
|
|
256
257
|
|
|
257
258
|
if (!this.additionalResources) {
|
|
@@ -306,7 +307,7 @@ class TerminologyWorker {
|
|
|
306
307
|
* @param {CodeSystemProvider} cs - Code system provider
|
|
307
308
|
* @param {Object} src - Source element (for extensions)
|
|
308
309
|
*/
|
|
309
|
-
checkSupplements(cs, src, requiredSupplements, usedSupplements = null) {
|
|
310
|
+
checkSupplements(cs, src, requiredSupplements, usedSupplements = null, reportedSupplements = null) {
|
|
310
311
|
// Check for required supplements in extensions
|
|
311
312
|
if (src && src.extension) {
|
|
312
313
|
const supplementExtensions = src.extension.filter(x => x.url == 'http://hl7.org/fhir/StructureDefinition/valueset-supplement');
|
|
@@ -318,7 +319,12 @@ class TerminologyWorker {
|
|
|
318
319
|
}
|
|
319
320
|
}
|
|
320
321
|
|
|
321
|
-
|
|
322
|
+
if (reportedSupplements) {
|
|
323
|
+
for (let s of cs.listSupplements(true)) {
|
|
324
|
+
reportedSupplements.add(s);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Note required supplements that are satisfied - and might be version independent
|
|
322
328
|
if (usedSupplements) {
|
|
323
329
|
for (const s of requiredSupplements) {
|
|
324
330
|
if (cs.hasSupplement(s)) {
|
|
@@ -9,11 +9,11 @@ const {VersionUtilities} = require("../../library/version-utilities");
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
function codeSystemToR5(jsonObj, version) {
|
|
12
|
-
if (version
|
|
12
|
+
if (VersionUtilities.isR5Ver(version)) {
|
|
13
13
|
return jsonObj; // Already R5, no conversion needed
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
if (version
|
|
16
|
+
if (VersionUtilities.isR3Ver(version)) {
|
|
17
17
|
// R3 to R5: Convert identifier from single object to array
|
|
18
18
|
if (jsonObj.identifier && !Array.isArray(jsonObj.identifier)) {
|
|
19
19
|
jsonObj.identifier = [jsonObj.identifier];
|
|
@@ -21,7 +21,7 @@ function codeSystemToR5(jsonObj, version) {
|
|
|
21
21
|
return jsonObj;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
if (version
|
|
24
|
+
if (VersionUtilities.isR4Ver(version)) {
|
|
25
25
|
// R4 to R5: identifier is already an array, no conversion needed
|
|
26
26
|
return jsonObj;
|
|
27
27
|
}
|
|
@@ -17,10 +17,10 @@ function parametersToR5(jsonObj, sourceVersion) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const {
|
|
20
|
+
const {convertResourceToR5} = require("./xv-resource");
|
|
21
21
|
for (let p of jsonObj.parameter) {
|
|
22
22
|
if (p.resource) {
|
|
23
|
-
p.resource =
|
|
23
|
+
p.resource = convertResourceToR5(p.resource, sourceVersion);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
return jsonObj;
|
|
@@ -203,8 +203,7 @@ function convertContainsPropertyR5ToR4(containsList) {
|
|
|
203
203
|
*/
|
|
204
204
|
function isR5OnlyFilterOperator(operator) {
|
|
205
205
|
const r5OnlyOperators = [
|
|
206
|
-
'
|
|
207
|
-
// Add other R5-only operators as they're identified
|
|
206
|
+
'child-of', ' descendent-leaf' // Added in R5
|
|
208
207
|
];
|
|
209
208
|
return r5OnlyOperators.includes(operator);
|
|
210
209
|
}
|