fhirsmith 0.11.2 → 0.13.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 (68) hide show
  1. package/CHANGELOG.md +377 -2
  2. package/README.md +1 -1
  3. package/config-template.json +31 -1
  4. package/library/languages.js +191 -34
  5. package/library/path-safety.js +51 -0
  6. package/library/request-token.js +56 -0
  7. package/package.json +2 -2
  8. package/packages/packages.js +17 -118
  9. package/publisher/publisher.js +208 -30
  10. package/publisher/validation.js +210 -0
  11. package/server.js +24 -15
  12. package/stats-db.js +127 -0
  13. package/stats.js +172 -6
  14. package/translations/Messages.properties +5 -1
  15. package/tx/README.md +21 -0
  16. package/tx/cs/cs-api.js +30 -1
  17. package/tx/cs/cs-api.md +1 -1
  18. package/tx/cs/cs-cs.js +1 -1
  19. package/tx/cs/cs-icd11.js +805 -0
  20. package/tx/cs/cs-lang.js +331 -85
  21. package/tx/cs/cs-loinc.js +45 -4
  22. package/tx/cs/cs-mimetypes.js +492 -21
  23. package/tx/cs/cs-snomed.js +141 -58
  24. package/tx/cs/cs-ucum.js +33 -3
  25. package/tx/cs/icd11-expressions.js +243 -0
  26. package/tx/importers/export-icd11-codesystem.js +823 -0
  27. package/tx/importers/icd11-schema.md +285 -0
  28. package/tx/importers/import-icd11.js +861 -0
  29. package/tx/importers/import-loinc.module.js +14 -7
  30. package/tx/importers/import-sct.module.js +10 -1
  31. package/tx/library/codesystem.js +21 -27
  32. package/tx/library/conceptmap.js +39 -0
  33. package/tx/library/nesting-limit.js +79 -0
  34. package/tx/library/operation-outcome.js +97 -3
  35. package/tx/library/parameter-check.js +139 -0
  36. package/tx/library/valueset.js +16 -20
  37. package/tx/library.js +23 -1
  38. package/tx/ocl/cache/cache-utils.cjs +5 -3
  39. package/tx/ocl/cs-ocl.cjs +73 -17
  40. package/tx/ocl/jobs/background-queue.cjs +6 -3
  41. package/tx/ocl/mappers/concept-mapper.cjs +9 -1
  42. package/tx/ocl/shared/patches.cjs +48 -1
  43. package/tx/ocl/vs-ocl.cjs +15 -13
  44. package/tx/operation-context.js +220 -10
  45. package/tx/params.js +226 -175
  46. package/tx/sct/expressions.js +677 -15
  47. package/tx/tx.fhir.org.yml +3 -2
  48. package/tx/tx.js +72 -92
  49. package/tx/workers/batch-validate.js +11 -18
  50. package/tx/workers/batch.js +16 -28
  51. package/tx/workers/cache-control.js +87 -17
  52. package/tx/workers/closure.js +3 -8
  53. package/tx/workers/compare.js +6 -34
  54. package/tx/workers/expand.js +108 -60
  55. package/tx/workers/lookup.js +35 -40
  56. package/tx/workers/read.js +6 -40
  57. package/tx/workers/search.js +2 -8
  58. package/tx/workers/subsumes.js +58 -41
  59. package/tx/workers/translate.js +472 -47
  60. package/tx/workers/validate.js +83 -78
  61. package/tx/workers/worker.js +92 -11
  62. package/tx/xml/xml-base.js +264 -77
  63. package/tx/xversion/xv-conceptmap.js +81 -0
  64. package/tx/xversion/xv-parameters.js +8 -0
  65. package/tx/xversion/xv-valueset.js +39 -1
  66. package/utilities/merge-audit.py +178 -0
  67. package/utilities/why-merge-audit.md +39 -0
  68. package/tx/data/snomed-subset.txt +0 -84
package/tx/ocl/cs-ocl.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  const fs = require('fs/promises');
2
2
  const { AbstractCodeSystemProvider } = require('../cs/cs-provider-api');
3
3
  const { CodeSystemProvider, CodeSystemFactoryProvider, CodeSystemContentMode, FilterExecutionContext } = require('../cs/cs-api');
4
+ const { BaseCSServices } = require('../cs/cs-base');
4
5
  const { CodeSystem } = require('../library/codesystem');
5
6
  const { SearchFilterText } = require('../library/designations');
6
7
  const { PAGE_SIZE, CONCEPT_PAGE_SIZE, COLD_CACHE_FRESHNESS_MS, OCL_CODESYSTEM_MARKER_EXTENSION } = require('./shared/constants');
@@ -12,8 +13,10 @@ const { computeCodeSystemFingerprint } = require('./fingerprint/fingerprint');
12
13
  const { OCLBackgroundJobQueue } = require('./jobs/background-queue');
13
14
  const { OCLConceptFilterContext } = require('./model/concept-filter-context');
14
15
  const { toConceptContext } = require('./mappers/concept-mapper');
15
- const { patchSearchWorkerForOCLCodeFiltering } = require('./shared/patches');
16
+ const { patchSearchWorkerForOCLCodeFiltering, patchProviderForOCLFactorySync } = require('./shared/patches');
16
17
  const regexUtilities = require("../../library/regex-utilities");
18
+ const Logger = require('../../library/logger');
19
+ const oclLog = Logger.getInstance().child({ module: 'ocl' });
17
20
 
18
21
  patchSearchWorkerForOCLCodeFiltering();
19
22
 
@@ -66,17 +69,17 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
66
69
  this._initializePromise = (async () => {
67
70
  try {
68
71
  const sources = await this.#fetchSourcesForDiscovery();
69
- console.log(`[OCL] Fetched ${sources.length} sources`);
72
+ oclLog.info(`Fetched ${sources.length} sources`);
70
73
 
71
74
  const snapshot = this.#buildSourceSnapshot(sources);
72
75
  this.#applySnapshot(snapshot);
73
76
 
74
- console.log(`[OCL] Loaded ${this._codeSystemsByCanonical.size} code systems`);
77
+ oclLog.info(`Loaded ${this._codeSystemsByCanonical.size} code systems`);
75
78
  this._initialized = true;
76
79
  } catch (error) {
77
- console.error(`[OCL] Initialization failed:`, error.message);
80
+ oclLog.error(`Initialization failed: ${error.message}`);
78
81
  if (error.response) {
79
- console.error(`[OCL] HTTP ${error.response.status}: ${error.response.statusText}`);
82
+ oclLog.error(`HTTP ${error.response.status}: ${error.response.statusText}`);
80
83
  }
81
84
  throw error;
82
85
  }
@@ -149,9 +152,18 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
149
152
  const nextSnapshot = this.#buildSourceSnapshot(sources);
150
153
  const changes = this.#diffSnapshots(this._sourceStateByCanonical, nextSnapshot);
151
154
  this.#applySnapshot(nextSnapshot);
155
+ for (const cs of changes.added || []) {
156
+ const entry = nextSnapshot.get(cs.url);
157
+ if (entry?.meta && !OCLSourceCodeSystemFactory.hasFactory(cs.url, cs.version || null)) {
158
+ const factory = OCLSourceCodeSystemFactory.createForDiscoveredSource(this.httpClient, entry.meta);
159
+ if (factory) {
160
+ oclLog.info(`Factory created for newly discovered source: ${cs.url}`);
161
+ }
162
+ }
163
+ }
152
164
  this._pendingChanges = changes;
153
165
  } catch (error) {
154
- console.error('[OCL] Incremental source refresh failed:', error.message);
166
+ oclLog.error(`Incremental source refresh failed: ${error.message}`);
155
167
  this._pendingChanges = this.#emptyChanges();
156
168
  } finally {
157
169
  this._refreshPromise = null;
@@ -326,7 +338,7 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
326
338
  const versionChanged = (previousEntry.cs.version || null) !== (nextEntry.cs.version || null);
327
339
  if (checksumChanged || versionChanged) {
328
340
  if (checksumChanged) {
329
- console.log(`[OCL] CodeSystem checksum changed: ${canonicalUrl} (${previousChecksum} -> ${nextChecksum})`);
341
+ oclLog.info(`CodeSystem checksum changed: ${canonicalUrl} (${previousChecksum} -> ${nextChecksum})`);
330
342
  }
331
343
  changed.push(nextEntry.cs);
332
344
  }
@@ -553,8 +565,8 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
553
565
  const result = await fetchAllPages(this.httpClient, path, {
554
566
  pageSize: PAGE_SIZE,
555
567
  baseUrl: this.baseUrl,
556
- logger: console,
557
- loggerPrefix: '[OCL]'
568
+ logger: oclLog,
569
+ loggerPrefix: ''
558
570
  });
559
571
  // Extra check: payload must be object or array
560
572
  if (!result || (typeof result !== 'object' && !Array.isArray(result))) {
@@ -563,8 +575,8 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
563
575
  return result;
564
576
  } catch (error) {
565
577
  if (error.response) {
566
- console.error(`[OCL] HTTP ${error.response.status}: ${error.response.statusText}`);
567
- console.error('[OCL] Response:', error.response.data);
578
+ oclLog.error(`HTTP ${error.response.status}: ${error.response.statusText}`);
579
+ oclLog.error(`Response: ${JSON.stringify(error.response.data)}`);
568
580
  }
569
581
  throw error;
570
582
  }
@@ -586,7 +598,7 @@ class OCLCodeSystemProvider extends AbstractCodeSystemProvider {
586
598
  }
587
599
  }
588
600
 
589
- class OCLSourceCodeSystemProvider extends CodeSystemProvider {
601
+ class OCLSourceCodeSystemProvider extends BaseCSServices {
590
602
  constructor(opContext, supplements, client, meta, sharedCaches = null) {
591
603
  super(opContext, supplements);
592
604
  this.httpClient = client;
@@ -727,6 +739,36 @@ class OCLSourceCodeSystemProvider extends CodeSystemProvider {
727
739
  }
728
740
  }
729
741
 
742
+ async extendLookup(ctxt, props, params) {
743
+ const context = await this.#ensureContext(ctxt);
744
+ const extras = context && context.extras;
745
+ if (!extras || typeof extras !== 'object') {
746
+ return;
747
+ }
748
+ for (const [key, value] of Object.entries(extras)) {
749
+ if (!key || value === null || value === undefined) {
750
+ continue;
751
+ }
752
+ if (!this._hasProp(props, key, true)) {
753
+ continue;
754
+ }
755
+ const part = [{ name: 'code', valueCode: key }];
756
+ if (typeof value === 'boolean') {
757
+ part.push({ name: 'value', valueBoolean: value });
758
+ } else if (typeof value === 'number' && Number.isInteger(value)) {
759
+ part.push({ name: 'value', valueInteger: value });
760
+ } else if (typeof value === 'number' && Number.isFinite(value)) {
761
+ part.push({ name: 'value', valueDecimal: value });
762
+ } else if (typeof value === 'string') {
763
+ part.push({ name: 'value', valueString: value });
764
+ } else {
765
+ // Extras may hold arbitrary JSON (arrays, objects); serialize rather than drop data.
766
+ part.push({ name: 'value', valueString: JSON.stringify(value) });
767
+ }
768
+ params.push({ name: 'property', part });
769
+ }
770
+ }
771
+
730
772
  async locate(code) {
731
773
  if (!code || typeof code !== 'string') {
732
774
  return { context: null, message: 'Empty code' };
@@ -1251,6 +1293,14 @@ class OCLSourceCodeSystemProvider extends CodeSystemProvider {
1251
1293
 
1252
1294
  class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1253
1295
  static factoriesByKey = new Map();
1296
+ static #sharedI18n = null;
1297
+
1298
+ static createForDiscoveredSource(httpClient, meta) {
1299
+ if (!OCLSourceCodeSystemFactory.#sharedI18n) {
1300
+ return null;
1301
+ }
1302
+ return new OCLSourceCodeSystemFactory(OCLSourceCodeSystemFactory.#sharedI18n, httpClient, meta);
1303
+ }
1254
1304
 
1255
1305
  static #normalizeSystem(system) {
1256
1306
  return normalizeCanonicalSystem(system);
@@ -1319,6 +1369,9 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1319
1369
 
1320
1370
  constructor(i18n, client, meta) {
1321
1371
  super(i18n);
1372
+ if (!OCLSourceCodeSystemFactory.#sharedI18n) {
1373
+ OCLSourceCodeSystemFactory.#sharedI18n = i18n;
1374
+ }
1322
1375
  this.httpClient = client;
1323
1376
  this.meta = meta;
1324
1377
  this.sharedConceptCache = new Map();
@@ -1375,7 +1428,7 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1375
1428
 
1376
1429
  } catch (error) {
1377
1430
  if (error.code !== 'ENOENT') {
1378
- console.error(`[OCL] Failed to load cold cache for CodeSystem ${canonicalUrl}:`, error.message);
1431
+ oclLog.error(`Failed to load cold cache for CodeSystem ${canonicalUrl}: ${error.message}`);
1379
1432
  }
1380
1433
  }
1381
1434
  }
@@ -1402,7 +1455,7 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1402
1455
 
1403
1456
  return fingerprint;
1404
1457
  } catch (error) {
1405
- console.error(`[OCL] Failed to save cold cache for CodeSystem ${canonicalUrl}:`, error.message);
1458
+ oclLog.error(`Failed to save cold cache for CodeSystem ${canonicalUrl}: ${error.message}`);
1406
1459
  return null;
1407
1460
  }
1408
1461
  }
@@ -1542,9 +1595,9 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1542
1595
  }
1543
1596
  }
1544
1597
 
1545
- console.log(`[OCL] CodeSystem loaded: ${this.system()} (${count} concepts)`);
1598
+ oclLog.info(`CodeSystem loaded: ${this.system()} (${count} concepts)`);
1546
1599
  } catch (error) {
1547
- console.error(`[OCL] CodeSystem background load failed: ${key}: ${error.message}`);
1600
+ oclLog.error(`CodeSystem background load failed: ${key}: ${error.message}`);
1548
1601
  }
1549
1602
  }
1550
1603
 
@@ -1660,7 +1713,7 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1660
1713
  this.meta.codeSystem.jsonObj.content = CodeSystemContentMode.NotPresent;
1661
1714
  delete this.meta.codeSystem.jsonObj.concept;
1662
1715
  }
1663
- console.log(`[OCL] CodeSystem checksum changed, invalidated warm cache: ${this.#resourceKey()}`);
1716
+ oclLog.info(`CodeSystem checksum changed, invalidated warm cache: ${this.#resourceKey()}`);
1664
1717
  }
1665
1718
  }
1666
1719
 
@@ -1824,8 +1877,11 @@ class OCLSourceCodeSystemFactory extends CodeSystemFactoryProvider {
1824
1877
  }
1825
1878
  }
1826
1879
 
1880
+ patchProviderForOCLFactorySync(() => OCLSourceCodeSystemFactory.factoriesByKey);
1881
+
1827
1882
  module.exports = {
1828
1883
  OCLCodeSystemProvider,
1884
+ OCLSourceCodeSystemProvider,
1829
1885
  OCLSourceCodeSystemFactory,
1830
1886
  OCLBackgroundJobQueue
1831
1887
  };
@@ -1,3 +1,6 @@
1
+ const Logger = require('../../../library/logger');
2
+ const oclLog = Logger.getInstance().child({ module: 'ocl' });
3
+
1
4
  class OCLBackgroundJobQueue {
2
5
  static MAX_CONCURRENT = 2;
3
6
  static HEARTBEAT_INTERVAL_MS = 30000;
@@ -42,7 +45,7 @@ class OCLBackgroundJobQueue {
42
45
  .catch((error) => {
43
46
  this.queuedOrRunningKeys.delete(jobKey);
44
47
  const message = error && error.message ? error.message : String(error);
45
- console.error(`[OCL] Failed to enqueue background job: ${jobType || 'background-job'} ${jobKey}: ${message}`);
48
+ oclLog.error(`Failed to enqueue background job: ${jobType || 'background-job'} ${jobKey}: ${message}`);
46
49
  });
47
50
 
48
51
  return true;
@@ -125,7 +128,7 @@ class OCLBackgroundJobQueue {
125
128
  lines.push(` progress: ${this.formatProgress(job.getProgress)}`);
126
129
  });
127
130
 
128
- console.log(lines.join('\n'));
131
+ oclLog.info(lines.join('\n'));
129
132
  }
130
133
 
131
134
  static formatProgress(getProgress) {
@@ -181,7 +184,7 @@ class OCLBackgroundJobQueue {
181
184
  .then(() => job.runJob())
182
185
  .catch((error) => {
183
186
  const message = error && error.message ? error.message : String(error);
184
- console.error(`[OCL] Background job failed: ${job.jobType} ${job.jobKey}: ${message}`);
187
+ oclLog.error(`Background job failed: ${job.jobType} ${job.jobKey}: ${message}`);
185
188
  })
186
189
  .finally(() => {
187
190
  this.activeCount -= 1;
@@ -8,13 +8,21 @@ function toConceptContext(concept) {
8
8
  return null;
9
9
  }
10
10
 
11
- return {
11
+ const ctx = {
12
12
  code,
13
13
  display: concept.display_name || concept.display || concept.name || null,
14
14
  definition: concept.description || concept.definition || null,
15
15
  retired: concept.retired === true,
16
16
  designation: extractDesignations(concept)
17
17
  };
18
+
19
+ const extras = concept.extras;
20
+ if (extras && typeof extras === 'object' && !Array.isArray(extras)
21
+ && Object.keys(extras).length > 0) {
22
+ ctx.extras = extras;
23
+ }
24
+
25
+ return ctx;
18
26
  }
19
27
 
20
28
  function extractDesignations(concept) {
@@ -254,9 +254,56 @@ function patchValueSetExpandWholeSystemForOcl() {
254
254
  }
255
255
 
256
256
 
257
+ const OCL_PROVIDER_FACTORY_SYNC_PATCH_FLAG = Symbol.for('fhirsmith.ocl.provider.factory-sync.patch');
258
+
259
+ function patchProviderForOCLFactorySync(getFactoriesByKey) {
260
+ let ProviderModule;
261
+ try {
262
+ ProviderModule = require('../../provider');
263
+ } catch (_error) {
264
+ return;
265
+ }
266
+
267
+ const Provider = ProviderModule?.Provider;
268
+ const proto = Provider?.prototype;
269
+ if (!proto || proto[OCL_PROVIDER_FACTORY_SYNC_PATCH_FLAG] === true) {
270
+ return;
271
+ }
272
+ if (typeof proto.updateCodeSystemList !== 'function') {
273
+ return;
274
+ }
275
+
276
+ const originalUpdateCodeSystemList = proto.updateCodeSystemList;
277
+ proto.updateCodeSystemList = async function patchedUpdateCodeSystemList() {
278
+ await originalUpdateCodeSystemList.call(this);
279
+ const factoriesByKey = getFactoriesByKey();
280
+ for (const factory of factoriesByKey.values()) {
281
+ if (!factory) continue;
282
+ const system = typeof factory.system === 'function' ? factory.system() : null;
283
+ if (!system) continue;
284
+ const ver = typeof factory.version === 'function' ? (factory.version() ?? '') : '';
285
+ const vurl = `${system}|${ver}`;
286
+ if (!this.codeSystemFactories.has(vurl)) {
287
+ if (!this.codeSystemFactories.has(system)) {
288
+ this.codeSystemFactories.set(system, factory);
289
+ }
290
+ this.codeSystemFactories.set(vurl, factory);
291
+ }
292
+ }
293
+ };
294
+
295
+ Object.defineProperty(proto, OCL_PROVIDER_FACTORY_SYNC_PATCH_FLAG, {
296
+ value: true,
297
+ writable: false,
298
+ configurable: false,
299
+ enumerable: false
300
+ });
301
+ }
302
+
257
303
  module.exports = {
258
304
  patchSearchWorkerForOCLCodeFiltering,
259
305
  ensureTxParametersHashIncludesFilter,
260
306
  patchValueSetExpandWholeSystemForOcl,
261
- normalizeFilterForCacheKey
307
+ normalizeFilterForCacheKey,
308
+ patchProviderForOCLFactorySync
262
309
  };
package/tx/ocl/vs-ocl.cjs CHANGED
@@ -13,6 +13,8 @@ const { CACHE_VS_DIR, getCacheFilePath } = require('./cache/cache-paths');
13
13
  const { ensureCacheDirectories, getColdCacheAgeMs, formatCacheAgeMinutes } = require('./cache/cache-utils');
14
14
  const { computeValueSetExpansionFingerprint } = require('./fingerprint/fingerprint');
15
15
  const { ensureTxParametersHashIncludesFilter, patchValueSetExpandWholeSystemForOcl } = require('./shared/patches');
16
+ const Logger = require('../../library/logger');
17
+ const oclVsLog = Logger.getInstance().child({ module: 'ocl-vs' });
16
18
 
17
19
 
18
20
  ensureTxParametersHashIncludesFilter(TxParameters);
@@ -122,16 +124,16 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
122
124
  this.valueSetFingerprints.set(cacheKey, cached.fingerprint || null);
123
125
  loadedCount++;
124
126
  } catch (error) {
125
- console.error(`[OCL-ValueSet] Failed to load cold cache file ${file}:`, error.message);
127
+ oclVsLog.error(`Failed to load cold cache file ${file}: ${error.message}`);
126
128
  }
127
129
  }
128
130
 
129
131
  if (loadedCount > 0) {
130
- console.log(`[OCL-ValueSet] Loaded ${loadedCount} ValueSet expansions from cold cache`);
132
+ oclVsLog.info(`Loaded ${loadedCount} ValueSet expansions from cold cache`);
131
133
  }
132
134
  } catch (error) {
133
135
  if (error.code !== 'ENOENT') {
134
- console.error('[OCL-ValueSet] Failed to load cold cache:', error.message);
136
+ oclVsLog.error(`Failed to load cold cache: ${error.message}`);
135
137
  }
136
138
  }
137
139
  }
@@ -165,11 +167,11 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
165
167
  };
166
168
 
167
169
  await fs.writeFile(cacheFilePath, JSON.stringify(cacheData, null, 2), 'utf-8');
168
- console.log(`[OCL-ValueSet] Saved ValueSet compose to cold cache: ${canonicalUrl} (${conceptCount} concepts, fingerprint=${fingerprint?.substring(0, 8)})`);
170
+ oclVsLog.info(`Saved ValueSet compose to cold cache: ${canonicalUrl} (${conceptCount} concepts, fingerprint=${fingerprint?.substring(0, 8)})`);
169
171
 
170
172
  return fingerprint;
171
173
  } catch (error) {
172
- console.error(`[OCL-ValueSet] Failed to save cold cache for ValueSet ${canonicalUrl}:`, error.message);
174
+ oclVsLog.error(`Failed to save cold cache for ValueSet ${canonicalUrl}: ${error.message}`);
173
175
  return null;
174
176
  }
175
177
  }
@@ -194,7 +196,7 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
194
196
  await this.#loadColdCacheForValueSets();
195
197
 
196
198
  const collections = await this.#fetchCollectionsForDiscovery();
197
- console.log(`[OCL-ValueSet] Fetched ${collections.length} collections`);
199
+ oclVsLog.info(`Fetched ${collections.length} collections`);
198
200
 
199
201
  for (const collection of collections) {
200
202
  const valueSet = this.#toValueSet(collection);
@@ -204,12 +206,12 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
204
206
  this.#indexValueSet(valueSet);
205
207
  }
206
208
 
207
- console.log(`[OCL-ValueSet] Loaded ${this.valueSetMap.size} value sets`);
209
+ oclVsLog.info(`Loaded ${this.valueSetMap.size} value sets`);
208
210
  this._initialized = true;
209
211
  } catch (error) {
210
- console.error(`[OCL-ValueSet] Initialization failed:`, error.message);
212
+ oclVsLog.error(`Initialization failed: ${error.message}`);
211
213
  if (error.response) {
212
- console.error(`[OCL-ValueSet] HTTP ${error.response.status}: ${error.response.statusText}`);
214
+ oclVsLog.error(`HTTP ${error.response.status}: ${error.response.statusText}`);
213
215
  }
214
216
  throw error;
215
217
  }
@@ -1104,9 +1106,9 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
1104
1106
  // Ensure no stale inline expansion
1105
1107
  delete vs.jsonObj.expansion;
1106
1108
 
1107
- console.log(`[OCL-ValueSet] compose cached: ${vs.url} (${conceptCount} concepts)`);
1109
+ oclVsLog.info(`compose cached: ${vs.url} (${conceptCount} concepts)`);
1108
1110
  } catch (error) {
1109
- console.error(`[OCL-ValueSet] ValueSet background expansion failed: ${cacheKey}: ${error.message}`);
1111
+ oclVsLog.error(`ValueSet background expansion failed: ${cacheKey}: ${error.message}`);
1110
1112
  } finally {
1111
1113
  this.backgroundExpansionProgress.delete(cacheKey);
1112
1114
  }
@@ -1350,7 +1352,7 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
1350
1352
 
1351
1353
  this._organizationIdsFetchPromise = (async () => {
1352
1354
  const endpoint = '/orgs/';
1353
- console.log(`[OCL-ValueSet] Loading organizations from: ${this.baseUrl}${endpoint}`);
1355
+ oclVsLog.info(`Loading organizations from: ${this.baseUrl}${endpoint}`);
1354
1356
  const orgs = await this.#fetchAllPages(endpoint);
1355
1357
 
1356
1358
  const ids = [];
@@ -1468,7 +1470,7 @@ class OCLValueSetProvider extends AbstractValueSetProvider {
1468
1470
  this.pendingCollectionConceptPageRequests.delete(cacheKey);
1469
1471
  }
1470
1472
  } catch (error) {
1471
- console.error(`[OCL-ValueSet] #fetchConceptPage ERROR: ${error.message}`);
1473
+ oclVsLog.error(`#fetchConceptPage ERROR: ${error.message}`);
1472
1474
  throw error;
1473
1475
  }
1474
1476
  }