@rethinkhealth/hl7v2-message-structure
v0.10.1
Published
Unified plugin to infer HL7v2 message structure from message code and trigger event
Maintainers
Readme
@rethinkhealth/hl7v2-annotate-message-structure
unified plugin to infer HL7v2 message structure when MSH-9.3 is missing.
Contents
What is this?
This package is a unified plugin that resolves the message structure (MSH-9.3) from message code (MSH-9.1) and trigger event (MSH-9.2) when the structure field is not present in the HL7v2 message.
Real-world HL7v2 messages often omit MSH-9.3, especially in older versions. This plugin resolves the canonical structure using built-in event maps from @rethinkhealth/hl7v2-profiles. For example, ADT^A04 resolves to ADT_A01 because A04 uses the A01 message structure definition. When the event is not found in the map, it falls back to naive concatenation: {messageCode}_{triggerEvent}.
When should I use this?
Use this plugin when:
- Processing HL7v2 messages that may not include MSH-9.3
- You want to normalize message metadata for downstream processing
- You need to ensure all messages have a message structure for routing or validation
Note: This plugin requires @rethinkhealth/hl7v2-annotate-message to run first to extract message metadata.
Install
npm install @rethinkhealth/hl7v2-annotate-message-structureUse
import { unified } from "unified";
import { hl7v2Parser } from "@rethinkhealth/hl7v2-parser";
import { hl7v2AnnotateMessage } from "@rethinkhealth/hl7v2-annotate-message";
import { hl7v2AnnotateMessageStructure } from "@rethinkhealth/hl7v2-annotate-message-structure";
const processor = unified()
.use(hl7v2Parser)
.use(hl7v2AnnotateMessage)
.use(hl7v2AnnotateMessageStructure);
// Message without MSH-9.3
const message = "MSH|^~\\&|SENDER||RECEIVER||20241201||ADT^A01|MSG123|P|2.5";
const tree = processor.parse(message);
await processor.run(tree);
console.log(tree.data.messageInfo);
// {
// version: "2.5",
// messageCode: "ADT",
// triggerEvent: "A01",
// messageStructure: "ADT_A01" // ← Inferred!
// }API
This package exports the identifier hl7v2AnnotateMessageStructure. There is no default export.
unified().use(hl7v2AnnotateMessageStructure[, options])
Resolve message structure from message code and trigger event.
This plugin:
- Checks if
tree.data.messageInfo.messageStructureis already set - If missing, checks for
messageCode,triggerEvent, andversion - Constructs
{messageCode}_{triggerEvent}and resolves it against the event map - Sets
messageStructureto the resolved value, or leaves itundefinedif not found
Parameters
options(AnnotateMessageStructureOptions, optional)eventMap(Record<string, Record<string, string>>) — Custom event map to use instead of the built-in profile event maps. Keyed by version, then by candidate (e.g."ADT_A04") to canonical structure (e.g."ADT_A01").
Returns
Transformer (function (Root) => Root)
Examples
Basic Inference
import { unified } from "unified";
import { hl7v2Parser } from "@rethinkhealth/hl7v2-parser";
import { hl7v2AnnotateMessage } from "@rethinkhealth/hl7v2-annotate-message";
import { hl7v2AnnotateMessageStructure } from "@rethinkhealth/hl7v2-annotate-message-structure";
const processor = unified()
.use(hl7v2Parser)
.use(hl7v2AnnotateMessage)
.use(hl7v2AnnotateMessageStructure);
// MSH-9.3 is missing
const message = "MSH|^~\\&|||||||VXU^V04|MSG001|P|2.5.1";
const tree = processor.parse(message);
await processor.run(tree);
console.log(tree.data.messageInfo.messageStructure); // "VXU_V04"Non-Destructive Behavior
// If MSH-9.3 is already present, it won't be overwritten
const messageWithStructure =
"MSH|^~\\&|||||||ADT^A01^ADT_A01_CUSTOM|MSG001|P|2.5";
const tree = processor.parse(messageWithStructure);
await processor.run(tree);
console.log(tree.data.messageInfo.messageStructure);
// "ADT_A01_CUSTOM" (original value preserved)Combined with Linting
import { hl7v2LintMessageStructure } from "@rethinkhealth/hl7v2-lint-message-structure";
// Infer structure and warn about missing source values
const processor = unified()
.use(hl7v2Parser)
.use(hl7v2AnnotateMessage)
.use(hl7v2AnnotateMessageStructure) // Fix missing structure
.use(hl7v2LintMessageStructure); // Warn about missing source
const result = await processor.process(message);
// Will have messageStructure populated, but may have warningsBehavior
When Structure is Resolved
- Both
messageCode(MSH-9.1) andtriggerEvent(MSH-9.2) must be present - If
versionis available, the candidate{messageCode}_{triggerEvent}is resolved against the event map - Examples:
ADT+A04(v2.5) →ADT_A01(A04 uses A01 structure)ADT+A07(v2.5) →ADT_A06(A07 uses A06 structure)ADT+A01(v2.5) →ADT_A01(identity mapping)
When Structure is NOT Resolved (remains undefined)
- Event not found in the event map for the given version
- Message structure already exists (won't override)
- Message code is missing or empty
- Trigger event is missing or empty
- Version is missing
- No
messageInfoexists in tree data
Compatibility
- Node.js: 18+
- TypeScript: 5.0+
- unified: 11.0+
Related
@rethinkhealth/hl7v2-annotate-message— Extract message metadata (required before this plugin)@rethinkhealth/hl7v2-lint-message-structure— Validate presence of MSH-9.3@rethinkhealth/hl7v2-util-message-info— Low-level utilities for extracting message metadata
Contributing
We welcome contributions! Please see our Contributing Guide for more details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code of Conduct
To ensure a welcoming and positive environment, we have a Code of Conduct that all contributors and participants are expected to adhere to.
License
Copyright 2025 Rethink Health, SUARL. All rights reserved.
This program is licensed to you under the terms of the MIT License. This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file for details.
