JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 56
  • Score
    100M100P100Q84372F
  • License MIT

hl7v2 utilities

Package Exports

  • @glion/utils

Readme

@glion/utils

A utility package for working with HL7v2 messages, most commonly used within the @glion/hl7v2 ecosystem — a unist-inspired collection of plugins and utilities designed to parse, transform, validate, and manipulate HL7v2 messages.

This package provides core utilities including:

  • Diagnostic reporting system for linters, validators, and transformers
  • Standard HL7v2 delimiters
  • AST node utility functions
  • Conformance validation utilities (cardinality, length, optionality)

Installation

npm install @glion/utils

API

report(file, rule, options?)

Report a diagnostic to a VFile. This function is the standard way to report issues in the HL7v2 ecosystem.

Parameters

  • file (VFile | null | undefined) - The VFile to report to
  • rule (Diagnostic) - The diagnostic rule definition
  • options (ReportOptions, optional)
    • node (Node, optional) - The AST node related to the diagnostic
    • context (Record<string, unknown>, optional) - Context data passed to the diagnostic's message function

Example

import { report } from "@glion/utils";
import type { Diagnostic } from "@glion/utils";
import { VFile } from "vfile";

// Define a diagnostic rule
const requiredFieldRule: Diagnostic = {
  type: "lint",
  namespace: "field",
  code: "required",
  title: "Required Field Missing",
  description: "A required field is missing from the segment.",
  severity: "error",
  message: (ctx) => `Field '${ctx.fieldPath}' is required`,
  helpUrl: "https://example.com/docs/required-field",
};

// Report the diagnostic
const file = new VFile();
report(file, requiredFieldRule, {
  context: { fieldPath: "PID-5" },
  node: segmentNode,
});

getByteLength(node)

Calculate the byte length of any HL7v2 AST node. This utility efficiently computes the total serialized length including all children and separators (assumed to be 1 byte each).

Parameters

  • node (Nodes | null | undefined) - The AST node to measure

Returns

number - The total byte length when the node is serialized

Algorithm

  • For literal nodes (Subcomponent, SegmentHeader): returns the byte length of the value using UTF-8 encoding (i.e., Buffer.byteLength(value, 'utf8'))
  • For parent nodes: recursively sums the byte length of all children plus 1 byte per separator between children
  • Handles all node types: Root, Segment, Group, Field, FieldRepetition, Component, Subcomponent

Performance

The function is optimized for performance with O(n) time complexity where n is the total number of nodes in the tree. It uses a simple recursive approach with minimal overhead.

Example

import { getByteLength } from "@glion/utils";
import type { Field } from "@glion/ast";

const field: Field = {
  type: "field",
  children: [
    {
      type: "field-repetition",
      children: [
        {
          type: "component",
          children: [
            { type: "subcomponent", value: "SMITH" },
            { type: "subcomponent", value: "JOHN" },
          ],
        },
      ],
    },
  ],
};

// Calculate: SMITH&JOHN = 5 + 1 + 4 = 10 bytes
const length = getByteLength(field); // Returns: 10

Use Cases

  • Validating field or message size constraints
  • Memory allocation planning
  • Message size reporting and analytics
  • Performance optimization by avoiding full serialization

getLength(node)

Calculate the string length of any HL7v2 AST node. This utility efficiently computes the total serialized character length including all children and separators (assumed to be 1 character each).

Parameters

  • node (Nodes | null | undefined) - The AST node to measure

Returns

number - The total string length when the node is serialized

Algorithm

  • For literal nodes (Subcomponent, SegmentHeader): returns value.length (JavaScript string length)
  • For parent nodes: recursively sums the string length of all children plus 1 character per separator between children
  • Handles all node types: Root, Segment, Group, Field, FieldRepetition, Component, Subcomponent

Important Note

Returns JavaScript string length (UTF-16 code units). For UTF-8 byte length (e.g., for wire protocol or size constraints), use getByteLength instead. These values differ for characters outside the ASCII range.

Performance

The function is optimized for performance with O(n) time complexity where n is the total number of nodes in the tree. It uses a simple recursive approach with minimal overhead.

Example

import { getLength } from "@glion/utils";
import type { Field } from "@glion/ast";

const field: Field = {
  type: "field",
  children: [
    {
      type: "field-repetition",
      children: [
        {
          type: "component",
          children: [
            { type: "subcomponent", value: "SMITH" },
            { type: "subcomponent", value: "JOHN" },
          ],
        },
      ],
    },
  ],
};

// Calculate: SMITH&JOHN = 5 + 1 + 4 = 10 characters
const length = getLength(field); // Returns: 10

Use Cases

  • UI display and text formatting
  • Character-based validation rules
  • String manipulation operations
  • Quick length checks where byte-level precision is not required

Comparison with getByteLength

import { getLength, getByteLength } from "@glion/utils";

const subcomponent = { type: "subcomponent", value: "café" };

getLength(subcomponent); // Returns: 4 (4 characters)
getByteLength(subcomponent); // Returns: 5 (5 bytes in UTF-8: c-a-f-C3-A9)

Conformance Utilities

The package provides stateless, composable functions to validate HL7v2 AST nodes against constraints like optionality (usage), cardinality, and length.

ValidationResult

All conformance functions return a ValidationResult object:

type ValidationResult =
  | { ok: true }
  | {
      ok: false;
      error: {
        code: string;
        message: string;
        expected?: string | number | Array<string | number>;
        actual?: string | number | Array<string | number>;
      };
    };

checkOptionality(node, optionality)

Checks if a node satisfies the optionality (usage) constraint.

  • node: Nodes | undefined - The AST node to check.
  • optionality: string - The usage code (e.g., 'R', 'O', 'X').
  • Returns: ValidationResult
import { checkOptionality } from "@glion/utils";

// 'R' (Required), 'RE' (Required or Empty), 'O' (Optional), 'X' (Not Supported)
const result = checkOptionality(myFieldNode, "R");

if (!result.ok) {
  console.error(result.error.message); // "is required but missing"
}

checkCardinality(node, min, max)

Checks if a field has the correct number of repetitions.

  • node: Field | undefined - The field node to check.
  • min: number - Minimum repetitions.
  • max: number | '*' - Maximum repetitions.
  • Returns: ValidationResult
import { checkCardinality } from "@glion/utils";

// Field must repeat between 1 and 5 times
const result = checkCardinality(myFieldNode, 1, 5);

checkLength(node, max, min?)

Checks if the content of a node falls within the minimum and maximum length.

  • node: Nodes | undefined - The node to check (length is calculated recursively).
  • max: number - Maximum length.
  • min: number (optional, default: 0) - Minimum length.
  • Returns: ValidationResult
import { checkLength } from "@glion/utils";

// Content length must be between 1 and 10 characters
const result = checkLength(myNode, 10, 1);

// Content length must be at most 10 characters (min defaults to 0)
const result2 = checkLength(myNode, 10);

Contributing

We welcome contributions! Please see our Contributing Guide for more details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. 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.