hl7v2 0.14.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.
- package/README.md +23 -17
- package/cjs/constants.js +12 -0
- package/cjs/hl7-component.js +153 -0
- package/cjs/hl7-error.js +28 -0
- package/cjs/hl7-field.js +98 -0
- package/cjs/hl7-message.js +248 -0
- package/cjs/hl7-repetition.js +89 -0
- package/cjs/hl7-segment.js +80 -0
- package/cjs/hl7-sub-component.js +83 -0
- package/cjs/index.js +13 -0
- package/cjs/package.json +3 -0
- package/cjs/utils/hl7-escape.js +88 -0
- package/esm/constants.js +9 -0
- package/esm/hl7-component.js +149 -0
- package/esm/hl7-error.js +24 -0
- package/esm/hl7-field.js +94 -0
- package/esm/hl7-message.js +243 -0
- package/esm/hl7-repetition.js +85 -0
- package/esm/hl7-segment.js +76 -0
- package/esm/hl7-sub-component.js +79 -0
- package/esm/index.js +10 -0
- package/esm/package.json +3 -0
- package/esm/utils/hl7-escape.js +83 -0
- package/package.json +50 -41
- package/types/constants.d.ts +9 -0
- package/types/hl7-component.d.ts +32 -0
- package/types/hl7-error.d.ts +27 -0
- package/types/hl7-field.d.ts +44 -0
- package/types/hl7-message.d.ts +41 -0
- package/types/hl7-repetition.d.ts +35 -0
- package/types/hl7-segment.d.ts +21 -0
- package/types/hl7-sub-component.d.ts +24 -0
- package/types/index.d.cts +10 -0
- package/types/index.d.ts +10 -0
- package/types/utils/hl7-escape.d.ts +3 -0
- package/index.js +0 -40
- package/lib/HL7Field.js +0 -187
- package/lib/HL7FieldData.js +0 -171
- package/lib/HL7Message.js +0 -194
- package/lib/HL7Segment.js +0 -195
- package/lib/ParseError.js +0 -12
- package/lib/dictionary/2.1/fields.js +0 -269
- package/lib/dictionary/2.1/index.js +0 -4
- package/lib/dictionary/2.1/segments.js +0 -3363
- package/lib/dictionary/2.2/fields.js +0 -1425
- package/lib/dictionary/2.2/index.js +0 -4
- package/lib/dictionary/2.2/segments.js +0 -5828
- package/lib/dictionary/2.3/fields.js +0 -2500
- package/lib/dictionary/2.3/index.js +0 -4
- package/lib/dictionary/2.3/segments.js +0 -11295
- package/lib/dictionary/2.3.1/fields.js +0 -2768
- package/lib/dictionary/2.3.1/index.js +0 -4
- package/lib/dictionary/2.3.1/segments.js +0 -11352
- package/lib/dictionary/2.4/fields.js +0 -2898
- package/lib/dictionary/2.4/index.js +0 -4
- package/lib/dictionary/2.4/segments.js +0 -13966
- package/lib/dictionary/2.5/fields.js +0 -3636
- package/lib/dictionary/2.5/index.js +0 -4
- package/lib/dictionary/2.5/segments.js +0 -15916
- package/lib/dictionary/2.5.1/fields.js +0 -3636
- package/lib/dictionary/2.5.1/index.js +0 -4
- package/lib/dictionary/2.5.1/segments.js +0 -15969
- package/lib/dictionary/2.6/fields.js +0 -3746
- package/lib/dictionary/2.6/index.js +0 -4
- package/lib/dictionary/2.6/segments.js +0 -18890
- package/lib/dictionary/2.7/fields.js +0 -3669
- package/lib/dictionary/2.7/index.js +0 -4
- package/lib/dictionary/2.7/segments.js +0 -17066
- package/lib/dictionary/2.7.1/fields.js +0 -3669
- package/lib/dictionary/2.7.1/index.js +0 -4
- package/lib/dictionary/2.7.1/segments.js +0 -17066
- package/lib/exchange/HL7Client.js +0 -354
- package/lib/exchange/HL7MessageRouter.js +0 -76
- package/lib/exchange/HL7ProtocolBuffer.js +0 -87
- package/lib/exchange/HL7Server.js +0 -370
- package/lib/helpers.js +0 -195
- package/lib/types.js +0 -32
package/README.md
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
# HL7v2
|
|
2
|
+
|
|
2
3
|
[![NPM Version][npm-image]][npm-url]
|
|
3
4
|
[![NPM Downloads][downloads-image]][downloads-url]
|
|
4
|
-
[![
|
|
5
|
+
[![CI Tests][ci-test-image]][ci-test-url]
|
|
5
6
|
[![Test Coverage][coveralls-image]][coveralls-url]
|
|
6
7
|
|
|
7
|
-
[![Dependencies][dependencies-image]][dependencies-url]
|
|
8
|
-
[![DevDependencies][devdependencies-image]][devdependencies-url]
|
|
9
|
-
[![Package Quality][quality-image]][quality-url]
|
|
10
|
-
|
|
11
|
-
|
|
12
8
|
## About
|
|
13
9
|
|
|
14
|
-
HL7 v2 parser, serializer
|
|
15
|
-
|
|
10
|
+
HL7 v2.x parser, serializer and validator
|
|
16
11
|
|
|
17
12
|
## Installation
|
|
18
13
|
|
|
@@ -22,29 +17,40 @@ $ npm install hl7v2 --save
|
|
|
22
17
|
|
|
23
18
|
## Node Compatibility
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## Change log
|
|
28
|
-
|
|
29
|
-
To see changelog click [here](https://github.com/panates/hl7v2/commits/master)
|
|
20
|
+
- node >= 18.x
|
|
30
21
|
|
|
31
|
-
|
|
32
22
|
### License
|
|
23
|
+
|
|
33
24
|
HL7v2 is available under [MIT](LICENSE) license.
|
|
34
25
|
|
|
35
26
|
[npm-image]: https://img.shields.io/npm/v/hl7v2.svg
|
|
27
|
+
|
|
36
28
|
[npm-url]: https://npmjs.org/package/hl7v2
|
|
37
|
-
|
|
38
|
-
[
|
|
29
|
+
|
|
30
|
+
[ci-test-image]: https://github.com/panates/hl7v2/actions/workflows/test.yml/badge.svg
|
|
31
|
+
|
|
32
|
+
[ci-test-url]: https://github.com/panates/hl7v2/actions/workflows/test.yml
|
|
33
|
+
|
|
39
34
|
[coveralls-image]: https://img.shields.io/coveralls/panates/hl7v2/master.svg
|
|
35
|
+
|
|
40
36
|
[coveralls-url]: https://coveralls.io/r/panates/hl7v2
|
|
37
|
+
|
|
41
38
|
[downloads-image]: https://img.shields.io/npm/dm/hl7v2.svg
|
|
39
|
+
|
|
42
40
|
[downloads-url]: https://npmjs.org/package/hl7v2
|
|
41
|
+
|
|
43
42
|
[gitter-image]: https://badges.gitter.im/panates/hl7v2.svg
|
|
43
|
+
|
|
44
44
|
[gitter-url]: https://gitter.im/panates/hl7v2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
|
45
|
+
|
|
45
46
|
[dependencies-image]: https://david-dm.org/panates/hl7v2/status.svg
|
|
47
|
+
|
|
46
48
|
[dependencies-url]:https://david-dm.org/panates/hl7v2
|
|
49
|
+
|
|
47
50
|
[devdependencies-image]: https://david-dm.org/panates/hl7v2/dev-status.svg
|
|
51
|
+
|
|
48
52
|
[devdependencies-url]:https://david-dm.org/panates/hl7v2?type=dev
|
|
53
|
+
|
|
49
54
|
[quality-image]: http://npm.packagequality.com/shield/hl7v2.png
|
|
55
|
+
|
|
50
56
|
[quality-url]: http://packagequality.com/#?package=hl7v2
|
package/cjs/constants.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FS = exports.VT = exports.LF = exports.CR = exports.SUBCOMPONENT_SEPARATOR = exports.ESCAPE_CHARACTER = exports.REPETITION_SEPARATOR = exports.COMPONENT_SEPARATOR = exports.FIELD_SEPARATOR = void 0;
|
|
4
|
+
exports.FIELD_SEPARATOR = '|';
|
|
5
|
+
exports.COMPONENT_SEPARATOR = '^';
|
|
6
|
+
exports.REPETITION_SEPARATOR = '~';
|
|
7
|
+
exports.ESCAPE_CHARACTER = '\\';
|
|
8
|
+
exports.SUBCOMPONENT_SEPARATOR = '&';
|
|
9
|
+
exports.CR = '\x0D';
|
|
10
|
+
exports.LF = '\x0A';
|
|
11
|
+
exports.VT = '\x0B';
|
|
12
|
+
exports.FS = '\x1C';
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Hl7Component = void 0;
|
|
4
|
+
const hl7v2_dictionary_1 = require("hl7v2-dictionary");
|
|
5
|
+
const hl7_error_js_1 = require("./hl7-error.js");
|
|
6
|
+
const hl7_sub_component_js_1 = require("./hl7-sub-component.js");
|
|
7
|
+
const hl7_escape_js_1 = require("./utils/hl7-escape.js");
|
|
8
|
+
class Hl7Component {
|
|
9
|
+
constructor(repetition, position, def) {
|
|
10
|
+
this.repetition = repetition;
|
|
11
|
+
this.position = position;
|
|
12
|
+
this._definition = def;
|
|
13
|
+
this._typeDef = this.message.dictionary.types[this._definition.type];
|
|
14
|
+
if (!this._typeDef)
|
|
15
|
+
throw new Error(`Unknown data type: ${this._definition.type}`);
|
|
16
|
+
if (this.isPrimitive) {
|
|
17
|
+
this._data = new hl7_sub_component_js_1.Hl7SubComponent(this, 1, this.definition);
|
|
18
|
+
}
|
|
19
|
+
this.clear();
|
|
20
|
+
}
|
|
21
|
+
get message() {
|
|
22
|
+
return this.field.message;
|
|
23
|
+
}
|
|
24
|
+
get segment() {
|
|
25
|
+
return this.field.segment;
|
|
26
|
+
}
|
|
27
|
+
get field() {
|
|
28
|
+
return this.repetition.field;
|
|
29
|
+
}
|
|
30
|
+
get definition() {
|
|
31
|
+
return this._definition;
|
|
32
|
+
}
|
|
33
|
+
get typeDef() {
|
|
34
|
+
return this._typeDef;
|
|
35
|
+
}
|
|
36
|
+
get isPrimitive() {
|
|
37
|
+
return !this.typeDef.fields;
|
|
38
|
+
}
|
|
39
|
+
get subComponents() {
|
|
40
|
+
return this._subComponents;
|
|
41
|
+
}
|
|
42
|
+
clear() {
|
|
43
|
+
if (this.field.isPrimitive) {
|
|
44
|
+
this._data.value = undefined;
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
this._subComponents = [];
|
|
48
|
+
}
|
|
49
|
+
subcomp(position) {
|
|
50
|
+
if (this.field.isPrimitive)
|
|
51
|
+
throw new Error('Primitive fields have no sub-component');
|
|
52
|
+
if (position < 1)
|
|
53
|
+
throw new Error('Invalid sub-component position');
|
|
54
|
+
let subComponent = this._subComponents[position - 1];
|
|
55
|
+
if (!subComponent) {
|
|
56
|
+
let fDef = this.typeDef.fields?.[String(position)];
|
|
57
|
+
if (!fDef) {
|
|
58
|
+
if (position === 1)
|
|
59
|
+
fDef = this.definition;
|
|
60
|
+
else
|
|
61
|
+
fDef = {
|
|
62
|
+
type: 'ST',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
subComponent = new hl7_sub_component_js_1.Hl7SubComponent(this, position, fDef);
|
|
66
|
+
this._subComponents[position - 1] = subComponent;
|
|
67
|
+
}
|
|
68
|
+
return subComponent;
|
|
69
|
+
}
|
|
70
|
+
getValue(subComponent) {
|
|
71
|
+
if (this._data)
|
|
72
|
+
return subComponent && subComponent > 1 ? undefined : this._data.value;
|
|
73
|
+
return this._subComponents[(subComponent ?? 1) - 1]?.value;
|
|
74
|
+
}
|
|
75
|
+
setValue(value, subComponent) {
|
|
76
|
+
if (subComponent || !this._data) {
|
|
77
|
+
this.subcomp(subComponent || 1).value = value;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
this._data.value = value;
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
fromHL7String(value) {
|
|
84
|
+
if (value === '') {
|
|
85
|
+
this.setValue(undefined);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (this._data) {
|
|
89
|
+
const decode = this.definition.decode || this.typeDef.decode;
|
|
90
|
+
const unescaped = (0, hl7_escape_js_1.hl7UnEscape)(value, this.field.message);
|
|
91
|
+
try {
|
|
92
|
+
if (Buffer.isBuffer(unescaped) || unescaped == null)
|
|
93
|
+
this._data.value = unescaped;
|
|
94
|
+
else
|
|
95
|
+
this._data.value = decode ? decode(unescaped) : unescaped;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
const location = `${this.segment.segmentType}.${this.field.position}.${this.position}[${this.repetition.index}]`;
|
|
99
|
+
let segmentIndex = this.segment.index;
|
|
100
|
+
if (segmentIndex < 0)
|
|
101
|
+
segmentIndex = this.message.segments.length;
|
|
102
|
+
throw new hl7_error_js_1.HL7Error(`The field (${location}) contained data of the wrong data type. ${e.message}.`, {
|
|
103
|
+
segmentType: this.segment.segmentType,
|
|
104
|
+
segmentSequence: segmentIndex,
|
|
105
|
+
fieldPosition: this.field.position,
|
|
106
|
+
componentPosition: this.position,
|
|
107
|
+
repetitionIndex: this.repetition.index,
|
|
108
|
+
hl7ErrorCode: 102,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this._subComponents = [];
|
|
115
|
+
const subComponents = value.split(this.field.message.subComponentSeparator);
|
|
116
|
+
let pos = 1;
|
|
117
|
+
for (const subComponent of subComponents) {
|
|
118
|
+
this.subcomp(pos++).fromHL7String(subComponent);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
toHL7String(options) {
|
|
123
|
+
let str;
|
|
124
|
+
if (this._data) {
|
|
125
|
+
let v = this._data.value;
|
|
126
|
+
if (v === null)
|
|
127
|
+
return '""';
|
|
128
|
+
if (v === undefined)
|
|
129
|
+
return '';
|
|
130
|
+
const encode = this.definition.encode || this.typeDef.encode;
|
|
131
|
+
if (encode)
|
|
132
|
+
v = encode(v);
|
|
133
|
+
else {
|
|
134
|
+
if (typeof v === 'object' && v instanceof Date)
|
|
135
|
+
v = (0, hl7v2_dictionary_1.encodeHL7DateTime)(v);
|
|
136
|
+
}
|
|
137
|
+
str = (0, hl7_escape_js_1.hl7Escape)(v, this.field.message);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const { subComponentSeparator } = this.segment.message;
|
|
141
|
+
str = this._subComponents.map(subComponent => subComponent.toHL7String(options)).join(subComponentSeparator);
|
|
142
|
+
while (str.endsWith(subComponentSeparator))
|
|
143
|
+
str = str.substring(0, str.length - 1);
|
|
144
|
+
}
|
|
145
|
+
if (options?.serializeComponent)
|
|
146
|
+
return String(options?.serializeComponent(this, str, options) || '');
|
|
147
|
+
return str;
|
|
148
|
+
}
|
|
149
|
+
[Symbol.toStringTag]() {
|
|
150
|
+
return this.toHL7String();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.Hl7Component = Hl7Component;
|
package/cjs/hl7-error.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HL7Error = void 0;
|
|
4
|
+
class HL7Error extends Error {
|
|
5
|
+
constructor(message, args) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.severity = 'E';
|
|
8
|
+
if (args?.hl7ErrorCode)
|
|
9
|
+
this.hl7ErrorCode = args?.hl7ErrorCode;
|
|
10
|
+
if (args?.severity)
|
|
11
|
+
this.severity = args?.severity;
|
|
12
|
+
if (args?.appErrorCode)
|
|
13
|
+
this.appErrorCode = args?.appErrorCode;
|
|
14
|
+
if (args?.segmentType)
|
|
15
|
+
this.segmentType = args?.segmentType;
|
|
16
|
+
if (args?.segmentSequence != null)
|
|
17
|
+
this.segmentSequence = args?.segmentSequence;
|
|
18
|
+
if (args?.fieldPosition != null)
|
|
19
|
+
this.fieldPosition = args?.fieldPosition;
|
|
20
|
+
if (args?.componentPosition != null)
|
|
21
|
+
this.componentPosition = args?.componentPosition;
|
|
22
|
+
if (args?.subComponentPosition != null)
|
|
23
|
+
this.subComponentPosition = args?.subComponentPosition;
|
|
24
|
+
if (args?.repetitionIndex != null)
|
|
25
|
+
this.repetitionIndex = args?.repetitionIndex;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.HL7Error = HL7Error;
|
package/cjs/hl7-field.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HL7Field = void 0;
|
|
4
|
+
const hl7_repetition_js_1 = require("./hl7-repetition.js");
|
|
5
|
+
class HL7Field {
|
|
6
|
+
constructor(segment, position, def) {
|
|
7
|
+
this.segment = segment;
|
|
8
|
+
this.position = position;
|
|
9
|
+
this._definition = def;
|
|
10
|
+
this._typeDef = this.message.dictionary.types[this._definition.type];
|
|
11
|
+
if (!this._typeDef)
|
|
12
|
+
throw new Error(`Unknown data type: ${this._definition.type}`);
|
|
13
|
+
this.clear();
|
|
14
|
+
}
|
|
15
|
+
get message() {
|
|
16
|
+
return this.segment.message;
|
|
17
|
+
}
|
|
18
|
+
get definition() {
|
|
19
|
+
return this._definition;
|
|
20
|
+
}
|
|
21
|
+
get typeDef() {
|
|
22
|
+
return this._typeDef;
|
|
23
|
+
}
|
|
24
|
+
get isPrimitive() {
|
|
25
|
+
return !this.typeDef.fields;
|
|
26
|
+
}
|
|
27
|
+
get repetitions() {
|
|
28
|
+
return this._repetitions;
|
|
29
|
+
}
|
|
30
|
+
add() {
|
|
31
|
+
const rep = new hl7_repetition_js_1.HL7Repetition(this);
|
|
32
|
+
this._repetitions.push(rep);
|
|
33
|
+
return rep;
|
|
34
|
+
}
|
|
35
|
+
clear() {
|
|
36
|
+
this._repetitions = [];
|
|
37
|
+
}
|
|
38
|
+
repetition(repetitionIndex = 0) {
|
|
39
|
+
while (repetitionIndex >= this._repetitions.length)
|
|
40
|
+
this.add();
|
|
41
|
+
return this._repetitions[repetitionIndex];
|
|
42
|
+
}
|
|
43
|
+
component(position) {
|
|
44
|
+
return this.repetition(0).comp(position);
|
|
45
|
+
}
|
|
46
|
+
subComponent(componentPos, subComponentPos) {
|
|
47
|
+
return this.repetition(0).comp(componentPos).subcomp(subComponentPos);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Alias of .repetition()
|
|
51
|
+
*/
|
|
52
|
+
rep(repetitionIndex = 0) {
|
|
53
|
+
return this.repetition(repetitionIndex);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Alias of .component()
|
|
57
|
+
*/
|
|
58
|
+
comp(position) {
|
|
59
|
+
return this.component(position);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Alias of .subComponent()
|
|
63
|
+
*/
|
|
64
|
+
subcomp(componentPos, subComponentPos) {
|
|
65
|
+
return this.subComponent(componentPos, subComponentPos);
|
|
66
|
+
}
|
|
67
|
+
getValue(component, subComponent) {
|
|
68
|
+
return this._repetitions[0]?.getValue(component, subComponent);
|
|
69
|
+
}
|
|
70
|
+
setValue(value, component, subComponent) {
|
|
71
|
+
return this.repetition(0).setValue(value, component, subComponent);
|
|
72
|
+
}
|
|
73
|
+
fromHL7String(value) {
|
|
74
|
+
const components = value.split(this.message.repetitionSeparator);
|
|
75
|
+
this._repetitions = [];
|
|
76
|
+
for (const cmp of components) {
|
|
77
|
+
this.add().fromHL7String(cmp);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
toHL7String(options) {
|
|
81
|
+
if (!this._repetitions.length)
|
|
82
|
+
return '';
|
|
83
|
+
const { repetitionSeparator } = this.segment.message;
|
|
84
|
+
let str = this._repetitions
|
|
85
|
+
.map(component => component.toHL7String(options))
|
|
86
|
+
.join(repetitionSeparator);
|
|
87
|
+
while (str.endsWith(repetitionSeparator))
|
|
88
|
+
str = str.substring(0, str.length - 1);
|
|
89
|
+
if (options?.serializeField) {
|
|
90
|
+
return options.serializeField(this, str, options) || '';
|
|
91
|
+
}
|
|
92
|
+
return str;
|
|
93
|
+
}
|
|
94
|
+
[Symbol.toStringTag]() {
|
|
95
|
+
return this.toHL7String();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.HL7Field = HL7Field;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HL7Message = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const hl7v2_dictionary_1 = require("hl7v2-dictionary");
|
|
6
|
+
const iconv_lite_1 = tslib_1.__importDefault(require("iconv-lite"));
|
|
7
|
+
const uid_1 = require("uid");
|
|
8
|
+
const constants_js_1 = require("./constants.js");
|
|
9
|
+
const hl7_error_js_1 = require("./hl7-error.js");
|
|
10
|
+
const hl7_segment_js_1 = require("./hl7-segment.js");
|
|
11
|
+
class HL7Message {
|
|
12
|
+
constructor(version = hl7v2_dictionary_1.HL7Version.v2_7_1, dictionaries) {
|
|
13
|
+
this.fieldSeparator = constants_js_1.FIELD_SEPARATOR;
|
|
14
|
+
this.componentSeparator = constants_js_1.COMPONENT_SEPARATOR;
|
|
15
|
+
this.subComponentSeparator = constants_js_1.SUBCOMPONENT_SEPARATOR;
|
|
16
|
+
this.repetitionSeparator = constants_js_1.REPETITION_SEPARATOR;
|
|
17
|
+
this.escapeCharacter = constants_js_1.ESCAPE_CHARACTER;
|
|
18
|
+
this.carriageReturn = constants_js_1.CR;
|
|
19
|
+
this._dictionaries = dictionaries || hl7v2_dictionary_1.dictionaries;
|
|
20
|
+
this._version = version;
|
|
21
|
+
this.clear(version);
|
|
22
|
+
}
|
|
23
|
+
get dictionary() {
|
|
24
|
+
return this._dictionary;
|
|
25
|
+
}
|
|
26
|
+
get segments() {
|
|
27
|
+
return this._segments;
|
|
28
|
+
}
|
|
29
|
+
get header() {
|
|
30
|
+
return this.getSegment('MSH');
|
|
31
|
+
}
|
|
32
|
+
get version() {
|
|
33
|
+
return this._version;
|
|
34
|
+
}
|
|
35
|
+
get messageType() {
|
|
36
|
+
return this.header.field(hl7v2_dictionary_1.MSHSegment.MessageType).toHL7String();
|
|
37
|
+
}
|
|
38
|
+
get controlId() {
|
|
39
|
+
return this.header.field(hl7v2_dictionary_1.MSHSegment.MessageControlID).toHL7String();
|
|
40
|
+
}
|
|
41
|
+
clear(version) {
|
|
42
|
+
if (!version)
|
|
43
|
+
version = this._version || hl7v2_dictionary_1.HL7Version.v2_7_1;
|
|
44
|
+
this._version = version;
|
|
45
|
+
const nearestVersion = (0, hl7v2_dictionary_1.findNearestHL7Version)(version);
|
|
46
|
+
this._dictionary = this._dictionaries[nearestVersion];
|
|
47
|
+
this._segments = [];
|
|
48
|
+
const msh = this.addSegment('MSH');
|
|
49
|
+
msh.field(hl7v2_dictionary_1.MSHSegment.DateTimeOfMessage).setValue(new Date());
|
|
50
|
+
msh.field(hl7v2_dictionary_1.MSHSegment.MessageControlID).setValue((0, uid_1.uid)(8));
|
|
51
|
+
msh.field(hl7v2_dictionary_1.MSHSegment.VersionID).setValue(version);
|
|
52
|
+
msh.field(hl7v2_dictionary_1.MSHSegment.CharacterSet).setValue('UTF-8');
|
|
53
|
+
}
|
|
54
|
+
addSegment(segmentType) {
|
|
55
|
+
const segment = new hl7_segment_js_1.HL7Segment(this, segmentType);
|
|
56
|
+
this.segments.push(segment);
|
|
57
|
+
return segment;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Searches for a segment of a given type
|
|
61
|
+
*/
|
|
62
|
+
getSegment(segmentType, index = 0) {
|
|
63
|
+
let k = 0;
|
|
64
|
+
for (const seg of this.segments) {
|
|
65
|
+
if (seg.segmentType === segmentType) {
|
|
66
|
+
if (!index || index === k)
|
|
67
|
+
return seg;
|
|
68
|
+
k++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Searches for a segment of a given type in reverse order
|
|
74
|
+
*/
|
|
75
|
+
getSegmentFromLast(segmentType, index = 0) {
|
|
76
|
+
for (let k = this.segments.length - 1; k >= 0; k--) {
|
|
77
|
+
const seg = this.segments[k];
|
|
78
|
+
if (seg.segmentType === segmentType) {
|
|
79
|
+
if (!index || index === k)
|
|
80
|
+
return seg;
|
|
81
|
+
k++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
toHL7String(options) {
|
|
86
|
+
return (this.segments
|
|
87
|
+
.map(segment => segment.toHL7String(options))
|
|
88
|
+
.filter(v => v)
|
|
89
|
+
.join(this.carriageReturn) + this.carriageReturn);
|
|
90
|
+
}
|
|
91
|
+
parse(input) {
|
|
92
|
+
let headerStr = '';
|
|
93
|
+
if (Buffer.isBuffer(input)) {
|
|
94
|
+
let crIdx = input.indexOf(constants_js_1.CR);
|
|
95
|
+
if (crIdx < 0)
|
|
96
|
+
crIdx = input.length;
|
|
97
|
+
headerStr = input.toString('utf8', 0, crIdx);
|
|
98
|
+
}
|
|
99
|
+
else if (typeof input === 'string') {
|
|
100
|
+
let crIdx = input.indexOf(constants_js_1.CR);
|
|
101
|
+
if (crIdx < 0)
|
|
102
|
+
crIdx = input.length;
|
|
103
|
+
headerStr = input.substring(0, crIdx);
|
|
104
|
+
} /* c8 ignore else */
|
|
105
|
+
else {
|
|
106
|
+
throw new TypeError('You must provide string or Buffer argument');
|
|
107
|
+
}
|
|
108
|
+
if (headerStr.startsWith(constants_js_1.VT))
|
|
109
|
+
headerStr = headerStr.substring(1);
|
|
110
|
+
if (!headerStr.startsWith('MSH'))
|
|
111
|
+
throw new hl7_error_js_1.HL7Error('Message must start with (MSH) segment', {
|
|
112
|
+
line: 1,
|
|
113
|
+
hl7ErrorCode: 100,
|
|
114
|
+
});
|
|
115
|
+
const fieldSeparator = headerStr[3];
|
|
116
|
+
/* Detect version and charset */
|
|
117
|
+
const headerItems = headerStr.split(fieldSeparator);
|
|
118
|
+
const version = headerItems[11];
|
|
119
|
+
const encoding = headerItems[17]?.split('^')[0];
|
|
120
|
+
let str = Buffer.isBuffer(input) ? iconv_lite_1.default.decode(input, encoding) : input;
|
|
121
|
+
if (str.startsWith(constants_js_1.VT))
|
|
122
|
+
str = str.substring(1);
|
|
123
|
+
const k = str.indexOf(constants_js_1.FS);
|
|
124
|
+
if (k >= 0)
|
|
125
|
+
str = str.substring(0, k);
|
|
126
|
+
this.clear(version);
|
|
127
|
+
this.fieldSeparator = fieldSeparator;
|
|
128
|
+
this.componentSeparator = headerItems[1][0];
|
|
129
|
+
this.repetitionSeparator = headerItems[1][1];
|
|
130
|
+
this.escapeCharacter = headerItems[1][2];
|
|
131
|
+
this.subComponentSeparator = headerItems[1][3];
|
|
132
|
+
this._segments = [];
|
|
133
|
+
const lines = str.split(constants_js_1.CR);
|
|
134
|
+
for (const [i, line] of lines.entries()) {
|
|
135
|
+
if (!line)
|
|
136
|
+
continue;
|
|
137
|
+
try {
|
|
138
|
+
const segment = hl7_segment_js_1.HL7Segment.parse(this, line);
|
|
139
|
+
this._segments.push(segment);
|
|
140
|
+
}
|
|
141
|
+
catch (e) {
|
|
142
|
+
if (!this.header) {
|
|
143
|
+
this.addSegment('MSH');
|
|
144
|
+
}
|
|
145
|
+
this.header
|
|
146
|
+
.field(hl7v2_dictionary_1.MSHSegment.SendingApplication)
|
|
147
|
+
.setValue(headerItems[2]);
|
|
148
|
+
this.header.field(hl7v2_dictionary_1.MSHSegment.SendingFacility).setValue(headerItems[3]);
|
|
149
|
+
this.header
|
|
150
|
+
.field(hl7v2_dictionary_1.MSHSegment.ReceivingApplication)
|
|
151
|
+
.setValue(headerItems[4]);
|
|
152
|
+
this.header
|
|
153
|
+
.field(hl7v2_dictionary_1.MSHSegment.ReceivingFacility)
|
|
154
|
+
.setValue(headerItems[5]);
|
|
155
|
+
this.header.field(hl7v2_dictionary_1.MSHSegment.EncodingCharacters).setValue(encoding);
|
|
156
|
+
this.header.field(hl7v2_dictionary_1.MSHSegment.MessageControlID).setValue(headerItems[9]);
|
|
157
|
+
this.header.field(hl7v2_dictionary_1.MSHSegment.VersionID).setValue(version);
|
|
158
|
+
/* c8 ignore next */
|
|
159
|
+
const e1 = e instanceof hl7_error_js_1.HL7Error ? e : new hl7_error_js_1.HL7Error(e.message);
|
|
160
|
+
if (e1.segmentType) {
|
|
161
|
+
const lastSeg = this.getSegmentFromLast(e.segmentType);
|
|
162
|
+
if (lastSeg)
|
|
163
|
+
e1.segmentSequence = lastSeg.index;
|
|
164
|
+
}
|
|
165
|
+
e1.line = i + 1;
|
|
166
|
+
throw e1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
createAck(ackCode = 'AA', textMessage) {
|
|
171
|
+
const out = new HL7Message(this.version);
|
|
172
|
+
const msh = out.header;
|
|
173
|
+
// Sending Application
|
|
174
|
+
msh
|
|
175
|
+
.field(hl7v2_dictionary_1.MSHSegment.ReceivingApplication)
|
|
176
|
+
.setValue(msh.field(hl7v2_dictionary_1.MSHSegment.SendingFacility).getValue());
|
|
177
|
+
msh
|
|
178
|
+
.field(hl7v2_dictionary_1.MSHSegment.ReceivingFacility)
|
|
179
|
+
.setValue(this.header.field(hl7v2_dictionary_1.MSHSegment.SendingFacility).getValue());
|
|
180
|
+
msh.field(hl7v2_dictionary_1.MSHSegment.MessageType).setValue('ACK');
|
|
181
|
+
msh
|
|
182
|
+
.field(hl7v2_dictionary_1.MSHSegment.MessageType)
|
|
183
|
+
.comp(2)
|
|
184
|
+
.setValue(this.header.field(hl7v2_dictionary_1.MSHSegment.MessageType).getValue(2));
|
|
185
|
+
msh
|
|
186
|
+
.field(hl7v2_dictionary_1.MSHSegment.MessageControlID)
|
|
187
|
+
.setValue(String(Date.now() + (0, uid_1.uid)(5)));
|
|
188
|
+
const msa = out.addSegment('MSA');
|
|
189
|
+
msa.field(hl7v2_dictionary_1.MSASegment.AcknowledgmentCode).setValue(ackCode);
|
|
190
|
+
msa
|
|
191
|
+
.field(hl7v2_dictionary_1.MSASegment.MessageControlID)
|
|
192
|
+
.setValue(this.header.field(hl7v2_dictionary_1.MSHSegment.MessageControlID).getValue());
|
|
193
|
+
if (textMessage) {
|
|
194
|
+
if (textMessage instanceof hl7_error_js_1.HL7Error) {
|
|
195
|
+
msa.field(hl7v2_dictionary_1.MSASegment.TextMessage).setValue(textMessage.message);
|
|
196
|
+
const err = out.addSegment('ERR');
|
|
197
|
+
err
|
|
198
|
+
.field(hl7v2_dictionary_1.ERRSegment.HL7ErrorCode)
|
|
199
|
+
.setValue(textMessage.hl7ErrorCode || 207);
|
|
200
|
+
err.field(hl7v2_dictionary_1.ERRSegment.Severity).setValue(textMessage.severity);
|
|
201
|
+
err
|
|
202
|
+
.field(hl7v2_dictionary_1.ERRSegment.ApplicationErrorCode)
|
|
203
|
+
.setValue(textMessage.appErrorCode);
|
|
204
|
+
const errLocation = err.field(hl7v2_dictionary_1.ERRSegment.ErrorLocation);
|
|
205
|
+
errLocation.comp(hl7v2_dictionary_1.ERLType.SegmentID).setValue(textMessage.segmentType);
|
|
206
|
+
errLocation
|
|
207
|
+
.comp(hl7v2_dictionary_1.ERLType.SegmentSequence)
|
|
208
|
+
.setValue(textMessage.segmentSequence);
|
|
209
|
+
errLocation
|
|
210
|
+
.comp(hl7v2_dictionary_1.ERLType.FieldPosition)
|
|
211
|
+
.setValue(textMessage.fieldPosition);
|
|
212
|
+
errLocation
|
|
213
|
+
.comp(hl7v2_dictionary_1.ERLType.ComponentNumber)
|
|
214
|
+
.setValue(textMessage.componentPosition);
|
|
215
|
+
errLocation
|
|
216
|
+
.comp(hl7v2_dictionary_1.ERLType.FieldRepetition)
|
|
217
|
+
.setValue(textMessage.repetitionIndex);
|
|
218
|
+
errLocation
|
|
219
|
+
.comp(hl7v2_dictionary_1.ERLType.SubComponentNumber)
|
|
220
|
+
.setValue(textMessage.subComponentPosition);
|
|
221
|
+
}
|
|
222
|
+
else if (textMessage instanceof Error) {
|
|
223
|
+
msa.field(hl7v2_dictionary_1.MSASegment.TextMessage).setValue(textMessage.message);
|
|
224
|
+
const err = out.addSegment('ERR');
|
|
225
|
+
err.field(hl7v2_dictionary_1.ERRSegment.HL7ErrorCode).setValue(207);
|
|
226
|
+
err.field(hl7v2_dictionary_1.ERRSegment.Severity).setValue('E');
|
|
227
|
+
if (textMessage.code)
|
|
228
|
+
err
|
|
229
|
+
.field(hl7v2_dictionary_1.ERRSegment.ApplicationErrorCode)
|
|
230
|
+
.setValue(textMessage);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
msa.field(hl7v2_dictionary_1.MSASegment.TextMessage).setValue(textMessage);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return out;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
*
|
|
240
|
+
* @static
|
|
241
|
+
*/
|
|
242
|
+
static parse(input, dictionaries) {
|
|
243
|
+
const message = new HL7Message(undefined, dictionaries);
|
|
244
|
+
message.parse(input);
|
|
245
|
+
return message;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.HL7Message = HL7Message;
|