fhirsmith 0.18.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/ACCESSIBILITY.md +119 -0
  2. package/CHANGELOG.md +190 -9
  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 +331 -33
  15. package/ips/jurisdictions.js +65 -0
  16. package/ips/nationality.js +120 -0
  17. package/ips/pipeline.js +131 -17
  18. package/ips/presenter.js +1 -1
  19. package/ips/profile-editor.js +283 -4
  20. package/ips/readme.md +170 -20
  21. package/ips/render.js +769 -109
  22. package/ips/scripts.js +46 -0
  23. package/ips/store.js +123 -11
  24. package/ips/structure.js +247 -0
  25. package/ips/terminology.js +1 -1
  26. package/library/body-limit.js +22 -0
  27. package/library/cache-generation.js +15 -0
  28. package/library/cgroup-memory.js +133 -1
  29. package/library/cluster-counts.js +121 -0
  30. package/library/cluster-events.js +153 -0
  31. package/library/cluster-metrics.js +193 -0
  32. package/library/cluster-status.js +468 -0
  33. package/library/config-reader.js +96 -0
  34. package/library/daily-report.js +100 -2
  35. package/library/html-server.js +27 -1
  36. package/library/i18nsupport.js +23 -1
  37. package/library/keep-alive.js +18 -0
  38. package/library/languages.js +17 -3
  39. package/library/logger.js +31 -0
  40. package/library/memory-guard.js +428 -0
  41. package/library/native-memory.js +52 -0
  42. package/library/npm-audit.js +51 -25
  43. package/library/openapi-doc.js +7 -5
  44. package/library/package-manager.js +8 -0
  45. package/library/role.js +197 -0
  46. package/library/server-credentials.js +169 -0
  47. package/library/sqlite-utilities.js +59 -0
  48. package/library/ssrf-guard.js +100 -0
  49. package/library/static-response-stats.js +16 -0
  50. package/library/version-utilities.js +50 -0
  51. package/library/worker-count.js +192 -0
  52. package/nginx.md +30 -11
  53. package/npmprojector/indexer.js +18 -10
  54. package/package.json +11 -8
  55. package/packages/feed-check-page.js +117 -0
  56. package/packages/feed-check.js +279 -0
  57. package/packages/npm-check.js +57 -3
  58. package/packages/npm-signing.js +219 -0
  59. package/packages/openapi.yaml +207 -1
  60. package/packages/package-crawler.js +322 -41
  61. package/packages/packages-template.html +6 -8
  62. package/packages/packages.js +604 -57
  63. package/packages/readme.md +113 -1
  64. package/publisher/publisher-template.html +2 -5
  65. package/publisher/publisher.js +121 -110
  66. package/publisher/readme.md +75 -0
  67. package/registry/api.js +179 -1
  68. package/registry/crawler.js +86 -108
  69. package/registry/documentation/api.md +68 -2
  70. package/registry/documentation/configuration.md +34 -0
  71. package/registry/documentation/internals.md +4 -1
  72. package/registry/documentation/readme.md +3 -2
  73. package/registry/model.js +8 -0
  74. package/registry/openapi.yaml +84 -0
  75. package/registry/registry-template.html +5 -8
  76. package/registry/registry.js +58 -6
  77. package/root-bare-template.html +7 -4
  78. package/root-template.html +5 -8
  79. package/server.js +398 -198
  80. package/shl/shl.js +38 -37
  81. package/static/a11y/a11y-check.js +832 -0
  82. package/static/a11y/axe.min.js +12 -0
  83. package/static/assets/css/bootstrap-fhir.css +15 -15
  84. package/static/assets/images/flags/au.svg +18 -0
  85. package/static/assets/images/flags/unknown.svg +11 -0
  86. package/static/assets/images/flags/us.svg +63 -0
  87. package/static/assets/images/icon_audit.png +0 -0
  88. package/static/assets/images/icon_clinical.png +0 -0
  89. package/static/assets/images/icon_document.png +0 -0
  90. package/static/assets/images/icon_external.png +0 -0
  91. package/static/assets/images/icon_medication.png +0 -0
  92. package/static/assets/images/icon_organization.png +0 -0
  93. package/static/assets/images/icon_other.png +0 -0
  94. package/static/assets/images/icon_person.png +0 -0
  95. package/static/assets/images/icon_section.png +0 -0
  96. package/stats-db.js +45 -0
  97. package/stats.js +197 -10
  98. package/testing/testing-template.html +5 -8
  99. package/token/nginx_passport_setup.md +1 -1
  100. package/token/security_guide.md +1 -1
  101. package/token/token-template.html +2 -5
  102. package/token/token.js +40 -36
  103. package/translations/Messages.properties +19 -0
  104. package/tx/README.md +158 -4
  105. package/tx/closure/closure-store.js +126 -3
  106. package/tx/cm/cm-database.js +69 -57
  107. package/tx/cm/cm-package.js +50 -16
  108. package/tx/cs/cs-api.js +284 -19
  109. package/tx/cs/cs-api.md +41 -4
  110. package/tx/cs/cs-areacode.js +1 -1
  111. package/tx/cs/cs-country.js +17 -5
  112. package/tx/cs/cs-cpt.js +33 -16
  113. package/tx/cs/cs-cs.js +199 -24
  114. package/tx/cs/cs-currency.js +1 -1
  115. package/tx/cs/cs-icd11.js +21 -13
  116. package/tx/cs/cs-icf.js +22 -3
  117. package/tx/cs/cs-lang.js +2 -2
  118. package/tx/cs/cs-loinc.js +193 -67
  119. package/tx/cs/cs-mimetypes.js +12 -2
  120. package/tx/cs/cs-ndc.js +40 -25
  121. package/tx/cs/cs-omop.js +54 -29
  122. package/tx/cs/cs-rxnorm.js +300 -196
  123. package/tx/cs/cs-snomed.js +861 -95
  124. package/tx/cs/cs-ucum.js +14 -4
  125. package/tx/cs/cs-unii.js +18 -14
  126. package/tx/cs/cs-virtual.js +210 -0
  127. package/tx/ecosystem-resolver.js +413 -0
  128. package/tx/html/cluster-dash-metrics.liquid +26 -0
  129. package/tx/html/cluster-home-metrics.liquid +31 -0
  130. package/tx/html/cluster-metrics-script.liquid +251 -0
  131. package/tx/html/codesystem-operations.liquid +3 -3
  132. package/tx/html/ecl-panel.liquid +1 -1
  133. package/tx/html/external-metrics.liquid +17 -0
  134. package/tx/html/operations-form.liquid +17 -17
  135. package/tx/html/search-form.liquid +11 -11
  136. package/tx/html/status-line.liquid +58 -0
  137. package/tx/html/status-panel.liquid +140 -0
  138. package/tx/html/status-tasks.liquid +25 -0
  139. package/tx/html/tx-template.html +2 -5
  140. package/tx/importers/atc-to-fhir.js +17 -16
  141. package/tx/importers/export-icd11-codesystem.js +3 -2
  142. package/tx/importers/import-icd11.js +4 -3
  143. package/tx/importers/import-loinc.module.js +118 -56
  144. package/tx/importers/import-ndc.module.js +56 -44
  145. package/tx/importers/import-rxnorm.module.js +118 -79
  146. package/tx/importers/import-sct.module.js +125 -61
  147. package/tx/importers/import-unii.module.js +37 -36
  148. package/tx/importers/subset-loinc.module.js +49 -48
  149. package/tx/importers/subset-rxnorm.module.js +29 -28
  150. package/tx/importers/terminal.js +18 -0
  151. package/tx/importers/tx-import-base.js +13 -12
  152. package/tx/importers/tx-import-settings.js +5 -4
  153. package/tx/importers/tx-import.js +53 -52
  154. package/tx/library/canonical-resource.js +49 -0
  155. package/tx/library/codesystem.js +94 -5
  156. package/tx/library/designations.js +45 -2
  157. package/tx/library/extensions.js +13 -7
  158. package/tx/library/implicit-valuesets.js +66 -0
  159. package/tx/library/renderer.js +77 -21
  160. package/tx/library/sqlite-utilities.js +2 -0
  161. package/tx/library/tho-precedence.js +40 -0
  162. package/tx/library/ucum-parsers.js +11 -1
  163. package/tx/library/wait-for-cache.js +43 -0
  164. package/tx/library.js +321 -22
  165. package/tx/openapi-operations.js +6 -4
  166. package/tx/operation-context.js +460 -99
  167. package/tx/params.js +25 -0
  168. package/tx/problems.js +3 -5
  169. package/tx/provider.js +314 -67
  170. package/tx/resource-cache-sqlite.js +1050 -0
  171. package/tx/sct/documentation.md +45 -21
  172. package/tx/sct/ecl.js +81 -17
  173. package/tx/sct/editions.js +39 -0
  174. package/tx/sct/expressions.js +10 -1
  175. package/tx/sct/load-config.js +107 -0
  176. package/tx/sct/mmap.js +109 -0
  177. package/tx/sct/structures.js +175 -15
  178. package/tx/sct/text-index.js +5 -1
  179. package/tx/syndication/syndication-feed.js +2 -2
  180. package/tx/tx-html.js +44 -8
  181. package/tx/tx.fhir.org.yml +8 -8
  182. package/tx/tx.js +282 -80
  183. package/tx/usage-tracker.js +39 -11
  184. package/tx/vs/vs-api.js +19 -0
  185. package/tx/vs/vs-database.js +386 -62
  186. package/tx/vs/vs-package.js +44 -17
  187. package/tx/vs/vs-vsac.js +649 -101
  188. package/tx/workers/batch-validate.js +37 -10
  189. package/tx/workers/batch.js +6 -1
  190. package/tx/workers/cache-control.js +15 -4
  191. package/tx/workers/closure.js +156 -13
  192. package/tx/workers/compare.js +8 -5
  193. package/tx/workers/expand.js +1173 -289
  194. package/tx/workers/metadata.js +35 -0
  195. package/tx/workers/search.js +53 -1
  196. package/tx/workers/supplement-filters.js +145 -0
  197. package/tx/workers/translate.js +169 -4
  198. package/tx/workers/validate.js +223 -119
  199. package/tx/workers/worker.js +123 -31
  200. package/tx/xversion/xv-valueset.js +7 -4
  201. package/utilities/submit-test-report.js +3 -1
  202. package/utilities/tx-stress-test.js +482 -0
  203. package/vcl/readme.md +37 -0
  204. package/vcl/vcl-parser.js +15 -0
  205. package/xig/readme.md +52 -0
  206. package/xig/xig-template.html +5 -8
  207. package/xig/xig.js +238 -422
  208. package/changelog-template.md +0 -22
  209. package/registry/test-runner.js +0 -237
  210. package/release.sh +0 -80
  211. package/test-scripts/repro-re2-wasm-leak.js +0 -34
  212. package/tsconfig.eslint.json +0 -9
  213. package/tx/html/dash-metrics.liquid +0 -147
  214. package/tx/html/home-metrics.liquid +0 -225
@@ -164,6 +164,74 @@ paths:
164
164
  '400': { $ref: '#/components/responses/BadRequest' }
165
165
  '500': { $ref: '#/components/responses/ServerError' }
166
166
 
167
+ /-/fhir/v1/signatures/{spec}:
168
+ get:
169
+ tags: [registry]
170
+ operationId: getPublisherSignature
171
+ summary: The publisher's signature of a package version
172
+ description: |
173
+ The signature a package's publisher made of it (its `{package}.tgz.sigstore.json`,
174
+ linked from the publisher's feed by `fhir:signature`), exactly as this registry fetched
175
+ and checked it. It is a Sigstore bundle: an ECDSA P-256 signature of an in-toto
176
+ statement naming the package (`pkg:npm/{name}@{version}`) and the sha512 of the
177
+ `.tgz`. The keys a feed may sign with are listed in the FHIR package registry's
178
+ `package-feeds.json`; a client can check the signature against them itself.
179
+
180
+ Each version's `dist.fhir-signature` in the package document links this, with what
181
+ the registry made of it (`confirmed` or `rejected`). It isn't `dist.attestations`:
182
+ npm would try to verify it as a Sigstore attestation, which it isn't (it has no
183
+ transparency log entry, and the publisher's key isn't the registry's).
184
+ parameters:
185
+ - name: spec
186
+ in: path
187
+ required: true
188
+ description: '`{name}@{version}`, as npm writes it (a scope''s `/` escaped).'
189
+ schema: { type: string }
190
+ example: hl7.fhir.uv.ips@2.0.0
191
+ responses:
192
+ '200':
193
+ description: The signature bundle, as fetched
194
+ content:
195
+ application/json:
196
+ schema: { type: object }
197
+ '400': { $ref: '#/components/responses/BadRequest' }
198
+ '404':
199
+ description: No signature is held for this package version
200
+ content:
201
+ application/json:
202
+ schema: { $ref: '#/components/schemas/Error' }
203
+ '500': { $ref: '#/components/responses/ServerError' }
204
+
205
+ /-/npm/v1/keys:
206
+ get:
207
+ tags: [registry]
208
+ operationId: getSigningKeys
209
+ summary: The registry's signing keys (npm registry signatures)
210
+ description: |
211
+ The public keys this registry signs package versions with, in the npm registry's
212
+ format, so `npm audit signatures` can check packages installed from here. Each
213
+ version's `dist.signatures` holds the signature of `{id}@{version}:{dist.integrity}`
214
+ (ECDSA P-256, SHA-256, base64 DER).
215
+
216
+ A signature says this registry served that tarball. It is the registry's, not the
217
+ publisher's: this registry signs every version it holds, wherever it was crawled
218
+ from.
219
+
220
+ A 404 means the registry doesn't sign, which npm accepts. It is also the answer
221
+ while the registry is still signing versions it stored before it signed, since
222
+ npm reports an unsigned version from a registry with keys as an error.
223
+ responses:
224
+ '200':
225
+ description: The keys
226
+ content:
227
+ application/json:
228
+ schema: { $ref: '#/components/schemas/SigningKeys' }
229
+ '404':
230
+ description: This registry doesn't sign packages (or hasn't finished signing them)
231
+ content:
232
+ application/json:
233
+ schema: { $ref: '#/components/schemas/Error' }
234
+
167
235
  /updates:
168
236
  get:
169
237
  tags: [search]
@@ -254,6 +322,9 @@ paths:
254
322
 
255
323
  With `Accept: text/html` and no parameters, this is a form for running the checks.
256
324
 
325
+ If the registry lists signing keys (`/-/npm/v1/keys`), it also checks that every
326
+ version of the package is signed with one of them, as `npm audit signatures` does.
327
+
257
328
  A run makes about ten requests, each limited in time and size, and only to public
258
329
  addresses. Runs are rate limited per client address, and the server runs only a
259
330
  few at once. A server can turn the check off (`npmCheck.enabled` in its
@@ -312,6 +383,103 @@ paths:
312
383
  schema: { $ref: '#/components/schemas/Error' }
313
384
  '500': { $ref: '#/components/responses/ServerError' }
314
385
 
386
+ /feed-check:
387
+ get:
388
+ tags: [tools]
389
+ operationId: checkPackageFeed
390
+ summary: Check a package feed the way the crawler reads it
391
+ description: |
392
+ Reads a package feed (RSS, as listed in the FHIR package registry's package-feeds.json)
393
+ the way this registry's crawler does, and reports what it finds, without storing
394
+ anything: for each item, its package (downloaded, unpacked and checked as the crawler
395
+ checks it before storing), whether the registry's package-restrictions allow it from
396
+ this feed, its signature (against the keys the registry lists for the feed), and
397
+ whether this registry already holds it. Next pages are followed, up to an item limit.
398
+
399
+ A check runs in the background: this starts one and returns `202` with its id
400
+ (`303` to its report page, for a browser). Poll `/feed-check/{run}` for the report.
401
+ With `Accept: text/html` and no `url`, this is a form.
402
+
403
+ Every request a check makes goes only to public addresses. Only one check runs at a
404
+ time, across all users. A server can turn the check off (`feedCheck.enabled`), and then
405
+ this returns 404.
406
+ parameters:
407
+ - name: url
408
+ in: query
409
+ required: true
410
+ description: The feed's URL.
411
+ schema:
412
+ type: string
413
+ maxLength: 500
414
+ pattern: '^https?:\/\/[^\s<>"''`]+$'
415
+ example: https://hl7.org/fhir/package-feed.xml
416
+ - name: signing
417
+ in: query
418
+ required: false
419
+ description: |
420
+ The feed's signing keys, as JSON: its `signing` block as it would be in
421
+ package-feeds.json (`{"required": false, "keys": [{"keyid": ..., "key": ..., "expires": null}]}`),
422
+ or the feed's whole entry. Signatures are checked against these instead of the keys
423
+ the registry lists for the feed.
424
+ schema:
425
+ type: string
426
+ maxLength: 5000
427
+ pattern: '^[^<>`]*$'
428
+ responses:
429
+ '202':
430
+ description: The check has started
431
+ content:
432
+ application/json:
433
+ schema:
434
+ type: object
435
+ properties:
436
+ id: { type: string }
437
+ state: { type: string, enum: [running] }
438
+ report: { type: string, description: Where to get the report }
439
+ '303': { description: 'For a browser: the report page' }
440
+ '400': { $ref: '#/components/responses/BadRequest' }
441
+ '404':
442
+ description: The check is turned off on this server
443
+ content:
444
+ application/json:
445
+ schema: { $ref: '#/components/schemas/Error' }
446
+ '503':
447
+ description: A check is already running (one at a time); try again shortly
448
+ content:
449
+ application/json:
450
+ schema: { $ref: '#/components/schemas/Error' }
451
+ '500': { $ref: '#/components/responses/ServerError' }
452
+
453
+ /feed-check/{run}:
454
+ get:
455
+ tags: [tools]
456
+ operationId: getFeedCheck
457
+ summary: A feed check's report
458
+ description: |
459
+ The report of a check started with `/feed-check`: `state` is `running` (the report so
460
+ far), `done` or `failed`. Reports are kept for a while (an hour, by default) after the
461
+ check finishes. A browser gets a page that reloads until the check is done.
462
+ parameters:
463
+ - name: run
464
+ in: path
465
+ required: true
466
+ description: The check's id, as `/feed-check` returned it.
467
+ schema: { type: string }
468
+ responses:
469
+ '200':
470
+ description: The check and its report
471
+ content:
472
+ application/json:
473
+ schema: { type: object }
474
+ text/html:
475
+ schema: { type: string }
476
+ '404':
477
+ description: No such check (or its report has been discarded)
478
+ content:
479
+ application/json:
480
+ schema: { $ref: '#/components/schemas/Error' }
481
+ '500': { $ref: '#/components/responses/ServerError' }
482
+
315
483
  /{id}:
316
484
  get:
317
485
  tags: [registry]
@@ -683,8 +851,46 @@ components:
683
851
  type: object
684
852
  required: [tarball]
685
853
  properties:
686
- shasum: { type: string }
854
+ shasum: { type: string, description: sha1 of the tarball, hex }
855
+ integrity: { type: string, description: 'sha512 of the tarball, as an SRI string (`sha512-{base64}`)' }
687
856
  tarball: { type: string, format: uri }
857
+ signatures:
858
+ type: array
859
+ description: |
860
+ The registry's signatures of `{id}@{version}:{integrity}`, by the keys at
861
+ `/-/npm/v1/keys`. Absent when the registry doesn't sign.
862
+ items:
863
+ type: object
864
+ required: [keyid, sig]
865
+ properties:
866
+ keyid: { type: string }
867
+ sig: { type: string, description: 'base64 DER ECDSA signature' }
868
+ fhir-signature:
869
+ type: object
870
+ description: |
871
+ The publisher's signature of this version, as this registry checked it, when
872
+ there is one. Absent when the package isn't signed, or its feed lists no keys.
873
+ required: [url, status]
874
+ properties:
875
+ url: { type: string, format: uri, description: 'The signature: `/-/fhir/v1/signatures/{name}@{version}`' }
876
+ status: { type: string, enum: [confirmed, rejected] }
877
+ keyid: { type: string, description: The key that signed it (when confirmed) }
878
+
879
+ SigningKeys:
880
+ type: object
881
+ required: [keys]
882
+ properties:
883
+ keys:
884
+ type: array
885
+ items:
886
+ type: object
887
+ required: [keyid, keytype, scheme, key]
888
+ properties:
889
+ keyid: { type: string, description: '`SHA256:` and the base64 sha256 of the key' }
890
+ keytype: { type: string, const: ecdsa-sha2-nistp256 }
891
+ scheme: { type: string, const: ecdsa-sha2-nistp256 }
892
+ key: { type: string, description: 'The public key: base64 DER SubjectPublicKeyInfo' }
893
+ expires: { type: [string, 'null'], format: date-time, description: 'null: no expiry' }
688
894
 
689
895
  BrokenDependencies:
690
896
  type: object