fastify-hl7 3.2.0 → 4.0.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/CHANGELOG.md +57 -0
- package/README.md +388 -60
- package/dist/api.d.ts +5 -0
- package/{lib/types → dist}/class/hL7Client.d.ts +49 -13
- package/{lib/esm → dist}/class/hL7Server.d.ts +2 -2
- package/dist/index.cjs +403 -0
- package/dist/index.cjs.map +1 -0
- package/{lib/types → dist}/index.d.ts +3 -3
- package/dist/index.mjs +377 -0
- package/dist/index.mjs.map +1 -0
- package/{lib/esm → dist}/types.d.ts +30 -21
- package/dist/validation.d.ts +6 -0
- package/package.json +43 -48
- package/lib/cjs/api.js +0 -13
- package/lib/cjs/class/hL7Client.js +0 -238
- package/lib/cjs/class/hL7Server.js +0 -81
- package/lib/cjs/decorate.js +0 -2
- package/lib/cjs/errors.js +0 -13
- package/lib/cjs/index.js +0 -144
- package/lib/cjs/package.json +0 -3
- package/lib/cjs/types.js +0 -2
- package/lib/cjs/validation.js +0 -15
- package/lib/esm/api.d.ts +0 -7
- package/lib/esm/api.js +0 -5
- package/lib/esm/class/hL7Client.d.ts +0 -99
- package/lib/esm/class/hL7Client.js +0 -201
- package/lib/esm/class/hL7Server.js +0 -77
- package/lib/esm/decorate.js +0 -1
- package/lib/esm/errors.js +0 -7
- package/lib/esm/index.d.ts +0 -5
- package/lib/esm/index.js +0 -125
- package/lib/esm/package.json +0 -3
- package/lib/esm/types.js +0 -1
- package/lib/esm/validation.d.ts +0 -6
- package/lib/esm/validation.js +0 -11
- package/lib/types/api.d.ts +0 -7
- package/lib/types/class/hL7Server.d.ts +0 -38
- package/lib/types/decorate.d.ts +0 -38
- package/lib/types/errors.d.ts +0 -10
- package/lib/types/types.d.ts +0 -66
- package/lib/types/validation.d.ts +0 -6
- package/{lib/esm → dist}/decorate.d.ts +16 -16
- /package/{lib/esm → dist}/errors.d.ts +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Fastify HL7
|
|
2
|
+
|
|
3
|
+
## v4.0.0 - 2026-06-08
|
|
4
|
+
|
|
5
|
+
### What Changed 👀
|
|
6
|
+
|
|
7
|
+
#### 💥 Breaking Changes
|
|
8
|
+
|
|
9
|
+
- feat!: upgrade to node-hl7 v4.0.0 @Bugs5382 (#88)
|
|
10
|
+
|
|
11
|
+
#### 🚀 Features
|
|
12
|
+
|
|
13
|
+
- feat(api): verified message builder (createBuilder) + v4.0.0 docs @Bugs5382 (#107)
|
|
14
|
+
|
|
15
|
+
#### 🧩 Dependency Updates
|
|
16
|
+
|
|
17
|
+
- chore(deps-dev): bump the development-dependencies group across 1 directory with 15 updates @[dependabot[bot]](https://github.com/apps/dependabot) (#97)
|
|
18
|
+
|
|
19
|
+
### Extra
|
|
20
|
+
|
|
21
|
+
**Full Changelog**: https://github.com/Bugs5382/fastify-hl7/compare/v3.3.0...v4.0.0
|
|
22
|
+
|
|
23
|
+
## v3.3.0 - 2025-03-25
|
|
24
|
+
|
|
25
|
+
#### What Changed 👀
|
|
26
|
+
|
|
27
|
+
#### 🧩 Dependency Updates
|
|
28
|
+
|
|
29
|
+
- feat: update dependencies @Bugs5382 (#84)
|
|
30
|
+
|
|
31
|
+
### Extra
|
|
32
|
+
|
|
33
|
+
**Full Changelog**: https://github.com/Bugs5382/fastify-hl7/compare/v3.2.0...v3.3.0
|
|
34
|
+
|
|
35
|
+
## v3.2.0 - 2024-12-18
|
|
36
|
+
|
|
37
|
+
#### What Changed 👀
|
|
38
|
+
|
|
39
|
+
#### 🚀 Features
|
|
40
|
+
|
|
41
|
+
- feat: hl7 startup message @Bugs5382 (#83)
|
|
42
|
+
|
|
43
|
+
### Extra
|
|
44
|
+
|
|
45
|
+
**Full Changelog**: https://github.com/Bugs5382/fastify-hl7/compare/v3.1.0...v3.2.0
|
|
46
|
+
|
|
47
|
+
## v3.1.0 - 2024-11-16
|
|
48
|
+
|
|
49
|
+
#### What Changed 👀
|
|
50
|
+
|
|
51
|
+
#### 🚀 Features
|
|
52
|
+
|
|
53
|
+
- feat: updated packages @Bugs5382 (#81)
|
|
54
|
+
|
|
55
|
+
### Extra
|
|
56
|
+
|
|
57
|
+
**Full Changelog**: https://github.com/Bugs5382/fastify-hl7/compare/v3.0.0...v3.1.0
|
package/README.md
CHANGED
|
@@ -1,121 +1,449 @@
|
|
|
1
|
-
# Fastify HL7
|
|
1
|
+
# 🏥 Fastify HL7
|
|
2
2
|
|
|
3
|
-
A Fastify
|
|
4
|
-
It
|
|
3
|
+
A Fastify HL7 plugin developed in pure TypeScript.
|
|
4
|
+
It wraps the `node-hl7-client` and `node-hl7-server` packages — both shipped from the
|
|
5
|
+
[`node-hl7`](https://github.com/Bugs5382/node-hl7) repo — so a Fastify app can send and
|
|
6
|
+
receive HL7 v2.x messages over MLLP.
|
|
5
7
|
|
|
6
|
-
The build exports
|
|
8
|
+
The build exports valid ESM and CJS for cross-compatibility.
|
|
7
9
|
|
|
8
|
-
If you
|
|
9
|
-
|
|
10
|
+
If you use this package, please consider giving it a ⭐ — it raises visibility and brings in more
|
|
11
|
+
contribution from the outside.
|
|
10
12
|
|
|
11
|
-
This documentation
|
|
12
|
-
|
|
13
|
+
> This documentation covers **how to use the plugin**. It does not re-document the underlying
|
|
14
|
+
> libraries (segment-by-segment message building, transport internals). For those, see
|
|
15
|
+
> [External Libraries](#-external-libraries).
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
> 🟢 **Requires Node.js ≥ 22** (inherited from the underlying `node-hl7` packages).
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
2.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
3. [Full Documentation](#full-documentation)
|
|
21
|
-
1. [This Library Options](#this-library-options)
|
|
22
|
-
2. [External Libraries Options](#external-libraries-options)
|
|
23
|
-
4. [Acknowledgements](#acknowledgements)
|
|
24
|
-
5. [License](#license)
|
|
19
|
+
> ⚠️ **HL7 version is required.** Every client and every inbound listener must pin an explicit
|
|
20
|
+
> `version` — one of `"2.1" | "2.2" | "2.3" | "2.3.1" | "2.4" | "2.5" | "2.5.1" | "2.6" | "2.7" |
|
|
21
|
+
> "2.7.1" | "2.8"`. There is no default. A client's `version` must match the `MSH.12` of every
|
|
22
|
+
> message it sends; an inbound listener rejects (`AR`) any message whose `MSH.12` differs.
|
|
25
23
|
|
|
26
|
-
##
|
|
24
|
+
## Table of Contents
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
1. [Install](#-install)
|
|
27
|
+
2. [Basic Usage](#-basic-usage)
|
|
28
|
+
1. [Register the plugin](#register-the-plugin)
|
|
29
|
+
2. [Server quick start](#server-quick-start)
|
|
30
|
+
3. [Client quick start](#client-quick-start)
|
|
31
|
+
3. [Recipes](#-recipes)
|
|
32
|
+
1. [Full round-trip in one app](#1-full-round-trip-in-one-app)
|
|
33
|
+
2. [Route multiple inbound listeners](#2-route-multiple-inbound-listeners)
|
|
34
|
+
3. [Multiple clients and outbound connections](#3-multiple-clients-and-outbound-connections)
|
|
35
|
+
4. [Build messages, batches, and file batches](#4-build-messages-batches-and-file-batches)
|
|
36
|
+
5. [Parse inbound HL7 and read files](#5-parse-inbound-hl7-and-read-files)
|
|
37
|
+
6. [ACK / NAK responses](#6-ack--nak-responses)
|
|
38
|
+
7. [Graceful shutdown](#7-graceful-shutdown)
|
|
39
|
+
8. [TLS and server options](#8-tls-and-server-options)
|
|
40
|
+
9. [Look up live clients and listeners](#9-look-up-live-clients-and-listeners)
|
|
41
|
+
10. [Error handling when the server is disabled](#10-error-handling-when-the-server-is-disabled)
|
|
42
|
+
4. [API Reference](#-api-reference-fastifyhl7)
|
|
43
|
+
5. [Plugin Options](#-plugin-options)
|
|
44
|
+
6. [External Libraries](#-external-libraries)
|
|
45
|
+
7. [Acknowledgements](#-acknowledgements)
|
|
46
|
+
8. [License](#-license)
|
|
47
|
+
|
|
48
|
+
## 📦 Install
|
|
49
|
+
|
|
50
|
+
```shell
|
|
29
51
|
npm install fastify-hl7
|
|
30
52
|
```
|
|
31
53
|
|
|
32
|
-
|
|
54
|
+
Requires Node.js ≥ 22.
|
|
55
|
+
|
|
56
|
+
## 🚀 Basic Usage
|
|
33
57
|
|
|
34
|
-
Register
|
|
58
|
+
### Register the plugin
|
|
35
59
|
|
|
36
60
|
```ts
|
|
37
|
-
|
|
61
|
+
import fastify from "fastify";
|
|
62
|
+
import fastifyHL7 from "fastify-hl7";
|
|
63
|
+
|
|
64
|
+
const app = fastify();
|
|
65
|
+
|
|
66
|
+
await app.register(fastifyHL7);
|
|
38
67
|
```
|
|
39
68
|
|
|
40
|
-
|
|
69
|
+
Registering decorates the Fastify instance with `app.hl7` — the single entry point for HL7
|
|
70
|
+
clients, inbound listeners, and message builders. By default the inbound **server** is enabled;
|
|
71
|
+
pass `{ enableServer: false }` for a client-only app (see [Plugin Options](#-plugin-options)).
|
|
72
|
+
|
|
73
|
+
### Server quick start
|
|
74
|
+
|
|
75
|
+
Create an inbound listener. It must pin an HL7 `version`. The handler receives each inbound message
|
|
76
|
+
and replies with an acknowledgement code (`"AA"` accept, `"AE"` error, `"AR"` reject):
|
|
41
77
|
|
|
42
78
|
```ts
|
|
43
|
-
const listener =
|
|
79
|
+
const listener = app.hl7.createInbound(
|
|
44
80
|
"ib_adt",
|
|
45
|
-
{ port: 3001 },
|
|
81
|
+
{ port: 3001, version: "2.7" },
|
|
46
82
|
async (req, res) => {
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
83
|
+
const message = req.getMessage();
|
|
84
|
+
const type = req.getType();
|
|
85
|
+
app.log.info("received %s", type);
|
|
86
|
+
// ...your logic here...
|
|
50
87
|
await res.sendResponse("AA");
|
|
51
88
|
},
|
|
52
89
|
);
|
|
53
90
|
```
|
|
54
91
|
|
|
55
|
-
|
|
92
|
+
`createInbound` returns the listener so you can attach advanced event handlers if needed. Any inbound
|
|
93
|
+
message whose `MSH.12` is not `"2.7"` is rejected with an `AR` before your handler runs.
|
|
94
|
+
|
|
95
|
+
### Client quick start
|
|
96
|
+
|
|
97
|
+
A **client** is a named handle to one remote host and pins the HL7 `version` for everything it
|
|
98
|
+
sends. Outbound **connections** are attached to that client by its name — so the first argument to
|
|
99
|
+
`createConnection` is the **client name**, not a new identifier (it inherits the client's version):
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
// 1. Register a named client pointed at a remote host, pinned to an HL7 version.
|
|
103
|
+
app.hl7.createClient("adt_host", { host: "127.0.0.1", version: "2.7" });
|
|
104
|
+
|
|
105
|
+
// 2. Attach an outbound connection to that client (note: "adt_host" matches above).
|
|
106
|
+
const connection = app.hl7.createConnection(
|
|
107
|
+
"adt_host",
|
|
108
|
+
{ port: 3001 },
|
|
109
|
+
async (res) => {
|
|
110
|
+
const reply = res.getMessage();
|
|
111
|
+
// Handle the ACK/NAK the remote returned, e.g. res.getMessage().get("MSA.1").
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// 3. Build a message (its MSH.12 must match the client version) and send it.
|
|
116
|
+
const message = app.hl7.buildMessage({
|
|
117
|
+
messageHeader: {
|
|
118
|
+
msh_9_1: "ADT",
|
|
119
|
+
msh_9_2: "A01",
|
|
120
|
+
msh_10: "MSG00001",
|
|
121
|
+
msh_11_1: "P",
|
|
122
|
+
msh_12: "2.7",
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await connection.sendMessage(message);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The client name is a unique identifier for a host, so you can attach several outbound connections
|
|
130
|
+
(different ports) to the same host, and create several clients for different hosts.
|
|
131
|
+
|
|
132
|
+
> ⚠️ A client name must be unique and may not contain spaces or the characters
|
|
133
|
+
> `` `!@#$%^&*()+-=[]{};':"\|,.<>/?~ ``. The same rule applies to inbound listener names.
|
|
56
134
|
|
|
57
|
-
|
|
135
|
+
## 🧩 Recipes
|
|
136
|
+
|
|
137
|
+
### 1. Full round-trip in one app
|
|
138
|
+
|
|
139
|
+
A single Fastify app that listens for inbound HL7 **and** sends outbound HL7 to itself — useful for
|
|
140
|
+
local testing or a relay. Keep the versions aligned across the listener, the client, and the
|
|
141
|
+
message:
|
|
58
142
|
|
|
59
143
|
```ts
|
|
60
144
|
import fastify from "fastify";
|
|
145
|
+
import fastifyHL7 from "fastify-hl7";
|
|
146
|
+
|
|
147
|
+
const app = fastify();
|
|
148
|
+
await app.register(fastifyHL7);
|
|
149
|
+
|
|
150
|
+
// Inbound: accept everything, echo back an "AA".
|
|
151
|
+
app.hl7.createInbound("ib_adt", { port: 3001, version: "2.7" }, async (req, res) => {
|
|
152
|
+
app.log.info("inbound %s", req.getType());
|
|
153
|
+
await res.sendResponse("AA");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Outbound: a client pointed at our own listener, same version.
|
|
157
|
+
app.hl7.createClient("self", { host: "127.0.0.1", version: "2.7" });
|
|
158
|
+
const out = app.hl7.createConnection("self", { port: 3001 }, async (res) => {
|
|
159
|
+
app.log.info("ack: %s", res.getMessage().get("MSA.1").toString());
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
await app.listen({ port: 3000 });
|
|
163
|
+
|
|
164
|
+
const message = app.hl7.buildMessage({
|
|
165
|
+
messageHeader: { msh_9_1: "ADT", msh_9_2: "A01", msh_11_1: "P", msh_12: "2.7" },
|
|
166
|
+
});
|
|
167
|
+
await out.sendMessage(message);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 2. Route multiple inbound listeners
|
|
171
|
+
|
|
172
|
+
One server hosts many inbound listeners on different ports — for example, one per feed. Each pins
|
|
173
|
+
its own version:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
app.hl7.createInbound("adt_feed", { port: 3001, version: "2.7" }, async (req, res) => {
|
|
177
|
+
// ADT (admit/discharge/transfer) feed.
|
|
178
|
+
await res.sendResponse("AA");
|
|
179
|
+
});
|
|
61
180
|
|
|
62
|
-
|
|
181
|
+
app.hl7.createInbound("oru_feed", { port: 3002, version: "2.7" }, async (req, res) => {
|
|
182
|
+
// ORU (observation result) feed; branch on the message type.
|
|
183
|
+
if (req.getType() === "ORU") {
|
|
184
|
+
// ...persist the result...
|
|
185
|
+
await res.sendResponse("AA");
|
|
186
|
+
} else {
|
|
187
|
+
await res.sendResponse("AR"); // reject anything unexpected on this port
|
|
188
|
+
}
|
|
189
|
+
});
|
|
63
190
|
```
|
|
64
191
|
|
|
65
|
-
|
|
66
|
-
|
|
192
|
+
> There is only **one** server per host (the machine this runs on), but it can host any number of
|
|
193
|
+
> inbound listeners on distinct ports.
|
|
67
194
|
|
|
68
|
-
|
|
195
|
+
### 3. Multiple clients and outbound connections
|
|
69
196
|
|
|
70
|
-
|
|
71
|
-
and
|
|
197
|
+
An interface engine often talks to several downstream systems. Create one client per host (each with
|
|
198
|
+
its version), and one connection per port on that host:
|
|
72
199
|
|
|
73
200
|
```ts
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
201
|
+
app.hl7.createClient("lab", { host: "10.0.0.10", version: "2.5.1" });
|
|
202
|
+
app.hl7.createClient("pharmacy", { host: "10.0.0.20", version: "2.7" });
|
|
203
|
+
|
|
204
|
+
const labOrders = app.hl7.createConnection("lab", { port: 6661 }, async () => {});
|
|
205
|
+
const labResults = app.hl7.createConnection("lab", { port: 6662 }, async () => {});
|
|
206
|
+
const rxOrders = app.hl7.createConnection("pharmacy", { port: 6661 }, async () => {});
|
|
207
|
+
|
|
208
|
+
await labOrders.sendMessage(
|
|
209
|
+
app.hl7.buildMessage({
|
|
210
|
+
messageHeader: { msh_9_1: "ORM", msh_9_2: "O01", msh_11_1: "P", msh_12: "2.5.1" },
|
|
211
|
+
}),
|
|
81
212
|
);
|
|
213
|
+
```
|
|
82
214
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
215
|
+
Reusing the same port on the same client throws — pick a distinct outbound port per connection.
|
|
216
|
+
|
|
217
|
+
### 4. Build messages, batches, and file batches
|
|
218
|
+
|
|
219
|
+
For a **validated** message, use `createBuilder(version)`. It returns node-hl7-client's
|
|
220
|
+
version-pinned builder, which validates every field against that HL7 version (withdrawn fields throw,
|
|
221
|
+
backward-compatibility fields warn, segments not in the version are rejected) and sets `MSH.12` to
|
|
222
|
+
the version for you. Chain `build*` calls and finish with `toMessage()`:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
const message = app.hl7
|
|
226
|
+
.createBuilder("2.7")
|
|
227
|
+
.buildMSH({
|
|
228
|
+
msh_3: "MY_APP",
|
|
229
|
+
msh_4: "MY_FAC",
|
|
230
|
+
msh_5: "EPIC",
|
|
231
|
+
msh_6: "HOSP",
|
|
86
232
|
msh_9_1: "ADT",
|
|
87
233
|
msh_9_2: "A01",
|
|
88
|
-
|
|
234
|
+
msh_10: "MSG00001",
|
|
235
|
+
msh_11_1: "P",
|
|
236
|
+
})
|
|
237
|
+
.buildPID({ pid_3: "MRN12345", pid_5: "DOE^JANE^A", pid_8: "F" })
|
|
238
|
+
.toMessage();
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Because the builder pins the version, its `MSH.12` always matches a client created with the same
|
|
242
|
+
`version`. For a lightweight, **unvalidated** message, `buildMessage` constructs one directly (set
|
|
243
|
+
`messageHeader.msh_12` yourself):
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
const quick = app.hl7.buildMessage({
|
|
247
|
+
messageHeader: { msh_9_1: "ADT", msh_9_2: "A01", msh_11_1: "P", msh_12: "2.7" },
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// A batch (BHS) that groups several messages.
|
|
251
|
+
const batch = app.hl7.buildBatch();
|
|
252
|
+
batch.start();
|
|
253
|
+
batch.add(message);
|
|
254
|
+
batch.end();
|
|
255
|
+
|
|
256
|
+
// A file batch (FHS) for writing HL7 to disk.
|
|
257
|
+
const fileBatch = app.hl7.buildFileBatch();
|
|
258
|
+
|
|
259
|
+
// An HL7-formatted timestamp (length 8, 12, or 14 — 14 is the default).
|
|
260
|
+
const stamp = app.hl7.buildDate(new Date(), 14);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
> `buildFileBatch` is for *creating* a file batch — to read an existing one, use `readFile` /
|
|
264
|
+
> `readFileBuffer` ([recipe 5](#5-parse-inbound-hl7-and-read-files)).
|
|
265
|
+
|
|
266
|
+
### 5. Parse inbound HL7 and read files
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
// Parse a raw string — returns a Batch if it starts with BHS, otherwise a Message.
|
|
270
|
+
const parsed = app.hl7.processHL7(rawHl7String);
|
|
271
|
+
|
|
272
|
+
// Read a file batch from disk.
|
|
273
|
+
const fromPath = app.hl7.readFile("temp/hl7.readTestBHS.20231208.hl7");
|
|
274
|
+
|
|
275
|
+
// Or from a Buffer you already have in memory.
|
|
276
|
+
import { readFileSync } from "node:fs";
|
|
277
|
+
const fromBuffer = app.hl7.readFileBuffer(readFileSync("temp/hl7.readTestBHS.20231208.hl7"));
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 6. ACK / NAK responses
|
|
281
|
+
|
|
282
|
+
Inside an inbound handler, reply with the acknowledgement code that fits the outcome:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
app.hl7.createInbound("ib_adt", { port: 3001, version: "2.7" }, async (req, res) => {
|
|
286
|
+
try {
|
|
287
|
+
const message = req.getMessage();
|
|
288
|
+
// ...process the message...
|
|
289
|
+
await res.sendResponse("AA"); // Application Accept
|
|
290
|
+
} catch (err) {
|
|
291
|
+
req.log?.error(err);
|
|
292
|
+
await res.sendResponse("AE"); // Application Error
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Use `"AR"` (Application Reject) for messages you will not process at all (wrong type, unsupported
|
|
298
|
+
trigger, etc.). For verbatim, vendor-shaped acknowledgements, `node-hl7-server` exposes
|
|
299
|
+
`sendCustomResponse`.
|
|
300
|
+
|
|
301
|
+
### 7. Graceful shutdown
|
|
302
|
+
|
|
303
|
+
You do **not** need to close clients or listeners by hand. The plugin registers Fastify `preClose`
|
|
304
|
+
hooks that close every outbound connection and inbound listener when the app shuts down:
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
const app = fastify();
|
|
308
|
+
await app.register(fastifyHL7);
|
|
309
|
+
// ...create clients and listeners...
|
|
310
|
+
|
|
311
|
+
// On app.close() / SIGINT, all HL7 connections close automatically.
|
|
312
|
+
await app.close();
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
To close a single listener early, use `app.hl7.closeServer(port)`; to close them all,
|
|
316
|
+
`app.hl7.closeServerAll()`.
|
|
317
|
+
|
|
318
|
+
### 8. TLS and server options
|
|
319
|
+
|
|
320
|
+
Server options pass straight through to `node-hl7-server` and can only be set at registration time
|
|
321
|
+
(you cannot change them after the server is created):
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
import { readFileSync } from "node:fs";
|
|
325
|
+
|
|
326
|
+
await app.register(fastifyHL7, {
|
|
327
|
+
serverOptions: {
|
|
328
|
+
// e.g. bindAddress, IPv6, or TLS — see node-hl7-server's ServerOptions.
|
|
329
|
+
bindAddress: "0.0.0.0",
|
|
330
|
+
tls: {
|
|
331
|
+
key: readFileSync("server.key"),
|
|
332
|
+
cert: readFileSync("server.crt"),
|
|
333
|
+
},
|
|
89
334
|
},
|
|
90
335
|
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Client-side TLS is set per client via the `tls` option on `createClient`
|
|
339
|
+
(`{ host, version, tls: true | ConnectionOptions }`).
|
|
340
|
+
|
|
341
|
+
### 9. Look up live clients and listeners
|
|
91
342
|
|
|
92
|
-
|
|
343
|
+
Retrieve handles you created earlier, by name or by port:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
const labClient = app.hl7.getClientByName("lab"); // Client | undefined
|
|
347
|
+
const conn = app.hl7.getClientConnectionByPort("6661"); // Connection | undefined
|
|
348
|
+
|
|
349
|
+
const adtListener = app.hl7.getServerByName("adt_feed"); // Inbound | undefined
|
|
350
|
+
const onPort = app.hl7.getServerByPort("3001"); // Inbound | undefined
|
|
93
351
|
```
|
|
94
352
|
|
|
95
|
-
|
|
353
|
+
### 10. Error handling when the server is disabled
|
|
354
|
+
|
|
355
|
+
If you register with `{ enableServer: false }`, every server-side method throws a usage error.
|
|
356
|
+
Guard accordingly:
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
await app.register(fastifyHL7, { enableServer: false });
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
app.hl7.createInbound("ib", { port: 3001, version: "2.7" }, async () => {});
|
|
363
|
+
} catch (err) {
|
|
364
|
+
// FASTIFY_HL7_ERR_USAGE: "server was not started.
|
|
365
|
+
// re-register plugin with enableServer set to true."
|
|
366
|
+
app.log.error(err);
|
|
367
|
+
}
|
|
368
|
+
```
|
|
96
369
|
|
|
97
|
-
|
|
370
|
+
Registering the plugin twice also throws (`FASTIFY_HL7_ERR_SETUP_ERRORS: "Already registered."`).
|
|
371
|
+
|
|
372
|
+
## 📖 API Reference (`fastify.hl7`)
|
|
373
|
+
|
|
374
|
+
All methods hang off the `hl7` decorator on the Fastify instance.
|
|
375
|
+
|
|
376
|
+
### Inbound / server
|
|
377
|
+
|
|
378
|
+
| Method | Returns | Description |
|
|
379
|
+
|---|---|---|
|
|
380
|
+
| `createInbound(name, options, handler)` | `Inbound` | Start an inbound listener on `options.port` pinned to `options.version`; `handler(req, res)` handles each message. |
|
|
381
|
+
| `closeServer(port)` | `Promise<boolean>` | Close the listener on `port`. |
|
|
382
|
+
| `closeServerAll()` | `Promise<boolean>` | Close all listeners. |
|
|
383
|
+
| `getServerByName(name)` | `Inbound \| undefined` | Look up a listener by name. |
|
|
384
|
+
| `getServerByPort(port)` | `Inbound \| undefined` | Look up a listener by port. |
|
|
385
|
+
|
|
386
|
+
The server methods throw `FASTIFY_HL7_ERR_USAGE` when the plugin was registered with
|
|
387
|
+
`enableServer: false`.
|
|
388
|
+
|
|
389
|
+
### Outbound / client
|
|
390
|
+
|
|
391
|
+
| Method | Returns | Description |
|
|
392
|
+
|---|---|---|
|
|
393
|
+
| `createClient(name, options)` | `Client` | Register a uniquely named client pointed at `options.host` and pinned to `options.version`. |
|
|
394
|
+
| `createConnection(name, options, handler)` | `Connection` | Attach an outbound connection (on `options.port`) to the client called `name`; `handler(res)` handles the reply. |
|
|
395
|
+
| `getClientByName(name)` | `Client \| undefined` | Look up a client by name. |
|
|
396
|
+
| `getClientConnectionByPort(port)` | `Connection \| undefined` | Look up an outbound connection by port. |
|
|
397
|
+
|
|
398
|
+
### Builders
|
|
399
|
+
|
|
400
|
+
| Method | Returns | Description |
|
|
401
|
+
|---|---|---|
|
|
402
|
+
| `createBuilder(version, options?)` | `HL7_2_x` | Version-pinned, **validated** builder; chain `build*` then `.toMessage()`. Rejects fields/segments not valid for the version. |
|
|
403
|
+
| `buildMessage(options?)` | `Message` | Build a single HL7 message directly, **unvalidated** (set `messageHeader.msh_12` to the client version). |
|
|
404
|
+
| `buildBatch(options?)` | `Batch` | Build an HL7 batch (BHS). |
|
|
405
|
+
| `buildFileBatch(options?)` | `FileBatch` | Build an HL7 file batch (FHS) for writing. |
|
|
406
|
+
| `buildDate(date, length?)` | `string` | Format a `Date` as an HL7 timestamp (length `8`, `12`, or `14`; default `14`). |
|
|
407
|
+
|
|
408
|
+
### Parsing & files
|
|
409
|
+
|
|
410
|
+
| Method | Returns | Description |
|
|
411
|
+
|---|---|---|
|
|
412
|
+
| `processHL7(text)` | `Batch \| Message` | Parse raw HL7 — `Batch` if it starts with BHS, else `Message`. |
|
|
413
|
+
| `readFile(fullFilePath)` | `FileBatch` | Read a file batch from a path. |
|
|
414
|
+
| `readFileBuffer(buffer)` | `FileBatch` | Read a file batch from a `Buffer`. |
|
|
415
|
+
|
|
416
|
+
## ⚙️ Plugin Options
|
|
417
|
+
|
|
418
|
+
Pass these to `app.register(fastifyHL7, options)`:
|
|
98
419
|
|
|
99
420
|
### `enableServer`
|
|
100
421
|
|
|
101
|
-
|
|
422
|
+
`boolean` — defaults to `true`. Set to `false` to turn off the inbound server (client-only app).
|
|
423
|
+
While disabled, the server-side methods throw `FASTIFY_HL7_ERR_USAGE`.
|
|
102
424
|
|
|
103
425
|
### `serverOptions`
|
|
104
426
|
|
|
105
|
-
|
|
106
|
-
|
|
427
|
+
The `ServerOptions` from
|
|
428
|
+
[`node-hl7-server`](https://github.com/Bugs5382/node-hl7) — `bindAddress`, encoding, TLS, and other
|
|
429
|
+
server-creation settings. It can only be set at registration time.
|
|
430
|
+
|
|
431
|
+
> Per-client and per-listener settings (including the required HL7 `version`, host, port, and TLS)
|
|
432
|
+
> are passed to `createClient` / `createConnection` / `createInbound`, not here.
|
|
107
433
|
|
|
108
|
-
|
|
434
|
+
## 🔌 External Libraries
|
|
109
435
|
|
|
110
|
-
|
|
111
|
-
|
|
436
|
+
This plugin documents only its own surface. For segment-by-segment message building (the class-based
|
|
437
|
+
`HL7_2_x` builders), transport internals, parsing, and the full client/server option sets, see the
|
|
438
|
+
[`node-hl7`](https://github.com/Bugs5382/node-hl7) repo, which ships both packages:
|
|
112
439
|
|
|
113
|
-
|
|
440
|
+
- `node-hl7-client` — Client, Parser, and Builder options.
|
|
441
|
+
- `node-hl7-server` — Server and Inbound options.
|
|
114
442
|
|
|
115
|
-
## Acknowledgements
|
|
443
|
+
## 🙏 Acknowledgements
|
|
116
444
|
|
|
117
445
|
- My Wife and Baby Girl.
|
|
118
446
|
|
|
119
|
-
## License
|
|
447
|
+
## 📄 License
|
|
120
448
|
|
|
121
449
|
Licensed under [MIT](./LICENSE).
|
package/dist/api.d.ts
ADDED