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.
Files changed (277) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/FHIRsmith.png +0 -0
  3. package/README.md +277 -0
  4. package/config-template.json +144 -0
  5. package/library/folder-setup.js +58 -0
  6. package/library/html-server.js +166 -0
  7. package/library/html.js +835 -0
  8. package/library/i18nsupport.js +259 -0
  9. package/library/languages.js +779 -0
  10. package/library/logger-telnet.js +205 -0
  11. package/library/logger.js +279 -0
  12. package/library/package-manager.js +876 -0
  13. package/library/utilities.js +196 -0
  14. package/library/version-utilities.js +1056 -0
  15. package/npmprojector/config-example.json +13 -0
  16. package/npmprojector/indexer.js +394 -0
  17. package/npmprojector/npmprojector.js +395 -0
  18. package/npmprojector/readme.md +174 -0
  19. package/npmprojector/watcher.js +335 -0
  20. package/package.json +119 -0
  21. package/packages/package-crawler.js +846 -0
  22. package/packages/packages-template.html +126 -0
  23. package/packages/packages.js +2838 -0
  24. package/passwords.ini +2 -0
  25. package/publisher/publisher-template.html +208 -0
  26. package/publisher/publisher.js +2167 -0
  27. package/publisher/task-draft.js +458 -0
  28. package/registry/api.js +735 -0
  29. package/registry/crawler.js +637 -0
  30. package/registry/model.js +513 -0
  31. package/registry/readme.md +243 -0
  32. package/registry/registry-data.json +121015 -0
  33. package/registry/registry-template.html +126 -0
  34. package/registry/registry.js +1395 -0
  35. package/registry/test-runner.js +237 -0
  36. package/root-template.html +124 -0
  37. package/server.js +524 -0
  38. package/shl/private-key.pem +5 -0
  39. package/shl/public-key.pem +18 -0
  40. package/shl/shl.js +1125 -0
  41. package/shl/vhl.js +69 -0
  42. package/static/FHIRsmith128.png +0 -0
  43. package/static/FHIRsmith16.png +0 -0
  44. package/static/FHIRsmith32.png +0 -0
  45. package/static/FHIRsmith64.png +0 -0
  46. package/static/assets/css/bootstrap-fhir.css +5302 -0
  47. package/static/assets/css/bootstrap-glyphicons.css +2 -0
  48. package/static/assets/css/bootstrap.css +4097 -0
  49. package/static/assets/css/jquery-ui.css +523 -0
  50. package/static/assets/css/jquery-ui.structure.css +863 -0
  51. package/static/assets/css/jquery-ui.structure.min.css +5 -0
  52. package/static/assets/css/jquery-ui.theme.css +439 -0
  53. package/static/assets/css/jquery-ui.theme.min.css +5 -0
  54. package/static/assets/css/jquery.ui.all.css +7 -0
  55. package/static/assets/css/modules.css +18 -0
  56. package/static/assets/css/project.css +367 -0
  57. package/static/assets/css/pygments-manni.css +66 -0
  58. package/static/assets/css/tags.css +74 -0
  59. package/static/assets/css/xml.css +2 -0
  60. package/static/assets/fonts/glyphiconshalflings-regular.eot +0 -0
  61. package/static/assets/fonts/glyphiconshalflings-regular.otf +0 -0
  62. package/static/assets/fonts/glyphiconshalflings-regular.svg +175 -0
  63. package/static/assets/fonts/glyphiconshalflings-regular.ttf +0 -0
  64. package/static/assets/fonts/glyphiconshalflings-regular.woff +0 -0
  65. package/static/assets/ico/apple-touch-icon-114-precomposed.png +0 -0
  66. package/static/assets/ico/apple-touch-icon-144-precomposed.png +0 -0
  67. package/static/assets/ico/apple-touch-icon-57-precomposed.png +0 -0
  68. package/static/assets/ico/apple-touch-icon-72-precomposed.png +0 -0
  69. package/static/assets/ico/favicon.ico +0 -0
  70. package/static/assets/ico/favicon.png +0 -0
  71. package/static/assets/images/fhir-logo-www.png +0 -0
  72. package/static/assets/images/fhir-logo.png +0 -0
  73. package/static/assets/images/hl7-logo.png +0 -0
  74. package/static/assets/images/logo_ansinew.jpg +0 -0
  75. package/static/assets/images/search.png +0 -0
  76. package/static/assets/images/stripe.png +0 -0
  77. package/static/assets/images/target.png +0 -0
  78. package/static/assets/images/tx-registry-root.gif +0 -0
  79. package/static/assets/images/tx-registry.png +0 -0
  80. package/static/assets/images/tx-server.png +0 -0
  81. package/static/assets/images/tx-version.png +0 -0
  82. package/static/assets/js/bootstrap.min.js +6 -0
  83. package/static/assets/js/fhir-gw.js +259 -0
  84. package/static/assets/js/fhir.js +2 -0
  85. package/static/assets/js/html5shiv.js +8 -0
  86. package/static/assets/js/jcookie.js +96 -0
  87. package/static/assets/js/jquery-ui.min.js +6 -0
  88. package/static/assets/js/jquery.js +10716 -0
  89. package/static/assets/js/jquery.min.js +2 -0
  90. package/static/assets/js/jquery.ui.core.js +314 -0
  91. package/static/assets/js/jquery.ui.draggable.js +825 -0
  92. package/static/assets/js/jquery.ui.mouse.js +162 -0
  93. package/static/assets/js/jquery.ui.resizable.js +842 -0
  94. package/static/assets/js/jquery.ui.widget.js +268 -0
  95. package/static/assets/js/json2.js +487 -0
  96. package/static/assets/js/jtip.js +97 -0
  97. package/static/assets/js/respond.min.js +6 -0
  98. package/static/assets/js/statuspage.js +70 -0
  99. package/static/assets/js/xml.js +2 -0
  100. package/static/dist/js/bootstrap.js +1964 -0
  101. package/static/favicon.png +0 -0
  102. package/static/fhir.css +626 -0
  103. package/static/icon-fhir-16.png +0 -0
  104. package/static/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  105. package/static/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  106. package/static/images/ui-bg_flat_10_000000_40x100.png +0 -0
  107. package/static/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  108. package/static/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  109. package/static/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  110. package/static/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  111. package/static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  112. package/static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  113. package/static/images/ui-icons_222222_256x240.png +0 -0
  114. package/static/images/ui-icons_228ef1_256x240.png +0 -0
  115. package/static/images/ui-icons_ef8c08_256x240.png +0 -0
  116. package/static/images/ui-icons_ffd27a_256x240.png +0 -0
  117. package/static/images/ui-icons_ffffff_256x240.png +0 -0
  118. package/static/js/jquery.effects.blind.js +49 -0
  119. package/static/js/jquery.effects.bounce.js +78 -0
  120. package/static/js/jquery.effects.clip.js +54 -0
  121. package/static/js/jquery.effects.core.js +763 -0
  122. package/static/js/jquery.effects.drop.js +50 -0
  123. package/static/js/jquery.effects.explode.js +79 -0
  124. package/static/js/jquery.effects.fade.js +32 -0
  125. package/static/js/jquery.effects.fold.js +56 -0
  126. package/static/js/jquery.effects.highlight.js +50 -0
  127. package/static/js/jquery.effects.pulsate.js +51 -0
  128. package/static/js/jquery.effects.scale.js +178 -0
  129. package/static/js/jquery.effects.shake.js +57 -0
  130. package/static/js/jquery.effects.slide.js +50 -0
  131. package/static/js/jquery.effects.transfer.js +45 -0
  132. package/static/js/jquery.ui.accordion.js +611 -0
  133. package/static/js/jquery.ui.autocomplete.js +612 -0
  134. package/static/js/jquery.ui.button.js +416 -0
  135. package/static/js/jquery.ui.datepicker.js +1823 -0
  136. package/static/js/jquery.ui.dialog.js +878 -0
  137. package/static/js/jquery.ui.droppable.js +296 -0
  138. package/static/js/jquery.ui.position.js +252 -0
  139. package/static/js/jquery.ui.progressbar.js +109 -0
  140. package/static/js/jquery.ui.selectable.js +266 -0
  141. package/static/js/jquery.ui.slider.js +666 -0
  142. package/static/js/jquery.ui.sortable.js +1077 -0
  143. package/static/js/jquery.ui.tabs.js +758 -0
  144. package/stats.js +80 -0
  145. package/test-cache/vsac/vsac-valuesets.db +0 -0
  146. package/token/nginx_passport_setup.md +383 -0
  147. package/token/security_guide.md +294 -0
  148. package/token/token-template.html +330 -0
  149. package/token/token.js +1300 -0
  150. package/translations/Messages.properties +1510 -0
  151. package/translations/Messages_ar.properties +1399 -0
  152. package/translations/Messages_de.properties +836 -0
  153. package/translations/Messages_es.properties +737 -0
  154. package/translations/Messages_fr.properties +1 -0
  155. package/translations/Messages_ja.properties +893 -0
  156. package/translations/Messages_nl.properties +1357 -0
  157. package/translations/Messages_pt.properties +1302 -0
  158. package/translations/Messages_ru.properties +1 -0
  159. package/translations/Messages_uz.properties +1 -0
  160. package/translations/Messages_zh.properties +1 -0
  161. package/translations/rendering-phrases.properties +1128 -0
  162. package/translations/rendering-phrases_ar.properties +1091 -0
  163. package/translations/rendering-phrases_de.properties +6 -0
  164. package/translations/rendering-phrases_es.properties +6 -0
  165. package/translations/rendering-phrases_fr.properties +624 -0
  166. package/translations/rendering-phrases_ja.properties +21 -0
  167. package/translations/rendering-phrases_nl.properties +970 -0
  168. package/translations/rendering-phrases_pt.properties +1020 -0
  169. package/translations/rendering-phrases_ru.properties +1094 -0
  170. package/translations/rendering-phrases_uz.properties +1 -0
  171. package/translations/rendering-phrases_zh.properties +1 -0
  172. package/tx/README.md +418 -0
  173. package/tx/cm/cm-api.js +110 -0
  174. package/tx/cm/cm-database.js +735 -0
  175. package/tx/cm/cm-package.js +325 -0
  176. package/tx/cs/cs-api.js +789 -0
  177. package/tx/cs/cs-areacode.js +615 -0
  178. package/tx/cs/cs-country.js +1110 -0
  179. package/tx/cs/cs-cpt.js +785 -0
  180. package/tx/cs/cs-cs.js +1579 -0
  181. package/tx/cs/cs-currency.js +539 -0
  182. package/tx/cs/cs-db.js +1321 -0
  183. package/tx/cs/cs-hgvs.js +329 -0
  184. package/tx/cs/cs-lang.js +465 -0
  185. package/tx/cs/cs-loinc.js +1485 -0
  186. package/tx/cs/cs-mimetypes.js +238 -0
  187. package/tx/cs/cs-ndc.js +704 -0
  188. package/tx/cs/cs-omop.js +1025 -0
  189. package/tx/cs/cs-provider-api.js +43 -0
  190. package/tx/cs/cs-provider-list.js +37 -0
  191. package/tx/cs/cs-rxnorm.js +808 -0
  192. package/tx/cs/cs-snomed.js +1102 -0
  193. package/tx/cs/cs-ucum.js +514 -0
  194. package/tx/cs/cs-unii.js +271 -0
  195. package/tx/cs/cs-uri.js +218 -0
  196. package/tx/cs/cs-usstates.js +305 -0
  197. package/tx/dev.fhir.org.yml +14 -0
  198. package/tx/fixtures/test-cases-setup.json +18 -0
  199. package/tx/fixtures/test-cases.yml +16 -0
  200. package/tx/html/codesystem-operations.liquid +25 -0
  201. package/tx/html/home-metrics.liquid +247 -0
  202. package/tx/html/operations-form.liquid +148 -0
  203. package/tx/html/search-form.liquid +62 -0
  204. package/tx/html/tx-template.html +133 -0
  205. package/tx/html/valueset-operations.liquid +54 -0
  206. package/tx/importers/atc-to-fhir.js +316 -0
  207. package/tx/importers/import-loinc.module.js +1536 -0
  208. package/tx/importers/import-ndc.module.js +1088 -0
  209. package/tx/importers/import-rxnorm.module.js +898 -0
  210. package/tx/importers/import-sct.module.js +2457 -0
  211. package/tx/importers/import-unii.module.js +601 -0
  212. package/tx/importers/readme.md +453 -0
  213. package/tx/importers/subset-loinc.module.js +1081 -0
  214. package/tx/importers/subset-rxnorm.module.js +938 -0
  215. package/tx/importers/tx-import-base.js +351 -0
  216. package/tx/importers/tx-import-settings.js +310 -0
  217. package/tx/importers/tx-import.js +357 -0
  218. package/tx/library/canonical-resource.js +88 -0
  219. package/tx/library/capabilitystatement.js +292 -0
  220. package/tx/library/codesystem.js +774 -0
  221. package/tx/library/conceptmap.js +568 -0
  222. package/tx/library/designations.js +932 -0
  223. package/tx/library/errors.js +77 -0
  224. package/tx/library/extensions.js +117 -0
  225. package/tx/library/namingsystem.js +322 -0
  226. package/tx/library/operation-outcome.js +127 -0
  227. package/tx/library/parameters.js +105 -0
  228. package/tx/library/renderer.js +1559 -0
  229. package/tx/library/terminologycapabilities.js +418 -0
  230. package/tx/library/ucum-parsers.js +1029 -0
  231. package/tx/library/ucum-service.js +370 -0
  232. package/tx/library/ucum-types.js +1099 -0
  233. package/tx/library/valueset.js +543 -0
  234. package/tx/library.js +676 -0
  235. package/tx/ocl/cm-ocl.js +106 -0
  236. package/tx/ocl/cs-ocl.js +39 -0
  237. package/tx/ocl/vs-ocl.js +105 -0
  238. package/tx/operation-context.js +568 -0
  239. package/tx/params.js +613 -0
  240. package/tx/provider.js +403 -0
  241. package/tx/sct/ecl.js +1560 -0
  242. package/tx/sct/expressions.js +2077 -0
  243. package/tx/sct/structures.js +1396 -0
  244. package/tx/tx-html.js +1063 -0
  245. package/tx/tx.fhir.org.yml +39 -0
  246. package/tx/tx.js +927 -0
  247. package/tx/vs/vs-api.js +112 -0
  248. package/tx/vs/vs-database.js +786 -0
  249. package/tx/vs/vs-package.js +358 -0
  250. package/tx/vs/vs-vsac.js +366 -0
  251. package/tx/workers/batch-validate.js +129 -0
  252. package/tx/workers/batch.js +361 -0
  253. package/tx/workers/closure.js +32 -0
  254. package/tx/workers/expand.js +1845 -0
  255. package/tx/workers/lookup.js +407 -0
  256. package/tx/workers/metadata.js +467 -0
  257. package/tx/workers/operations.js +34 -0
  258. package/tx/workers/read.js +164 -0
  259. package/tx/workers/search.js +384 -0
  260. package/tx/workers/subsumes.js +334 -0
  261. package/tx/workers/translate.js +492 -0
  262. package/tx/workers/validate.js +2504 -0
  263. package/tx/workers/worker.js +904 -0
  264. package/tx/xml/capabilitystatement-xml.js +63 -0
  265. package/tx/xml/codesystem-xml.js +62 -0
  266. package/tx/xml/conceptmap-xml.js +65 -0
  267. package/tx/xml/namingsystem-xml.js +65 -0
  268. package/tx/xml/operationoutcome-xml.js +127 -0
  269. package/tx/xml/parameters-xml.js +312 -0
  270. package/tx/xml/terminologycapabilities-xml.js +64 -0
  271. package/tx/xml/valueset-xml.js +64 -0
  272. package/tx/xml/xml-base.js +603 -0
  273. package/vcl/vcl-parser.js +1098 -0
  274. package/vcl/vcl.js +253 -0
  275. package/windows-install.js +19 -0
  276. package/xig/xig-template.html +124 -0
  277. package/xig/xig.js +3049 -0
@@ -0,0 +1,789 @@
1
+ /* eslint-disable no-unused-vars */
2
+
3
+ const assert = require('assert');
4
+ const {CodeSystem, CodeSystemContentMode} = require("../library/codesystem");
5
+ const {Languages, Language, LanguageDefinitions} = require("../../library/languages");
6
+ const { OperationContext } = require("../operation-context");
7
+ const {Extensions} = require("../library/extensions");
8
+ const {validateParameter, validateArrayParameter} = require("../../library/utilities");
9
+ const {I18nSupport} = require("../../library/i18nsupport");
10
+ const {VersionUtilities} = require("../../library/version-utilities");
11
+
12
+ class FilterExecutionContext {
13
+ filters = [];
14
+ }
15
+
16
+ class CodeSystemProvider {
17
+
18
+ /**
19
+ * {OperationContext} The context in which this is executing
20
+ */
21
+ opContext;
22
+
23
+ /**
24
+ * @type {CodeSystem[]}
25
+ */
26
+ supplements;
27
+
28
+ constructor(opContext, supplements) {
29
+ this.opContext = opContext;
30
+ this.supplements = supplements;
31
+ this._ensureOpContext(opContext);
32
+ this._validateSupplements();
33
+ }
34
+
35
+ _ensureOpContext(opContext) {
36
+ assert(opContext && opContext instanceof OperationContext, "opContext is not an instance of OperationContext");
37
+ }
38
+
39
+ /**
40
+ * Validates that supplements are CodeSystem instances
41
+ * @private
42
+ */
43
+ _validateSupplements() {
44
+ if (!this.supplements) return;
45
+
46
+ if (!Array.isArray(this.supplements)) {
47
+ throw new Error('Supplements must be an array');
48
+ }
49
+
50
+ this.supplements.forEach((supplement, index) => {
51
+ if (!(supplement instanceof CodeSystem)) {
52
+ throw new Error(`Supplement ${index} must be a CodeSystem instance, got ${typeof supplement}`);
53
+ }
54
+ });
55
+ }
56
+
57
+ /**
58
+ * @section Metadata for the code system
59
+ */
60
+
61
+ /**
62
+ * @returns {string} uri for the code system
63
+ */
64
+ name() { return this.system() + (this.version() ? "|"+this.version() : "") }
65
+
66
+ /**
67
+ * @returns {string} uri for the code system
68
+ */
69
+ system() { throw new Error("Must override"); }
70
+
71
+ /**
72
+ * @returns {string} version for the code system
73
+ */
74
+ version() { throw new Error("Must override"); }
75
+
76
+ vurl() {
77
+ if (this.version()) {
78
+ return this.system()+ "|"+ this.version();
79
+ } else {
80
+ return this.system();
81
+ }
82
+ }
83
+ /**
84
+ * @returns {string} default language for the code system
85
+ */
86
+ defLang() { return 'en' }
87
+
88
+ /**
89
+ * @returns {CodeSystemContentMode} content mode for the CodeSystem
90
+ */
91
+ contentMode() { return CodeSystemContentMode.Complete; }
92
+
93
+ /**
94
+ * @returns {integer} agreed limitation of expansions (see CPT). 0 means no limitation
95
+ */
96
+ expandLimitation() { return 0; }
97
+
98
+ /**
99
+ * @returns {string} description for the code system
100
+ */
101
+ description() { throw new Error("Must override"); }
102
+
103
+ /**
104
+ * @returns {string} source package for the code system, if known
105
+ */
106
+ sourcePackage() { return null; }
107
+
108
+ /**
109
+ * @returns {integer} total number of concepts in the code system
110
+ */
111
+ totalCount() { throw new Error("Must override"); }
112
+
113
+ /**
114
+ * @returns {CodeSystem.property[]} defined properties for the code system
115
+ */
116
+ propertyDefinitions() { return null; }
117
+
118
+ /**
119
+ * returns true if the code system cannot be completely enumerated - e.g. it has a grammar
120
+ * @returns {boolean}
121
+ */
122
+ isNotClosed() {
123
+ return false;
124
+ }
125
+ /**
126
+ * @param {Languages} languages language specification
127
+ * @returns {boolean} defined properties for the code system
128
+ */
129
+ hasAnyDisplays(languages) {
130
+ const langs = this._ensureLanguages(languages);
131
+ return langs.isEnglishOrNothing();
132
+ }
133
+
134
+ resourceLanguageMatches(resource, languages, ifNoLang = false) {
135
+ if (resource.language) {
136
+ const resourceLang = new Language(resource.language);
137
+ for (const requestedLang of languages) {
138
+ if (resourceLang.matchesForDisplay(requestedLang)) {
139
+ return true;
140
+ }
141
+ }
142
+ } else {
143
+ return ifNoLang;
144
+ }
145
+ }
146
+
147
+ _hasAnySupplementDisplays(languages) {
148
+ // Check if any supplements have displays in the requested languages
149
+ if (this.supplements) {
150
+ // displays have preference
151
+ for (const supplement of this.supplements) {
152
+ // Check if supplement language matches and has displays
153
+ if (this.resourceLanguageMatches(supplement.jsonObj, languages, false)) {
154
+ // Check if any concept has a display
155
+ const allConcepts = supplement.getAllConcepts();
156
+ if (allConcepts.some(c => c.display)) {
157
+ return true;
158
+ }
159
+ }
160
+ }
161
+ // Check concept designations for display uses
162
+ for (const supplement of this.supplements) {
163
+ const allConcepts = supplement.getAllConcepts();
164
+ for (const concept of allConcepts) {
165
+ if (concept.designation) {
166
+ for (const designation of concept.designation) {
167
+ if (CodeSystem.isUseADisplay(designation.use)) {
168
+ if (designation.language) {
169
+ const designationLang = new Language(designation.language);
170
+ for (const requestedLang of languages) {
171
+ if (designationLang.matchesForDisplay(requestedLang)) {
172
+ return true;
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+ return false; // nothing in the supplements
183
+ }
184
+
185
+ /**
186
+ * @returns {boolean} true if there's a heirarchy
187
+ */
188
+ hasParents() { return false; }
189
+
190
+ /**
191
+ * @returns {string} true if the code system nominates an enumeration to use in place of iterating (UCUM)
192
+ */
193
+ specialEnumeration() { return null; }
194
+
195
+ /**
196
+ * @param {string} url the supplement of interest
197
+ * @returns {boolean} true if the nominated supplement is in scope
198
+ */
199
+ hasSupplement(url) {
200
+ if (!this.supplements) return false;
201
+ return this.supplements.some(supp => supp.url === url || supp.vurl === url);
202
+ }
203
+
204
+ /**
205
+ * @returns {string[]} all supplements in scope
206
+ */
207
+ listSupplements() {
208
+ return this.supplements ? this.supplements.map(s => s.vurl) : [];
209
+ }
210
+
211
+ /**
212
+ * @returns {Feature[]} applicable Features
213
+ */
214
+ listFeatures() { return null; }
215
+
216
+ /**
217
+ * @param {string} checkVersion - first version
218
+ * @param {string} actualVersion - second version
219
+ * @returns {boolean} True if actualVersion is more detailed than checkVersion (for SCT)
220
+ */
221
+ versionIsMoreDetailed(checkVersion, actualVersion) {
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * @returns { {status, standardsStatus : String, experimental : boolean} } applicable Features
227
+ */
228
+ status() { return {}; }
229
+
230
+ /**
231
+ * @section Getting Information about the concepts in the CodeSystem
232
+ */
233
+
234
+ /**
235
+ * @param {String | CodeSystemProviderContext} code
236
+ * @returns {string} the correct code for the concept specified
237
+ */
238
+ async code(code) {throw new Error("Must override"); }
239
+
240
+ /**
241
+ * @param {String | CodeSystemProviderContext} code
242
+ * @returns {string} the best display given the languages in the operation context
243
+ */
244
+ async display(code) {
245
+ throw new Error("Must override");
246
+ }
247
+
248
+ /**
249
+ * Protected!
250
+ *
251
+
252
+ * @param {String} code
253
+ * @returns {string} the best display given the languages in the operation context
254
+ */
255
+ _displayFromSupplements(code) {
256
+ assert(typeof code === 'string', 'code must be string');
257
+ if (this.supplements) {
258
+ const concepts = [];
259
+ // displays have preference
260
+ for (const supplement of this.supplements) {
261
+ // Check if supplement language matches and has displays
262
+ if (this.resourceLanguageMatches(supplement.jsonObj, this.opContext.langs, false)) {
263
+ // Check if any concept has a display
264
+ const concept= supplement.getConceptByCode(code);
265
+ if (concept) {
266
+ if (concept.display) {
267
+ return concept.display;
268
+ }
269
+ concepts.push(concept);
270
+ }
271
+ }
272
+ }
273
+ // Check concept designations for display uses
274
+ for (const concept in concepts) {
275
+ if (concept.designation) {
276
+ for (const designation of concept.designation) {
277
+ if (CodeSystem.isUseADisplay(designation.use) && this.opContext.langs.hasMatch(designation.language)) {
278
+ return designation.value;
279
+ }
280
+ }
281
+ }
282
+ }
283
+ // still here? try again, for any non-language display
284
+ for (const supplement of this.supplements) {
285
+ if (!supplement.jsonObj.language) {
286
+ const concept= supplement.getConceptByCode(code);
287
+ if (concept && concept.display) {
288
+ return concept.display;
289
+ }
290
+ }
291
+ }
292
+ }
293
+ return null; // nothing in the supplements
294
+ }
295
+
296
+ /**
297
+
298
+ * @param {string | CodeSystemProviderContext} code
299
+ * @returns {string} the definition for the concept (if available)
300
+ */
301
+ async definition(code) {throw new Error("Must override"); }
302
+
303
+ /**
304
+
305
+ * @param {string | CodeSystemProviderContext} code
306
+ * @returns {boolean} if the concept is abstract
307
+ */
308
+ async isAbstract(code) { return false; }
309
+
310
+ /**
311
+
312
+ * @param {string | CodeSystemProviderContext} code
313
+ * @returns {boolean} if the concept is inactive
314
+ */
315
+ async isInactive(code) { return false; }
316
+
317
+ /**
318
+
319
+ * @param {string | CodeSystemProviderContext} code
320
+ * @returns {boolean} if the concept is inactive
321
+ */
322
+ async isDeprecated(code) { return false; }
323
+
324
+ /**
325
+
326
+ * @param {string | CodeSystemProviderContext} code
327
+ * @returns {string} status
328
+ */
329
+ async getStatus(code) { return null; }
330
+
331
+ /**
332
+
333
+ * @param {string | CodeSystemProviderContext} code
334
+ * @returns {string} assigned itemWeight - if there is one
335
+ */
336
+ async itemWeight(code) { return null; }
337
+
338
+ /**
339
+
340
+ * @param {string | CodeSystemProviderContext} code
341
+ * @returns {string} parent, if there is one
342
+ */
343
+ async parent(code) { return null; }
344
+
345
+ /**
346
+ * This is calleed if the designation is not marked with a usual use code indicating that it is considered as a display
347
+ * @param designation
348
+ * @returns {boolean}
349
+ */
350
+ isDisplay(designation) {
351
+ return false;
352
+ }
353
+
354
+ /**
355
+ * @param {string | CodeSystemProviderContext} code
356
+ * @param {ConceptDesignations} designation list
357
+ * @returns {Designation[]} whatever designations exist (in all languages)
358
+ */
359
+ async designations(code, displays) { return null; }
360
+
361
+ _listSupplementDesignations(code, displays) {
362
+ assert(typeof code === 'string', 'code must be string');
363
+
364
+ if (this.supplements) {
365
+ for (const supplement of this.supplements) {
366
+ const concept= supplement.getConceptByCode(code);
367
+ if (concept) {
368
+ if (concept.display) {
369
+ displays.addDesignation(true, 'active', supplement.jsonObj.language, CodeSystem.makeUseForDisplay(), concept.display);
370
+ }
371
+ if (concept.designation) {
372
+ for (const d of concept.designation) {
373
+ let status = Extensions.readString(d, "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status");
374
+ displays.addDesignation(false, status || 'active', d.language, d.use, d.value, d.extension?.length > 0 ? d.extension : []);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+
382
+ /**
383
+
384
+ * @param {string | CodeSystemProviderContext} code
385
+ * @returns {Extension[]} extensions, if any
386
+ */
387
+ async extensions(code) { return null; }
388
+
389
+ /**
390
+
391
+ * @param {string | CodeSystemProviderContext} code
392
+ * @returns {CodeSystem.concept.property[]} list of properties (may be empty)
393
+ */
394
+ async properties(code) { return []; }
395
+
396
+ /**
397
+
398
+ * @param {string | CodeSystemProviderContext} code
399
+ * @returns {string} information about incomplete validation on the concept, if there is any information (SCT)
400
+ */
401
+ async incompleteValidationMessage(code) { return null; }
402
+
403
+ /**
404
+
405
+ * @param {string | CodeSystemProviderContext} a
406
+ * @param {string | CodeSystemProviderContext} b
407
+ * @returns {boolean} true if they're the same
408
+ */
409
+ async sameConcept(a, b) { return false; }
410
+
411
+ /**
412
+ * @section Finding concepts in the CodeSystem
413
+ */
414
+
415
+ /**
416
+
417
+ * @param {string } code
418
+ * @returns {{context : CodeSystemProviderContext, message : String} the result of looking for the code
419
+ */
420
+ async locate(code) { throw new Error("Must override"); }
421
+
422
+ /**
423
+
424
+ * @param {string} code
425
+ * @param {string} parent
426
+ * @param {boolean} disallowParent
427
+ * @returns {{context : CodeSystemProviderContext, message : String} the result of looking for the code in the context of the parent
428
+ */
429
+ async locateIsA(code) {
430
+ if (this.hasParents()) throw new Error("Must override"); else return { context : null, message: "The CodeSystem "+this.name()+" does not have parents"}
431
+ }
432
+
433
+ /**
434
+ iterate all the root concepts
435
+ * @param {string | CodeSystemProviderContext} code
436
+ * @returns {CodeSystemIterator} a handle that can be passed to nextConcept (or null, if it can't be iterated)
437
+ */
438
+ async iterator(code) { return null }
439
+
440
+ /**
441
+ iterate all the concepts
442
+ * @param {string | CodeSystemProviderContext} code
443
+ * @returns {CodeSystemIterator} a handle that can be passed to nextConcept (or null, if it can't be iterated)
444
+ */
445
+ async iteratorAll() {
446
+ if (this.hasParents()) throw new Error("Must override"); else return await this.iterator(null);
447
+ }
448
+
449
+ /**
450
+
451
+ * @param {CodeSystemIterator} context
452
+ * @returns {CodeSystemProviderContext} the next concept, or null
453
+ */
454
+ async nextContext(context) { return null; }
455
+
456
+ /**
457
+
458
+ * @param {string | CodeSystemProviderContext} codeA
459
+ * @param {string | CodeSystemProviderContext} codeB
460
+ * @returns {string} one of: equivalent, subsumes, subsumed-by, and not-subsumed
461
+ */
462
+ async subsumesTest(codeA, codeB) { return 'not-subsumed'; }
463
+
464
+ /**
465
+
466
+ * @param {CodeSystemProviderContext} ctxt the context to add properties for
467
+ * @param {string[]} props the properties requested
468
+ * @param {Parameters} params the parameters response to add to
469
+ */
470
+
471
+ async extendLookup(ctxt, props, params) { }
472
+
473
+ // procedure getCDSInfo(card : TCDSHookCard; langList : THTTPLanguageList; baseURL, code, display : String); virtual;
474
+
475
+ /**
476
+ * returns true if a filter is supported
477
+ *
478
+ * @param {String} prop
479
+ * @param {ValueSetFilterOperator} op
480
+ * @param {String} prop
481
+ * @returns {boolean} true if suppoted
482
+ * */
483
+ async doesFilter(prop, op, value) { return false; }
484
+
485
+ /**
486
+ * gets a single context in which filters will be evaluated. The application doesn't make use of this context;
487
+ * it's only use is to be passed back to the CodeSystem provider so it can make use of it - if it wants
488
+ *
489
+ * @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
+ * @returns {FilterExecutionContext} filter (or null, it no use for this)
491
+ * */
492
+ async getPrepContext(iterate) { return new FilterExecutionContext(); }
493
+
494
+ /**
495
+ * executes a text search filter (whatever that means) and returns a FilterConceptSet
496
+ *
497
+ * throws an exception if the search filter can't be handled
498
+ *
499
+ * @param {FilterExecutionContext} filterContext filtering context
500
+ * @param {String} filter user entered text search
501
+ * @param {boolean} sort ?
502
+ **/
503
+ async searchFilter(filterContext, filter, sort) { throw new Error("Must override"); } // ? must override?
504
+
505
+ /**
506
+ * Used for searching ucum (see specialEnumeration)
507
+ *
508
+ * throws an exception if the search filter can't be handled
509
+ * @param {FilterExecutionContext} filterContext filtering context
510
+ * @param {boolean} sort ?
511
+ **/
512
+ async specialFilter(filterContext, sort) {
513
+ if (this.specialEnumeration()) {
514
+ throw new Error("Must override");
515
+ }
516
+ } // ? must override?
517
+
518
+ /**
519
+ * Get a FilterConceptSet for a value set filter
520
+ *
521
+ * throws an exception if the search filter can't be handled
522
+ *
523
+ * @param {FilterExecutionContext} filterContext filtering context
524
+ * @param {String} prop
525
+ * @param {ValueSetFilterOperator} op
526
+ * @param {String} prop
527
+ **/
528
+ async filter(filterContext, prop, op, value) { throw new Error("Must override"); } // well, only if any filters are actually supported
529
+
530
+ /**
531
+ * called once all the filters have been handled, and iteration is about to happen.
532
+ * this function returns one more filters. If there were multiple filters, but only
533
+ * one FilterConceptSet, then the code system provider has done the join across the
534
+ * filters, otherwise the engine will do so as required
535
+ *
536
+ * @param {FilterExecutionContext} filterContext filtering context
537
+ * @returns {FilterConceptSet[]} filter sets
538
+ **/
539
+ async executeFilters(filterContext) { throw new Error("Must override"); } // well, only if any filters are actually supported
540
+
541
+ /**
542
+ * return how many concepts are in the filter set
543
+ @param {FilterExecutionContext} filterContext filtering context
544
+ @param {FilterConceptSet} set of interest
545
+ @returns {int} number of concepts in the set
546
+ */
547
+ async filterSize(filterContext, set) {throw new Error("Must override"); }
548
+
549
+ /**
550
+ * return true if there's an infinite number of members (or at least, beyond knowing)
551
+ *
552
+ * This is true if the code system defines a grammar
553
+ *
554
+ @param {FilterExecutionContext} filterContext filtering context
555
+ @returns {boolean} true if not closed
556
+ */
557
+ async filtersNotClosed(filterContext) { return false; }
558
+
559
+ /**
560
+ * iterate the filter set. Iteration is forwards only, using the style
561
+ * while (filterMore()) { something(filterConcept()};
562
+ *
563
+ @param {FilterExecutionContext} filterContext filtering context
564
+ @param {FilterConceptSet} set of interest
565
+ @returns {boolean} if there is a concept
566
+ */
567
+ async filterMore(filterContext, set) {throw new Error("Must override"); }
568
+
569
+ /**
570
+ * get the current concept
571
+ *
572
+ @param {FilterExecutionContext} filterContext filtering context
573
+ @param {FilterConceptSet} set of interest
574
+ @returns {CodeSystemProviderContext} if there is a concept
575
+ */
576
+ async filterConcept(filterContext, set) {throw new Error("Must override"); }
577
+
578
+ /**
579
+ * filterLocate - instead of iterating, find a code in the FilterConceptSet
580
+ *
581
+ @param {FilterExecutionContext} filterContext filtering context
582
+ @param {FilterConceptSet} set of interest
583
+ @param {string} code the code to find
584
+ @returns {string | CodeSystemProviderContext} an error explaining why it isn't in the set, or a handle to the concept
585
+ */
586
+ async filterLocate(filterContext, set, code) {throw new Error("Must override"); }
587
+
588
+ /**
589
+ * filterLocate - instead of iterating, find a code in the FilterConceptSet
590
+ *
591
+ @param {FilterExecutionContext} filterContext filtering context
592
+ @param {FilterConceptSet} set of interest
593
+ @param {CodeSystemProviderContext} concept the code to find
594
+ @returns {string | boolean } an error explaining why it isn't in the set, or true if it is
595
+ */
596
+ async filterCheck(filterContext, set, concept) {throw new Error("Must override"); }
597
+
598
+ /**
599
+ * filterFinish - opportunity for the provider to close up and recover resources etc
600
+ *
601
+ @param {FilterExecutionContext} filterContext filtering context
602
+ */
603
+ async filterFinish(filterContext) {
604
+
605
+ }
606
+
607
+ /**
608
+ * register the concept maps that are implicitly defined as part of the code system
609
+ *
610
+ * @param {ConceptMap[]} conceptMaps
611
+ *
612
+ */
613
+ registerConceptMaps(list) {}
614
+
615
+
616
+ /**
617
+ * register the concept maps that are implicitly defined as part of the code system
618
+ *
619
+ * @param {Coding} coding the coding to translate
620
+ * @param {String} target
621
+ * @returns {CodeTranslation[]} the list of translations
622
+ */
623
+ async getTranslations(coding, target) { return null;}
624
+
625
+ // ==== Parameter checking methods =========
626
+ _ensureLanguages(param) {
627
+ assert(
628
+ typeof param === 'string' ||
629
+ param instanceof Languages ||
630
+ (Array.isArray(param) && param.every(item => typeof item === 'string')),
631
+ 'Parameter must be string, Languages object, or array of strings'
632
+ );
633
+
634
+ if (typeof param === 'string') {
635
+ return Languages.fromAcceptLanguage(param, this.languageDefinitions, false);
636
+ } else if (Array.isArray(param)) {
637
+ const languages = new Languages();
638
+ for (const str of param) {
639
+ const lang = new Language(str);
640
+ languages.add(lang);
641
+ }
642
+ return languages;
643
+ } else {
644
+ return param; // Already a Languages object
645
+ }
646
+ }
647
+
648
+ /**
649
+ * @returns {String} the version algorithm for this version of the code system
650
+ */
651
+ versionAlgorithm() {
652
+ return null;
653
+ }
654
+
655
+ versionNeeded() {
656
+ return false;
657
+ }
658
+
659
+ /**
660
+ * @returns {string} valueset for the code system
661
+ */
662
+ valueSet() {
663
+ return null;
664
+ }
665
+ }
666
+
667
+ class CodeSystemFactoryProvider {
668
+ uses = 0;
669
+
670
+ /**
671
+ * {I18nSupport}
672
+ */
673
+ i18n;
674
+
675
+ constructor(i18n) {
676
+ validateParameter(i18n, "i18n", I18nSupport);
677
+
678
+ this.i18n = i18n;
679
+ }
680
+
681
+
682
+ /**
683
+ * @returns {String} the latest version, if known
684
+ */
685
+ defaultVersion() { throw new Error("Must override"); }
686
+
687
+ async load() {
688
+ // nothing here
689
+ }
690
+
691
+ /**
692
+
693
+ * @param {CodeSystem[]} supplements any supplements that are in scope
694
+ * @returns {CodeSystemProvider} a built provider - or an exception
695
+ */
696
+ build(opContext, supplements) { throw new Error("Must override Factory"); }
697
+
698
+ /**
699
+ * @returns {string} uri for the code system
700
+ */
701
+ system() {
702
+ throw new Error("Must override");
703
+ }
704
+
705
+ /**
706
+ * @returns {string} uri for the code system
707
+ */
708
+ name() {
709
+ throw new Error("Must override");
710
+ }
711
+
712
+ /**
713
+ * @returns {string} version for the code system
714
+ */
715
+ version() { throw new Error("Must override"); }
716
+
717
+ getPartialVersion() {
718
+ let ver = this.version();
719
+ if (ver && VersionUtilities.isSemVer(ver)) {
720
+ return VersionUtilities.getMajMin(ver);
721
+ }
722
+ return ver;
723
+ }
724
+ /**
725
+ * @returns {number} how many times the factory has been asked to construct a provider
726
+ */
727
+ useCount() {return this.uses}
728
+
729
+ recordUse() {
730
+ this.uses++;
731
+ }
732
+
733
+ /**
734
+ * build and return a known value set from the URL, if there is one.
735
+ *
736
+ * @param url
737
+ * @param version
738
+ * @returns {ValueSet}
739
+ */
740
+ async buildKnownValueSet(url, version) {
741
+ return null;
742
+ }
743
+
744
+ /**
745
+ * build and return a known concept map from the URL, if there is one.
746
+ *
747
+ * @param url
748
+ * @param version
749
+ * @returns {ConceptMap}
750
+ */
751
+ async findImplicitConceptMaps(conceptMaps, source, dest) {
752
+ return null;
753
+ }
754
+
755
+ /**
756
+ * build and return a known concept map from the URL, if there is one.
757
+ *
758
+ * @param url
759
+ * @param version
760
+ * @returns {ConceptMap}
761
+ */
762
+ async findImplicitConceptMap(url, version) {
763
+ return null;
764
+ }
765
+
766
+ id() {
767
+ throw new Error("Must override");
768
+ }
769
+
770
+ codeLink(code) {
771
+ return undefined;
772
+ }
773
+
774
+ iteratable() {
775
+ return false;
776
+ }
777
+
778
+ // nothing here - might be overriden
779
+ async close() {
780
+
781
+ }
782
+ }
783
+
784
+ module.exports = {
785
+ FilterExecutionContext,
786
+ CodeSystemProvider,
787
+ CodeSystemContentMode,
788
+ CodeSystemFactoryProvider
789
+ };