Skip to content

v0.1.0

Latest

Choose a tag to compare

@NSchatz NSchatz released this 25 Sep 23:05
20b008e

HL7 v2 for Node.js and TypeScript. @cosyte/hl7 parses the messages hospital systems actually send,
vendor quirks included, and hands fields back by name (msg.patient?.mrn) rather than by position
(PID-3.1). It also builds messages and writes them back spec-clean.

npm install @cosyte/hl7@0.1.0

Node.js 22 or newer. ESM and CommonJS, with type declarations. No runtime dependencies. MIT.

What 0.1 means

This is the first release whose public API we treat as settled: the exported functions, the message
and helper surfaces, and the warning and finding codes. Renaming a warning code is a breaking change.
While the package is below 1.0, a breaking change bumps the minor version (0.1 to 0.2) and is called
out in the changelog; a fix that changes no public value ships as a patch.

What you can build on

  • One-line reads through named helpers (msg.patient, msg.meta, msg.observations()), dot-paths
    (msg.get("PID.5.1")) or structural traversal.
  • A lenient parser that tolerates what real feeds send and reports each deviation as a warning with a
    stable code and a position, never the field's value. Four structural failures are fatal;
    { strict: true } turns every warning into an error for CI.
  • Eight built-in vendor profiles and defineProfile() for your own senders.
  • Parse, modify and toString() to emit spec-clean HL7, with escape sequences re-emitted byte for byte.
  • parseStream for batch files too large to buffer.

What changed

  • Five new typed builders: buildOrm, buildSiu, buildMdm, buildDft and buildVxu, plus
    prior-identity content on the ADT builder for merges.
  • Typed message overlays. msg.is("ADT^A01") answers at run time and narrows at compile time, so
    the accessors after the check are scoped to that message type's published structure.
  • Opt-in structure validation. validateMessageStructure(msg) checks segment order and counts
    against HL7's published message structures, which the library now derives from HL7's
    machine-readable definitions: 94 message and trigger-event pairs, up from 32.
  • Clinical status on the helpers. Observations and orders carry resultStatus (OBX-11 and OBR-25,
    classified by HL7's published tables), immunizations carry administrationStatus, and medications
    carry orderControl from ORC-1.
  • Allergies from IAM as well as AL1, so an ADT^A60 no longer returns an empty list that reads
    as "no allergies recorded".
  • Profiles can name fields on standard segments (segmentOverrides: { PID: { fields: { siteMrn: 19 } } }), and a profile's field names are checked by the compiler.
  • Conformance profiles gain condition predicates, value sets bound to a coding system, declared
    conformance levels, component rules, and the C(a/b) and B usages.
  • Schemas for toJSON(). emitMessageSchema produces the JSON Schema and Zod description of the
    serialized message.
  • Dates. One conversion surface shared with the other @cosyte parsers (toObject, toISO,
    toDate); vendor date formats gain month names, AM/PM and 12-hour clocks; declared formats now
    reach every datetime the library returns.
  • Segment names are matched regardless of case, so a sender shipping pid no longer loses the segment.

Upgrading from 0.0.x

  • buildAdt refuses a merge event with no prior identity. For the ten triggers whose published
    structure requires MRG (A40, A41, A42, A43, A44, A45, A47, A49, A50 and A51), it used to return a
    message carrying a MISSING_EXPECTED_GROUP warning; it now throws a TypeError naming the message
    type and the member that would supply the segment. Pass the prior identity.
  • msg.identityEvents() recognizes five more triggers, A45, A47, A49, A50 and A51, which used to
    return an empty list.
  • An order-ambiguous slash date is refused instead of being read in US order. If you relied on
    that default, declare it: parseHL7(raw, { dateFormats: ["MM/DD/YYYY"] }).
  • dateFormats is validated strictly: a format that constructed and never matched now throws where
    you wrote it.
  • Conformance profiles: a usage paired with a cardinality the methodology disallows is refused when
    the profile is defined; FindingCode gains PROFILE_UNDECLARED_CONTENT and UsageCode gains B
    and the conditional form, so exhaustive switch statements need new cases.
  • msg.allergies() now also returns entries from IAM segments.
  • Immunization gains the required administrationStatus key, so code that builds Immunization
    objects by hand must supply it.

Not covered

  • Network transport: MLLP framing is stripped on read, and sending or receiving over a socket belongs
    to @cosyte/mllp.
  • Conversion to FHIR. That is @cosyte/transform.
  • HL7 v3 and CDA: the parser reads v2 only. C-CDA documents are @cosyte/ccda.
  • Exhaustive coded-value validation: the library validates structure, not every coded value against
    every HL7 table.

Links