fhirsmith 0.18.2 → 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.
Files changed (203) hide show
  1. package/ACCESSIBILITY.md +119 -0
  2. package/CHANGELOG.md +149 -0
  3. package/CONFIGURATION.md +305 -0
  4. package/LICENSE +29 -0
  5. package/README.md +29 -122
  6. package/cluster.js +1220 -0
  7. package/cluster.md +707 -0
  8. package/config-template.json +77 -8
  9. package/extension-tracker/extension-tracker-template.html +5 -8
  10. package/extension-tracker/extension-tracker.js +0 -2
  11. package/folder/folder.js +7 -6
  12. package/ips/analysis.js +560 -0
  13. package/ips/ips-template.html +5 -8
  14. package/ips/ips.js +132 -59
  15. package/ips/nationality.js +120 -0
  16. package/ips/pipeline.js +74 -21
  17. package/ips/presenter.js +1 -1
  18. package/ips/readme.md +132 -25
  19. package/ips/render.js +466 -77
  20. package/ips/store.js +79 -22
  21. package/ips/structure.js +247 -0
  22. package/ips/terminology.js +1 -1
  23. package/library/body-limit.js +22 -0
  24. package/library/cache-generation.js +15 -0
  25. package/library/cgroup-memory.js +133 -1
  26. package/library/cluster-counts.js +121 -0
  27. package/library/cluster-events.js +153 -0
  28. package/library/cluster-metrics.js +193 -0
  29. package/library/cluster-status.js +468 -0
  30. package/library/config-reader.js +96 -0
  31. package/library/daily-report.js +100 -2
  32. package/library/html-server.js +27 -1
  33. package/library/i18nsupport.js +23 -1
  34. package/library/keep-alive.js +18 -0
  35. package/library/languages.js +17 -3
  36. package/library/logger.js +31 -0
  37. package/library/memory-guard.js +428 -0
  38. package/library/native-memory.js +52 -0
  39. package/library/npm-audit.js +51 -25
  40. package/library/openapi-doc.js +7 -5
  41. package/library/package-manager.js +8 -0
  42. package/library/role.js +197 -0
  43. package/library/server-credentials.js +169 -0
  44. package/library/sqlite-utilities.js +59 -0
  45. package/library/ssrf-guard.js +100 -0
  46. package/library/static-response-stats.js +16 -0
  47. package/library/version-utilities.js +50 -0
  48. package/library/worker-count.js +192 -0
  49. package/nginx.md +30 -11
  50. package/npmprojector/indexer.js +18 -10
  51. package/package.json +11 -8
  52. package/packages/feed-check-page.js +117 -0
  53. package/packages/feed-check.js +279 -0
  54. package/packages/npm-check.js +57 -3
  55. package/packages/npm-signing.js +219 -0
  56. package/packages/openapi.yaml +207 -1
  57. package/packages/package-crawler.js +322 -41
  58. package/packages/packages-template.html +6 -8
  59. package/packages/packages.js +604 -57
  60. package/packages/readme.md +113 -1
  61. package/publisher/publisher-template.html +2 -5
  62. package/publisher/publisher.js +121 -110
  63. package/publisher/readme.md +75 -0
  64. package/registry/crawler.js +84 -108
  65. package/registry/documentation/configuration.md +34 -0
  66. package/registry/registry-template.html +5 -8
  67. package/registry/registry.js +5 -4
  68. package/root-bare-template.html +7 -4
  69. package/root-template.html +5 -8
  70. package/server.js +398 -198
  71. package/shl/shl.js +38 -37
  72. package/static/a11y/a11y-check.js +832 -0
  73. package/static/a11y/axe.min.js +12 -0
  74. package/static/assets/css/bootstrap-fhir.css +15 -15
  75. package/static/assets/images/flags/au.svg +18 -0
  76. package/static/assets/images/flags/unknown.svg +11 -0
  77. package/static/assets/images/flags/us.svg +63 -0
  78. package/static/assets/images/icon_audit.png +0 -0
  79. package/static/assets/images/icon_clinical.png +0 -0
  80. package/static/assets/images/icon_document.png +0 -0
  81. package/static/assets/images/icon_external.png +0 -0
  82. package/static/assets/images/icon_medication.png +0 -0
  83. package/static/assets/images/icon_organization.png +0 -0
  84. package/static/assets/images/icon_other.png +0 -0
  85. package/static/assets/images/icon_person.png +0 -0
  86. package/static/assets/images/icon_section.png +0 -0
  87. package/stats-db.js +45 -0
  88. package/stats.js +197 -10
  89. package/testing/testing-template.html +5 -8
  90. package/token/nginx_passport_setup.md +1 -1
  91. package/token/security_guide.md +1 -1
  92. package/token/token-template.html +2 -5
  93. package/token/token.js +40 -36
  94. package/translations/Messages.properties +19 -0
  95. package/tx/README.md +154 -4
  96. package/tx/closure/closure-store.js +126 -3
  97. package/tx/cm/cm-database.js +69 -57
  98. package/tx/cm/cm-package.js +29 -1
  99. package/tx/cs/cs-api.js +284 -19
  100. package/tx/cs/cs-api.md +41 -4
  101. package/tx/cs/cs-areacode.js +1 -1
  102. package/tx/cs/cs-country.js +17 -5
  103. package/tx/cs/cs-cpt.js +33 -16
  104. package/tx/cs/cs-cs.js +148 -14
  105. package/tx/cs/cs-currency.js +1 -1
  106. package/tx/cs/cs-icd11.js +21 -13
  107. package/tx/cs/cs-icf.js +22 -3
  108. package/tx/cs/cs-lang.js +2 -2
  109. package/tx/cs/cs-loinc.js +185 -66
  110. package/tx/cs/cs-mimetypes.js +12 -2
  111. package/tx/cs/cs-ndc.js +40 -25
  112. package/tx/cs/cs-omop.js +54 -29
  113. package/tx/cs/cs-rxnorm.js +300 -196
  114. package/tx/cs/cs-snomed.js +608 -64
  115. package/tx/cs/cs-ucum.js +14 -4
  116. package/tx/cs/cs-unii.js +18 -14
  117. package/tx/cs/cs-virtual.js +210 -0
  118. package/tx/ecosystem-resolver.js +413 -0
  119. package/tx/html/cluster-dash-metrics.liquid +26 -0
  120. package/tx/html/cluster-home-metrics.liquid +31 -0
  121. package/tx/html/cluster-metrics-script.liquid +251 -0
  122. package/tx/html/codesystem-operations.liquid +3 -3
  123. package/tx/html/ecl-panel.liquid +1 -1
  124. package/tx/html/external-metrics.liquid +17 -0
  125. package/tx/html/operations-form.liquid +17 -17
  126. package/tx/html/search-form.liquid +11 -11
  127. package/tx/html/status-line.liquid +58 -0
  128. package/tx/html/status-panel.liquid +140 -0
  129. package/tx/html/status-tasks.liquid +25 -0
  130. package/tx/html/tx-template.html +2 -5
  131. package/tx/importers/atc-to-fhir.js +17 -16
  132. package/tx/importers/export-icd11-codesystem.js +3 -2
  133. package/tx/importers/import-icd11.js +4 -3
  134. package/tx/importers/import-loinc.module.js +118 -56
  135. package/tx/importers/import-ndc.module.js +56 -44
  136. package/tx/importers/import-rxnorm.module.js +118 -79
  137. package/tx/importers/import-sct.module.js +57 -58
  138. package/tx/importers/import-unii.module.js +37 -36
  139. package/tx/importers/subset-loinc.module.js +49 -48
  140. package/tx/importers/subset-rxnorm.module.js +29 -28
  141. package/tx/importers/terminal.js +18 -0
  142. package/tx/importers/tx-import-base.js +13 -12
  143. package/tx/importers/tx-import-settings.js +5 -4
  144. package/tx/importers/tx-import.js +53 -52
  145. package/tx/library/canonical-resource.js +49 -0
  146. package/tx/library/codesystem.js +94 -5
  147. package/tx/library/designations.js +45 -2
  148. package/tx/library/extensions.js +13 -7
  149. package/tx/library/implicit-valuesets.js +66 -0
  150. package/tx/library/renderer.js +77 -21
  151. package/tx/library/sqlite-utilities.js +2 -0
  152. package/tx/library/ucum-parsers.js +11 -1
  153. package/tx/library/wait-for-cache.js +43 -0
  154. package/tx/library.js +321 -22
  155. package/tx/openapi-operations.js +6 -4
  156. package/tx/operation-context.js +460 -99
  157. package/tx/params.js +25 -0
  158. package/tx/problems.js +3 -5
  159. package/tx/provider.js +278 -42
  160. package/tx/resource-cache-sqlite.js +1050 -0
  161. package/tx/sct/ecl.js +47 -6
  162. package/tx/sct/editions.js +39 -0
  163. package/tx/sct/expressions.js +10 -1
  164. package/tx/sct/load-config.js +107 -0
  165. package/tx/sct/mmap.js +109 -0
  166. package/tx/sct/structures.js +166 -13
  167. package/tx/sct/text-index.js +5 -1
  168. package/tx/syndication/syndication-feed.js +2 -2
  169. package/tx/tx-html.js +44 -8
  170. package/tx/tx.fhir.org.yml +8 -8
  171. package/tx/tx.js +282 -80
  172. package/tx/usage-tracker.js +39 -11
  173. package/tx/vs/vs-api.js +19 -0
  174. package/tx/vs/vs-database.js +386 -62
  175. package/tx/vs/vs-package.js +27 -4
  176. package/tx/vs/vs-vsac.js +648 -100
  177. package/tx/workers/batch-validate.js +37 -10
  178. package/tx/workers/batch.js +6 -1
  179. package/tx/workers/cache-control.js +15 -4
  180. package/tx/workers/closure.js +156 -13
  181. package/tx/workers/compare.js +8 -5
  182. package/tx/workers/expand.js +1173 -289
  183. package/tx/workers/metadata.js +35 -0
  184. package/tx/workers/search.js +53 -1
  185. package/tx/workers/supplement-filters.js +145 -0
  186. package/tx/workers/translate.js +169 -4
  187. package/tx/workers/validate.js +223 -119
  188. package/tx/workers/worker.js +123 -31
  189. package/tx/xversion/xv-valueset.js +7 -4
  190. package/utilities/submit-test-report.js +3 -1
  191. package/utilities/tx-stress-test.js +482 -0
  192. package/vcl/readme.md +37 -0
  193. package/vcl/vcl-parser.js +15 -0
  194. package/xig/readme.md +52 -0
  195. package/xig/xig-template.html +5 -8
  196. package/xig/xig.js +238 -422
  197. package/changelog-template.md +0 -22
  198. package/registry/test-runner.js +0 -237
  199. package/release.sh +0 -80
  200. package/test-scripts/repro-re2-wasm-leak.js +0 -34
  201. package/tsconfig.eslint.json +0 -9
  202. package/tx/html/dash-metrics.liquid +0 -147
  203. package/tx/html/home-metrics.liquid +0 -225
@@ -1,22 +0,0 @@
1
- ## [m.n.p] - 2026-mm-dd
2
-
3
- ### Security
4
-
5
- -
6
-
7
- ### Added
8
-
9
- -
10
-
11
- ### Changed
12
-
13
- -
14
-
15
- ### Fixed
16
-
17
- -
18
-
19
- ### Tx Conformance Statement
20
-
21
- (paste)
22
-
@@ -1,237 +0,0 @@
1
- // test-runner.js
2
- // Quick test runner to verify the fixes
3
-
4
- const {
5
- ServerRegistries,
6
- ServerRegistry,
7
- ServerInformation,
8
- ServerVersionInformation
9
- } = require('./registry-model');
10
- const RegistryCrawler = require('./registry/crawler');
11
- const RegistryAPI = require('./registry-api');
12
-
13
- // Create sample test data
14
- function createSampleData() {
15
- const data = new ServerRegistries();
16
- data.address = 'https://registry.example.org';
17
- data.lastRun = new Date('2024-01-15T10:00:00Z');
18
- data.outcome = 'Crawled 2 registries successfully, 0 errors';
19
- data.doco = 'Test registry for unit tests';
20
-
21
- // Registry 1: Main Registry
22
- const reg1 = new ServerRegistry();
23
- reg1.code = 'main';
24
- reg1.name = 'Main Terminology Registry';
25
- reg1.address = 'https://main.registry.org';
26
- reg1.authority = 'HL7 International';
27
-
28
- // Server 1.1: TX Server
29
- const server11 = new ServerInformation();
30
- server11.code = 'tx1';
31
- server11.name = 'TX Terminology Server';
32
- server11.address = 'https://tx.fhir.org';
33
- server11.accessInfo = 'Public FHIR terminology server';
34
- server11.authCSList = ['http://loinc.org*', 'http://snomed.info/sct*'];
35
- server11.authVSList = ['http://hl7.org/fhir/ValueSet/loinc*'];
36
- server11.usageList = ['production', 'public'];
37
-
38
- // Version 4.0.1 for TX Server
39
- const version111 = new ServerVersionInformation();
40
- version111.version = '4.0.1';
41
- version111.address = 'https://tx.fhir.org/r4';
42
- version111.security = 'open';
43
- version111.lastSuccess = new Date('2024-01-15T09:55:00Z');
44
- version111.lastTat = '250ms';
45
- version111.codeSystems = [
46
- 'http://loinc.org',
47
- 'http://snomed.info/sct',
48
- 'http://hl7.org/fhir/sid/icd-10',
49
- 'http://www.nlm.nih.gov/research/umls/rxnorm'
50
- ].sort();
51
- version111.valueSets = [
52
- 'http://hl7.org/fhir/ValueSet/observation-codes',
53
- 'http://hl7.org/fhir/ValueSet/condition-code',
54
- 'http://hl7.org/fhir/ValueSet/loinc-diagnostic-report-codes'
55
- ].sort();
56
- server11.versions.push(version111);
57
-
58
- // Version 5.0.0 for TX Server (doesn't have loinc-diagnostic-report-codes)
59
- const version112 = new ServerVersionInformation();
60
- version112.version = '5.0.0';
61
- version112.address = 'https://tx.fhir.org/r5';
62
- version112.security = 'open';
63
- version112.lastSuccess = new Date('2024-01-15T09:56:00Z');
64
- version112.lastTat = '180ms';
65
- version112.codeSystems = [
66
- 'http://loinc.org',
67
- 'http://snomed.info/sct',
68
- 'http://hl7.org/fhir/sid/icd-11'
69
- ].sort();
70
- version112.valueSets = [
71
- 'http://hl7.org/fhir/ValueSet/observation-codes'
72
- ].sort();
73
- server11.versions.push(version112);
74
-
75
- // Server 1.2: Ontoserver
76
- const server12 = new ServerInformation();
77
- server12.code = 'onto';
78
- server12.name = 'Ontoserver';
79
- server12.address = 'https://ontoserver.example.org';
80
- server12.accessInfo = 'Enterprise terminology server';
81
- server12.authCSList = ['http://snomed.info/sct*'];
82
- server12.authVSList = [];
83
- server12.usageList = ['production'];
84
-
85
- const version121 = new ServerVersionInformation();
86
- version121.version = '6.4.0';
87
- version121.address = 'https://ontoserver.example.org/fhir';
88
- version121.security = 'oauth';
89
- version121.lastSuccess = new Date('2024-01-15T09:50:00Z');
90
- version121.lastTat = '180ms';
91
- version121.codeSystems = [
92
- 'http://snomed.info/sct',
93
- 'http://snomed.info/sct/32506021000036107',
94
- 'http://loinc.org'
95
- ].sort();
96
- version121.valueSets = [
97
- 'http://snomed.info/sct?fhir_vs=ecl/<404684003',
98
- 'http://snomed.info/sct?fhir_vs=ecl/<373873005'
99
- ].sort();
100
- server12.versions.push(version121);
101
-
102
- reg1.servers.push(server11);
103
- reg1.servers.push(server12);
104
-
105
- // Registry 2: Test Registry
106
- const reg2 = new ServerRegistry();
107
- reg2.code = 'test';
108
- reg2.name = 'Test Terminology Registry';
109
- reg2.address = 'https://test.registry.org';
110
- reg2.authority = 'Testing Authority';
111
-
112
- // Server 2.1: Test Server with error
113
- const server21 = new ServerInformation();
114
- server21.code = 'test-server';
115
- server21.name = 'Test Server';
116
- server21.address = 'https://test.server.org';
117
- server21.accessInfo = 'Test server (currently down)';
118
-
119
- const version211 = new ServerVersionInformation();
120
- version211.version = '1.0.0';
121
- version211.address = 'https://test.server.org/fhir';
122
- version211.error = 'Connection timeout';
123
- server21.versions.push(version211);
124
-
125
- // Server 2.2: Local Dev Server
126
- const server22 = new ServerInformation();
127
- server22.code = 'local';
128
- server22.name = 'Local Development Server';
129
- server22.address = 'http://localhost:8080';
130
- server22.accessInfo = 'Local development instance';
131
- server22.authCSList = ['http://example.org/codesystem/*'];
132
- server22.authVSList = ['http://example.org/valueset/*'];
133
-
134
- const version221 = new ServerVersionInformation();
135
- version221.version = '5.0.0';
136
- version221.address = 'http://localhost:8080/fhir';
137
- version221.security = 'open';
138
- version221.lastSuccess = new Date('2024-01-15T08:00:00Z');
139
- version221.lastTat = '50ms';
140
- version221.codeSystems = [
141
- 'http://example.org/codesystem/test1',
142
- 'http://example.org/codesystem/test2',
143
- 'http://hl7.org/fhir/sid/icd-10'
144
- ].sort();
145
- version221.valueSets = [
146
- 'http://example.org/valueset/test1',
147
- 'http://example.org/valueset/test2'
148
- ].sort();
149
- server22.versions.push(version221);
150
-
151
- reg2.servers.push(server21);
152
- reg2.servers.push(server22);
153
-
154
- data.registries.push(reg1);
155
- data.registries.push(reg2);
156
-
157
- return data;
158
- }
159
-
160
- // Run specific tests
161
- function runTests() {
162
- const crawler = new RegistryCrawler();
163
- crawler.loadData(createSampleData().toJSON());
164
- const api = new RegistryAPI(crawler);
165
-
166
- console.log('\nRunning problematic tests:\n');
167
-
168
- // Test 1: should return all servers when no filter specified
169
- console.log('Test 1: should return all servers when no filter specified');
170
- const rows1 = api.buildRowsForCodeSystem({});
171
- console.log(` Expected: 4 working versions`);
172
- console.log(` Received: ${rows1.length} versions`);
173
- console.log(` Server codes: ${rows1.map(r => `${r.serverCode}(${r.version})`).join(', ')}`);
174
- console.log(` Test ${rows1.length === 4 ? '✓ PASSED' : '✗ FAILED'}\n`);
175
-
176
- // Test 2: should handle wildcard value set matching
177
- console.log('Test 2: should handle wildcard value set matching');
178
- const rows2 = api.buildRowsForValueSet({
179
- valueSet: 'http://hl7.org/fhir/ValueSet/loinc-diagnostic-report-codes'
180
- });
181
- console.log(` Query: 'http://hl7.org/fhir/ValueSet/loinc-diagnostic-report-codes'`);
182
- console.log(` TX server is authoritative for: 'http://hl7.org/fhir/ValueSet/loinc*'`);
183
- console.log(` Version 4.0.1 HAS this value set`);
184
- console.log(` Version 5.0.0 does NOT have this value set`);
185
- console.log(` Expected: 1 version (4.0.1 which has the value set) OR 2 versions (both authoritative)?`);
186
- console.log(` Received: ${rows2.length} version(s)`);
187
- if (rows2.length > 0) {
188
- console.log(` Versions: ${rows2.map(r => `${r.version} (auth=${r.authoritative})`).join(', ')}`);
189
- }
190
- console.log(` Test ${rows2.length === 1 && rows2[0].version === '4.0.1' ? '✓ PASSED (strict)' : rows2.length === 2 ? '✓ PASSED (lenient)' : '✗ FAILED'}\n`);
191
-
192
- // Test 3: should rank servers without errors higher
193
- console.log('Test 3: should not include servers with errors even if authoritative');
194
- const data = crawler.getData();
195
- const testServer = data.registries[1].servers[0];
196
- testServer.authCSList = ['http://test.org/*'];
197
-
198
- const rows3 = api.buildRowsForCodeSystem({
199
- codeSystem: 'http://test.org/cs'
200
- });
201
- const hasErrorServer = rows3.some(r => r.serverCode === 'test-server');
202
- console.log(` Expected: No test-server in results`);
203
- console.log(` Received: ${hasErrorServer ? 'test-server found' : 'test-server not found'}`);
204
- console.log(` Servers in result: ${rows3.map(r => r.serverCode).join(', ')}`);
205
- console.log(` Test ${!hasErrorServer ? '✓ PASSED' : '✗ FAILED'}\n`);
206
-
207
- // Run all the other tests to make sure we didn't break anything
208
- console.log('Running additional validation tests:\n');
209
-
210
- // Test: Find servers supporting LOINC
211
- const loincRows = api.buildRowsForCodeSystem({
212
- codeSystem: 'http://loinc.org'
213
- });
214
- console.log('Test: Find servers supporting LOINC');
215
- console.log(` Expected: 3 servers (tx1 v4, tx1 v5, onto v6)`);
216
- console.log(` Received: ${loincRows.length} servers`);
217
- console.log(` Test ${loincRows.length === 3 ? '✓ PASSED' : '✗ FAILED'}\n`);
218
-
219
- // Test: Filter by version
220
- const versionRows = api.buildRowsForCodeSystem({
221
- version: '4.0',
222
- codeSystem: 'http://loinc.org'
223
- });
224
- console.log('Test: Filter by version 4.0');
225
- console.log(` Expected: 1 server (version 4.0.1)`);
226
- console.log(` Received: ${versionRows.length} server(s)`);
227
- if (versionRows.length > 0) {
228
- console.log(` Version: ${versionRows[0].version}`);
229
- }
230
- console.log(` Test ${versionRows.length === 1 && versionRows[0].version === '4.0.1' ? '✓ PASSED' : '✗ FAILED'}\n`);
231
-
232
- console.log('================================');
233
- console.log('Test run complete!');
234
- }
235
-
236
- // Run the tests
237
- runTests();
package/release.sh DELETED
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # Release FHIRsmith: ./release.sh 0.17.0
4
- #
5
- # Checks that the release is ready, submits the tx test report to the /testing server, then
6
- # tags the release and pushes the tag (which starts .github/workflows/release.yml).
7
- # Stops at the first problem, before anything is tagged.
8
- #
9
- # The test report: run the tx tests first (npx jest tests/tx/test-cases.test.js). If the
10
- # /testing server needs a token, set FHIRSMITH_TESTING_TOKEN.
11
-
12
- set -euo pipefail
13
-
14
- fail() {
15
- echo "gr.sh: $*" >&2
16
- exit 1
17
- }
18
-
19
- [ $# -eq 1 ] || fail "usage: ./gr.sh <version>, e.g. ./gr.sh 0.17.0"
20
- VERSION="${1#v}"
21
- TAG="v$VERSION"
22
- [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "'$1' is not a release version (X.Y.Z)"
23
-
24
- cd "$(dirname "$0")"
25
-
26
- # --- git: on main, nothing uncommitted, and exactly what is on GitHub -------------------
27
- [ "$(git rev-parse --abbrev-ref HEAD)" = "main" ] || fail "not on main"
28
- [ -z "$(git status --porcelain --untracked-files=no)" ] || fail "there are uncommitted changes"
29
- git fetch --quiet origin main --tags
30
- [ "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)" ] \
31
- || fail "main is not the same as origin/main - push (or pull) first, so the tag is on a commit GitHub has"
32
- ! git rev-parse -q --verify "refs/tags/$TAG" >/dev/null || fail "tag $TAG already exists"
33
-
34
- # --- versions: what release.yml's verify-version job checks ----------------------------
35
- check_version() {
36
- local what="$1" found="$2"
37
- [ "$found" = "$VERSION" ] || fail "$what is '$found', not $VERSION (npm version --no-git-tag-version $VERSION && npm install --package-lock-only)"
38
- }
39
- check_version "package.json version" "$(node -p "require('./package.json').version")"
40
- check_version "package-lock.json version" "$(node -p "require('./package-lock.json').version")"
41
- check_version 'package-lock.json packages[""]' "$(node -p "require('./package-lock.json').packages[''].version")"
42
-
43
- # --- CHANGELOG: a dated section for this version, with the conformance statement in -----
44
- HEADING=$(grep -E "^## \[v?${VERSION//./\\.}\]" CHANGELOG.md || true)
45
- [ -n "$HEADING" ] || fail "CHANGELOG.md has no section for $VERSION"
46
- [[ "$HEADING" =~ [0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || fail "the CHANGELOG.md section for $VERSION has no date: $HEADING"
47
- SECTION=$(sed -n "/^## \[v\{0,1\}${VERSION//./\\.}\]/,/^## \[/p" CHANGELOG.md | sed '$d')
48
- ! grep -qx '(paste)' <<<"$SECTION" || fail "the Tx Conformance Statement for $VERSION hasn't been pasted into CHANGELOG.md"
49
-
50
- # --- the test report: this version, passed, and run on what is being released ----------
51
- REPORT=test-cases-report.json
52
- [ -f "$REPORT" ] || fail "no $REPORT - run the tx tests first (npx jest tests/tx/test-cases.test.js)"
53
- # the last commit that changed what the tests run - not the notes, nor the version bump
54
- CODE_COMMITTED=$(git log -1 --format=%cI -- . ':(exclude)*.md' ':(exclude)release.sh' ':(exclude)package.json' ':(exclude)package-lock.json')
55
- node - "$REPORT" "$VERSION" "$CODE_COMMITTED" <<'NODE' || exit 1
56
- const [file, version, committed] = process.argv.slice(2);
57
- const report = JSON.parse(require('fs').readFileSync(file, 'utf8'));
58
- const fhirsmith = (report.participant || []).find(p => p.uri === 'https://github.com/HealthIntersections/FHIRsmith');
59
- const problems = [];
60
- if (!fhirsmith || fhirsmith.version !== version) {
61
- problems.push(`it is from FHIRsmith ${fhirsmith ? fhirsmith.version : '(unknown)'}, not ${version}`);
62
- }
63
- if (report.result !== 'pass') {
64
- problems.push(`its result is '${report.result}', not 'pass'`);
65
- }
66
- if (!report.issued || new Date(report.issued) < new Date(committed)) {
67
- problems.push(`it was run (${report.issued}) before the last change to the code (${committed})`);
68
- }
69
- if (problems.length > 0) {
70
- console.error(`gr.sh: ${file} can't be submitted for ${version}: ${problems.join('; ')} - run the tx tests again`);
71
- process.exit(1);
72
- }
73
- NODE
74
-
75
- # --- submit the report, then tag ---------------------------------------------------------
76
- node utilities/submit-test-report.js -file "$REPORT" || fail "the test report was not accepted, so $TAG has not been tagged"
77
-
78
- git tag -a "$TAG" -m "FHIRsmith $VERSION"
79
- git push origin "$TAG"
80
- echo "Tagged and pushed $TAG - the release workflow is now running"
@@ -1,34 +0,0 @@
1
- // Historical reproducer for the re2-wasm WASM heap leak.
2
- // regex-utilities.js now sits on top of re2js (a pure-JS RE2 port), so the
3
- // underlying leak is gone. Kept as a stress test for the compile cache:
4
- //
5
- // node test-scripts/repro-re2-wasm-leak.js # same-pattern stress
6
- // node test-scripts/repro-re2-wasm-leak.js --unique # unique-pattern stress
7
- //
8
- // Background (re2-wasm era): without the cache, same-pattern OOMed at ~2965
9
- // iterations; with the cache, same-pattern ran indefinitely but unique-pattern
10
- // still OOMed because every distinct pattern was a real compile and re2-wasm
11
- // could not free its WASM heap. Under re2js both modes now run indefinitely
12
- // (unique-pattern is bounded only by ordinary V8 heap growth from the cache).
13
-
14
- const re = require('../library/regex-utilities');
15
-
16
- const mode = process.argv.includes('--unique') ? 'unique' : 'same';
17
- const basePattern =
18
- 'CYTO|HL7\\.CYTOGEN|HL7\\.GENETICS|^PATH(\\..*)?|^MOLPATH(\\..*)?|NR STATS|H&P\\.HX\\.LAB|CHALSKIN|LABORDERS';
19
-
20
- console.log(`mode: ${mode}-pattern`);
21
-
22
- let i = 0;
23
- try {
24
- for (;;) {
25
- const pattern = mode === 'unique' ? basePattern + `|UNIQUE${i}` : basePattern;
26
- re.compile(pattern);
27
- i++;
28
- if (i % 100 === 0) console.log(`iter ${i}`);
29
- }
30
- } catch (e) {
31
- console.error(`OOMed at iteration ${i}: ${e.message}`);
32
- process.exit(1);
33
- }
34
-
@@ -1,9 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true, "checkJs": false, "noEmit": true,
4
- "moduleResolution": "node", "target": "es2022", "module": "commonjs",
5
- "strict": false, "skipLibCheck": true
6
- },
7
- "include": ["**/*.js"],
8
- "exclude": ["node_modules", "static", "**/*.test.js", "tests", "coverage"]
9
- }
@@ -1,147 +0,0 @@
1
- <div style="display: flex; gap: 20px; margin-bottom: 20px;">
2
- <div style="flex: 1;">
3
- <h6>Memory Usage (Heap Used)</h6>
4
- <canvas id="memoryChart" height="200"></canvas>
5
- </div>
6
- <div style="flex: 1;">
7
- <h6>Turnaround Time</h6>
8
- <canvas id="tatChart" height="200"></canvas>
9
- </div>
10
- <div style="flex: 1;">
11
- <h6>Requests per Minute</h6>
12
- <canvas id="requestChart" height="200"></canvas>
13
- </div>
14
- </div>
15
-
16
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
17
- <script>
18
- (function() {
19
- const historyData = {{ historyJson }};
20
- const startTime = {{ startTime }};
21
-
22
- function formatTime(timestamp) {
23
- const d = new Date(timestamp);
24
- return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
25
- }
26
-
27
- function formatMB(bytes) {
28
- return (bytes / 1024 / 1024).toFixed(1);
29
- }
30
-
31
- function formatDuration(ms) {
32
- const hours = ms / 3600000;
33
- if (hours < 1) {
34
- return Math.round(ms / 60000) + 'm ago';
35
- }
36
- return hours.toFixed(1) + 'h ago';
37
- }
38
-
39
- const chartOptions = {
40
- responsive: false,
41
- maintainAspectRatio: false,
42
- scales: {
43
- x: {
44
- ticks: {
45
- maxTicksAuto: 6
46
- }
47
- },
48
- y: {
49
- beginAtZero: true
50
- }
51
- },
52
- plugins: {
53
- legend: {
54
- display: false
55
- }
56
- }
57
- };
58
-
59
- // Memory chart
60
- new Chart(document.getElementById('memoryChart'), {
61
- type: 'line',
62
- data: {
63
- labels: historyData.map(d => formatTime(d.time)),
64
- datasets: [{
65
- data: historyData.map(d => parseFloat(formatMB(d.mem))),
66
- borderColor: '#007bff',
67
- backgroundColor: 'rgba(0, 123, 255, 0.1)',
68
- fill: true,
69
- tension: 0.3,
70
- pointRadius: 2
71
- }]
72
- },
73
- options: {
74
- ...chartOptions,
75
- scales: {
76
- ...chartOptions.scales,
77
- y: {
78
- ...chartOptions.scales.y,
79
- title: {
80
- display: true,
81
- text: 'MB (𝚫 from start)'
82
- }
83
- }
84
- }
85
- }
86
- });
87
-
88
-
89
- // Tat chart
90
- new Chart(document.getElementById('tatChart'), {
91
- type: 'line',
92
- data: {
93
- labels: historyData.map(d => formatTime(d.time)),
94
- datasets: [{
95
- data: historyData.map(d => d.tat),
96
- borderColor: '#7b7b7b',
97
- backgroundColor: 'rgba(123, 123, 123, 0.1)',
98
- fill: true,
99
- tension: 0.3,
100
- pointRadius: 2
101
- }]
102
- },
103
- options: {
104
- ...chartOptions,
105
- scales: {
106
- ...chartOptions.scales,
107
- y: {
108
- ...chartOptions.scales.y,
109
- title: {
110
- display: true,
111
- text: 'ms'
112
- }
113
- }
114
- }
115
- }
116
- });
117
-
118
- // Requests chart
119
- new Chart(document.getElementById('requestChart'), {
120
- type: 'line',
121
- data: {
122
- labels: historyData.map(d => formatTime(d.time)),
123
- datasets: [{
124
- data: historyData.map(d => d.rpm.toFixed(2)),
125
- borderColor: '#28a745',
126
- backgroundColor: 'rgba(40, 167, 69, 0.1)',
127
- fill: true,
128
- tension: 0.3,
129
- pointRadius: 2
130
- }]
131
- },
132
- options: {
133
- ...chartOptions,
134
- scales: {
135
- ...chartOptions.scales,
136
- y: {
137
- ...chartOptions.scales.y,
138
- title: {
139
- display: true,
140
- text: 'req/min'
141
- }
142
- }
143
- }
144
- }
145
- });
146
- })();
147
- </script>