hl7v2 0.9.1 → 0.12.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.
- package/lib/HL7Field.js +5 -2
- package/lib/HL7FieldData.js +7 -2
- package/lib/HL7Message.js +19 -8
- package/lib/HL7Segment.js +22 -4
- package/lib/exchange/HL7Client.js +22 -7
- package/lib/exchange/HL7Server.js +9 -6
- package/package.json +1 -1
package/lib/HL7Field.js
CHANGED
|
@@ -14,8 +14,10 @@ class HL7Field {
|
|
|
14
14
|
* @param {HL7Segment} segment
|
|
15
15
|
* @param {string} name
|
|
16
16
|
* @param {Object} def
|
|
17
|
+
* @param {Object} [customDict]
|
|
18
|
+
* @param {Object} [customDict.fields]
|
|
17
19
|
*/
|
|
18
|
-
constructor(segment, name, def) {
|
|
20
|
+
constructor(segment, name, def, customDict) {
|
|
19
21
|
Object.defineProperty(this, '_segment', {
|
|
20
22
|
value: segment,
|
|
21
23
|
enumerable: false
|
|
@@ -23,6 +25,7 @@ class HL7Field {
|
|
|
23
25
|
this._name = name;
|
|
24
26
|
this._def = def;
|
|
25
27
|
this._data = null;
|
|
28
|
+
this._customDict = customDict;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -131,7 +134,7 @@ class HL7Field {
|
|
|
131
134
|
|
|
132
135
|
add() {
|
|
133
136
|
this._data = this._data || [];
|
|
134
|
-
const data = new HL7FieldData(this, this._def);
|
|
137
|
+
const data = new HL7FieldData(this, this._def, undefined, this._customDict);
|
|
135
138
|
const k = this._data.length;
|
|
136
139
|
this._data.push(data);
|
|
137
140
|
Object.defineProperty(this, k, {
|
package/lib/HL7FieldData.js
CHANGED
|
@@ -15,8 +15,10 @@ class HL7FieldData {
|
|
|
15
15
|
* @param {HL7Field} field
|
|
16
16
|
* @param {Object} def
|
|
17
17
|
* @param {Number} level
|
|
18
|
+
* @param {Object} [customDict]
|
|
19
|
+
* @param {Object} [customDict.fields]
|
|
18
20
|
*/
|
|
19
|
-
constructor(field, def, level) {
|
|
21
|
+
constructor(field, def, level, customDict) {
|
|
20
22
|
Object.defineProperty(this, '_field', {
|
|
21
23
|
value: field,
|
|
22
24
|
enumerable: false
|
|
@@ -25,8 +27,11 @@ class HL7FieldData {
|
|
|
25
27
|
this._level = level || 0;
|
|
26
28
|
this._items = null;
|
|
27
29
|
this._value = null;
|
|
30
|
+
this._customDict = customDict;
|
|
28
31
|
|
|
29
32
|
const dict = require('./dictionary/' + this.message.version);
|
|
33
|
+
if (this._customDict && this._customDict.fields)
|
|
34
|
+
dict.fields = {...dict.fields, ...this._customDict.fields};
|
|
30
35
|
const fldDict = dict.fields[def.dt];
|
|
31
36
|
/* istanbul ignore next */
|
|
32
37
|
if (!fldDict)
|
|
@@ -50,7 +55,7 @@ class HL7FieldData {
|
|
|
50
55
|
defineComponent(sequence, def) {
|
|
51
56
|
this._items = this._items || [];
|
|
52
57
|
const index = sequence - 1;
|
|
53
|
-
const comp = new HL7FieldData(this._field, def, 1);
|
|
58
|
+
const comp = new HL7FieldData(this._field, def, 1, this._customDict);
|
|
54
59
|
Object.defineProperty(this, sequence, {
|
|
55
60
|
get: () => this._items[index],
|
|
56
61
|
enumerable: false
|
package/lib/HL7Message.js
CHANGED
|
@@ -25,11 +25,13 @@ class HL7Message {
|
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* @param {Object} [options]
|
|
28
|
+
* @param {Object} [options.customDict]
|
|
28
29
|
*/
|
|
29
30
|
constructor(options) {
|
|
30
31
|
options = options || {};
|
|
31
32
|
this.version = options.version;
|
|
32
33
|
this._segments = [];
|
|
34
|
+
this._customDict = options.customDict;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -68,7 +70,7 @@ class HL7Message {
|
|
|
68
70
|
* @return {HL7Segment}
|
|
69
71
|
*/
|
|
70
72
|
add(type) {
|
|
71
|
-
const segment = new HL7Segment(this);
|
|
73
|
+
const segment = new HL7Segment(this, {customDict: this._customDict});
|
|
72
74
|
segment.parse(type);
|
|
73
75
|
this.segments.push(segment);
|
|
74
76
|
return segment;
|
|
@@ -94,15 +96,21 @@ class HL7Message {
|
|
|
94
96
|
|
|
95
97
|
/**
|
|
96
98
|
*
|
|
97
|
-
* @param {Buffer|
|
|
99
|
+
* @param {Buffer|string} buf
|
|
98
100
|
* @param {Object} [options]
|
|
99
101
|
* @param {string} [options.encoding='utf8']
|
|
102
|
+
* @param {Object} [options.customDict]
|
|
100
103
|
* @private
|
|
101
104
|
*/
|
|
102
105
|
parse(buf, options) {
|
|
103
106
|
this._segments = [];
|
|
107
|
+
|
|
108
|
+
let customDict = this._customDict;
|
|
109
|
+
if (options && options.customDict)
|
|
110
|
+
customDict = options.customDict;
|
|
111
|
+
|
|
104
112
|
let str;
|
|
105
|
-
if (buf instanceof
|
|
113
|
+
if (buf instanceof Buffer) {
|
|
106
114
|
let encoding = (options && options.encoding) || 'utf8';
|
|
107
115
|
/* Character set detection */
|
|
108
116
|
const sep = FIELD_SEPARATOR.charCodeAt(0);
|
|
@@ -121,8 +129,11 @@ class HL7Message {
|
|
|
121
129
|
}
|
|
122
130
|
} while (l > 0 && l < crIdx);
|
|
123
131
|
str = iconv.decode(buf, encoding.replace(/^UNICODE/, ''));
|
|
124
|
-
} else
|
|
125
|
-
str =
|
|
132
|
+
} else if (typeof buf === 'string') {
|
|
133
|
+
str = buf;
|
|
134
|
+
} else {
|
|
135
|
+
throw new ArgumentError('You must provide string or Buffer argument');
|
|
136
|
+
}
|
|
126
137
|
|
|
127
138
|
if (str.startsWith(VT))
|
|
128
139
|
str = str.substring(1);
|
|
@@ -137,11 +148,11 @@ class HL7Message {
|
|
|
137
148
|
if (!str.startsWith('MSH'))
|
|
138
149
|
throw new ParseError('Message must start with (MSH) segment');
|
|
139
150
|
|
|
140
|
-
const lines = str.split(
|
|
151
|
+
const lines = str.split(CR);
|
|
141
152
|
for (const [i, line] of lines.entries()) {
|
|
142
153
|
if (!line)
|
|
143
154
|
continue;
|
|
144
|
-
const segment = new HL7Segment(this);
|
|
155
|
+
const segment = new HL7Segment(this, {customDict});
|
|
145
156
|
try {
|
|
146
157
|
segment.parse(line);
|
|
147
158
|
} catch (e) {
|
|
@@ -164,7 +175,7 @@ class HL7Message {
|
|
|
164
175
|
}
|
|
165
176
|
|
|
166
177
|
static parse(input, options) {
|
|
167
|
-
const msg = new HL7Message();
|
|
178
|
+
const msg = new HL7Message(options);
|
|
168
179
|
msg.parse(input, options);
|
|
169
180
|
return msg;
|
|
170
181
|
}
|
package/lib/HL7Segment.js
CHANGED
|
@@ -27,14 +27,32 @@ class HL7Segment {
|
|
|
27
27
|
/**
|
|
28
28
|
*
|
|
29
29
|
* @param {HL7Message} message
|
|
30
|
+
* @param {Object} [options]
|
|
31
|
+
* @param {Object} [options.customDict]
|
|
30
32
|
*/
|
|
31
|
-
constructor(message) {
|
|
33
|
+
constructor(message, options) {
|
|
32
34
|
Object.defineProperty(this, '_message', {
|
|
33
35
|
value: message,
|
|
34
36
|
enumerable: false
|
|
35
37
|
});
|
|
36
38
|
this._type = null;
|
|
37
39
|
this._fields = null;
|
|
40
|
+
if (options && options.customDict)
|
|
41
|
+
this._customDict = options.customDict;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getDict(version) {
|
|
45
|
+
const dict = require(path.resolve(__dirname, 'dictionary', version));
|
|
46
|
+
return {
|
|
47
|
+
fields: {
|
|
48
|
+
...dict.fields,
|
|
49
|
+
...(this._customDict || {}).fields
|
|
50
|
+
},
|
|
51
|
+
segments: {
|
|
52
|
+
...dict.segments,
|
|
53
|
+
...(this._customDict || {}).segments
|
|
54
|
+
}
|
|
55
|
+
};
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
/**
|
|
@@ -71,7 +89,7 @@ class HL7Segment {
|
|
|
71
89
|
if (typeof def !== 'object')
|
|
72
90
|
throw new ArgumentError('You must provide config object');
|
|
73
91
|
|
|
74
|
-
const dict =
|
|
92
|
+
const dict = this.getDict(this.message.version);
|
|
75
93
|
const dataType = def.dt;
|
|
76
94
|
const fldDict = dict.fields[dataType];
|
|
77
95
|
if (!fldDict)
|
|
@@ -81,7 +99,7 @@ class HL7Segment {
|
|
|
81
99
|
const name = def.desc ?
|
|
82
100
|
capitalizeFirst(def.desc).replace(/[^\w]/g, '') :
|
|
83
101
|
'CustomField' + sequence;
|
|
84
|
-
const field = this._fields[index] = new HL7Field(this, name, def);
|
|
102
|
+
const field = this._fields[index] = new HL7Field(this, name, def, this._customDict);
|
|
85
103
|
delete this[sequence];
|
|
86
104
|
delete this[name];
|
|
87
105
|
Object.defineProperty(this, sequence, {
|
|
@@ -107,7 +125,7 @@ class HL7Segment {
|
|
|
107
125
|
|
|
108
126
|
const segmentType = values[0];
|
|
109
127
|
const sequence = values[1];
|
|
110
|
-
const dict =
|
|
128
|
+
const dict = this.getDict(this.message.version);
|
|
111
129
|
const segDict = dict.segments[segmentType];
|
|
112
130
|
if (!segDict) {
|
|
113
131
|
const e = new ParseError('Unknown HL7 segment type (%s)', segmentType);
|
|
@@ -17,10 +17,25 @@ class HL7Client extends EventEmitter {
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
*
|
|
20
|
-
* @param {net.Socket} [
|
|
20
|
+
* @param {net.Socket|Object} [param1]
|
|
21
|
+
* @param {Object} [param2]
|
|
22
|
+
* @param {Object} [param2.customDict]
|
|
21
23
|
*/
|
|
22
|
-
constructor(
|
|
24
|
+
constructor(param1, param2) {
|
|
23
25
|
super();
|
|
26
|
+
let options;
|
|
27
|
+
let socket = undefined;
|
|
28
|
+
if (param2 !== undefined) {
|
|
29
|
+
socket = param1;
|
|
30
|
+
options = param2 || {};
|
|
31
|
+
} else if (param1 instanceof net.Socket) {
|
|
32
|
+
socket = param1;
|
|
33
|
+
} else {
|
|
34
|
+
options = param1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (options && options.customDict)
|
|
38
|
+
this._customDict = options.customDict;
|
|
24
39
|
if (socket && !(socket instanceof net.Socket))
|
|
25
40
|
throw new ArgumentError('You can provide Socket instance as fist argument');
|
|
26
41
|
this._extSocket = socket;
|
|
@@ -147,7 +162,7 @@ class HL7Client extends EventEmitter {
|
|
|
147
162
|
this._buffer.on('block', data => this._onHL7Data(data));
|
|
148
163
|
|
|
149
164
|
this._socket = socket = socket ||
|
|
150
|
-
(opts.cert ? tls.connect(opts) : net.connect(opts));
|
|
165
|
+
(opts.protocol === 'mllps' || opts.cert ? tls.connect(opts) : net.connect(opts));
|
|
151
166
|
|
|
152
167
|
socket.removeListener('connect', this._connectionListener);
|
|
153
168
|
socket.removeListener('secureConnect', this._connectionListener);
|
|
@@ -214,7 +229,7 @@ class HL7Client extends EventEmitter {
|
|
|
214
229
|
send(msg) {
|
|
215
230
|
return new Promise(resolve => {
|
|
216
231
|
if (typeof msg === 'string')
|
|
217
|
-
msg = HL7Message.parse(msg);
|
|
232
|
+
msg = HL7Message.parse(msg, {customDict: this._customDict});
|
|
218
233
|
|
|
219
234
|
/* istanbul ignore next */
|
|
220
235
|
if (!(msg instanceof HL7Message))
|
|
@@ -228,7 +243,7 @@ class HL7Client extends EventEmitter {
|
|
|
228
243
|
msg.MSH.MessageControlId.value = ++this._controlIdSeq;
|
|
229
244
|
|
|
230
245
|
const str = msg.toHL7();
|
|
231
|
-
let charset = 'utf8';
|
|
246
|
+
let charset = this.encoding || 'utf8';
|
|
232
247
|
if (msg.MSH[18]) {
|
|
233
248
|
if (this.encoding && !msg.MSH[18].value)
|
|
234
249
|
msg.MSH[18].value = this.encoding;
|
|
@@ -248,7 +263,7 @@ class HL7Client extends EventEmitter {
|
|
|
248
263
|
sendReceive(msg, timeout) {
|
|
249
264
|
return Promise.resolve().then(() => {
|
|
250
265
|
if (typeof msg === 'string')
|
|
251
|
-
msg = HL7Message.parse(msg);
|
|
266
|
+
msg = HL7Message.parse(msg, {customDict: this._customDict});
|
|
252
267
|
}).then(() => this.send(msg))
|
|
253
268
|
.then(() => {
|
|
254
269
|
|
|
@@ -293,7 +308,7 @@ class HL7Client extends EventEmitter {
|
|
|
293
308
|
_onHL7Data(data) {
|
|
294
309
|
let msg;
|
|
295
310
|
try {
|
|
296
|
-
msg = HL7Message.parse(data, {encoding: this.encoding});
|
|
311
|
+
msg = HL7Message.parse(data, {encoding: this.encoding, customDict: this._customDict});
|
|
297
312
|
} catch (e) /* istanbul ignore next */ {
|
|
298
313
|
e.message = 'Invalid HL7 data received from server. ' + e.message;
|
|
299
314
|
this.emitSafe('error', e);
|
|
@@ -22,12 +22,13 @@ class HL7Server extends EventEmitter {
|
|
|
22
22
|
* @param {Object} [param2]
|
|
23
23
|
* @param {string} [param2.applicationName]
|
|
24
24
|
* @param {string} [param2.facilityName]
|
|
25
|
-
* @param {string} [param2.
|
|
25
|
+
* @param {string} [param2.encoding]
|
|
26
26
|
* @param {string} [param2.defaultVersion]
|
|
27
27
|
* @param {number} [param2.maxBufferPerSocket]
|
|
28
28
|
* @param {string} [param2.cert]
|
|
29
29
|
* @param {string} [param2.key]
|
|
30
30
|
* @param {boolean} [param2.rejectUnauthorized]
|
|
31
|
+
* @param {Object} [param2.customDict]
|
|
31
32
|
*/
|
|
32
33
|
constructor(param1, param2) {
|
|
33
34
|
super();
|
|
@@ -56,6 +57,7 @@ class HL7Server extends EventEmitter {
|
|
|
56
57
|
options.maxBufferPerSocket : 5;
|
|
57
58
|
this.shutdownWait = options.shutdownWait;
|
|
58
59
|
this._controlIdSeq = 0;
|
|
60
|
+
this._customDict = options.customDict;
|
|
59
61
|
|
|
60
62
|
this._connectionListener = (socket) => this._onConnect(socket);
|
|
61
63
|
this._closeListener = (...args) => this.emitSafe('close', ...args);
|
|
@@ -220,14 +222,14 @@ class HL7Server extends EventEmitter {
|
|
|
220
222
|
/**
|
|
221
223
|
*
|
|
222
224
|
* @param {net.Socket} socket
|
|
223
|
-
* @param {
|
|
225
|
+
* @param {Buffer} block
|
|
224
226
|
* @private
|
|
225
227
|
*/
|
|
226
228
|
_onHl7Block(socket, block) {
|
|
227
229
|
let msg;
|
|
228
230
|
// Parse message
|
|
229
231
|
try {
|
|
230
|
-
msg = HL7Message.parse(block, {encoding: this.
|
|
232
|
+
msg = HL7Message.parse(block, {encoding: this.encoding, customDict: this._customDict});
|
|
231
233
|
socket._errorCount = 0;
|
|
232
234
|
} catch (e) {
|
|
233
235
|
const ack = this._createACK(msg, 'AR',
|
|
@@ -288,14 +290,14 @@ class HL7Server extends EventEmitter {
|
|
|
288
290
|
return new Promise(resolve => {
|
|
289
291
|
/* istanbul ignore next: same in client */
|
|
290
292
|
if (typeof msg === 'string')
|
|
291
|
-
msg = HL7Message.parse(msg);
|
|
293
|
+
msg = HL7Message.parse(msg, {customDict: this._customDict});
|
|
292
294
|
|
|
293
295
|
/* istanbul ignore next */
|
|
294
296
|
if (!(msg instanceof HL7Message))
|
|
295
297
|
throw new ArgumentError('You must provide HL7Message or string argument');
|
|
296
298
|
|
|
297
299
|
const str = msg.toHL7();
|
|
298
|
-
let charset = 'utf8';
|
|
300
|
+
let charset = this.encoding || 'utf8';
|
|
299
301
|
/* istanbul ignore next: same in client */
|
|
300
302
|
if (msg.MSH[18]) {
|
|
301
303
|
if (this.encoding && !msg.MSH[18].value)
|
|
@@ -318,7 +320,8 @@ class HL7Server extends EventEmitter {
|
|
|
318
320
|
*/
|
|
319
321
|
_createACK(req, ackCode, textMessage) {
|
|
320
322
|
const ack = new HL7Message({
|
|
321
|
-
version: (req && req.MSH.VersionId.value) || '2.5'
|
|
323
|
+
version: (req && req.MSH.VersionId.value) || '2.5',
|
|
324
|
+
customDict: this._customDict
|
|
322
325
|
});
|
|
323
326
|
const msh = ack.add('MSH');
|
|
324
327
|
msh[3].value = this.applicationName;
|
package/package.json
CHANGED