fhirsmith 0.3.0 → 0.5.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 +24 -0
- package/README.md +4 -2
- package/library/cron-utilities.js +136 -0
- package/library/folder-setup.js +6 -0
- package/library/html-server.js +13 -29
- package/library/html.js +3 -8
- package/library/languages.js +160 -37
- package/library/package-manager.js +48 -1
- package/library/utilities.js +100 -19
- package/package.json +2 -2
- package/packages/package-crawler.js +6 -1
- package/packages/packages.js +38 -54
- package/publisher/publisher.js +19 -27
- package/registry/api.js +11 -10
- package/registry/crawler.js +31 -29
- package/registry/model.js +5 -26
- package/registry/readme.md +1 -11
- package/registry/registry.js +32 -41
- package/server.js +53 -5
- package/shl/shl.js +0 -18
- package/static/assets/js/statuspage.js +1 -9
- package/stats.js +39 -1
- package/token/token.js +14 -9
- package/translations/Messages.properties +2 -1
- package/tx/README.md +17 -6
- package/tx/cs/cs-api.js +19 -1
- package/tx/cs/cs-base.js +77 -0
- package/tx/cs/cs-country.js +46 -0
- package/tx/cs/cs-cpt.js +9 -5
- package/tx/cs/cs-cs.js +27 -13
- package/tx/cs/cs-db.js +0 -13
- package/tx/cs/cs-lang.js +60 -22
- package/tx/cs/cs-loinc.js +69 -98
- package/tx/cs/cs-mimetypes.js +4 -0
- package/tx/cs/cs-ndc.js +6 -0
- package/tx/cs/cs-omop.js +16 -15
- package/tx/cs/cs-rxnorm.js +23 -1
- package/tx/cs/cs-snomed.js +283 -40
- package/tx/cs/cs-ucum.js +90 -70
- package/tx/importers/import-sct.module.js +371 -35
- package/tx/importers/readme.md +117 -7
- package/tx/library/bundle.js +5 -0
- package/tx/library/capabilitystatement.js +3 -142
- package/tx/library/codesystem.js +19 -173
- package/tx/library/conceptmap.js +4 -218
- package/tx/library/designations.js +14 -1
- package/tx/library/extensions.js +7 -0
- package/tx/library/namingsystem.js +3 -89
- package/tx/library/operation-outcome.js +8 -3
- package/tx/library/parameters.js +3 -2
- package/tx/library/renderer.js +10 -6
- package/tx/library/terminologycapabilities.js +3 -243
- package/tx/library/valueset.js +3 -235
- package/tx/library.js +100 -13
- package/tx/operation-context.js +23 -4
- package/tx/params.js +35 -38
- package/tx/provider.js +6 -5
- package/tx/sct/expressions.js +12 -3
- package/tx/tx-html.js +80 -89
- package/tx/tx.fhir.org.yml +6 -5
- package/tx/tx.js +163 -13
- package/tx/vs/vs-database.js +56 -39
- package/tx/vs/vs-package.js +21 -2
- package/tx/vs/vs-vsac.js +175 -39
- package/tx/workers/batch-validate.js +2 -0
- package/tx/workers/batch.js +2 -0
- package/tx/workers/expand.js +132 -112
- package/tx/workers/lookup.js +33 -14
- package/tx/workers/metadata.js +2 -2
- package/tx/workers/read.js +3 -2
- package/tx/workers/related.js +574 -0
- package/tx/workers/search.js +46 -9
- package/tx/workers/subsumes.js +13 -3
- package/tx/workers/translate.js +7 -3
- package/tx/workers/validate.js +258 -285
- package/tx/workers/worker.js +43 -39
- package/tx/xml/bundle-xml.js +237 -0
- package/tx/xml/xml-base.js +215 -64
- package/tx/xversion/xv-bundle.js +71 -0
- package/tx/xversion/xv-capabiliityStatement.js +137 -0
- package/tx/xversion/xv-codesystem.js +169 -0
- package/tx/xversion/xv-conceptmap.js +224 -0
- package/tx/xversion/xv-namingsystem.js +88 -0
- package/tx/xversion/xv-operationoutcome.js +27 -0
- package/tx/xversion/xv-parameters.js +87 -0
- package/tx/xversion/xv-resource.js +45 -0
- package/tx/xversion/xv-terminologyCapabilities.js +214 -0
- package/tx/xversion/xv-valueset.js +234 -0
- package/utilities/dev-proxy-server.js +126 -0
- package/utilities/explode-results.js +58 -0
- package/utilities/split-by-system.js +198 -0
- package/utilities/vsac-cs-fetcher.js +0 -0
- package/{windows-install.js → utilities/windows-install.js} +2 -0
- package/vcl/vcl.js +0 -18
- package/xig/xig.js +108 -99
- package/passwords.ini +0 -2
- package/registry/registry-data.json +0 -121015
- package/shl/private-key.pem +0 -5
- package/shl/public-key.pem +0 -18
- package/test-cache/vsac/vsac-valuesets.db +0 -0
- package/tx/dev.fhir.org.yml +0 -14
- package/tx/fixtures/test-cases-setup.json +0 -18
- package/tx/fixtures/test-cases.yml +0 -16
package/stats.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const { monitorEventLoopDelay } = require('perf_hooks');
|
|
2
|
-
const {
|
|
2
|
+
const {Utilities} = require("./library/utilities");
|
|
3
|
+
const escape = require('escape-html');
|
|
3
4
|
|
|
4
5
|
class ServerStats {
|
|
5
6
|
started = false;
|
|
@@ -13,6 +14,7 @@ class ServerStats {
|
|
|
13
14
|
startTime = Date.now();
|
|
14
15
|
timer;
|
|
15
16
|
cachingModules = [];
|
|
17
|
+
taskMap = new Map();
|
|
16
18
|
|
|
17
19
|
constructor() {
|
|
18
20
|
this.timer = setInterval(() => {
|
|
@@ -73,6 +75,42 @@ class ServerStats {
|
|
|
73
75
|
this.requestTime = this.requestTime + tat;
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
addTask(name, frequency) {
|
|
79
|
+
let info = {};
|
|
80
|
+
this.taskMap.set(name, info);
|
|
81
|
+
info.frequency = frequency;
|
|
82
|
+
info.state = "Started";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
task(name, state) {
|
|
86
|
+
let info = this.taskMap.get(name);
|
|
87
|
+
if (info) {
|
|
88
|
+
info.date = Date.now();
|
|
89
|
+
info.state = state;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
taskDetails() {
|
|
94
|
+
if (this.taskMap.size == 0) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
let html = '<table class="grid"><tr style="background-color: #EEEEEE"><th colspan="4">Background Tasks</th></tr>';
|
|
98
|
+
html += "<tr><th>Task</th><th>Status</th><th>Frequency</th><th>Last Seen</th></tr>";
|
|
99
|
+
for (let m of this.taskMap.keys()) {
|
|
100
|
+
html += "<tr><td>";
|
|
101
|
+
html += escape(m);
|
|
102
|
+
html += "</td><td>";
|
|
103
|
+
html += escape(this.taskMap.get(m).state);
|
|
104
|
+
html += "</td><td>";
|
|
105
|
+
html += this.taskMap.get(m).frequency;
|
|
106
|
+
html += "</td><td>";
|
|
107
|
+
html += Utilities.formatDuration(this.taskMap.get(m).date, Date.now());
|
|
108
|
+
html += "</td></tr>";
|
|
109
|
+
}
|
|
110
|
+
html += "</table>";
|
|
111
|
+
return html;
|
|
112
|
+
}
|
|
113
|
+
|
|
76
114
|
finishStats() {
|
|
77
115
|
clearInterval(this.timer);
|
|
78
116
|
}
|
package/token/token.js
CHANGED
|
@@ -19,6 +19,7 @@ const GitHubStrategy = require('passport-github2').Strategy;
|
|
|
19
19
|
const rateLimit = require('express-rate-limit');
|
|
20
20
|
const lusca = require('lusca');
|
|
21
21
|
const folders = require('../library/folder-setup');
|
|
22
|
+
const escape = require('escape-html');
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
const Logger = require('../library/logger');
|
|
@@ -325,6 +326,7 @@ class TokenModule {
|
|
|
325
326
|
this.log.info('OAuth strategies configured:', configuredStrategies);
|
|
326
327
|
}
|
|
327
328
|
|
|
329
|
+
// eslint-disable-next-line no-unused-vars
|
|
328
330
|
async handleOAuthCallback(req, provider, profile, tokens) {
|
|
329
331
|
const email = this.extractEmail(profile);
|
|
330
332
|
const name = this.extractName(profile);
|
|
@@ -928,6 +930,7 @@ class TokenModule {
|
|
|
928
930
|
});
|
|
929
931
|
}
|
|
930
932
|
|
|
933
|
+
// eslint-disable-next-line no-unused-vars
|
|
931
934
|
async updateKeyLastUsed(keyId, ip = null) {
|
|
932
935
|
return new Promise((resolve, reject) => {
|
|
933
936
|
this.db.run(
|
|
@@ -1004,6 +1007,7 @@ class TokenModule {
|
|
|
1004
1007
|
}
|
|
1005
1008
|
|
|
1006
1009
|
async logSecurityEvent(userId, eventType, ip, userAgent, details) {
|
|
1010
|
+
// eslint-disable-next-line no-unused-vars
|
|
1007
1011
|
return new Promise((resolve, reject) => {
|
|
1008
1012
|
this.db.run(
|
|
1009
1013
|
'INSERT INTO security_log (user_id, event_type, ip_address, user_agent, details) VALUES (?, ?, ?, ?, ?)',
|
|
@@ -1020,14 +1024,15 @@ class TokenModule {
|
|
|
1020
1024
|
}
|
|
1021
1025
|
|
|
1022
1026
|
// Content builders
|
|
1027
|
+
// eslint-disable-next-line no-unused-vars
|
|
1023
1028
|
buildDashboardContent(user, apiKeys, usageStats) {
|
|
1024
1029
|
let content = `
|
|
1025
1030
|
<div class="row mb-4">
|
|
1026
1031
|
<div class="col-12">
|
|
1027
1032
|
<div class="d-flex justify-content-between align-items-center">
|
|
1028
1033
|
<div>
|
|
1029
|
-
<h3>Welcome, ${
|
|
1030
|
-
<p class="text-muted">Email: ${
|
|
1034
|
+
<h3>Welcome, ${escape(user.name)}</h3>
|
|
1035
|
+
<p class="text-muted">Email: ${escape(user.email)} | Provider: ${escape(user.provider)}</p>
|
|
1031
1036
|
</div>
|
|
1032
1037
|
<form method="POST" action="/token/logout" class="d-inline">
|
|
1033
1038
|
<button type="submit" class="btn btn-outline-secondary">Logout</button>
|
|
@@ -1126,16 +1131,16 @@ class TokenModule {
|
|
|
1126
1131
|
|
|
1127
1132
|
content += `
|
|
1128
1133
|
<tr>
|
|
1129
|
-
<td><strong>${
|
|
1130
|
-
<td><code>${
|
|
1131
|
-
<td><span class="badge bg-secondary">${
|
|
1134
|
+
<td><strong>${escape(key.name)}</strong></td>
|
|
1135
|
+
<td><code>${escape(key.key_prefix)}...</code></td>
|
|
1136
|
+
<td><span class="badge bg-secondary">${escape(scopes)}</span></td>
|
|
1132
1137
|
<td>${new Date(key.created_at).toLocaleDateString()}</td>
|
|
1133
1138
|
<td>${lastUsed}</td>
|
|
1134
1139
|
<td>${expires}</td>
|
|
1135
1140
|
<td><span class="${statusClass}">${status}</span></td>
|
|
1136
1141
|
<td>
|
|
1137
1142
|
${key.is_active ?
|
|
1138
|
-
`<button class="btn btn-sm btn-danger" onclick="deleteKey(${key.id}, '${
|
|
1143
|
+
`<button class="btn btn-sm btn-danger" onclick="deleteKey(${key.id}, '${escape(key.name)}')">Delete</button>` :
|
|
1139
1144
|
'<span class="text-muted">-</span>'
|
|
1140
1145
|
}
|
|
1141
1146
|
</td>
|
|
@@ -1176,7 +1181,7 @@ class TokenModule {
|
|
|
1176
1181
|
|
|
1177
1182
|
content += `
|
|
1178
1183
|
<div class="alert alert-danger" role="alert">
|
|
1179
|
-
<strong>Error:</strong> ${
|
|
1184
|
+
<strong>Error:</strong> ${escape(errorMessage)}
|
|
1180
1185
|
</div>
|
|
1181
1186
|
`;
|
|
1182
1187
|
}
|
|
@@ -1252,7 +1257,7 @@ class TokenModule {
|
|
|
1252
1257
|
<!DOCTYPE html>
|
|
1253
1258
|
<html lang="en">
|
|
1254
1259
|
<head>
|
|
1255
|
-
<title>${
|
|
1260
|
+
<title>${escape(title)} - FHIR Token Server</title>
|
|
1256
1261
|
<meta charset="utf-8">
|
|
1257
1262
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1258
1263
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
@@ -1263,7 +1268,7 @@ class TokenModule {
|
|
|
1263
1268
|
<nav class="mb-4">
|
|
1264
1269
|
<a href="/" class="text-decoration-none">← Back to Server Home</a>
|
|
1265
1270
|
</nav>
|
|
1266
|
-
<h1 class="mb-4">${
|
|
1271
|
+
<h1 class="mb-4">${escape(title)}</h1>
|
|
1267
1272
|
${content}
|
|
1268
1273
|
</div>
|
|
1269
1274
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
@@ -1312,7 +1312,8 @@ VS_EXP_IMPORT_UNK_PINNED = Unable to find included value set ''{0}'' version ''{
|
|
|
1312
1312
|
VS_EXP_IMPORT_UNK_PINNED_X = Unable to find excluded value set ''{0}'' version ''{1}''
|
|
1313
1313
|
VS_EXP_IMPORT_UNK_X = Unable to find excluded value set ''{0}''
|
|
1314
1314
|
Wrong_namespace__expected_ = Wrong namespace - expected ''{0}''
|
|
1315
|
-
Wrong_type_for_resource = Wrong type for resource
|
|
1315
|
+
Wrong_type_for_resource = Wrong type for resource
|
|
1316
|
+
Wrong_type_for_resource_expected = Wrong type for resource. Expected {0} but found {1}
|
|
1316
1317
|
TEXT_LINK_DATA_NOT_FOUND = The target of the textLink data reference ''{0}'' was not found in the resource
|
|
1317
1318
|
TEXT_LINK_DATA_MULTIPLE_MATCHES = Multiple matching targets for the textLink data reference ''{0}'' were found in the resource
|
|
1318
1319
|
XHTML_URL_DATA_DATA_INVALID = The data should be valid base64 content for a data: URL: {0}
|
package/tx/README.md
CHANGED
|
@@ -4,12 +4,7 @@ The TX module provides FHIR terminology services for CodeSystem, ValueSet, and C
|
|
|
4
4
|
|
|
5
5
|
## Todo
|
|
6
6
|
|
|
7
|
-
*
|
|
8
|
-
* add more tests for the code system providers - filters, extended lookup, designations and languages
|
|
9
|
-
* more refactoring in validate.js and expand.js
|
|
10
|
-
* full batch support
|
|
11
|
-
* check vsac support
|
|
12
|
-
* get tx tests running in pipelines
|
|
7
|
+
* Improve batch support
|
|
13
8
|
|
|
14
9
|
## Overview
|
|
15
10
|
|
|
@@ -303,6 +298,22 @@ You can specify a version using the `#` syntax:
|
|
|
303
298
|
|
|
304
299
|
If no version is specified, the latest released version is fetched.
|
|
305
300
|
|
|
301
|
+
#### `url` - FHIR Packages from Direct URLs
|
|
302
|
+
|
|
303
|
+
Loads a FHIR package directly from a tarball URL instead of the FHIR package registry. Useful for packages hosted on CI build servers, branches, or other locations.
|
|
304
|
+
|
|
305
|
+
Use `url/cs` to load only CodeSystem resources from the package (same as `npm/cs`).
|
|
306
|
+
|
|
307
|
+
```yaml
|
|
308
|
+
# Load a package from a CI build server
|
|
309
|
+
- url:https://example.com/my-package/package.tgz
|
|
310
|
+
|
|
311
|
+
# Load a code-systems-only package from a URL
|
|
312
|
+
- url/cs:https://example.com/my-codesystems/package.tgz
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
The URL must point to a `.tgz` file in standard FHIR NPM package format. Downloaded packages are cached locally by URL.
|
|
316
|
+
|
|
306
317
|
### Default Marker (`!`)
|
|
307
318
|
|
|
308
319
|
When multiple versions of the same code system are loaded, append `!` to mark one as the default:
|
package/tx/cs/cs-api.js
CHANGED
|
@@ -11,6 +11,11 @@ const {VersionUtilities} = require("../../library/version-utilities");
|
|
|
11
11
|
|
|
12
12
|
class FilterExecutionContext {
|
|
13
13
|
filters = [];
|
|
14
|
+
forIterate = false;
|
|
15
|
+
|
|
16
|
+
constructor(forIterate) {
|
|
17
|
+
this.forIterate = forIterate;
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
class CodeSystemProvider {
|
|
@@ -122,6 +127,17 @@ class CodeSystemProvider {
|
|
|
122
127
|
isNotClosed() {
|
|
123
128
|
return false;
|
|
124
129
|
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* returns true if the code system is case sensitive when comparing codes.
|
|
133
|
+
* this is true by default
|
|
134
|
+
*
|
|
135
|
+
* @returns {boolean}
|
|
136
|
+
*/
|
|
137
|
+
isCaseSensitive() {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
125
141
|
/**
|
|
126
142
|
* @param {Languages} languages language specification
|
|
127
143
|
* @returns {boolean} defined properties for the code system
|
|
@@ -489,7 +505,7 @@ class CodeSystemProvider {
|
|
|
489
505
|
* @param {boolean} iterate true if the conceptSets that result from this will be iterated, and false if they'll be used to locate a single code
|
|
490
506
|
* @returns {FilterExecutionContext} filter (or null, it no use for this)
|
|
491
507
|
* */
|
|
492
|
-
async getPrepContext(iterate) { return new FilterExecutionContext(); }
|
|
508
|
+
async getPrepContext(iterate) { return new FilterExecutionContext(iterate); }
|
|
493
509
|
|
|
494
510
|
/**
|
|
495
511
|
* executes a text search filter (whatever that means) and returns a FilterConceptSet
|
|
@@ -662,6 +678,8 @@ class CodeSystemProvider {
|
|
|
662
678
|
valueSet() {
|
|
663
679
|
return null;
|
|
664
680
|
}
|
|
681
|
+
|
|
682
|
+
|
|
665
683
|
}
|
|
666
684
|
|
|
667
685
|
class CodeSystemFactoryProvider {
|
package/tx/cs/cs-base.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const {CodeSystemProvider} = require("./cs-api");
|
|
2
|
+
|
|
3
|
+
class BaseCSServices extends CodeSystemProvider {
|
|
4
|
+
|
|
5
|
+
_addProperty(params, type, name, value, language = null) {
|
|
6
|
+
|
|
7
|
+
const property = {
|
|
8
|
+
name: type,
|
|
9
|
+
part: [
|
|
10
|
+
{name: 'code', valueCode: name},
|
|
11
|
+
{name: 'value', valueString: value}
|
|
12
|
+
]
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
if (language) {
|
|
16
|
+
property.part.push({name: 'language', valueCode: language});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
params.push(property);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_addCodeProperty(params, type, name, value, language = null, description = null) {
|
|
24
|
+
|
|
25
|
+
const property = {
|
|
26
|
+
name: type,
|
|
27
|
+
part: [
|
|
28
|
+
{name: 'code', valueCode: name},
|
|
29
|
+
{name: 'value', valueCode: value}
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (language) {
|
|
34
|
+
property.part.push({name: 'language', valueCode: language});
|
|
35
|
+
}
|
|
36
|
+
if (description) {
|
|
37
|
+
property.part.push({name: 'description', valueString: description});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
params.push(property);
|
|
41
|
+
return property;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
_addStringProperty(params, type, name, value, language = null) {
|
|
45
|
+
|
|
46
|
+
const property = {
|
|
47
|
+
name: type,
|
|
48
|
+
part: [
|
|
49
|
+
{name: 'code', valueCode: name},
|
|
50
|
+
{name: 'value', valueString: value}
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (language) {
|
|
55
|
+
property.part.push({name: 'language', valueCode: language});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
params.push(property);
|
|
59
|
+
return property;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// Helper to check if a property should be included
|
|
64
|
+
_hasProp = (props, name, defaultValue = true) => {
|
|
65
|
+
if (!props || props.length === 0) {
|
|
66
|
+
return defaultValue;
|
|
67
|
+
}
|
|
68
|
+
const lowerName = name.toLowerCase();
|
|
69
|
+
return props.some(p =>
|
|
70
|
+
p.toLowerCase() === lowerName || p === '*'
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = {
|
|
76
|
+
BaseCSServices
|
|
77
|
+
};
|
package/tx/cs/cs-country.js
CHANGED
|
@@ -578,6 +578,52 @@ class CountryCodeFactoryProvider extends CodeSystemFactoryProvider {
|
|
|
578
578
|
['ZM', 'Zambia'],
|
|
579
579
|
['ZW', 'Zimbabwe'],
|
|
580
580
|
|
|
581
|
+
// ISO 3166-1 User-assigned code elements
|
|
582
|
+
// These codes are reserved for user assignment and will never be used for country names
|
|
583
|
+
// See: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#User-assigned_code_elements
|
|
584
|
+
['AA', 'User-assigned'],
|
|
585
|
+
['QM', 'User-assigned'],
|
|
586
|
+
['QN', 'User-assigned'],
|
|
587
|
+
['QO', 'User-assigned'],
|
|
588
|
+
['QP', 'User-assigned'],
|
|
589
|
+
['QQ', 'User-assigned'],
|
|
590
|
+
['QR', 'User-assigned'],
|
|
591
|
+
['QS', 'User-assigned'],
|
|
592
|
+
['QT', 'User-assigned'],
|
|
593
|
+
['QU', 'User-assigned'],
|
|
594
|
+
['QV', 'User-assigned'],
|
|
595
|
+
['QW', 'User-assigned'],
|
|
596
|
+
['QX', 'User-assigned'],
|
|
597
|
+
['QY', 'User-assigned'],
|
|
598
|
+
['QZ', 'User-assigned'],
|
|
599
|
+
['XA', 'User-assigned'],
|
|
600
|
+
['XB', 'User-assigned'],
|
|
601
|
+
['XC', 'User-assigned'],
|
|
602
|
+
['XD', 'User-assigned'],
|
|
603
|
+
['XE', 'User-assigned'],
|
|
604
|
+
['XF', 'User-assigned'],
|
|
605
|
+
['XG', 'User-assigned'],
|
|
606
|
+
['XH', 'User-assigned'],
|
|
607
|
+
['XI', 'User-assigned'],
|
|
608
|
+
['XJ', 'User-assigned'],
|
|
609
|
+
['XK', 'Kosovo'],
|
|
610
|
+
['XL', 'User-assigned'],
|
|
611
|
+
['XM', 'User-assigned'],
|
|
612
|
+
['XN', 'User-assigned'],
|
|
613
|
+
['XO', 'User-assigned'],
|
|
614
|
+
['XP', 'User-assigned'],
|
|
615
|
+
['XQ', 'User-assigned'],
|
|
616
|
+
['XR', 'User-assigned'],
|
|
617
|
+
['XS', 'User-assigned'],
|
|
618
|
+
['XT', 'User-assigned'],
|
|
619
|
+
['XU', 'User-assigned'],
|
|
620
|
+
['XV', 'User-assigned'],
|
|
621
|
+
['XW', 'User-assigned'],
|
|
622
|
+
['XX', 'Unknown'],
|
|
623
|
+
['XY', 'User-assigned'],
|
|
624
|
+
['XZ', 'International Waters'],
|
|
625
|
+
['ZZ', 'Unknown or Invalid Territory'],
|
|
626
|
+
|
|
581
627
|
// 3-letter codes
|
|
582
628
|
['ABW', 'Aruba'],
|
|
583
629
|
['AFG', 'Afghanistan'],
|
package/tx/cs/cs-cpt.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const sqlite3 = require('sqlite3').verbose();
|
|
2
2
|
const assert = require('assert');
|
|
3
3
|
const { CodeSystem } = require('../library/codesystem');
|
|
4
|
-
const {
|
|
4
|
+
const { FilterExecutionContext, CodeSystemFactoryProvider } = require('./cs-api');
|
|
5
5
|
const {validateArrayParameter} = require("../../library/utilities");
|
|
6
|
+
const {BaseCSServices} = require("./cs-base");
|
|
6
7
|
|
|
7
8
|
class CPTConceptDesignation {
|
|
8
9
|
constructor(kind, value) {
|
|
@@ -108,7 +109,7 @@ class CPTPrep extends FilterExecutionContext {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
class CPTServices extends
|
|
112
|
+
class CPTServices extends BaseCSServices {
|
|
112
113
|
constructor(opContext, supplements, db, sharedData) {
|
|
113
114
|
super(opContext, supplements);
|
|
114
115
|
this.db = db;
|
|
@@ -224,6 +225,9 @@ class CPTServices extends CodeSystemProvider {
|
|
|
224
225
|
|
|
225
226
|
}
|
|
226
227
|
|
|
228
|
+
isNotClosed() {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
227
231
|
async extendLookup(ctxt, props, params) {
|
|
228
232
|
validateArrayParameter(props, 'props', String);
|
|
229
233
|
validateArrayParameter(params, 'params', Object);
|
|
@@ -255,7 +259,7 @@ class CPTServices extends CodeSystemProvider {
|
|
|
255
259
|
}
|
|
256
260
|
} else if (ctxt instanceof CPTConcept) {
|
|
257
261
|
// Add designations
|
|
258
|
-
if (this
|
|
262
|
+
if (this._hasProp(props, 'designation', true)) {
|
|
259
263
|
for (const d of ctxt.designations) {
|
|
260
264
|
this.#addProperty(params, 'designation', d.kind, d.value, 'en');
|
|
261
265
|
}
|
|
@@ -263,7 +267,7 @@ class CPTServices extends CodeSystemProvider {
|
|
|
263
267
|
|
|
264
268
|
// Add properties
|
|
265
269
|
for (const p of ctxt.properties) {
|
|
266
|
-
if (this
|
|
270
|
+
if (this._hasProp(props, p.name, true)) {
|
|
267
271
|
this.#addProperty(params, 'property', p.name, p.value);
|
|
268
272
|
}
|
|
269
273
|
}
|
|
@@ -545,7 +549,7 @@ class CPTServices extends CodeSystemProvider {
|
|
|
545
549
|
if (concept) {
|
|
546
550
|
return concept;
|
|
547
551
|
}
|
|
548
|
-
return
|
|
552
|
+
return null;
|
|
549
553
|
}
|
|
550
554
|
|
|
551
555
|
async filterCheck(filterContext, set, concept) {
|
package/tx/cs/cs-cs.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const { CodeSystem} = require("../library/codesystem");
|
|
2
|
-
const { CodeSystemFactoryProvider,
|
|
2
|
+
const { CodeSystemFactoryProvider, FilterExecutionContext } = require( "./cs-api");
|
|
3
3
|
const { VersionUtilities } = require("../../library/version-utilities");
|
|
4
4
|
const { Language } = require ("../../library/languages");
|
|
5
5
|
const { validateOptionalParameter, getValuePrimitive, validateArrayParameter} = require("../../library/utilities");
|
|
6
6
|
const {Issue} = require("../library/operation-outcome");
|
|
7
7
|
const {Extensions} = require("../library/extensions");
|
|
8
|
+
const {BaseCSServices} = require("./cs-base");
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Context class for FHIR CodeSystem provider concepts
|
|
@@ -101,7 +102,7 @@ class FhirCodeSystemProviderFilterContext {
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
class FhirCodeSystemProvider extends
|
|
105
|
+
class FhirCodeSystemProvider extends BaseCSServices {
|
|
105
106
|
/**
|
|
106
107
|
* @param {CodeSystem} codeSystem - The primary CodeSystem
|
|
107
108
|
* @param {CodeSystem[]} supplements - Array of supplement CodeSystems
|
|
@@ -385,6 +386,10 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
385
386
|
return ctxt ? (ctxt.concept.definition || null) : null;
|
|
386
387
|
}
|
|
387
388
|
|
|
389
|
+
isCaseSensitive() {
|
|
390
|
+
return !this.codeSystem.caseInsensitive();
|
|
391
|
+
}
|
|
392
|
+
|
|
388
393
|
/**
|
|
389
394
|
* @param {string|FhirCodeSystemProviderContext} context - Code or context
|
|
390
395
|
* @returns {Promise<boolean>} If the concept is abstract
|
|
@@ -642,6 +647,15 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
642
647
|
return extensions.length > 0 ? extensions : null;
|
|
643
648
|
}
|
|
644
649
|
|
|
650
|
+
getPropertyDefinition(cs, code) {
|
|
651
|
+
for (let p of cs.property || []) {
|
|
652
|
+
if (code == p.code) {
|
|
653
|
+
return p;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return undefined;
|
|
657
|
+
}
|
|
658
|
+
|
|
645
659
|
/**
|
|
646
660
|
* @param {string|FhirCodeSystemProviderContext} context - Code or context
|
|
647
661
|
* @returns {Promise<Object[]|null>} Properties, if any
|
|
@@ -656,16 +670,20 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
656
670
|
const properties = [];
|
|
657
671
|
|
|
658
672
|
// Add properties from main concept
|
|
659
|
-
|
|
660
|
-
|
|
673
|
+
for (let p of ctxt.concept.property || []) {
|
|
674
|
+
let pd = this.getPropertyDefinition(this.codeSystem.jsonObj, p.code);
|
|
675
|
+
properties.push({ ...p, definition: pd });
|
|
661
676
|
}
|
|
662
677
|
|
|
663
678
|
// Add properties from supplements
|
|
664
679
|
if (this.supplements) {
|
|
665
680
|
for (const supplement of this.supplements) {
|
|
666
681
|
const supplementConcept = supplement.getConceptByCode(ctxt.code);
|
|
667
|
-
if (supplementConcept
|
|
668
|
-
|
|
682
|
+
if (supplementConcept) {
|
|
683
|
+
for (let p of supplementConcept.property || []) {
|
|
684
|
+
let pd = this.getPropertyDefinition(supplement.jsonObj, p.code);
|
|
685
|
+
properties.push({...p, definition: pd});
|
|
686
|
+
}
|
|
669
687
|
}
|
|
670
688
|
}
|
|
671
689
|
}
|
|
@@ -886,12 +904,8 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
886
904
|
return;
|
|
887
905
|
}
|
|
888
906
|
|
|
889
|
-
// Set abstract status
|
|
890
|
-
if (!params.find(p => p.name == "abstract") && await this.isAbstract(ctxt)) {
|
|
891
|
-
params.push({ name: 'property', part: [ { name: 'code', valueCode: 'abstract' }, { name: 'value', valueBoolean: true } ]});
|
|
892
|
-
}
|
|
893
907
|
// Add properties if requested (or by default)
|
|
894
|
-
if (
|
|
908
|
+
if (this._hasProp(props, 'property', true)) {
|
|
895
909
|
const properties = await this.properties(ctxt);
|
|
896
910
|
if (properties) {
|
|
897
911
|
for (const property of properties) {
|
|
@@ -920,7 +934,7 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
920
934
|
}
|
|
921
935
|
|
|
922
936
|
// Add parent if requested and exists
|
|
923
|
-
if (
|
|
937
|
+
if (this._hasProp(props, 'parent', true)) {
|
|
924
938
|
const parentCode = await this.parent(ctxt);
|
|
925
939
|
if (parentCode) {
|
|
926
940
|
let parts = [];
|
|
@@ -932,7 +946,7 @@ class FhirCodeSystemProvider extends CodeSystemProvider {
|
|
|
932
946
|
}
|
|
933
947
|
|
|
934
948
|
// Add children if requested
|
|
935
|
-
if (
|
|
949
|
+
if (this._hasProp(props, 'child', true)) {
|
|
936
950
|
const children = this.codeSystem.getChildren(ctxt.code);
|
|
937
951
|
if (children.length > 0) {
|
|
938
952
|
for (const childCode of children) {
|
package/tx/cs/cs-db.js
CHANGED
|
@@ -5,19 +5,6 @@ const { Language, Languages} = require('../../library/languages');
|
|
|
5
5
|
const { CodeSystemProvider, CodeSystemFactoryProvider} = require('./cs-api');
|
|
6
6
|
const { validateOptionalParameter, validateArrayParameter} = require("../../library/utilities");
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* SQL Tables:
|
|
10
|
-
*
|
|
11
|
-
* Metadata: Name, Value
|
|
12
|
-
* Concepts: ConceptKey, Code, Display, Definition, Parent
|
|
13
|
-
* Closure: ParentKey, ChildKey
|
|
14
|
-
* DesignationUses: DesignationUseKey, System, Version, Code, Display
|
|
15
|
-
* Languages: LanguageKey, LanguageCode
|
|
16
|
-
* Designations: ConceptKey, LanguageKey, DesignationUseKey, Value
|
|
17
|
-
* PropertyDefinitions: PropertyDefinitionKey, Code, Uri, Description, Type
|
|
18
|
-
* Properties: PropertyKey, PropertyDefinitionKey, Value, System, Version, Display
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
8
|
class CachedDesignation {
|
|
22
9
|
constructor(display, language, use) {
|
|
23
10
|
this.display = display;
|