fhirsmith 0.18.1 → 1.0.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/ACCESSIBILITY.md +119 -0
- package/CHANGELOG.md +190 -9
- package/CONFIGURATION.md +305 -0
- package/LICENSE +29 -0
- package/README.md +29 -122
- package/cluster.js +1220 -0
- package/cluster.md +707 -0
- package/config-template.json +77 -8
- package/extension-tracker/extension-tracker-template.html +5 -8
- package/extension-tracker/extension-tracker.js +0 -2
- package/folder/folder.js +7 -6
- package/ips/analysis.js +560 -0
- package/ips/ips-template.html +5 -8
- package/ips/ips.js +331 -33
- package/ips/jurisdictions.js +65 -0
- package/ips/nationality.js +120 -0
- package/ips/pipeline.js +131 -17
- package/ips/presenter.js +1 -1
- package/ips/profile-editor.js +283 -4
- package/ips/readme.md +170 -20
- package/ips/render.js +769 -109
- package/ips/scripts.js +46 -0
- package/ips/store.js +123 -11
- package/ips/structure.js +247 -0
- package/ips/terminology.js +1 -1
- package/library/body-limit.js +22 -0
- package/library/cache-generation.js +15 -0
- package/library/cgroup-memory.js +133 -1
- package/library/cluster-counts.js +121 -0
- package/library/cluster-events.js +153 -0
- package/library/cluster-metrics.js +193 -0
- package/library/cluster-status.js +468 -0
- package/library/config-reader.js +96 -0
- package/library/daily-report.js +100 -2
- package/library/html-server.js +27 -1
- package/library/i18nsupport.js +23 -1
- package/library/keep-alive.js +18 -0
- package/library/languages.js +17 -3
- package/library/logger.js +31 -0
- package/library/memory-guard.js +428 -0
- package/library/native-memory.js +52 -0
- package/library/npm-audit.js +51 -25
- package/library/openapi-doc.js +7 -5
- package/library/package-manager.js +8 -0
- package/library/role.js +197 -0
- package/library/server-credentials.js +169 -0
- package/library/sqlite-utilities.js +59 -0
- package/library/ssrf-guard.js +100 -0
- package/library/static-response-stats.js +16 -0
- package/library/version-utilities.js +50 -0
- package/library/worker-count.js +192 -0
- package/nginx.md +30 -11
- package/npmprojector/indexer.js +18 -10
- package/package.json +11 -8
- package/packages/feed-check-page.js +117 -0
- package/packages/feed-check.js +279 -0
- package/packages/npm-check.js +57 -3
- package/packages/npm-signing.js +219 -0
- package/packages/openapi.yaml +207 -1
- package/packages/package-crawler.js +322 -41
- package/packages/packages-template.html +6 -8
- package/packages/packages.js +604 -57
- package/packages/readme.md +113 -1
- package/publisher/publisher-template.html +2 -5
- package/publisher/publisher.js +121 -110
- package/publisher/readme.md +75 -0
- package/registry/api.js +179 -1
- package/registry/crawler.js +86 -108
- package/registry/documentation/api.md +68 -2
- package/registry/documentation/configuration.md +34 -0
- package/registry/documentation/internals.md +4 -1
- package/registry/documentation/readme.md +3 -2
- package/registry/model.js +8 -0
- package/registry/openapi.yaml +84 -0
- package/registry/registry-template.html +5 -8
- package/registry/registry.js +58 -6
- package/root-bare-template.html +7 -4
- package/root-template.html +5 -8
- package/server.js +398 -198
- package/shl/shl.js +38 -37
- package/static/a11y/a11y-check.js +832 -0
- package/static/a11y/axe.min.js +12 -0
- package/static/assets/css/bootstrap-fhir.css +15 -15
- package/static/assets/images/flags/au.svg +18 -0
- package/static/assets/images/flags/unknown.svg +11 -0
- package/static/assets/images/flags/us.svg +63 -0
- package/static/assets/images/icon_audit.png +0 -0
- package/static/assets/images/icon_clinical.png +0 -0
- package/static/assets/images/icon_document.png +0 -0
- package/static/assets/images/icon_external.png +0 -0
- package/static/assets/images/icon_medication.png +0 -0
- package/static/assets/images/icon_organization.png +0 -0
- package/static/assets/images/icon_other.png +0 -0
- package/static/assets/images/icon_person.png +0 -0
- package/static/assets/images/icon_section.png +0 -0
- package/stats-db.js +45 -0
- package/stats.js +197 -10
- package/testing/testing-template.html +5 -8
- package/token/nginx_passport_setup.md +1 -1
- package/token/security_guide.md +1 -1
- package/token/token-template.html +2 -5
- package/token/token.js +40 -36
- package/translations/Messages.properties +19 -0
- package/tx/README.md +158 -4
- package/tx/closure/closure-store.js +126 -3
- package/tx/cm/cm-database.js +69 -57
- package/tx/cm/cm-package.js +50 -16
- package/tx/cs/cs-api.js +284 -19
- package/tx/cs/cs-api.md +41 -4
- package/tx/cs/cs-areacode.js +1 -1
- package/tx/cs/cs-country.js +17 -5
- package/tx/cs/cs-cpt.js +33 -16
- package/tx/cs/cs-cs.js +199 -24
- package/tx/cs/cs-currency.js +1 -1
- package/tx/cs/cs-icd11.js +21 -13
- package/tx/cs/cs-icf.js +22 -3
- package/tx/cs/cs-lang.js +2 -2
- package/tx/cs/cs-loinc.js +193 -67
- package/tx/cs/cs-mimetypes.js +12 -2
- package/tx/cs/cs-ndc.js +40 -25
- package/tx/cs/cs-omop.js +54 -29
- package/tx/cs/cs-rxnorm.js +300 -196
- package/tx/cs/cs-snomed.js +861 -95
- package/tx/cs/cs-ucum.js +14 -4
- package/tx/cs/cs-unii.js +18 -14
- package/tx/cs/cs-virtual.js +210 -0
- package/tx/ecosystem-resolver.js +413 -0
- package/tx/html/cluster-dash-metrics.liquid +26 -0
- package/tx/html/cluster-home-metrics.liquid +31 -0
- package/tx/html/cluster-metrics-script.liquid +251 -0
- package/tx/html/codesystem-operations.liquid +3 -3
- package/tx/html/ecl-panel.liquid +1 -1
- package/tx/html/external-metrics.liquid +17 -0
- package/tx/html/operations-form.liquid +17 -17
- package/tx/html/search-form.liquid +11 -11
- package/tx/html/status-line.liquid +58 -0
- package/tx/html/status-panel.liquid +140 -0
- package/tx/html/status-tasks.liquid +25 -0
- package/tx/html/tx-template.html +2 -5
- package/tx/importers/atc-to-fhir.js +17 -16
- package/tx/importers/export-icd11-codesystem.js +3 -2
- package/tx/importers/import-icd11.js +4 -3
- package/tx/importers/import-loinc.module.js +118 -56
- package/tx/importers/import-ndc.module.js +56 -44
- package/tx/importers/import-rxnorm.module.js +118 -79
- package/tx/importers/import-sct.module.js +125 -61
- package/tx/importers/import-unii.module.js +37 -36
- package/tx/importers/subset-loinc.module.js +49 -48
- package/tx/importers/subset-rxnorm.module.js +29 -28
- package/tx/importers/terminal.js +18 -0
- package/tx/importers/tx-import-base.js +13 -12
- package/tx/importers/tx-import-settings.js +5 -4
- package/tx/importers/tx-import.js +53 -52
- package/tx/library/canonical-resource.js +49 -0
- package/tx/library/codesystem.js +94 -5
- package/tx/library/designations.js +45 -2
- package/tx/library/extensions.js +13 -7
- package/tx/library/implicit-valuesets.js +66 -0
- package/tx/library/renderer.js +77 -21
- package/tx/library/sqlite-utilities.js +2 -0
- package/tx/library/tho-precedence.js +40 -0
- package/tx/library/ucum-parsers.js +11 -1
- package/tx/library/wait-for-cache.js +43 -0
- package/tx/library.js +321 -22
- package/tx/openapi-operations.js +6 -4
- package/tx/operation-context.js +460 -99
- package/tx/params.js +25 -0
- package/tx/problems.js +3 -5
- package/tx/provider.js +314 -67
- package/tx/resource-cache-sqlite.js +1050 -0
- package/tx/sct/documentation.md +45 -21
- package/tx/sct/ecl.js +81 -17
- package/tx/sct/editions.js +39 -0
- package/tx/sct/expressions.js +10 -1
- package/tx/sct/load-config.js +107 -0
- package/tx/sct/mmap.js +109 -0
- package/tx/sct/structures.js +175 -15
- package/tx/sct/text-index.js +5 -1
- package/tx/syndication/syndication-feed.js +2 -2
- package/tx/tx-html.js +44 -8
- package/tx/tx.fhir.org.yml +8 -8
- package/tx/tx.js +282 -80
- package/tx/usage-tracker.js +39 -11
- package/tx/vs/vs-api.js +19 -0
- package/tx/vs/vs-database.js +386 -62
- package/tx/vs/vs-package.js +44 -17
- package/tx/vs/vs-vsac.js +649 -101
- package/tx/workers/batch-validate.js +37 -10
- package/tx/workers/batch.js +6 -1
- package/tx/workers/cache-control.js +15 -4
- package/tx/workers/closure.js +156 -13
- package/tx/workers/compare.js +8 -5
- package/tx/workers/expand.js +1173 -289
- package/tx/workers/metadata.js +35 -0
- package/tx/workers/search.js +53 -1
- package/tx/workers/supplement-filters.js +145 -0
- package/tx/workers/translate.js +169 -4
- package/tx/workers/validate.js +223 -119
- package/tx/workers/worker.js +123 -31
- package/tx/xversion/xv-valueset.js +7 -4
- package/utilities/submit-test-report.js +3 -1
- package/utilities/tx-stress-test.js +482 -0
- package/vcl/readme.md +37 -0
- package/vcl/vcl-parser.js +15 -0
- package/xig/readme.md +52 -0
- package/xig/xig-template.html +5 -8
- package/xig/xig.js +238 -422
- package/changelog-template.md +0 -22
- package/registry/test-runner.js +0 -237
- package/release.sh +0 -80
- package/test-scripts/repro-re2-wasm-leak.js +0 -34
- package/tsconfig.eslint.json +0 -9
- package/tx/html/dash-metrics.liquid +0 -147
- package/tx/html/home-metrics.liquid +0 -225
package/tx/cs/cs-icd11.js
CHANGED
|
@@ -22,6 +22,7 @@ const { ICD11Expression, parseExpression, axisLabel } = require('./icd11-express
|
|
|
22
22
|
const { Issue } = require('../library/operation-outcome');
|
|
23
23
|
const { DesignationUse } = require('../library/designations');
|
|
24
24
|
const assert = require('assert');
|
|
25
|
+
const { guarded } = require('../library/sqlite-utilities');
|
|
25
26
|
|
|
26
27
|
// WHO's own vocabulary for the kinds of text an entity carries, used as designation.use.
|
|
27
28
|
const SCHEMA_NS = 'http://id.who.int/icd/schema';
|
|
@@ -100,10 +101,7 @@ class ICD11Services extends BaseCSServices {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
close() {
|
|
103
|
-
|
|
104
|
-
this.db.close();
|
|
105
|
-
this.db = null;
|
|
106
|
-
}
|
|
104
|
+
this.closeDb();
|
|
107
105
|
}
|
|
108
106
|
|
|
109
107
|
// -- small promise wrappers, so no query below carries callback boilerplate -----------
|
|
@@ -116,7 +114,7 @@ class ICD11Services extends BaseCSServices {
|
|
|
116
114
|
|
|
117
115
|
#all(sql, params = []) {
|
|
118
116
|
return new Promise((resolve, reject) => {
|
|
119
|
-
this.db.all(sql, params, (err, rows) => err ? reject(err) : resolve(rows || []));
|
|
117
|
+
this.db.all(sql, params, guarded(reject, (err, rows) => err ? reject(err) : resolve(rows || [])));
|
|
120
118
|
});
|
|
121
119
|
}
|
|
122
120
|
|
|
@@ -993,12 +991,22 @@ class ICD11ServicesFactory extends CodeSystemFactoryProvider {
|
|
|
993
991
|
|
|
994
992
|
id() { return `icd11-${this.systemCode}`; }
|
|
995
993
|
|
|
994
|
+
/**
|
|
995
|
+
* The WHO browser page for the concept, as the ICD-API gives it (browserUrl, kept in the
|
|
996
|
+
* database: https://icd.who.int/browse/2026-01/mms/en#257068234). A postcoordinated
|
|
997
|
+
* expression links to its stem.
|
|
998
|
+
*/
|
|
999
|
+
codeLink(context) {
|
|
1000
|
+
const concept = context && context.tokens ? context.tokens[0]?.concept : context;
|
|
1001
|
+
return concept && concept.browserUrl ? concept.browserUrl : undefined;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
996
1004
|
async load() {
|
|
997
1005
|
if (this._loaded) return;
|
|
998
1006
|
const db = new sqlite3.Database(this.dbPath, sqlite3.OPEN_READONLY);
|
|
999
1007
|
try {
|
|
1000
1008
|
const get = (sql, p) => new Promise((res, rej) =>
|
|
1001
|
-
db.get(sql, p, (e, r) => e ? rej(e) : res(r)));
|
|
1009
|
+
db.get(sql, p, guarded(rej, (e, r) => e ? rej(e) : res(r))));
|
|
1002
1010
|
const sys = await get('SELECT * FROM system WHERE code = ?', [this.systemCode]);
|
|
1003
1011
|
if (!sys) {
|
|
1004
1012
|
throw new Error(`ICD-11 database ${this.dbPath} has no '${this.systemCode}' code system`);
|
|
@@ -1007,7 +1015,7 @@ class ICD11ServicesFactory extends CodeSystemFactoryProvider {
|
|
|
1007
1015
|
const langs = await get("SELECT value FROM meta WHERE key = 'languages'", []);
|
|
1008
1016
|
// per-language titles; a database built before system_title existed has none
|
|
1009
1017
|
const all = (sql, p) => new Promise((res, rej) =>
|
|
1010
|
-
db.all(sql, p, (e, r) => e ? rej(e) : res(r || [])));
|
|
1018
|
+
db.all(sql, p, guarded(rej, (e, r) => e ? rej(e) : res(r || []))));
|
|
1011
1019
|
const titles = {};
|
|
1012
1020
|
const hasTitles = await get(
|
|
1013
1021
|
"SELECT 1 x FROM sqlite_master WHERE type = 'table' AND name = 'system_title'", []);
|
|
@@ -1054,8 +1062,8 @@ class ICD11ServicesFactory extends CodeSystemFactoryProvider {
|
|
|
1054
1062
|
|
|
1055
1063
|
const db = new sqlite3.Database(this.dbPath, sqlite3.OPEN_READONLY);
|
|
1056
1064
|
try {
|
|
1057
|
-
const get = (sql, p) => new Promise((res, rej) => db.get(sql, p, (e, r) => e ? rej(e) : res(r)));
|
|
1058
|
-
const all = (sql, p) => new Promise((res, rej) => db.all(sql, p, (e, r) => e ? rej(e) : res(r || [])));
|
|
1065
|
+
const get = (sql, p) => new Promise((res, rej) => db.get(sql, p, guarded(rej, (e, r) => e ? rej(e) : res(r))));
|
|
1066
|
+
const all = (sql, p) => new Promise((res, rej) => db.all(sql, p, guarded(rej, (e, r) => e ? rej(e) : res(r || []))));
|
|
1059
1067
|
const scale = await get(
|
|
1060
1068
|
`SELECT ps.id, ps.axis, ps.axis_name, ps.required, ps.allow_multiple,
|
|
1061
1069
|
c.entity_id, c.code AS stem_code, c.uri AS stem_uri
|
|
@@ -1100,14 +1108,14 @@ class ICD11ServicesFactory extends CodeSystemFactoryProvider {
|
|
|
1100
1108
|
/** Which code systems a given database holds, so the library can register one each. */
|
|
1101
1109
|
static listSystems(dbPath) {
|
|
1102
1110
|
return new Promise((resolve, reject) => {
|
|
1103
|
-
const db = new sqlite3.Database(dbPath, sqlite3.OPEN_READONLY, (err) => {
|
|
1111
|
+
const db = new sqlite3.Database(dbPath, sqlite3.OPEN_READONLY, guarded(reject, (err) => {
|
|
1104
1112
|
if (err) { reject(new Error(`cannot open ICD-11 database ${dbPath}: ${err.message}`)); return; }
|
|
1105
|
-
db.all('SELECT code, url, version, title FROM system ORDER BY code', (e, rows) => {
|
|
1113
|
+
db.all('SELECT code, url, version, title FROM system ORDER BY code', guarded(reject, (e, rows) => {
|
|
1106
1114
|
db.close();
|
|
1107
1115
|
if (e) reject(new Error(`${dbPath} is not an ICD-11 database: ${e.message}`));
|
|
1108
1116
|
else resolve(rows || []);
|
|
1109
|
-
});
|
|
1110
|
-
});
|
|
1117
|
+
}));
|
|
1118
|
+
}));
|
|
1111
1119
|
});
|
|
1112
1120
|
}
|
|
1113
1121
|
}
|
package/tx/cs/cs-icf.js
CHANGED
|
@@ -195,9 +195,23 @@ class IcfCodeSystemProvider extends FhirCodeSystemProvider {
|
|
|
195
195
|
return ctxt instanceof IcfQualifiedContext ? ctxt.qualifiedCode : super.code(ctxt);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
/**
|
|
198
|
+
/**
|
|
199
|
+
* A qualified code's display is the one an extension-codes supplement in scope gives it, if one
|
|
200
|
+
* does. Otherwise it is generated: the category's display, then the qualifiers' displays, leaving
|
|
201
|
+
* out any 8 (not specified).
|
|
202
|
+
*/
|
|
199
203
|
async display(context) {
|
|
200
204
|
const ctxt = await this.#resolve(context);
|
|
205
|
+
if (ctxt instanceof IcfQualifiedContext) {
|
|
206
|
+
const ext = this._extensionCodeDisplay(ctxt.qualifiedCode);
|
|
207
|
+
if (ext) {
|
|
208
|
+
return ext;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return this.#generatedDisplay(ctxt);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async #generatedDisplay(ctxt) {
|
|
201
215
|
const display = await super.display(ctxt);
|
|
202
216
|
if (!(ctxt instanceof IcfQualifiedContext)) {
|
|
203
217
|
return display;
|
|
@@ -207,14 +221,19 @@ class IcfCodeSystemProvider extends FhirCodeSystemProvider {
|
|
|
207
221
|
return parts.length > 0 ? display + ': ' + parts.join(', ') : display;
|
|
208
222
|
}
|
|
209
223
|
|
|
210
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* A qualified code's designations: the display an extension-codes supplement in scope gives it
|
|
226
|
+
* (first, so it is the preferred display), and its generated display, which stays a valid one. The
|
|
227
|
+
* category's translations do not describe it.
|
|
228
|
+
*/
|
|
211
229
|
async designations(context, displays) {
|
|
212
230
|
const ctxt = await this.#resolve(context);
|
|
213
231
|
if (!(ctxt instanceof IcfQualifiedContext)) {
|
|
214
232
|
return super.designations(ctxt, displays);
|
|
215
233
|
}
|
|
234
|
+
this._listSupplementDesignations(ctxt.qualifiedCode, displays, true);
|
|
216
235
|
const lang = this.defaultLanguage ? this.defaultLanguage.toString() : null;
|
|
217
|
-
displays.addDesignation(true, 'active', lang, CodeSystem.makeUseForDisplay(), await this
|
|
236
|
+
displays.addDesignation(true, 'active', lang, CodeSystem.makeUseForDisplay(), await this.#generatedDisplay(ctxt));
|
|
218
237
|
}
|
|
219
238
|
|
|
220
239
|
/**
|
package/tx/cs/cs-lang.js
CHANGED
|
@@ -75,7 +75,7 @@ class IETFLanguageCodeFilter {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/** Why a code did not match, for the caller. @returns {string} */
|
|
78
|
-
describe(code
|
|
78
|
+
describe(code) {
|
|
79
79
|
const action = this.status ? 'does not contain' : 'contains';
|
|
80
80
|
const requirement = this.status ? 'required' : 'not allowed';
|
|
81
81
|
return `The language code ${code} ${action} a ${this.component}, and it is ${requirement}`;
|
|
@@ -101,7 +101,7 @@ class IETFLanguageEqualityFilter {
|
|
|
101
101
|
return value.toLowerCase() === this.value.toLowerCase();
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
describe(code
|
|
104
|
+
describe(code) {
|
|
105
105
|
return `The language code ${code} does not have a ${this.component} of '${this.value}'`;
|
|
106
106
|
}
|
|
107
107
|
}
|