fhirsmith 0.3.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 +42 -0
- package/FHIRsmith.png +0 -0
- package/README.md +277 -0
- package/config-template.json +144 -0
- package/library/folder-setup.js +58 -0
- package/library/html-server.js +166 -0
- package/library/html.js +835 -0
- package/library/i18nsupport.js +259 -0
- package/library/languages.js +779 -0
- package/library/logger-telnet.js +205 -0
- package/library/logger.js +279 -0
- package/library/package-manager.js +876 -0
- package/library/utilities.js +196 -0
- package/library/version-utilities.js +1056 -0
- package/npmprojector/config-example.json +13 -0
- package/npmprojector/indexer.js +394 -0
- package/npmprojector/npmprojector.js +395 -0
- package/npmprojector/readme.md +174 -0
- package/npmprojector/watcher.js +335 -0
- package/package.json +119 -0
- package/packages/package-crawler.js +846 -0
- package/packages/packages-template.html +126 -0
- package/packages/packages.js +2838 -0
- package/passwords.ini +2 -0
- package/publisher/publisher-template.html +208 -0
- package/publisher/publisher.js +2167 -0
- package/publisher/task-draft.js +458 -0
- package/registry/api.js +735 -0
- package/registry/crawler.js +637 -0
- package/registry/model.js +513 -0
- package/registry/readme.md +243 -0
- package/registry/registry-data.json +121015 -0
- package/registry/registry-template.html +126 -0
- package/registry/registry.js +1395 -0
- package/registry/test-runner.js +237 -0
- package/root-template.html +124 -0
- package/server.js +524 -0
- package/shl/private-key.pem +5 -0
- package/shl/public-key.pem +18 -0
- package/shl/shl.js +1125 -0
- package/shl/vhl.js +69 -0
- package/static/FHIRsmith128.png +0 -0
- package/static/FHIRsmith16.png +0 -0
- package/static/FHIRsmith32.png +0 -0
- package/static/FHIRsmith64.png +0 -0
- package/static/assets/css/bootstrap-fhir.css +5302 -0
- package/static/assets/css/bootstrap-glyphicons.css +2 -0
- package/static/assets/css/bootstrap.css +4097 -0
- package/static/assets/css/jquery-ui.css +523 -0
- package/static/assets/css/jquery-ui.structure.css +863 -0
- package/static/assets/css/jquery-ui.structure.min.css +5 -0
- package/static/assets/css/jquery-ui.theme.css +439 -0
- package/static/assets/css/jquery-ui.theme.min.css +5 -0
- package/static/assets/css/jquery.ui.all.css +7 -0
- package/static/assets/css/modules.css +18 -0
- package/static/assets/css/project.css +367 -0
- package/static/assets/css/pygments-manni.css +66 -0
- package/static/assets/css/tags.css +74 -0
- package/static/assets/css/xml.css +2 -0
- package/static/assets/fonts/glyphiconshalflings-regular.eot +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.otf +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.svg +175 -0
- package/static/assets/fonts/glyphiconshalflings-regular.ttf +0 -0
- package/static/assets/fonts/glyphiconshalflings-regular.woff +0 -0
- package/static/assets/ico/apple-touch-icon-114-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-144-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-57-precomposed.png +0 -0
- package/static/assets/ico/apple-touch-icon-72-precomposed.png +0 -0
- package/static/assets/ico/favicon.ico +0 -0
- package/static/assets/ico/favicon.png +0 -0
- package/static/assets/images/fhir-logo-www.png +0 -0
- package/static/assets/images/fhir-logo.png +0 -0
- package/static/assets/images/hl7-logo.png +0 -0
- package/static/assets/images/logo_ansinew.jpg +0 -0
- package/static/assets/images/search.png +0 -0
- package/static/assets/images/stripe.png +0 -0
- package/static/assets/images/target.png +0 -0
- package/static/assets/images/tx-registry-root.gif +0 -0
- package/static/assets/images/tx-registry.png +0 -0
- package/static/assets/images/tx-server.png +0 -0
- package/static/assets/images/tx-version.png +0 -0
- package/static/assets/js/bootstrap.min.js +6 -0
- package/static/assets/js/fhir-gw.js +259 -0
- package/static/assets/js/fhir.js +2 -0
- package/static/assets/js/html5shiv.js +8 -0
- package/static/assets/js/jcookie.js +96 -0
- package/static/assets/js/jquery-ui.min.js +6 -0
- package/static/assets/js/jquery.js +10716 -0
- package/static/assets/js/jquery.min.js +2 -0
- package/static/assets/js/jquery.ui.core.js +314 -0
- package/static/assets/js/jquery.ui.draggable.js +825 -0
- package/static/assets/js/jquery.ui.mouse.js +162 -0
- package/static/assets/js/jquery.ui.resizable.js +842 -0
- package/static/assets/js/jquery.ui.widget.js +268 -0
- package/static/assets/js/json2.js +487 -0
- package/static/assets/js/jtip.js +97 -0
- package/static/assets/js/respond.min.js +6 -0
- package/static/assets/js/statuspage.js +70 -0
- package/static/assets/js/xml.js +2 -0
- package/static/dist/js/bootstrap.js +1964 -0
- package/static/favicon.png +0 -0
- package/static/fhir.css +626 -0
- package/static/icon-fhir-16.png +0 -0
- package/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- package/static/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- package/static/images/ui-bg_flat_10_000000_40x100.png +0 -0
- package/static/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- package/static/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- package/static/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- package/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- package/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- package/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- package/static/images/ui-icons_222222_256x240.png +0 -0
- package/static/images/ui-icons_228ef1_256x240.png +0 -0
- package/static/images/ui-icons_ef8c08_256x240.png +0 -0
- package/static/images/ui-icons_ffd27a_256x240.png +0 -0
- package/static/images/ui-icons_ffffff_256x240.png +0 -0
- package/static/js/jquery.effects.blind.js +49 -0
- package/static/js/jquery.effects.bounce.js +78 -0
- package/static/js/jquery.effects.clip.js +54 -0
- package/static/js/jquery.effects.core.js +763 -0
- package/static/js/jquery.effects.drop.js +50 -0
- package/static/js/jquery.effects.explode.js +79 -0
- package/static/js/jquery.effects.fade.js +32 -0
- package/static/js/jquery.effects.fold.js +56 -0
- package/static/js/jquery.effects.highlight.js +50 -0
- package/static/js/jquery.effects.pulsate.js +51 -0
- package/static/js/jquery.effects.scale.js +178 -0
- package/static/js/jquery.effects.shake.js +57 -0
- package/static/js/jquery.effects.slide.js +50 -0
- package/static/js/jquery.effects.transfer.js +45 -0
- package/static/js/jquery.ui.accordion.js +611 -0
- package/static/js/jquery.ui.autocomplete.js +612 -0
- package/static/js/jquery.ui.button.js +416 -0
- package/static/js/jquery.ui.datepicker.js +1823 -0
- package/static/js/jquery.ui.dialog.js +878 -0
- package/static/js/jquery.ui.droppable.js +296 -0
- package/static/js/jquery.ui.position.js +252 -0
- package/static/js/jquery.ui.progressbar.js +109 -0
- package/static/js/jquery.ui.selectable.js +266 -0
- package/static/js/jquery.ui.slider.js +666 -0
- package/static/js/jquery.ui.sortable.js +1077 -0
- package/static/js/jquery.ui.tabs.js +758 -0
- package/stats.js +80 -0
- package/test-cache/vsac/vsac-valuesets.db +0 -0
- package/token/nginx_passport_setup.md +383 -0
- package/token/security_guide.md +294 -0
- package/token/token-template.html +330 -0
- package/token/token.js +1300 -0
- package/translations/Messages.properties +1510 -0
- package/translations/Messages_ar.properties +1399 -0
- package/translations/Messages_de.properties +836 -0
- package/translations/Messages_es.properties +737 -0
- package/translations/Messages_fr.properties +1 -0
- package/translations/Messages_ja.properties +893 -0
- package/translations/Messages_nl.properties +1357 -0
- package/translations/Messages_pt.properties +1302 -0
- package/translations/Messages_ru.properties +1 -0
- package/translations/Messages_uz.properties +1 -0
- package/translations/Messages_zh.properties +1 -0
- package/translations/rendering-phrases.properties +1128 -0
- package/translations/rendering-phrases_ar.properties +1091 -0
- package/translations/rendering-phrases_de.properties +6 -0
- package/translations/rendering-phrases_es.properties +6 -0
- package/translations/rendering-phrases_fr.properties +624 -0
- package/translations/rendering-phrases_ja.properties +21 -0
- package/translations/rendering-phrases_nl.properties +970 -0
- package/translations/rendering-phrases_pt.properties +1020 -0
- package/translations/rendering-phrases_ru.properties +1094 -0
- package/translations/rendering-phrases_uz.properties +1 -0
- package/translations/rendering-phrases_zh.properties +1 -0
- package/tx/README.md +418 -0
- package/tx/cm/cm-api.js +110 -0
- package/tx/cm/cm-database.js +735 -0
- package/tx/cm/cm-package.js +325 -0
- package/tx/cs/cs-api.js +789 -0
- package/tx/cs/cs-areacode.js +615 -0
- package/tx/cs/cs-country.js +1110 -0
- package/tx/cs/cs-cpt.js +785 -0
- package/tx/cs/cs-cs.js +1579 -0
- package/tx/cs/cs-currency.js +539 -0
- package/tx/cs/cs-db.js +1321 -0
- package/tx/cs/cs-hgvs.js +329 -0
- package/tx/cs/cs-lang.js +465 -0
- package/tx/cs/cs-loinc.js +1485 -0
- package/tx/cs/cs-mimetypes.js +238 -0
- package/tx/cs/cs-ndc.js +704 -0
- package/tx/cs/cs-omop.js +1025 -0
- package/tx/cs/cs-provider-api.js +43 -0
- package/tx/cs/cs-provider-list.js +37 -0
- package/tx/cs/cs-rxnorm.js +808 -0
- package/tx/cs/cs-snomed.js +1102 -0
- package/tx/cs/cs-ucum.js +514 -0
- package/tx/cs/cs-unii.js +271 -0
- package/tx/cs/cs-uri.js +218 -0
- package/tx/cs/cs-usstates.js +305 -0
- package/tx/dev.fhir.org.yml +14 -0
- package/tx/fixtures/test-cases-setup.json +18 -0
- package/tx/fixtures/test-cases.yml +16 -0
- package/tx/html/codesystem-operations.liquid +25 -0
- package/tx/html/home-metrics.liquid +247 -0
- package/tx/html/operations-form.liquid +148 -0
- package/tx/html/search-form.liquid +62 -0
- package/tx/html/tx-template.html +133 -0
- package/tx/html/valueset-operations.liquid +54 -0
- package/tx/importers/atc-to-fhir.js +316 -0
- package/tx/importers/import-loinc.module.js +1536 -0
- package/tx/importers/import-ndc.module.js +1088 -0
- package/tx/importers/import-rxnorm.module.js +898 -0
- package/tx/importers/import-sct.module.js +2457 -0
- package/tx/importers/import-unii.module.js +601 -0
- package/tx/importers/readme.md +453 -0
- package/tx/importers/subset-loinc.module.js +1081 -0
- package/tx/importers/subset-rxnorm.module.js +938 -0
- package/tx/importers/tx-import-base.js +351 -0
- package/tx/importers/tx-import-settings.js +310 -0
- package/tx/importers/tx-import.js +357 -0
- package/tx/library/canonical-resource.js +88 -0
- package/tx/library/capabilitystatement.js +292 -0
- package/tx/library/codesystem.js +774 -0
- package/tx/library/conceptmap.js +568 -0
- package/tx/library/designations.js +932 -0
- package/tx/library/errors.js +77 -0
- package/tx/library/extensions.js +117 -0
- package/tx/library/namingsystem.js +322 -0
- package/tx/library/operation-outcome.js +127 -0
- package/tx/library/parameters.js +105 -0
- package/tx/library/renderer.js +1559 -0
- package/tx/library/terminologycapabilities.js +418 -0
- package/tx/library/ucum-parsers.js +1029 -0
- package/tx/library/ucum-service.js +370 -0
- package/tx/library/ucum-types.js +1099 -0
- package/tx/library/valueset.js +543 -0
- package/tx/library.js +676 -0
- package/tx/ocl/cm-ocl.js +106 -0
- package/tx/ocl/cs-ocl.js +39 -0
- package/tx/ocl/vs-ocl.js +105 -0
- package/tx/operation-context.js +568 -0
- package/tx/params.js +613 -0
- package/tx/provider.js +403 -0
- package/tx/sct/ecl.js +1560 -0
- package/tx/sct/expressions.js +2077 -0
- package/tx/sct/structures.js +1396 -0
- package/tx/tx-html.js +1063 -0
- package/tx/tx.fhir.org.yml +39 -0
- package/tx/tx.js +927 -0
- package/tx/vs/vs-api.js +112 -0
- package/tx/vs/vs-database.js +786 -0
- package/tx/vs/vs-package.js +358 -0
- package/tx/vs/vs-vsac.js +366 -0
- package/tx/workers/batch-validate.js +129 -0
- package/tx/workers/batch.js +361 -0
- package/tx/workers/closure.js +32 -0
- package/tx/workers/expand.js +1845 -0
- package/tx/workers/lookup.js +407 -0
- package/tx/workers/metadata.js +467 -0
- package/tx/workers/operations.js +34 -0
- package/tx/workers/read.js +164 -0
- package/tx/workers/search.js +384 -0
- package/tx/workers/subsumes.js +334 -0
- package/tx/workers/translate.js +492 -0
- package/tx/workers/validate.js +2504 -0
- package/tx/workers/worker.js +904 -0
- package/tx/xml/capabilitystatement-xml.js +63 -0
- package/tx/xml/codesystem-xml.js +62 -0
- package/tx/xml/conceptmap-xml.js +65 -0
- package/tx/xml/namingsystem-xml.js +65 -0
- package/tx/xml/operationoutcome-xml.js +127 -0
- package/tx/xml/parameters-xml.js +312 -0
- package/tx/xml/terminologycapabilities-xml.js +64 -0
- package/tx/xml/valueset-xml.js +64 -0
- package/tx/xml/xml-base.js +603 -0
- package/vcl/vcl-parser.js +1098 -0
- package/vcl/vcl.js +253 -0
- package/windows-install.js +19 -0
- package/xig/xig-template.html +124 -0
- package/xig/xig.js +3049 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Lookup Worker - Handles CodeSystem $lookup operation
|
|
3
|
+
//
|
|
4
|
+
// GET /CodeSystem/$lookup?{params}
|
|
5
|
+
// POST /CodeSystem/$lookup
|
|
6
|
+
// GET /CodeSystem/{id}/$lookup?{params}
|
|
7
|
+
// POST /CodeSystem/{id}/$lookup
|
|
8
|
+
//
|
|
9
|
+
|
|
10
|
+
const { TerminologyWorker } = require('./worker');
|
|
11
|
+
const { FhirCodeSystemProvider } = require('../cs/cs-cs');
|
|
12
|
+
const { Designations} = require("../library/designations");
|
|
13
|
+
const {TxParameters} = require("../params");
|
|
14
|
+
const {Parameters} = require("../library/parameters");
|
|
15
|
+
const {Issue, OperationOutcome} = require("../library/operation-outcome");
|
|
16
|
+
|
|
17
|
+
class LookupWorker extends TerminologyWorker {
|
|
18
|
+
/**
|
|
19
|
+
* @param {OperationContext} opContext - Operation context
|
|
20
|
+
* @param {Logger} log - Logger instance
|
|
21
|
+
* @param {Provider} provider - Provider for code systems and resources
|
|
22
|
+
* @param {LanguageDefinitions} languages - Language definitions
|
|
23
|
+
* @param {I18nSupport} i18n - Internationalization support
|
|
24
|
+
*/
|
|
25
|
+
constructor(opContext, log, provider, languages, i18n) {
|
|
26
|
+
super(opContext, log, provider, languages, i18n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get operation name
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
opName() {
|
|
34
|
+
return 'lookup';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Static factory method to handle type-level lookup from Express
|
|
39
|
+
* GET/POST /CodeSystem/$lookup
|
|
40
|
+
* @param {express.Request} req - Express request
|
|
41
|
+
* @param {express.Response} res - Express response
|
|
42
|
+
*/
|
|
43
|
+
async handle(req, res) {
|
|
44
|
+
try {
|
|
45
|
+
await this.handleTypeLevelLookup(req, res);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.log(error);
|
|
48
|
+
req.logInfo = this.usedSources.join("|")+" - error"+(error.msgId ? " "+error.msgId : "");
|
|
49
|
+
this.log.error(error);
|
|
50
|
+
const statusCode = error.statusCode || 500;
|
|
51
|
+
const issueCode = error.issueCode || 'exception';
|
|
52
|
+
return res.status(statusCode).json({
|
|
53
|
+
resourceType: 'OperationOutcome',
|
|
54
|
+
issue: [{
|
|
55
|
+
severity: 'error',
|
|
56
|
+
code: issueCode,
|
|
57
|
+
diagnostics: error.message
|
|
58
|
+
}]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Static factory method to handle instance-level lookup from Express
|
|
65
|
+
* GET/POST /CodeSystem/{id}/$lookup
|
|
66
|
+
* @param {express.Request} req - Express request
|
|
67
|
+
* @param {express.Response} res - Express response
|
|
68
|
+
*/
|
|
69
|
+
async handleInstance(req, res) {
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await this.handleInstanceLevelLookup(req, res);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
req.logInfo = this.usedSources.join("|")+" - error"+(error.msgId ? " "+error.msgId : "");
|
|
75
|
+
this.log.error(error);
|
|
76
|
+
const issueCode = error.issueCode || 'exception';
|
|
77
|
+
return res.status(400).json({
|
|
78
|
+
resourceType: 'OperationOutcome',
|
|
79
|
+
issue: [{
|
|
80
|
+
severity: 'error',
|
|
81
|
+
code: issueCode,
|
|
82
|
+
diagnostics: error.message
|
|
83
|
+
}]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Handle type-level lookup: /CodeSystem/$lookup
|
|
90
|
+
* CodeSystem identified by system+version params or coding parameter
|
|
91
|
+
*/
|
|
92
|
+
async handleTypeLevelLookup(req, res) {
|
|
93
|
+
try {
|
|
94
|
+
this.deadCheck('lookup-type-level');
|
|
95
|
+
|
|
96
|
+
// Handle tx-resource and cache-id parameters from Parameters resource
|
|
97
|
+
if (req.body && req.body.resourceType === 'Parameters') {
|
|
98
|
+
this.setupAdditionalResources(req.body);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Parse parameters from request
|
|
102
|
+
const params = new Parameters(this.buildParameters(req));
|
|
103
|
+
const txp = new TxParameters(this.opContext.i18n.languageDefinitions, this.opContext.i18n);
|
|
104
|
+
txp.readParams(params.jsonObj);
|
|
105
|
+
|
|
106
|
+
// Determine how the code system is identified
|
|
107
|
+
let csProvider;
|
|
108
|
+
let code;
|
|
109
|
+
|
|
110
|
+
if (params.has('coding')) {
|
|
111
|
+
// Coding parameter provided - extract system, version, code
|
|
112
|
+
const coding = params.get('coding');
|
|
113
|
+
if (!coding.system) {
|
|
114
|
+
return res.status(400).json(this.operationOutcome('error', 'invalid',
|
|
115
|
+
'Coding parameter must include a system'));
|
|
116
|
+
}
|
|
117
|
+
if (!coding.code) {
|
|
118
|
+
return res.status(400).json(this.operationOutcome('error', 'invalid',
|
|
119
|
+
'Coding parameter must include a code'));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Allow complete or fragment content modes, nullOk = true to handle not-found ourselves
|
|
123
|
+
csProvider = await this.findCodeSystem(coding.system, coding.version || '', txp, ['complete', 'fragment'], true);
|
|
124
|
+
this.seeSourceProvider(csProvider, coding.system);
|
|
125
|
+
code = coding.code;
|
|
126
|
+
|
|
127
|
+
} else if (params.has('system') && params.has('code')) {
|
|
128
|
+
// system + code parameters
|
|
129
|
+
csProvider = await this.findCodeSystem(params.get('system'), params.get('version') || '', txp, ['complete', 'fragment'], true);
|
|
130
|
+
this.seeSourceProvider(csProvider, params.get('system'));
|
|
131
|
+
code = params.get('code');
|
|
132
|
+
|
|
133
|
+
} else {
|
|
134
|
+
return res.status(400).json(this.operationOutcome('error', 'invalid',
|
|
135
|
+
'Must provide either coding parameter, or system and code parameters'));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!csProvider) {
|
|
139
|
+
const systemUrl = params.system || params.coding?.system;
|
|
140
|
+
const versionStr = params.version || params.coding?.version;
|
|
141
|
+
const msg = versionStr
|
|
142
|
+
? `CodeSystem not found: ${systemUrl} version ${versionStr}`
|
|
143
|
+
: `CodeSystem not found: ${systemUrl}`;
|
|
144
|
+
return res.status(404).json(this.operationOutcome('error', 'not-found', msg));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Perform the lookup
|
|
148
|
+
const result = await this.doLookup(csProvider, code, txp);
|
|
149
|
+
return res.status(200).json(result);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
req.logInfo = this.usedSources.join("|")+" - error"+(error.msgId ? " "+error.msgId : "");
|
|
152
|
+
this.log.error(error);
|
|
153
|
+
if (error instanceof Issue) {
|
|
154
|
+
let oo = new OperationOutcome();
|
|
155
|
+
oo.addIssue(error);
|
|
156
|
+
return res.status(error.statusCode || 500).json(oo.jsonObj);
|
|
157
|
+
} else {
|
|
158
|
+
return res.status(error.statusCode || 500).json(this.operationOutcome(
|
|
159
|
+
'error', error.issueCode || 'exception', error.message));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Handle instance-level lookup: /CodeSystem/{id}/$lookup
|
|
166
|
+
* CodeSystem identified by resource ID
|
|
167
|
+
*/
|
|
168
|
+
async handleInstanceLevelLookup(req, res) {
|
|
169
|
+
try {
|
|
170
|
+
this.deadCheck('lookup-instance-level');
|
|
171
|
+
|
|
172
|
+
const {id} = req.params;
|
|
173
|
+
|
|
174
|
+
// Find the CodeSystem by ID
|
|
175
|
+
let codeSystem = this.provider.getCodeSystemById(this.opContext, id);
|
|
176
|
+
this.seeSourceProvider(codeSystem, id);
|
|
177
|
+
|
|
178
|
+
if (!codeSystem) {
|
|
179
|
+
return res.status(404).json(this.operationOutcome('error', 'not-found',
|
|
180
|
+
`CodeSystem/${id} not found`));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Handle tx-resource and cache-id parameters from Parameters resource
|
|
184
|
+
if (req.body && req.body.resourceType === 'Parameters') {
|
|
185
|
+
this.setupAdditionalResources(req.body);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Parse parameters from request
|
|
189
|
+
const params = new Parameters(this.buildParameters(req));
|
|
190
|
+
const txp = new TxParameters(this.opContext.i18n.languageDefinitions, this.opContext.i18n);
|
|
191
|
+
txp.readParams(params.jsonObj);
|
|
192
|
+
|
|
193
|
+
// For instance-level, code is required (system/version come from the resource)
|
|
194
|
+
let code;
|
|
195
|
+
if (params.has('coding')) {
|
|
196
|
+
code = params.get('coding').code;
|
|
197
|
+
} else if (params.has('code')) {
|
|
198
|
+
code = params.get('code');
|
|
199
|
+
} else {
|
|
200
|
+
return res.status(400).json(this.operationOutcome('error', 'invalid',
|
|
201
|
+
'Must provide code parameter or coding parameter with code'));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Load any supplements
|
|
205
|
+
const supplements = this.loadSupplements(codeSystem.url, codeSystem.version);
|
|
206
|
+
|
|
207
|
+
// Create a FhirCodeSystemProvider for this CodeSystem
|
|
208
|
+
const csProvider = new FhirCodeSystemProvider(this.opContext, codeSystem, supplements);
|
|
209
|
+
|
|
210
|
+
// Perform the lookup
|
|
211
|
+
const result = await this.doLookup(csProvider, code, txp);
|
|
212
|
+
return res.status(200).json(result);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
req.logInfo = this.usedSources.join("|")+" - error"+(error.msgId ? " "+error.msgId : "");
|
|
215
|
+
this.log.error(error);
|
|
216
|
+
if (error instanceof Issue) {
|
|
217
|
+
let oo = new OperationOutcome();
|
|
218
|
+
oo.addIssue(error);
|
|
219
|
+
return res.status(error.statusCode || 500).json(oo.jsonObj);
|
|
220
|
+
} else {
|
|
221
|
+
return res.status(error.statusCode || 500).json(this.operationOutcome(
|
|
222
|
+
'error', error.issueCode || 'exception', error.message));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Perform the actual lookup operation
|
|
229
|
+
* @param {CodeSystemProvider} csProvider - CodeSystem provider
|
|
230
|
+
* @param {string} code - Code to look up
|
|
231
|
+
* @param {Object} params - Parsed parameters
|
|
232
|
+
* @returns {Object} Parameters resource with lookup result
|
|
233
|
+
*/
|
|
234
|
+
async doLookup(csProvider, code, params) {
|
|
235
|
+
this.deadCheck('doLookup');
|
|
236
|
+
|
|
237
|
+
// Helper to check if a property should be included
|
|
238
|
+
const hasProp = (name, defaultValue = true) => {
|
|
239
|
+
if (!params.properties || params.properties.length === 0) {
|
|
240
|
+
return defaultValue;
|
|
241
|
+
}
|
|
242
|
+
const lowerName = name.toLowerCase();
|
|
243
|
+
return params.properties.some(p =>
|
|
244
|
+
p.toLowerCase() === lowerName || p === '*'
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Locate the code in the code system
|
|
249
|
+
const locateResult = await csProvider.locate(code);
|
|
250
|
+
|
|
251
|
+
if (!locateResult || !locateResult.context) {
|
|
252
|
+
const message = locateResult?.message ||
|
|
253
|
+
`Unable to find code '${code}' in ${csProvider.system()} version ${csProvider.version() || 'unknown'}`;
|
|
254
|
+
throw new Issue('error', 'not-found', null, null, message, null, 404);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const ctxt = locateResult.context;
|
|
258
|
+
|
|
259
|
+
// Build the response parameters
|
|
260
|
+
const responseParams = [];
|
|
261
|
+
|
|
262
|
+
// name (required)
|
|
263
|
+
responseParams.push({
|
|
264
|
+
name: 'name',
|
|
265
|
+
valueString: csProvider.name()
|
|
266
|
+
});
|
|
267
|
+
responseParams.push({
|
|
268
|
+
name: 'code',
|
|
269
|
+
valueCode: code
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
responseParams.push({
|
|
273
|
+
name: 'system',
|
|
274
|
+
valueUri: csProvider.system()
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// version (optional)
|
|
278
|
+
const version = csProvider.version();
|
|
279
|
+
if (version) {
|
|
280
|
+
responseParams.push({
|
|
281
|
+
name: 'version',
|
|
282
|
+
valueString: version
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// display (required)
|
|
287
|
+
const display = await csProvider.display(ctxt);
|
|
288
|
+
responseParams.push({
|
|
289
|
+
name: 'display',
|
|
290
|
+
valueString: display || code
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// definition (optional) - top-level parameter
|
|
294
|
+
if (hasProp('definition', true)) {
|
|
295
|
+
const definition = await csProvider.definition(ctxt);
|
|
296
|
+
if (definition) {
|
|
297
|
+
responseParams.push({
|
|
298
|
+
name: 'definition',
|
|
299
|
+
valueString: definition
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// abstract property (optional)
|
|
305
|
+
if (hasProp('abstract', true)) {
|
|
306
|
+
const isAbstract = await csProvider.isAbstract(ctxt);
|
|
307
|
+
responseParams.push({
|
|
308
|
+
name: 'abstract',
|
|
309
|
+
valueBoolean: isAbstract
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// inactive property (optional)
|
|
314
|
+
if (hasProp('inactive', true)) {
|
|
315
|
+
const isInactive = await csProvider.isInactive(ctxt);
|
|
316
|
+
responseParams.push({
|
|
317
|
+
name: 'property',
|
|
318
|
+
part: [
|
|
319
|
+
{ name: 'code', valueCode: 'inactive' },
|
|
320
|
+
{ name: 'value', valueBoolean: isInactive }
|
|
321
|
+
]
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// designations (optional)
|
|
326
|
+
if (hasProp('designation', true)) {
|
|
327
|
+
let designations = new Designations(this.languages);
|
|
328
|
+
await csProvider.designations(ctxt, designations);
|
|
329
|
+
if (designations && Array.isArray(designations.designations)) {
|
|
330
|
+
for (const designation of designations.designations) {
|
|
331
|
+
this.deadCheck('doLookup-designations');
|
|
332
|
+
const designationParts = [];
|
|
333
|
+
|
|
334
|
+
if (designation.language) {
|
|
335
|
+
designationParts.push({
|
|
336
|
+
name: 'language',
|
|
337
|
+
valueCode: designation.language.code
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (designation.use) {
|
|
342
|
+
designationParts.push({
|
|
343
|
+
name: 'use',
|
|
344
|
+
valueCoding: designation.use
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
designationParts.push({
|
|
349
|
+
name: 'value',
|
|
350
|
+
valueString: designation.value
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
responseParams.push({
|
|
354
|
+
name: 'designation',
|
|
355
|
+
part: designationParts
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Let the provider add additional properties
|
|
362
|
+
await csProvider.extendLookup(ctxt, params.property || [], responseParams);
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
resourceType: 'Parameters',
|
|
366
|
+
parameter: responseParams
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Add a property to the response parameters
|
|
372
|
+
* @param {Array} responseParams - Response parameters array
|
|
373
|
+
* @param {string} code - Property code
|
|
374
|
+
* @param {*} value - Property value
|
|
375
|
+
* @param {string} valueType - FHIR value type (e.g., 'valueString', 'valueBoolean')
|
|
376
|
+
*/
|
|
377
|
+
addProperty(responseParams, code, value, valueType) {
|
|
378
|
+
responseParams.push({
|
|
379
|
+
name: 'property',
|
|
380
|
+
part: [
|
|
381
|
+
{ name: 'code', valueCode: code },
|
|
382
|
+
{ name: 'value', [valueType]: value }
|
|
383
|
+
]
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Build an OperationOutcome
|
|
390
|
+
* @param {string} severity - error, warning, information
|
|
391
|
+
* @param {string} code - Issue code
|
|
392
|
+
* @param {string} message - Diagnostic message
|
|
393
|
+
* @returns {Object} OperationOutcome resource
|
|
394
|
+
*/
|
|
395
|
+
operationOutcome(severity, code, message) {
|
|
396
|
+
return {
|
|
397
|
+
resourceType: 'OperationOutcome',
|
|
398
|
+
issue: [{
|
|
399
|
+
severity,
|
|
400
|
+
code,
|
|
401
|
+
diagnostics: message
|
|
402
|
+
}]
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
module.exports = LookupWorker;
|