Skip to content

AST types

AST types and helpers for HL7v2 messages.

TypeScript types and specification for the HL7v2 abstract syntax tree.

What it does

@glion/ast defines the shape of HL7v2 messages as an abstract syntax tree. The tree implements the unist spec, so every Glion parser, transformer, linter, and serializer — and any third-party unist utility — can consume the same representation. This package ships only TypeScript types; runtime behavior (parsing, visiting, building) lives in the parser, builder, and util packages that consume these types.

Install

npm install @glion/ast

Use

import type { Root, Segment, Field, Subcomponent } from "@glion/ast";

function firstSegment(tree: Root): Segment | undefined {
  return tree.children.find(
    (child): child is Segment => child.type === "segment"
  );
}

Use these types whenever you write a plugin, visitor, or helper that operates on the HL7v2 AST — they are the contract shared by every package in the ecosystem.

API

The package exports interface declarations only. There is no runtime JavaScript.

TypeNode kindRole
Roottype: "root"Top-level node representing a message or fragment
Segmenttype: "segment"A single HL7v2 segment (MSH, PID, OBX, …)
Grouptype: "group"A repeating or optional group of related segments
Fieldtype: "field"A field within a segment
FieldRepetitiontype: "field-repetition"A ~-separated instance of a field
Componenttype: "component"A ^-separated component within a repetition
Subcomponenttype: "subcomponent"An &-separated subcomponent — the only node with value

Every node may also carry a position property ({ start, end } with line, column, and offset) following the unist spec.

Node types

The AST mirrors the full HL7v2 delimiter hierarchy:

root
└── segment
    └── field (|)
        └── field-repetition (~)
            └── component (^)
                └── subcomponent (&)
  • Every field always contains one or more field-repetition nodes, even when no ~ appears in the input.
  • Every component always contains one or more subcomponent nodes, even when no & appears.
  • Only subcomponent nodes carry a value string.

Abstract shapes

interface Literal <: UnistLiteral {
  value: string
}

interface Parent <: UnistParent {
  children: [HL7v2Node]
}

Literal is the leaf (Subcomponent). Parent is anything that contains other nodes.

Concrete nodes

interface Root <: Parent {
  type: 'root'
  children: [Segment | Group]
}

interface Segment <: Parent {
  type: 'segment'
  name?: string
  children: [Field]
}

interface Group <: Parent {
  type: 'group'
  name: string
  children: [Segment]
}

interface Field <: Parent {
  type: 'field'
  index: number
  children: [FieldRepetition]
}

interface FieldRepetition <: Parent {
  type: 'field-repetition'
  index?: number
  children: [Component]
}

interface Component <: Parent {
  type: 'component'
  index: number
  children: [Subcomponent]
}

interface Subcomponent <: Literal {
  type: 'subcomponent'
  index: number
  value: string
}

Segment.name carries the segment identifier (for example "MSH", "PID", "OBX") so visitors can filter without traversing the field hierarchy. Group.name names the logical group (for example "ORDER_OBSERVATION").

Position

interface Position {
  start: Point
  end: Point
}

interface Point {
  line: number
  column: number
  offset: number
}

Position is optional per the unist spec but is always populated by @glion/parser.

Content model

type HL7v2Content =
  Root | Segment | Group | Field | FieldRepetition | Component | Subcomponent

Delimiters themselves live on file.data.delimiters (populated by @glion/annotate-delimiters), not on individual nodes — a single source of truth for the six HL7v2 delimiter characters.