fhirsmith 0.10.0 → 0.11.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 (55) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/changelog-template.md +22 -0
  3. package/library/logger.js +8 -1
  4. package/library/package-manager.js +40 -2
  5. package/npmprojector/watcher.js +1 -1
  6. package/package.json +3 -2
  7. package/packages/packages.js +28 -15
  8. package/publisher/publisher.js +8 -8
  9. package/registry/api.js +92 -31
  10. package/registry/crawler.js +15 -1
  11. package/registry/model.js +158 -8
  12. package/registry/readme.md +5 -13
  13. package/registry/registry.js +87 -46
  14. package/registry/test-runner.js +1 -1
  15. package/server.js +8 -1
  16. package/token/token.js +1 -1
  17. package/translations/Messages.properties +3 -1
  18. package/translations/rendering-phrases.properties +1227 -1218
  19. package/translations/rendering-phrases_ar.properties +1097 -1091
  20. package/translations/rendering-phrases_fr.properties +626 -624
  21. package/translations/rendering-phrases_nl.properties +976 -970
  22. package/translations/rendering-phrases_pt.properties +1026 -1020
  23. package/translations/rendering-phrases_ru.properties +1100 -1094
  24. package/tsconfig.eslint.json +9 -0
  25. package/tx/cs/cs-api.js +57 -4
  26. package/tx/cs/cs-cs.js +98 -25
  27. package/tx/cs/cs-hgvs.js +4 -0
  28. package/tx/cs/cs-lang.js +8 -0
  29. package/tx/cs/cs-mimetypes.js +4 -0
  30. package/tx/cs/cs-snomed.js +530 -75
  31. package/tx/cs/cs-uri.js +4 -0
  32. package/tx/data/snomed-subset.txt +40 -3
  33. package/tx/importers/import-sct.module.js +18 -0
  34. package/tx/library/designations.js +3 -5
  35. package/tx/library/renderer.js +235 -38
  36. package/tx/library.js +5 -1
  37. package/tx/operation-context.js +40 -3
  38. package/tx/provider.js +41 -12
  39. package/tx/sct/ecl.js +30 -11
  40. package/tx/sct/expressions.js +28 -1
  41. package/tx/sct/structures.js +5 -5
  42. package/tx/tx-html.js +24 -15
  43. package/tx/tx.fhir.org.yml +1 -4
  44. package/tx/vs/vs-database.js +41 -8
  45. package/tx/vs/vs-package.js +55 -0
  46. package/tx/vs/vs-vsac.js +4 -0
  47. package/tx/workers/batch-validate.js +125 -18
  48. package/tx/workers/cache-control.js +31 -2
  49. package/tx/workers/expand.js +50 -32
  50. package/tx/workers/metadata.js +27 -6
  51. package/tx/workers/search.js +7 -1
  52. package/tx/workers/validate.js +30 -18
  53. package/tx/workers/worker.js +30 -7
  54. package/tx/xversion/xv-valueset.js +5 -2
  55. package/xig/xig.js +3 -3
@@ -661,19 +661,42 @@ class TerminologyWorker {
661
661
  // specific coded issue rather than silently auto-creating a fresh cache and
662
662
  // then failing obscurely later when a by-reference resource can't be found.
663
663
  if (!this.opContext.resourceCache.has(cacheId)) {
664
+ // A comma in the cache-id means the request carried multiple X-Cache-Id
665
+ // headers (Node joins duplicate headers with ", "): server-minted ids are
666
+ // single uuids. This happens when a client attaches a new cache-id header
667
+ // without clearing the old one (e.g. IG publisher builds where a second
668
+ // client context wrapped the same HTTP client) - report that specifically,
669
+ // because the generic "unknown cache" message sends people looking for an
670
+ // expiry problem that isn't there.
671
+ if (cacheId.includes(',')) {
672
+ throw new Issue('error', 'invalid', null, 'CACHE_ID_DUPLICATE',
673
+ `The request carried multiple ${CACHE_ID_HEADER} headers (combined value '${cacheId}'). ` +
674
+ 'This is a client error: each request must carry exactly one cache-id. It usually means the client ' +
675
+ 'started a second cache on a connection that already had one, without removing the first header.',
676
+ 'cache-id-duplicate', 400);
677
+ }
664
678
  throw new Issue('error', 'not-found', null, 'CACHE_ID_UNKNOWN',
665
679
  this.i18n.translate('CACHE_ID_UNKNOWN', this.opContext.langs, [cacheId]),
666
680
  'cache-id-unknown', 404);
667
681
  }
668
682
 
669
- // The cache exists: merge any resources supplied on this request into it
670
- // (incremental population is allowed), then expose the full cache contents.
671
- const toCache = txResources.concat(primaryResources);
672
- if (toCache.length > 0) {
673
- this.opContext.resourceCache.add(cacheId, toCache);
683
+ // The cache exists. If it is unsealed, merge any resources supplied on this
684
+ // request into it (incremental population). If it is sealed, the cache is
685
+ // fixed at what it was created with: resources supplied now are still used
686
+ // for this request (via additionalResources below) but are NOT added to the
687
+ // shared cache, so a sealed cache never grows.
688
+ if (!this.opContext.resourceCache.isSealed(cacheId)) {
689
+ const toCache = txResources.concat(primaryResources);
690
+ if (toCache.length > 0) {
691
+ this.opContext.resourceCache.add(cacheId, toCache);
692
+ }
693
+ this.additionalResources = this.opContext.resourceCache.get(cacheId);
694
+ } else {
695
+ // Sealed: expose the cache contents plus this request's own inline
696
+ // resources (used for this call only), without mutating the cache.
697
+ this.additionalResources = this.opContext.resourceCache.get(cacheId)
698
+ .concat(txResources, primaryResources);
674
699
  }
675
-
676
- this.additionalResources = this.opContext.resourceCache.get(cacheId);
677
700
  this.additionalResourcesCacheId = cacheId;
678
701
  } else {
679
702
  // No cache-id, just use the tx-resources directly
@@ -131,9 +131,12 @@ function valueSetR5ToR4(r5Obj) {
131
131
  });
132
132
  }
133
133
  delete exp.property;
134
- convertContainsPropertyR5ToR4(exp.contains);
135
-
136
134
  }
135
+
136
+ // ValueSet.expansion.contains.property is R5-only too, and must be converted
137
+ // whether or not the expansion declares expansion-level property definitions:
138
+ // a contained code can carry a property with no expansion.property present.
139
+ convertContainsPropertyR5ToR4(exp.contains);
137
140
  }
138
141
 
139
142
  return r5Obj;
package/xig/xig.js CHANGED
@@ -977,7 +977,7 @@ async function fetchResourceRows(queryParams, offset = 0, limit = 200) {
977
977
  }
978
978
 
979
979
  function rowToObject(row, queryParams) {
980
- const { ver, realm, auth, type, rt } = queryParams;
980
+ const { type } = queryParams;
981
981
  const packageObj = getPackage(row.PackageKey);
982
982
 
983
983
  const obj = {
@@ -3156,7 +3156,7 @@ async function initializeXigModule(stats, xigConfig) {
3156
3156
  if (!fs.existsSync(XIG_DB_PATH)) {
3157
3157
  xigLog.info('No existing XIG database found, triggering initial download');
3158
3158
  setTimeout(() => {
3159
- updateXigDatabase();
3159
+ updateXigDatabase().catch((err) => xigLog.error('XIG database update failed: ' + err.message));
3160
3160
  }, 5000);
3161
3161
  }
3162
3162
 
@@ -3167,7 +3167,7 @@ async function initializeXigModule(stats, xigConfig) {
3167
3167
  // Note: This assumes we're called only when XIG is enabled
3168
3168
  if (xigConfig?.autoUpdate !== false) {
3169
3169
  cron.schedule('0 2 * * *', () => {
3170
- updateXigDatabase();
3170
+ updateXigDatabase().catch((err) => xigLog.error('XIG database update failed: ' + err.message));
3171
3171
  });
3172
3172
  }
3173
3173