fhir-validator-wrapper 1.0.0 → 1.1.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 (2) hide show
  1. package/fhir-validator.js +58 -30
  2. package/package.json +3 -3
package/fhir-validator.js CHANGED
@@ -7,14 +7,51 @@ const { URL } = require('url');
7
7
  * Node.js wrapper for the FHIR Validator HTTP Service
8
8
  */
9
9
  class FhirValidator {
10
- constructor(validatorJarPath) {
10
+ /**
11
+ * Create a new FHIR Validator instance
12
+ * @param {string} validatorJarPath - Path to the validator JAR file
13
+ * @param {Object} [logger] - Winston logger instance (optional)
14
+ */
15
+ constructor(validatorJarPath, logger = null) {
11
16
  this.validatorJarPath = validatorJarPath;
17
+ this.logger = logger; // Store the logger
12
18
  this.process = null;
13
19
  this.port = null;
14
20
  this.baseUrl = null;
15
21
  this.isReady = false;
16
22
  }
17
23
 
24
+ /**
25
+ * Set a logger after initialization
26
+ * @param {Object} logger - Winston logger instance
27
+ */
28
+ setLogger(logger) {
29
+ this.logger = logger;
30
+ }
31
+
32
+ /**
33
+ * Log a message with the appropriate level
34
+ * @private
35
+ * @param {string} level - Log level ('info', 'error', 'warn')
36
+ * @param {string} message - Message to log
37
+ * @param {Object} [meta] - Optional metadata
38
+ */
39
+ log(level, message, meta = {}) {
40
+ if (this.logger) {
41
+ // Use the Winston logger if available
42
+ this.logger[level](message, meta);
43
+ } else {
44
+ // Fall back to console
45
+ if (level === 'error') {
46
+ console.error(message, meta);
47
+ } else if (level === 'warn') {
48
+ console.warn(message, meta);
49
+ } else {
50
+ console.log(message, meta);
51
+ }
52
+ }
53
+ }
54
+
18
55
  /**
19
56
  * Start the FHIR validator service
20
57
  * @param {Object} config - Configuration object
@@ -54,7 +91,7 @@ class FhirValidator {
54
91
  args.push('-ig', ig);
55
92
  }
56
93
 
57
- console.log(`Starting FHIR validator with command: java ${args.join(' ')}`);
94
+ this.log('info', `Starting FHIR validator with command: java ${args.join(' ')}`);
58
95
 
59
96
  // Spawn the Java process
60
97
  this.process = spawn('java', args, {
@@ -63,12 +100,12 @@ class FhirValidator {
63
100
 
64
101
  // Handle process events
65
102
  this.process.on('error', (error) => {
66
- console.error('Failed to start validator process:', error);
103
+ this.log('error', 'Failed to start validator process:', error);
67
104
  throw error;
68
105
  });
69
106
 
70
107
  this.process.on('exit', (code, signal) => {
71
- console.log(`Validator process exited with code ${code} and signal ${signal}`);
108
+ this.log('info', `Validator process exited with code ${code} and signal ${signal}`);
72
109
  this.cleanup();
73
110
  });
74
111
 
@@ -79,18 +116,18 @@ class FhirValidator {
79
116
  // Remove ANSI escape sequences (color codes, etc.)
80
117
  const cleanLine = line.replace(/\u001b\[[0-9;]*m/g, '').trim();
81
118
  if (cleanLine.length > 1) { // Only log non-empty lines
82
- console.log(`Validator: ${cleanLine}`);
119
+ this.log('info', `Validator: ${cleanLine}`);
83
120
  }
84
121
  });
85
122
  });
86
123
 
87
124
  this.process.stderr.on('data', (data) => {
88
- console.error(`Validator-err: ${data}`);
125
+ this.log('error', `Validator-err: ${data}`);
89
126
  });
90
127
 
91
128
  // Wait for the service to be ready
92
129
  await this.waitForReady(timeout);
93
- console.log('FHIR validator service is ready');
130
+ this.log('info', 'FHIR validator service is ready');
94
131
  }
95
132
 
96
133
  /**
@@ -100,7 +137,7 @@ class FhirValidator {
100
137
  */
101
138
  async waitForReady(timeout) {
102
139
  const startTime = Date.now();
103
-
140
+
104
141
  while (Date.now() - startTime < timeout) {
105
142
  try {
106
143
  await this.healthCheck();
@@ -111,7 +148,7 @@ class FhirValidator {
111
148
  await new Promise(resolve => setTimeout(resolve, 1000));
112
149
  }
113
150
  }
114
-
151
+
115
152
  throw new Error(`Validator service did not become ready within ${timeout}ms`);
116
153
  }
117
154
 
@@ -181,7 +218,7 @@ class FhirValidator {
181
218
 
182
219
  // Build query parameters
183
220
  const queryParams = new URLSearchParams();
184
-
221
+
185
222
  if (options.profiles && options.profiles.length > 0) {
186
223
  queryParams.set('profiles', options.profiles.join(','));
187
224
  }
@@ -216,11 +253,11 @@ class FhirValidator {
216
253
 
217
254
  const req = http.request(requestOptions, (res) => {
218
255
  let data = '';
219
-
256
+
220
257
  res.on('data', (chunk) => {
221
258
  data += chunk;
222
259
  });
223
-
260
+
224
261
  res.on('end', () => {
225
262
  try {
226
263
  const result = JSON.parse(data);
@@ -232,7 +269,7 @@ class FhirValidator {
232
269
  });
233
270
 
234
271
  req.on('error', reject);
235
-
272
+
236
273
  req.setTimeout(30000, () => {
237
274
  req.destroy();
238
275
  reject(new Error('Validation request timeout'));
@@ -254,7 +291,7 @@ class FhirValidator {
254
291
  if (!Buffer.isBuffer(resourceBytes)) {
255
292
  throw new Error('resourceBytes must be a Buffer');
256
293
  }
257
-
294
+
258
295
  return this.validate(resourceBytes, options);
259
296
  }
260
297
 
@@ -268,7 +305,7 @@ class FhirValidator {
268
305
  if (typeof resourceObject !== 'object' || resourceObject === null) {
269
306
  throw new Error('resourceObject must be an object');
270
307
  }
271
-
308
+
272
309
  return this.validate(resourceObject, options);
273
310
  }
274
311
 
@@ -303,11 +340,11 @@ class FhirValidator {
303
340
 
304
341
  const req = http.request(requestOptions, (res) => {
305
342
  let data = '';
306
-
343
+
307
344
  res.on('data', (chunk) => {
308
345
  data += chunk;
309
346
  });
310
-
347
+
311
348
  res.on('end', () => {
312
349
  try {
313
350
  const result = JSON.parse(data);
@@ -319,7 +356,7 @@ class FhirValidator {
319
356
  });
320
357
 
321
358
  req.on('error', reject);
322
-
359
+
323
360
  req.setTimeout(30000, () => {
324
361
  req.destroy();
325
362
  reject(new Error('Load IG request timeout'));
@@ -340,7 +377,7 @@ class FhirValidator {
340
377
 
341
378
  return new Promise((resolve, reject) => {
342
379
  const timeout = setTimeout(() => {
343
- console.warn('Force killing validator process after timeout');
380
+ this.log('warn', 'Force killing validator process after timeout');
344
381
  if (this.process && !this.process.killed) {
345
382
  this.process.kill('SIGKILL');
346
383
  }
@@ -359,17 +396,8 @@ class FhirValidator {
359
396
 
360
397
  // Since Java process is blocking on System.in.read(), SIGTERM likely won't work
361
398
  // Go straight to SIGKILL for immediate termination
362
- console.log('Stopping validator process...');
399
+ this.log('info', 'Stopping validator process...');
363
400
  this.process.kill('SIGKILL');
364
-
365
- // Backup: try SIGTERM first, then SIGKILL after 2 seconds
366
- // this.process.kill('SIGTERM');
367
- // setTimeout(() => {
368
- // if (this.process && !this.process.killed) {
369
- // console.log('Escalating to SIGKILL...');
370
- // this.process.kill('SIGKILL');
371
- // }
372
- // }, 2000);
373
401
  });
374
402
  }
375
403
 
@@ -393,4 +421,4 @@ class FhirValidator {
393
421
  }
394
422
  }
395
423
 
396
- module.exports = FhirValidator;
424
+ module.exports = FhirValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fhir-validator-wrapper",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Node.js wrapper for the HL7 FHIR Validator CLI",
5
5
  "main": "fhir-validator.js",
6
6
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "repository": {
28
28
  "type": "git",
29
- "url": "https://github.com/FHIR/fhir-validator-wrapper.git"
29
+ "url": "git+https://github.com/FHIR/fhir-validator-wrapper.git"
30
30
  },
31
31
  "bugs": {
32
32
  "url": "https://github.com/FHIR/fhir-validator-wrapper/issues"
@@ -41,4 +41,4 @@
41
41
  "README.md",
42
42
  "LICENSE"
43
43
  ]
44
- }
44
+ }