@cosyte/transform
Public entry point for @cosyte/transform: the HL7 v2 → FHIR R4 transformation library.
@cosyte/transform is not a parser; it is a consumer one tier above the parser suite. It
takes already-parsed @cosyte/hl7 composites and produces validated @cosyte/fhir model nodes,
grounded on the official HL7 Version 2 to FHIR Implementation Guide (hl7.fhir.uv.v2mappings,
STU Edition 1). Its whole promise is narrow and honest: IG-grounded, fail-safe transformation
with typed, value-free diagnostics, never a confident wrong FHIR value.
This module ships the six safety-critical datatype converters, the immutable
OperationOutcome-shaped diagnostic channel and the NamingSystem resolver they consult,
the message-level assembly (HL7 v2 ADT → FHIR Patient + Encounter, the
ORU^R01 → DiagnosticReport + Observation results graph, the order-entry graph
(ORM_O01 / OML_O21 → ServiceRequest and RXO → MedicationRequest), and the thin IG
singles (VXU_V04 → Immunization, SIU_S12 → Appointment, MDM_T02 → DocumentReference),
all through toFhir(msg)), and the terminology value-translation layer: a
$translate-shaped toFhirCodeableConceptVia engine applying the license-clean IG value
ConceptMaps to the previously structural-only coded fields (route/site, appointment type, order
priority, substitution).
It also ships a narrow reverse path, FHIR → v2: toV2Patient and
toV2Observation emit a complete v2 message carrying a PID or an OBX built from the
subset of the IG segment maps whose inverse is defensible. Each requires the caller to supply the
v2 trigger, because no FHIR resource carries one. It is lossy by design and not a round-trip:
a value the inverse of the IG map cannot ground is flagged and left absent, never guessed.
Terminology depth beyond these maps, profiles, and any wider FHIR → v2 conversion are not
implemented.
Classes
SegmentReachLedger
Tracks, across one message-level assembly, which segment occurrences CONTRIBUTED to a resource the returned bundle contains, and turns the rest into one value-free issue each.
The assembly marks an occurrence only where a resource has just cleared the emit gate and joined the bundle, so "reached" means contributed-and-present by construction: an occurrence that was read and refused, or that built a resource the gate withheld, is never marked and is therefore reported.
Example
import { parseHL7 } from "@cosyte/hl7";
import { SegmentReachLedger } from "@cosyte/transform";
// const ledger = new SegmentReachLedger(parseHL7(raw));
// ledger.markFirstOfType("MSH");
// ledger.issues(); // one issue per occurrence that reached nothing
Constructors
Constructor
new SegmentReachLedger(
msg):SegmentReachLedger
Parameters
msg
Hl7Message
The parsed message whose occurrences are being tracked.
Returns
Methods
issues()
issues(): readonly
TransformIssue[]
One value-free issue per reportable occurrence, in message order: the library-gap code when the IG publishes a segment map for the name, the standard-gap code otherwise, and the standard-gap code for every name that could not be classified at all.
Returns
readonly TransformIssue[]
mark()
mark(...
segments):void
Record that each given segment contributed to a resource now present in the bundle. undefined
entries are ignored, so a call site can pass an optional part of a group without branching.
Parameters
segments
...readonly any[]
Returns
void
markFirstOfType()
markFirstOfType(
type):void
Record that the FIRST occurrence of type contributed. The parser's derived views (patient,
visit, meta) are built from the first segment of their type, so this is how a resource built
from a view marks the occurrence it came from.
Parameters
type
string
Returns
void
markNthOfType()
markNthOfType(
type,index):void
Record that the index-th (0-based) occurrence of type contributed: the counterpart of
SegmentReachLedger.markFirstOfType for the repeating views (nextOfKin()), whose
entries are in document order.
Parameters
type
string
index
number
Returns
void
reportable()
reportable(): readonly
SegmentOccurrence[]
The occurrences that contributed to no resource present in the bundle, in message order.
Returns
readonly SegmentOccurrence[]
Interfaces
AllergyBuildOptions
How much of the IG's AL1 mapping to carry: the alternate-codes extension is the one variable.
Properties
carryAlternateCodes?
readonlyoptionalcarryAlternateCodes?:boolean
Whether to carry the IG's alternate-codes extension on category / criticality. Defaults to
true; the emit path builds a second draft with it off only when the first draft fails the
conservative-emit gate.
CodedTarget
A translated FHIR target coding: the target CodeSystem URI + code, and the IG's target display.
Properties
code
readonlycode:string
The FHIR target code.
display?
readonlyoptionaldisplay?:string
The IG map's target display, when it carries one (absent for the identity table maps).
system
readonlysystem:string
The FHIR target CodeSystem canonical URI.
CodedValueMap
A license-clean v2-table → FHIR value ConceptMap: it translates a source table code to its
CodedTarget, or undefined when the code is not in the map's mapped group (the IG's
(unmapped) group). Never fabricates a target.
Properties
name
readonlyname:string
The IG ConceptMap id this map transcribes (its citation).
sourceMnemonics
readonlysourceMnemonics:ReadonlySet<string>
The CWE.3 (nameOfCodingSystem) mnemonics that denote this map's bound source table: the
HL7 forms ("HL70162", "0162", …). Translation applies only when the field's primary
coding is from the bound table: CWE.3 absent/empty (a positionally-bound bare code) or CWE.3 ∈
this set. A CWE that declares a different coding system (a local 99…, or SNOMED) is not a
source-table code, so the map is not applied to it: the raw coding is carried structurally + its
system flagged, never asserted as the standard concept.
sourceSystem
readonlysourceSystem:string
The source table's canonical CodeSystem URI (what the raw v2 code is a member of when mapped).
translate
readonlytranslate: (code) =>CodedTarget|undefined
Translate a source table code to its FHIR target, or undefined when the IG map has no target.
Parameters
code
string
Returns
CodedTarget | undefined
ConvertResult
The result of one datatype conversion: the produced FHIR value (or undefined when the input was
empty or un-emittable) plus the diagnostics raised.
Example
import { toFhirHumanName } from "@cosyte/transform";
const { value, issues } = toFhirHumanName({ familyName: "Public" });
// value is a FHIR HumanName node; issues is [] here
void value;
void issues;
Type Parameters
T
T
The produced FHIR value's type (a FhirComplex datatype node, or a lexical string
for dateTime).
Properties
issues
readonlyissues: readonlyTransformIssue[]
The value-free diagnostics raised during the conversion, in emission order.
value
readonlyvalue:T|undefined
The produced FHIR value, or undefined when nothing could be safely emitted.
EntityIdentifier
One EI field read as a FHIR Identifier: the value, and whether an authority went unused.
Properties
authorityValued
readonlyauthorityValued:boolean
Whether EI.2, EI.3 or EI.4 carried an assigning authority this library did not resolve.
identifier
readonlyidentifier:any
The Identifier node built from EI.1, or undefined when EI.1 carries nothing.
NamingSystemRegistry
The resolver consulted by the identity- and code-conversion paths.
Properties
resolveAssigningAuthority
readonlyresolveAssigningAuthority: (hd) =>string|undefined
Resolve an assigning authority (HD) to a FHIR Identifier.system URI, or undefined when it
cannot be resolved safely. Never synthesizes a URI from HD.1 alone.
Parameters
hd
HD
Returns
string | undefined
resolveCodeSystem
readonlyresolveCodeSystem: (mnemonic) =>string|undefined
Resolve a v2 coding-system mnemonic to a canonical URI, or undefined when unrecognized.
Parameters
mnemonic
string
Returns
string | undefined
NamingSystemSeed
A seed for createNamingSystem: extra coding systems and explicit assigning authorities.
Properties
authorities?
readonlyoptionalauthorities?:Readonly<Record<string,string>>
Explicit assigning-authority entries, keyed by HD.1 namespace mnemonic and/or HD.2
universal ID (OID) → the Identifier.system URI. This is the safe, caller-vetted path the IG
calls for; the registry never derives a system from a mnemonic on its own.
codeSystems?
readonlyoptionalcodeSystems?:Readonly<Record<string,string>>
Extra v2 coding-system mnemonic → canonical URI entries (merged over the defaults).
ReverseOptions
Caller context for a reverse (FHIR to v2) conversion. Every entry is caller-vetted: nothing here is derived from resource content, and omitting all of it is safe (the conversion then flags what it cannot resolve rather than guessing it).
Example
import { toV2Patient } from "@cosyte/transform";
const options = {
assigningAuthorities: { "urn:oid:1.2.840.114350": "HOSP" },
envelope: { sendingApp: "EHR", sendingFacility: "MAIN" },
};
void options;
void toV2Patient;
Properties
assigningAuthorities?
readonlyoptionalassigningAuthorities?:Readonly<Record<string,string>>
Identifier.system URI to the v2 assigning-authority namespace (HD.1) that stands for it. There
is no derivation from a URI to a namespace, so an identifier whose system is absent here is
emitted with its value and no assigning authority, flagged rather than invented.
codeSystems?
readonlyoptionalcodeSystems?:Readonly<Record<string,string>>
Extra v2 coding-system mnemonic to canonical URI entries, merged over DEFAULT_V2_CODE_SYSTEMS and then inverted. Same shape and direction as the forward registry's seed, so one declaration serves both directions.
envelope?
readonlyoptionalenvelope?:Omit<BuildMessageInit,"type">
MSH envelope fields for the emitted message (sending/receiving application and facility, control id, timestamp, version, processing id). The message type is never taken from here: it is fixed by the shape plus the caller's trigger argument.
SegmentOccurrence
One segment occurrence of a parsed message: a segment as it appears in the message, in message order, with everything needed to locate it in a value-free way and nothing else.
Properties
name
readonlyname:string|undefined
The renderable segment name, present only when it passed the shape test.
nameIndex
readonlynameIndex:number|undefined
1-based position among the occurrences of SegmentOccurrence.name, when there is one.
ordinal
readonlyordinal:number
1-based position among all parsed positions, empty ones included, so it matches the wire.
segment
readonlysegment:Segment
The parsed segment this occurrence wraps.
TransformContext
The context a converter consults. Carries the NamingSystemRegistry used to resolve an
assigning authority (HD) to an Identifier.system and a v2 coding-system mnemonic to a canonical
URI, plus the TransformOptions.
Properties
namingSystem?
readonlyoptionalnamingSystem?:NamingSystemRegistry
The registry used to resolve HD → system and v2 mnemonic → canonical URI.
options?
readonlyoptionaloptions?:TransformOptions
Conversion policy.
TransformIssue
A single value-free diagnostic.
Example
import { ISSUE_CODES } from "@cosyte/transform";
// issue.code === ISSUE_CODES.TRANSFORM_TIMESTAMP_NO_TIMEZONE
// issue.v2Location === "TS.1"; issue.fhirPath === "dateTime"
Properties
code
readonlycode:IssueCode
The stable code. One of ISSUE_CODES.
fhirPath?
readonlyoptionalfhirPath?:string
The FHIR path this issue concerns (e.g. Identifier.system), when applicable.
message
readonlymessage:string
A static, value-free description drawn from ISSUE_REGISTRY.
severity
readonlyseverity:TransformSeverity
The OperationOutcome-style severity, fixed per code.
v2Location
readonlyv2Location:string
The v2 source location: a segment / field / component index, never a value.
TransformOptions
Caller/profile policy for a conversion.
Remarks
assumeTimezoneOffsetMinutes is the only way a naked v2 timestamp acquires a time-of-day in
FHIR: the caller asserts the sender's offset (in minutes east of UTC, e.g. -300 for US Eastern
standard time). It is a sender-asserted value, flagged as such; absent it, a naked timestamp is
reduced to date precision, never assumed to be UTC.
Properties
assumeTimezoneOffsetMinutes?
readonlyoptionalassumeTimezoneOffsetMinutes?:number
The sender's UTC offset in minutes, asserted by the caller to resolve naked timestamps.
generateId?
readonlyoptionalgenerateId?: () =>string
Allocator for the urn:uuid: Bundle.entry.fullUrl / reference identities the assembler mints.
Defaults to crypto.randomUUID. Inject a deterministic generator to make bundle output
reproducible (e.g. for golden fixtures). It must return a fresh, unique value per call: the
assembler relies on uniqueness for intra-bundle reference integrity.
Returns
string
namingSystem?
readonlyoptionalnamingSystem?:NamingSystemRegistry
The NamingSystemRegistry the message-level transform threads into every datatype
conversion (HD → Identifier.system, v2 mnemonic → canonical URI). When omitted, a default
registry (createNamingSystem()) is used: it resolves only the FHIR-core-fixed systems and the
two unambiguous HD auto-derivations, so an un-seeded assigning authority surfaces a typed issue
rather than a guessed system.
TransformResult
The immutable result of a message-level transform: the FHIR Bundle model and the value-free
diagnostics raised assembling it.
Properties
bundle
readonlybundle:FhirComplex
The FHIR R4 Bundle resource node (a message Bundle: MessageHeader first, then focal resources).
issues
readonlyissues: readonlyTransformIssue[]
The value-free diagnostics raised during assembly, in emission order.
Type Aliases
CodedElement
CodedElement =
Pick<CWE,"identifier"|"text"|"nameOfCodingSystem"|"alternateIdentifier"|"alternateText"|"nameOfAlternateCodingSystem"|"codingSystemVersionId"|"alternateCodingSystemVersionId"|"originalText">
The subset of CWE fields a CE also provides, so toFhirCodeableConcept accepts both.
FatalCode
FatalCode = typeof
FATAL_CODES[keyof typeofFATAL_CODES]
A value from FATAL_CODES: the type carried by a thrown fatal error.
IssueCode
IssueCode = typeof
ISSUE_CODES[keyof typeofISSUE_CODES]
A value from ISSUE_CODES: the type consumers narrow issue.code against.
ReverseResult
ReverseResult =
ConvertResult<Hl7Message>
What a reverse conversion returns: the complete @cosyte/hl7 message it could faithfully build
(or undefined when it could not), plus the value-free diagnostics it raised. The same fail-safe
envelope the forward converters return, in the other direction.
Example
import { toV2Patient } from "@cosyte/transform";
// const { value, issues } = toV2Patient(patientNode, "A28");
// value?.toString() -> "MSH|^~\\&|...|ADT^A28|...\rPID|||MRN1\r"
void toV2Patient;
TransformSeverity
TransformSeverity =
"error"|"warning"|"information"
The severity a TransformIssue carries: an OperationOutcome.issue.severity value.
Variables
ADDRESS_TYPE_MAP
constADDRESS_TYPE_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0190 address-type code → FHIR address-type, exactly per the IG HL70190→address-type map.
ADDRESS_USE_MAP
constADDRESS_USE_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0190 address-type code → FHIR address-use, exactly per the IG HL70190→address-use map.
ADDRESS_USE_TO_V2
constADDRESS_USE_TO_V2:Readonly<Record<string,string>>
FHIR address-use to HL7 v2 Table 0190, the invertible rows of the IG's HL70190 to
address-use map. work is absent on purpose (B and O), as is every Address.type row.
Example
import { ADDRESS_USE_TO_V2 } from "@cosyte/transform";
ADDRESS_USE_TO_V2["home"]; // => "H"
ADMINISTRATIVE_GENDER_MAP
constADMINISTRATIVE_GENDER_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0001 (Administrative Sex) → FHIR administrative-gender, exactly per the IG
Table HL70001 to Administrative Gender ConceptMap (every row "is equivalent to"). A
(Ambiguous) and N (Not applicable) both narrow to other: the map's stated equivalence, carried
as-is. A code absent here (the map defines no unmapped default) leaves gender absent and is
flagged ISSUE_CODES.TRANSFORM_CODE_UNMAPPED, never coerced to unknown.
AL1_ONSET_WITHDRAWN_AT
constAL1_ONSET_WITHDRAWN_AT: readonlynumber[]
The HL7 v2 version at which AL1-6 Identification Date was withdrawn, per the IG map's own comment on that row ("Withdrawn as of 2.7, Refer to IAM-11 Onset or IAM-13 Reported Date"). A message at this version or later carries no AL1-6 that this library will read as an onset.
Example
import { AL1_ONSET_WITHDRAWN_AT } from "@cosyte/transform";
AL1_ONSET_WITHDRAWN_AT; // [2, 7]
ALLERGY_CATEGORY_VALUE_MAP
constALLERGY_CATEGORY_VALUE_MAP:CodedValueMap
AL1-2 Allergen Type to category: IG ConceptMap/table-hl70127-to-allergy-intolerance-category.
One mapped group of six rows into the FHIR R4 AllergyIntoleranceCategory code system (DA
drug to medication, FA food to food, EA environmental to environment, AA animal to
biologic, PA plant to environment, LA pollen to environment, each equivalent, with the
IG target displays), and an (unmapped) group of two: MA and MC have no category target.
The IG applies this map to AllergyIntolerance.category only; AllergyIntolerance.type has
its own map (ALLERGY_TYPE_VALUE_MAP) over the same source table, and the two are resolved
independently. MA therefore yields a type and no category, which is the guide's answer and not a
gap to be filled: a category is never borrowed from the type map or from a neighbouring code.
ALLERGY_CLINICAL_STATUS_CODE
constALLERGY_CLINICAL_STATUS_CODE:"active"="active"
The fixed clinicalStatus code the IG assigns. The guide's own note explains why it is fixed
rather than derived: constraint ait-1 requires a clinicalStatus unless the verificationStatus is
entered-in-error, and no AL1 component can ground that retraction.
Example
import { ALLERGY_CLINICAL_STATUS_CODE } from "@cosyte/transform";
ALLERGY_CLINICAL_STATUS_CODE; // "active"
ALLERGY_CLINICAL_STATUS_SYSTEM
constALLERGY_CLINICAL_STATUS_SYSTEM:"http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical"="http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical"
The code system of the fixed clinicalStatus the IG assigns to every AllergyIntolerance built
from an AL1, transcribed from the segment map's own sort-order 0 row.
Example
import { ALLERGY_CLINICAL_STATUS_SYSTEM } from "@cosyte/transform";
ALLERGY_CLINICAL_STATUS_SYSTEM.endsWith("allergyintolerance-clinical"); // true
ALLERGY_CRITICALITY_VALUE_MAP
constALLERGY_CRITICALITY_VALUE_MAP:CodedValueMap
AL1-4 Allergy Severity to criticality: IG
ConceptMap/table-hl70128-to-allergy-intolerance-criticality. One mapped group of two rows
into the FHIR R4 AllergyIntoleranceCriticality code system (SV severe to high, MI mild to
low, both equivalent, with the IG target displays), and an (unmapped) group of two: MO
moderate and U unknown have no criticality target.
The unmapped pair is the whole reason this field fails safe. criticality is an overall risk
assessment a prescriber acts on, so a moderate severity is left absent and flagged rather than
rounded to low or high, and AllergyIntolerance.reaction.severity is never populated from the
same component instead: the IG offers that only as a local variation, conditioned on a severity
that was not used equivalently to criticality, which no v2 message states.
ALLERGY_INTOLERANCE_CATEGORY_SYSTEM
constALLERGY_INTOLERANCE_CATEGORY_SYSTEM:"http://hl7.org/fhir/allergy-intolerance-category"="http://hl7.org/fhir/allergy-intolerance-category"
FHIR R4 AllergyIntoleranceCategory CodeSystem URI (the IG's AL1-2 category target).
ALLERGY_INTOLERANCE_CRITICALITY_SYSTEM
constALLERGY_INTOLERANCE_CRITICALITY_SYSTEM:"http://hl7.org/fhir/allergy-intolerance-criticality"="http://hl7.org/fhir/allergy-intolerance-criticality"
FHIR R4 AllergyIntoleranceCriticality CodeSystem URI (the IG's AL1-4 criticality target).
ALLERGY_INTOLERANCE_TYPE_SYSTEM
constALLERGY_INTOLERANCE_TYPE_SYSTEM:"http://hl7.org/fhir/allergy-intolerance-type"="http://hl7.org/fhir/allergy-intolerance-type"
FHIR R4 AllergyIntoleranceType CodeSystem URI (the IG's AL1-2 type target).
ALLERGY_ORIGINAL_CATEGORY_VALUE_MAP
constALLERGY_ORIGINAL_CATEGORY_VALUE_MAP:CodedValueMap
AL1-2 original code: IG ConceptMap/table-hl70127-to-v2-0127. A single identity group of
all eight Table 0127 codes (DA, FA, MA, MC, EA, AA, PA, LA to themselves, each
equivalent, source and target both v2-0127).
This is the map behind the alternate-codes extension the IG puts on category: whatever the
category map does or does not translate, the code the sender actually wrote survives on the
resource in its own code system, so a consumer can always see what the message said.
ALLERGY_ORIGINAL_CRITICALITY_VALUE_MAP
constALLERGY_ORIGINAL_CRITICALITY_VALUE_MAP:CodedValueMap
AL1-4 original code: IG ConceptMap/table-hl70128-original-to-v2-0128. A single identity
group of all four Table 0128 codes (SV, MO, MI, U to themselves, each equivalent, source
and target both v2-0128), the map behind the alternate-codes extension on criticality.
Its four codes are a superset of the two ALLERGY_CRITICALITY_VALUE_MAP translates, which
is the point: a MO that yields no criticality still yields the original severity code here.
ALLERGY_TYPE_VALUE_MAP
constALLERGY_TYPE_VALUE_MAP:CodedValueMap
AL1-2 Allergen Type to type: IG ConceptMap/table-hl70127-to-allergy-intolerance-type. One
mapped group of seven rows into the FHIR R4 AllergyIntoleranceType code system (DA, FA,
MA, EA, AA, PA, LA all to allergy, each equivalent, display Allergy), and an
(unmapped) group of one: MC miscellaneous contraindication has no type target.
Read beside ALLERGY_CATEGORY_VALUE_MAP: the guide publishes two maps over Table 0127 with
different unmapped sets, so a code can be mapped by one and not the other. MC is the only code
neither map carries.
ALTERNATE_CODES_EXTENSION_URL
constALTERNATE_CODES_EXTENSION_URL:"http://hl7.org/fhir/StructureDefinition/alternate-codes"="http://hl7.org/fhir/StructureDefinition/alternate-codes"
The canonical URL of the FHIR alternate-codes extension, the IG's fixed assignment for the
category.extension.url and criticality.extension.url rows.
Example
import { ALTERNATE_CODES_EXTENSION_URL } from "@cosyte/transform";
ALTERNATE_CODES_EXTENSION_URL; // "http://hl7.org/fhir/StructureDefinition/alternate-codes"
APPOINTMENT_STATUS_MAP
constAPPOINTMENT_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0278 (Filler Status Code) → FHIR appointmentstatus (Appointment.status), per the IG
Table HL70278 to AppointmentStatus ConceptMap (each is equivalent to). The three source codes
the IG leaves unmatched (Discontinued, Blocked, Overbook) are absent here on purpose: an
SCH-25 carrying one of them (or any local code) leaves Appointment.status absent + flagged and the
required-status emit gate withholds the Appointment.
APPOINTMENT_TYPE_VALUE_MAP
constAPPOINTMENT_TYPE_VALUE_MAP:CodedValueMap
SCH-8 Appointment Type: IG ConceptMap/table-hl70277-to-v2-0277. A single identity group
of the three v2-0277 codes (Normal, Tentative, Complete → themselves, each equivalent,
source and target both v2-0277). Any other code is unmapped → raw coding preserved + flagged.
CONDITION_ENTERED_IN_ERROR
constCONDITION_ENTERED_IN_ERROR:"entered-in-error"="entered-in-error"
The verificationStatus code the DG1-21 row assigns, transcribed from the segment map's own
Condition.verificationStatus.coding.code assignment.
Example
import { CONDITION_ENTERED_IN_ERROR } from "@cosyte/transform";
CONDITION_ENTERED_IN_ERROR; // "entered-in-error"
CONDITION_VERIFICATION_STATUS_SYSTEM
constCONDITION_VERIFICATION_STATUS_SYSTEM:"http://terminology.hl7.org/CodeSystem/condition-ver-status"="http://terminology.hl7.org/CodeSystem/condition-ver-status"
The code system of the verificationStatus the DG1-21 row assigns, transcribed from the segment
map's own Condition.verificationStatus.coding.system assignment.
Example
import { CONDITION_VERIFICATION_STATUS_SYSTEM } from "@cosyte/transform";
CONDITION_VERIFICATION_STATUS_SYSTEM.endsWith("condition-ver-status"); // true
COVERAGE_STATUS_UNKNOWN
constCOVERAGE_STATUS_UNKNOWN:"unknown"="unknown"
The data-absent-reason code carried by Coverage.status, the one FHIR-required element of this
resource that no published row of the segment map grounds.
Example
import { COVERAGE_STATUS_UNKNOWN } from "@cosyte/transform";
COVERAGE_STATUS_UNKNOWN; // "unknown"
COVERAGE_SUBSCRIBER_ID_EXTENSION_URL
constCOVERAGE_SUBSCRIBER_ID_EXTENSION_URL:"http://hl7.org/fhir/5.0/StructureDefinition/extension-subscriberId"="http://hl7.org/fhir/5.0/StructureDefinition/extension-subscriberId"
The canonical URL of the subscriber-id extension the IN1-10 and IN1-49 rows assign, transcribed
from the segment map's own Coverage.extension.url assignment.
Example
import { COVERAGE_SUBSCRIBER_ID_EXTENSION_URL } from "@cosyte/transform";
COVERAGE_SUBSCRIBER_ID_EXTENSION_URL.endsWith("extension-subscriberId"); // true
DEFAULT_V2_CODE_SYSTEMS
constDEFAULT_V2_CODE_SYSTEMS:Readonly<Record<string,string>>
A small, license-clean seed of v2 Table 0396 coding-system mnemonic → canonical URI, for the FHIR-core-fixed systems whose URIs are universally cited (FHIR R4 terminologies-systems.html). The full HL7 THO NamingSystem crosswalk is not bundled; callers extend this via createNamingSystem. No terminology content is bundled: only identity URIs.
DG1_RETRACTION_ACTION_CODE
constDG1_RETRACTION_ACTION_CODE:"D"="D"
The Table 0206 (Segment Action Code) code the DG1-21 assignment covers. The row assigns a
retraction and names no source code; D is Delete, and the row's own comment excludes the rest.
Example
import { DG1_RETRACTION_ACTION_CODE } from "@cosyte/transform";
DG1_RETRACTION_ACTION_CODE; // "D"
DIAGNOSTIC_REPORT_STATUS_MAP
constDIAGNOSTIC_REPORT_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0123 (Result Status) → FHIR diagnostic-report-status (DiagnosticReport.status), per
the IG Table HL70123 [Queries] to Diagnostic Report Status ConceptMap (each is equivalent to).
Only these eight source codes carry a target; the IG leaves A, M, N, Y, Z unmapped
(verified firsthand against the published v1.0.0 ConceptMap: N "Procedure completed, results
pending" is in the (not mapped) group, and the map declares no unmapped default), so an OBR-25
with one of them leaves status absent + flagged and the report is withheld. In particular a
results-pending N is never emitted as the post-final appended. C→corrected and
X→cancelled guarantee a corrected/cancelled report never emits as final.
ED_BASE64_ENCODING
constED_BASE64_ENCODING:"Base64"="Base64"
The OBX-5.4 encoding the OBX map conditions both of its ED rows on. Any other encoding
(A, Hex, Ascii, a local token) leaves those rows unapplied, so no attachment is built.
Example
import { ED_BASE64_ENCODING } from "@cosyte/transform";
ED_BASE64_ENCODING; // "Base64"
ENCOUNTER_CLASS_V3_MAP
constENCOUNTER_CLASS_V3_MAP:Readonly<Record<string, {code:string;display:string; }>>
HL7 v2 Table 0004 (Patient Class) → FHIR v3 ActCode (Encounter.class), per the IG Table HL70004
to V3 ActCode ConceptMap (each "is equivalent to"). Only these four v2 classes have a v3 ActCode
equivalent; the remaining classes (R/B/C/N/U) map to themselves and stay in the v2-0004 system
(V2_0004_SYSTEM) per the same map's V2→V2 rows.
ENCOUNTER_STATUS_MAP
constENCOUNTER_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0004 (Patient Class) → FHIR Encounter.status, per the IG Table HL70004 to
Encounter Status ConceptMap. Applied only when PV1-45 (discharge date) is not valued: a valued
discharge sets status = finished per the PV1→Encounter map.
FATAL_CODES
constFATAL_CODES:object
Stable fatal codes: the reserved names for unrecoverable input conditions. Nothing in this library throws one today; every path, datatype and message level alike, fails safe to a value-free issue instead. They are declared so that a future one is an addition rather than a rename.
Type Declaration
EMPTY_INPUT
readonlyEMPTY_INPUT:"EMPTY_INPUT"="EMPTY_INPUT"
The input carried nothing to transform.
TRANSFORM_UNSUPPORTED_INPUT
readonlyTRANSFORM_UNSUPPORTED_INPUT:"TRANSFORM_UNSUPPORTED_INPUT"="TRANSFORM_UNSUPPORTED_INPUT"
The input was not a shape this transform accepts.
Example
import { FATAL_CODES } from "@cosyte/transform";
void FATAL_CODES.EMPTY_INPUT;
GENDER_TO_V2
constGENDER_TO_V2:Readonly<Record<string,string>>
FHIR administrative-gender to HL7 v2 Table 0001, the invertible rows of the IG's HL70001 to
Administrative Gender map. other is absent on purpose: three source codes carry it.
Example
import { GENDER_TO_V2 } from "@cosyte/transform";
GENDER_TO_V2["female"]; // => "F"
GENDER_TO_V2["other"]; // => undefined (ambiguous inverse, flagged instead)
HL70078_INTERPRETATION_CODES
constHL70078_INTERPRETATION_CODES:ReadonlySet<string>
HL7 v2 Table 0078 (Abnormal Flags) → FHIR v3 ObservationInterpretation (Observation.interpretation),
per the IG Table HL70078 to v3 ObservationInterpretation ConceptMap. Every mapped row is
is equivalent to an identically-spelled v3 code (the map is code-preserving), so this is the set
of codes that carry a target: a flag absent from this set has no equivalent and is flagged
ISSUE_CODES.TRANSFORM_CODE_UNMAPPED, never coerced (the IG leaves AC/HM/OBX/QCF/TOX
and any local flag unmapped, and declares no unmapped default).
IG_ALLERGY_VALUE_MAPS_PUBLISHED
constIG_ALLERGY_VALUE_MAPS_PUBLISHED:"2025-10-07"="2025-10-07"
The publication date of IG_ALLERGY_VALUE_MAPS_VERSION, so a later release of the guide can be told apart from a defect in this library.
Example
import { IG_ALLERGY_VALUE_MAPS_PUBLISHED } from "@cosyte/transform";
IG_ALLERGY_VALUE_MAPS_PUBLISHED; // "2025-10-07"
IG_ALLERGY_VALUE_MAPS_RETRIEVED
constIG_ALLERGY_VALUE_MAPS_RETRIEVED:"2026-08-28"="2026-08-28"
The date the five AL1 allergy ConceptMaps were retrieved and transcribed into the maps below. A target that surprises a reader is answered by re-reading the guide at this date: each map is a transcription of a published document at a moment, not a live query.
Example
import { IG_ALLERGY_VALUE_MAPS_RETRIEVED } from "@cosyte/transform";
IG_ALLERGY_VALUE_MAPS_RETRIEVED; // "2026-08-28"
IG_ALLERGY_VALUE_MAPS_SOURCE
constIG_ALLERGY_VALUE_MAPS_SOURCE:"https://hl7.org/fhir/uv/v2mappings/ConceptMap-segment-al1-to-allergyintolerance.html"="https://hl7.org/fhir/uv/v2mappings/ConceptMap-segment-al1-to-allergyintolerance.html"
The IG segment map the five AL1 allergy value maps hang off, so a reader can audit any row: it is the page that names which vocabulary map applies to which AL1 field.
Example
import { IG_ALLERGY_VALUE_MAPS_SOURCE } from "@cosyte/transform";
IG_ALLERGY_VALUE_MAPS_SOURCE.startsWith("https://"); // true
IG_ALLERGY_VALUE_MAPS_VERSION
constIG_ALLERGY_VALUE_MAPS_VERSION:"1.0.0"="1.0.0"
The published version of the HL7 Version 2 to FHIR Implementation Guide the five AL1 allergy value maps below were transcribed from.
Recorded per map family rather than once for the file, because the earlier value maps here were transcribed on their own date and this constant must not backdate or forward-date them.
Example
import { IG_ALLERGY_VALUE_MAPS_VERSION } from "@cosyte/transform";
IG_ALLERGY_VALUE_MAPS_VERSION; // "1.0.0"
IG_MAPPED_ADT_TRIGGERS
constIG_MAPPED_ADT_TRIGGERS:ReadonlySet<string>
The ADT trigger events the IG ships a message map for. Other triggers still transform, from the reusable segment maps, but are flagged ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_APPOINTMENT_TRIGGERS
constIG_MAPPED_APPOINTMENT_TRIGGERS:ReadonlySet<string>
The scheduling trigger the IG ships a message map for. The IG maps only SIU^S12; other SIU
triggers still assemble their Appointment from the reusable SCH/AIS/PID segment maps but are flagged
ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_DOCUMENT_TRIGGERS
constIG_MAPPED_DOCUMENT_TRIGGERS:ReadonlySet<string>
The medical-document trigger the IG ships a message map for. The IG maps only MDM^T02; other MDM
triggers still assemble their DocumentReference from the reusable TXA/OBX segment maps but are flagged
ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_IMMUNIZATION_TRIGGERS
constIG_MAPPED_IMMUNIZATION_TRIGGERS:ReadonlySet<string>
The immunization trigger the IG ships a message map for. The IG maps only VXU^V04; other VXU
triggers still assemble their Immunization graph from the reusable RXA/RXR/ORC segment maps but are
flagged ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_ORDER_TRIGGERS
constIG_MAPPED_ORDER_TRIGGERS:ReadonlySet<string>
The order-message trigger events the IG ships a message map for, keyed CODE^TRIGGER. Only
ORM^O01 and OML^O21 are message-map-grounded; other order families (OMP, OMG, RDE, …)
still assemble their request graph from the reusable ORC/OBR/RXO/RXR segment maps but are flagged
ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_ORU_TRIGGERS
constIG_MAPPED_ORU_TRIGGERS:ReadonlySet<string>
The ORU trigger events the IG ships a message map for. The IG maps only R01; other ORU triggers
still assemble their results graph from the reusable OBR/OBX segment maps but are flagged
ISSUE_CODES.TRANSFORM_SEGMENT_ASSEMBLED.
IG_MAPPED_SEGMENT_NAMES
constIG_MAPPED_SEGMENT_NAMES:ReadonlySet<string>
Every v2 segment name the guide publishes at least one segment-to-resource map for, at IG_SEGMENT_MAPS_VERSION, as of IG_SEGMENT_MAPS_RETRIEVED.
Thirty-three names, transcribed chapter by chapter from IG_SEGMENT_MAPS_SOURCE: Control
(MSA, MSH, NTE, SFT), Patient Administration (AL1, EVN, IAM, MRG, NK1, PD1,
PID, PV1, PV2), Order Entry (OBR, ORC, TQ1), Pharmacy and Vaccination (RXA, RXO,
RXR), Financial Management (DG1, IN1, IN3, PR1), Observation Reporting (OBX, PRT,
SPM), Medical Records (TXA), Scheduling (AIG, AIL, AIP, AIS, SCH) and Personnel
Management (ROL).
Two absences a reader is most likely to check, because they look like oversights and are not:
RXE is not on this set (the guide publishes no map for it, which is why this library counts
an RXE and refuses to assemble one), and neither is GT1.
Example
import { IG_MAPPED_SEGMENT_NAMES } from "@cosyte/transform";
IG_MAPPED_SEGMENT_NAMES.has("IAM"); // true
IG_MAPPED_SEGMENT_NAMES.has("RXE"); // false
IG_SEGMENT_MAPS_PUBLISHED
constIG_SEGMENT_MAPS_PUBLISHED:"2025-10-07"="2025-10-07"
The publication date of IG_SEGMENT_MAPS_VERSION, so a later release of the guide can be told apart from a defect in this library.
Example
import { IG_SEGMENT_MAPS_PUBLISHED } from "@cosyte/transform";
IG_SEGMENT_MAPS_PUBLISHED; // "2025-10-07"
IG_SEGMENT_MAPS_RETRIEVED
constIG_SEGMENT_MAPS_RETRIEVED:"2026-08-22"="2026-08-22"
The date the Segment Maps index was retrieved and transcribed into IG_MAPPED_SEGMENT_NAMES.
A classification that surprises a reader is answered by re-reading the index at this date: the set is a transcription of a published document at a moment, not a live query.
Example
import { IG_SEGMENT_MAPS_RETRIEVED } from "@cosyte/transform";
IG_SEGMENT_MAPS_RETRIEVED; // "2026-08-22"
IG_SEGMENT_MAPS_SOURCE
constIG_SEGMENT_MAPS_SOURCE:"https://hl7.org/fhir/uv/v2mappings/segment_maps.html"="https://hl7.org/fhir/uv/v2mappings/segment_maps.html"
The Segment Maps index this set was transcribed from, so a reader can audit any entry.
Example
import { IG_SEGMENT_MAPS_SOURCE } from "@cosyte/transform";
IG_SEGMENT_MAPS_SOURCE.startsWith("https://"); // true
IG_SEGMENT_MAPS_VERSION
constIG_SEGMENT_MAPS_VERSION:"1.0.0"="1.0.0"
The published version of the HL7 Version 2 to FHIR Implementation Guide this set was read from.
Example
import { IG_SEGMENT_MAPS_VERSION } from "@cosyte/transform";
IG_SEGMENT_MAPS_VERSION; // "1.0.0"
IMMUNIZATION_STATUS_MAP
constIMMUNIZATION_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0322 (Completion Status) → FHIR Immunization.status, per the IG Table HL70322 to
Event Status ConceptMap (each is equivalent to). Table 0322 has exactly these four source
codes and every one carries a target; the two distinct targets (completed, not-done) are both
valid members of the immunization-status required binding, so applying this map to
Immunization.status is faithful. Consulted only for a valued RXA-20 when RXA-21 ≠ "D" (the
IG's mappedVia condition on that row); the two other IG status rows assign fixed values directly (a
delete → entered-in-error, an unvalued RXA-20 → completed) and do not consult this map. See
buildStatus.
IN1_SUBSCRIBER_NUMBER_TYPE
constIN1_SUBSCRIBER_NUMBER_TYPE:"SN"="SN"
The Table 0203 identifier-type code the IN1-10 row conditions its subscriber-id assignment on
(IF CX.5 IS "SN", Subscriber Number). Any other identifier type leaves that row unapplied.
Example
import { IN1_SUBSCRIBER_NUMBER_TYPE } from "@cosyte/transform";
IN1_SUBSCRIBER_NUMBER_TYPE; // "SN"
ISSUE_CODES
constISSUE_CODES:object
Stable non-fatal issue codes: the typed diagnostics the fail-safe rule emits.
Type Declaration
TRANSFORM_ADDRESS_USE_UNMAPPED
readonlyTRANSFORM_ADDRESS_USE_UNMAPPED:"TRANSFORM_ADDRESS_USE_UNMAPPED"="TRANSFORM_ADDRESS_USE_UNMAPPED"
An XAD.7 address-type code has no equivalent in the IG's HL70190 → address-use/type
ConceptMaps; Address.use/.type are left absent rather than guessed.
TRANSFORM_CODE_NOT_INVERTIBLE
readonlyTRANSFORM_CODE_NOT_INVERTIBLE:"TRANSFORM_CODE_NOT_INVERTIBLE"="TRANSFORM_CODE_NOT_INVERTIBLE"
A FHIR code has no usable inverse in the IG ConceptMap that governs its field: either several v2 source codes map onto it (so the inverse is ambiguous) or the map has no row for it at all. The v2 field is left absent, never resolved to one arbitrary member of the ambiguous set.
TRANSFORM_CODE_SYSTEM_NOT_V2
readonlyTRANSFORM_CODE_SYSTEM_NOT_V2:"TRANSFORM_CODE_SYSTEM_NOT_V2"="TRANSFORM_CODE_SYSTEM_NOT_V2"
A Coding.system is not a system this library can name with a v2 coding-system mnemonic, so
the coding cannot be written into a v2 coded field. It is flagged rather than emitted with no
table context or with a code from an unrelated table.
TRANSFORM_CODE_SYSTEM_UNRESOLVED
readonlyTRANSFORM_CODE_SYSTEM_UNRESOLVED:"TRANSFORM_CODE_SYSTEM_UNRESOLVED"="TRANSFORM_CODE_SYSTEM_UNRESOLVED"
A coding-system mnemonic (CWE.3 / CWE.6) was not recognized, so no canonical system URI could be emitted. The code is preserved; a URI is never invented.
TRANSFORM_CODE_UNMAPPED
readonlyTRANSFORM_CODE_UNMAPPED:"TRANSFORM_CODE_UNMAPPED"="TRANSFORM_CODE_UNMAPPED"
A coded value could not be mapped to a FHIR concept: either it carried no coding-system context
(CWE.3 absent), or it is a table code the IG ConceptMap has no target for (e.g. an OBX-11/
OBR-25 result status the HL70085/HL70123 map does not carry, or an OBX-8 abnormal flag absent from
HL70078). The original code is preserved / the FHIR value left absent; never coerced to a
neighbor and never guessed to final/normal.
TRANSFORM_ELEMENT_DROPPED
readonlyTRANSFORM_ELEMENT_DROPPED:"TRANSFORM_ELEMENT_DROPPED"="TRANSFORM_ELEMENT_DROPPED"
A populated source element was not carried to its FHIR target and was dropped, either because the IG map defines no target, or because that target's conversion is not implemented (e.g. XTN→ContactPoint telecom, PV1 participants). Surfaced here rather than silently discarded, never a fabricated value.
TRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED
readonlyTRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED:"TRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED"="TRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED"
The assigning authority (HD) could not be resolved to a FHIR Identifier.system URI via the
NamingSystem registry. The identifier is emitted with its value and no system: a system URI
is never synthesized from HD.1 alone.
TRANSFORM_MISSING_TRIGGER
readonlyTRANSFORM_MISSING_TRIGGER:"TRANSFORM_MISSING_TRIGGER"="TRANSFORM_MISSING_TRIGGER"
A reverse (FHIR to v2) conversion was called without the explicit message trigger it requires. No FHIR resource carries a v2 trigger, so it is never inferred from resource content and never defaulted: no message is built and no builder is called.
TRANSFORM_NAME_USE_UNMAPPED
readonlyTRANSFORM_NAME_USE_UNMAPPED:"TRANSFORM_NAME_USE_UNMAPPED"="TRANSFORM_NAME_USE_UNMAPPED"
An XPN.7 name-type code has no equivalent in the IG's HL70200 → name-use ConceptMap;
HumanName.use is left absent rather than guessed.
TRANSFORM_NO_V2_MESSAGE_EMITTED
readonlyTRANSFORM_NO_V2_MESSAGE_EMITTED:"TRANSFORM_NO_V2_MESSAGE_EMITTED"="TRANSFORM_NO_V2_MESSAGE_EMITTED"
A reverse (FHIR to v2) conversion produced no message at all: nothing in the resource grounded a single field of the target segment, and an empty segment is never emitted. Raised so that an empty-handed conversion is never indistinguishable from a successful one, and separate from the refusals that name their own cause (an absent trigger, an unsupported resource type, a structurally malformed resource).
TRANSFORM_NO_V2_TARGET
readonlyTRANSFORM_NO_V2_TARGET:"TRANSFORM_NO_V2_TARGET"="TRANSFORM_NO_V2_TARGET"
A populated FHIR element has no v2 field in the narrow reverse map that covers this shape (the IG map defines no source for it, or its inverse is not implemented here). The element is surfaced and left out, never approximated into a neighbouring v2 field.
TRANSFORM_QUANTITY_VALUE_INVALID
readonlyTRANSFORM_QUANTITY_VALUE_INVALID:"TRANSFORM_QUANTITY_VALUE_INVALID"="TRANSFORM_QUANTITY_VALUE_INVALID"
A v2 numeric value (NM) could not be represented as a FHIR decimal without altering it, e.g.
a leading +, a leading zero, or a trailing dot, which FHIR's decimal lexical form forbids. No
Quantity value is emitted rather than a canonicalized (and therefore altered) magnitude.
TRANSFORM_REQUIRED_ELEMENT_UNKNOWN
readonlyTRANSFORM_REQUIRED_ELEMENT_UNKNOWN:"TRANSFORM_REQUIRED_ELEMENT_UNKNOWN"="TRANSFORM_REQUIRED_ELEMENT_UNKNOWN"
A FHIR-required element's value could not be faithfully derived from the source, so it was
emitted with a data-absent-reason extension (value unknown) rather than fabricated, e.g.
MessageHeader.source.endpoint from an MSH-3 application namespace that is not a URL.
TRANSFORM_RESOURCE_INVALID
readonlyTRANSFORM_RESOURCE_INVALID:"TRANSFORM_RESOURCE_INVALID"="TRANSFORM_RESOURCE_INVALID"
A produced FHIR resource failed @cosyte/fhir R4 structural validation and was withheld
from the bundle rather than emitted as a silently-invalid resource: the conservative-emit gate.
TRANSFORM_RESOURCE_MALFORMED
readonlyTRANSFORM_RESOURCE_MALFORMED:"TRANSFORM_RESOURCE_MALFORMED"="TRANSFORM_RESOURCE_MALFORMED"
A resource handed to a reverse (FHIR to v2) conversion is not structurally a FHIR resource of
its expected type (not an object, no resourceType, or an element carrying the wrong node
kind). Nothing is emitted and nothing is thrown.
TRANSFORM_SEGMENT_ASSEMBLED
readonlyTRANSFORM_SEGMENT_ASSEMBLED:"TRANSFORM_SEGMENT_ASSEMBLED"="TRANSFORM_SEGMENT_ASSEMBLED"
The message's trigger event has no IG message map, so its resource graph was assembled from the reusable IG segment maps rather than a message map. The graph is best-effort and flagged as such, never a fabricated message map.
TRANSFORM_SEGMENT_NO_IG_MAP
readonlyTRANSFORM_SEGMENT_NO_IG_MAP:"TRANSFORM_SEGMENT_NO_IG_MAP"="TRANSFORM_SEGMENT_NO_IG_MAP"
A segment the message carried did not reach any resource in the returned bundle, and its
name is not one the IG publishes a segment map for: a standard gap, not fixable here.
Custom Z-segments and RXE land on this code, and so does a name this library could not
classify at all, because a damaged segment identifier is never re-derived from the line: an
AL1 whose identifier arrived as AL11 reads as unclassifiable, not as an IG omission. Such an
occurrence is located [#n] by its 1-based position among the segments of the message, with no
name part at all.
TRANSFORM_SEGMENT_NOT_EMITTED
readonlyTRANSFORM_SEGMENT_NOT_EMITTED:"TRANSFORM_SEGMENT_NOT_EMITTED"="TRANSFORM_SEGMENT_NOT_EMITTED"
A segment the message carried did not reach any resource in the returned bundle, and the IG
does publish a segment map for its name: a library gap, fixable here. Raised once per
occurrence, located NAME[k] with k counted 1-based among the occurrences of that name
(DG1[1], DG1[2]), so a consumer can tell how much of the message the bundle represents
without diffing the two by hand. The occurrence may have been read and refused rather than never
read: being counted, or already named by another issue, is not the same as reaching a resource.
TRANSFORM_TIMESTAMP_INVALID
readonlyTRANSFORM_TIMESTAMP_INVALID:"TRANSFORM_TIMESTAMP_INVALID"="TRANSFORM_TIMESTAMP_INVALID"
A v2 DTM/TS could not be parsed into a valid FHIR date/time; no value was emitted.
TRANSFORM_TIMESTAMP_NO_TIMEZONE
readonlyTRANSFORM_TIMESTAMP_NO_TIMEZONE:"TRANSFORM_TIMESTAMP_NO_TIMEZONE"="TRANSFORM_TIMESTAMP_NO_TIMEZONE"
A v2 DTM/TS carried a time-of-day but no timezone offset. FHIR forbids time-without-zone, so the value was reduced to date precision (or an explicit sender offset applied via options), never a guessed UTC.
TRANSFORM_UNIT_NOT_UCUM
readonlyTRANSFORM_UNIT_NOT_UCUM:"TRANSFORM_UNIT_NOT_UCUM"="TRANSFORM_UNIT_NOT_UCUM"
A unit was not a valid UCUM code (or was not declared UCUM). It is preserved verbatim in
Quantity.unit; Quantity.code/.system are left absent: a UCUM code is never fabricated
and a magnitude is never converted.
TRANSFORM_UNSUPPORTED_RESOURCE
readonlyTRANSFORM_UNSUPPORTED_RESOURCE:"TRANSFORM_UNSUPPORTED_RESOURCE"="TRANSFORM_UNSUPPORTED_RESOURCE"
A reverse (FHIR to v2) conversion was handed a resource outside the narrow set of shapes it supports. No v2 message is emitted and no segment layout is guessed.
TRANSFORM_V2_REQUIRED_FIELD_ABSENT
readonlyTRANSFORM_V2_REQUIRED_FIELD_ABSENT:"TRANSFORM_V2_REQUIRED_FIELD_ABSENT"="TRANSFORM_V2_REQUIRED_FIELD_ABSENT"
A v2 field the segment's own attribute table marks required (usage R) is absent from an
emitted segment, because the FHIR resource carried no source this reverse map could ground it
from, or the source it carried had no faithful v2 form. The field is left absent per v2
optionality rules and declared here: a placeholder is never written to satisfy v2 structure,
and the receiver is never left to discover the gap. Distinct from
ISSUE_CODES.TRANSFORM_REQUIRED_ELEMENT_UNKNOWN, which is the forward direction's
FHIR-required element.
TRANSFORM_VALUE_NOT_REPRESENTABLE
readonlyTRANSFORM_VALUE_NOT_REPRESENTABLE:"TRANSFORM_VALUE_NOT_REPRESENTABLE"="TRANSFORM_VALUE_NOT_REPRESENTABLE"
A FHIR value cannot be carried into its v2 target without altering it (a lexical form v2 has no representation for, or content that exceeds the target's component structure). The v2 field is left absent rather than truncated, rounded, or coerced.
Example
import { ISSUE_CODES } from "@cosyte/transform";
if (issue.code === ISSUE_CODES.TRANSFORM_TIMESTAMP_NO_TIMEZONE) {
// a v2 timestamp had a time-of-day but no timezone offset: reduced to date precision
}
ISSUE_REGISTRY
constISSUE_REGISTRY:Readonly<Record<IssueCode,IssueMeta>>
The per-code registry: severity, FHIR issue-type, and a static message. Frozen and exhaustive
over ISSUE_CODES (enforced by the Record<IssueCode, …> type: a new code will not
compile until it has an entry).
NAME_USE_MAP
constNAME_USE_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0200 name-type code → FHIR name-use, exactly per the IG HL70200 → name-use
ConceptMap (every row is "is equivalent to"). Codes absent here (A, B, C, F, I, K, NB, NOUSE, P,
REL, S, T, U, …) have no FHIR equivalent and are surfaced, never guessed.
NAME_USE_TO_V2
constNAME_USE_TO_V2:Readonly<Record<string,string>>
FHIR name-use to HL7 v2 Table 0200, the invertible rows of the IG's HL70200 to name-use map.
official and temp are absent on purpose: two source codes each.
Example
import { NAME_USE_TO_V2 } from "@cosyte/transform";
NAME_USE_TO_V2["maiden"]; // => "M"
OBSERVATION_STATUS_MAP
constOBSERVATION_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0085 (Observation Result Status) → FHIR observation-status (Observation.status),
per the IG Table HL70085 to Observation Status ConceptMap (each is equivalent to). Only these
seven source codes carry a target; the codes the IG leaves unmapped (B, I, N, O, R, S,
U, V) are absent here on purpose: an OBX-11 with one of them (or any local code) leaves
Observation.status absent + flagged, and the required-status emit gate withholds the Observation.
C→corrected and X→cancelled guarantee a corrected/cancelled result never emits as final.
OBSERVATION_STATUS_TO_V2
constOBSERVATION_STATUS_TO_V2:Readonly<Record<string,string>>
FHIR observation-status to HL7 v2 Table 0085, the invertible rows of the IG's HL70085 to
Observation Status map. entered-in-error is absent on purpose (D and W both carry it), as
are the FHIR statuses the map never targets (registered, unknown).
Example
import { OBSERVATION_STATUS_TO_V2 } from "@cosyte/transform";
OBSERVATION_STATUS_TO_V2["corrected"]; // => "C"
OBSERVATION_STATUS_TO_V2["entered-in-error"]; // => undefined (ambiguous inverse, flagged instead)
OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL
constOBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL:"https://hl7.org/fhir/5.0/StructureDefinition/extension-Observation.valueAttachment"="https://hl7.org/fhir/5.0/StructureDefinition/extension-Observation.valueAttachment"
The extension URL the OBX map fixes on the IF OBX-2 EQUALS "ED" AND IF OBX-5.4 EQUALS "Base64" rows, transcribed from the map's own Observation.extension.url assignment. R4 has no
Observation.valueAttachment, so the guide carries the R5 element as this named extension.
Example
import { OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL } from "@cosyte/transform";
OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL.endsWith("extension-Observation.valueAttachment"); // true
PROCEDURE_STATUS_UNKNOWN
constPROCEDURE_STATUS_UNKNOWN:"unknown"="unknown"
The Procedure.status the PR1 map's own narrative row directs when the message context does not
determine one. No PR1 component carries a procedure status, so this is the value every Procedure
built from a PR1 carries.
Example
import { PROCEDURE_STATUS_UNKNOWN } from "@cosyte/transform";
PROCEDURE_STATUS_UNKNOWN; // "unknown"
REQUEST_STATUS_MAP
constREQUEST_STATUS_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0119 (Order Control Codes) → FHIR request-status (ServiceRequest.status), per the
IG Table HL70119 to Request Status ConceptMap (each is equivalent to). Only these 19 source
codes carry a target; every other v2-0119 code sits in the IG's explicit (unmapped) group
(verified firsthand against the published v1.0.0 ConceptMap: CH/CN/CP/DE/LI/NA/OE/OF/OP/OR/PA/RE/
RF/RP/RR/RU/SC/SN/SR/SS/UA/UC/UD/UF/UH/UM/UN/UR/UX/XO/XR/XX/MC are all unmatched, and the map
declares no unmapped default), so an ORC-1 with one of them leaves status absent + flagged and
the request is withheld. request-status has no cancelled; the cancel/discontinue codes map to
revoked and the hold codes to on-hold, exactly as the IG table specifies.
ROUTE_VALUE_MAP
constROUTE_VALUE_MAP:CodedValueMap
RXR-1 Route: IG ConceptMap/table-hl70162-to-v2-0162. Two IG groups, transcribed verbatim:
a 41-code identity group (source v2-0162 → target v2-0162, each equivalent) and a 6-code
remap group into v3-RouteOfAdministration (ID→IDINJ, IM→IM, IV→IVINJ, PO→PO, SC→SQ,
TD→TRNSDERM, each equivalent, with the IG target displays). The two source-code sets are
disjoint. Any other v2-0162 code (or a non-table code) is unmapped → the raw coding is preserved
and flagged, never coerced.
SAMPLED_DATA_ABSENT_POINT
constSAMPLED_DATA_ABSENT_POINT:"E"="E"
The SampledData.data token the Implementation Considerations chapter's own worked example
directs for a data point a repetition did not carry ("set .dimensions to 4 and use E for the data points not present"). It is the FHIR-defined "error" token, and it is written only for
an absent position, never for a value that arrived and could not be converted.
Example
import { SAMPLED_DATA_ABSENT_POINT } from "@cosyte/transform";
SAMPLED_DATA_ABSENT_POINT; // "E"
SAMPLED_DATA_UNGROUNDED
constSAMPLED_DATA_UNGROUNDED:"unknown"="unknown"
The data-absent-reason code carried by SampledData.origin and SampledData.period, the two
R4-required elements of that datatype that no row of the IG's NA map, and no line of the
Implementation Considerations chapter it points at, supplies a source for.
Example
import { SAMPLED_DATA_UNGROUNDED } from "@cosyte/transform";
SAMPLED_DATA_UNGROUNDED; // "unknown"
SEGMENT_IDENTIFIER_SHAPE
constSEGMENT_IDENTIFIER_SHAPE:RegExp
The HL7 v2 Chapter 2 segment-identifier shape: three characters, a leading letter, applied to the name value ITSELF as a positive membership test that must pass before any name is rendered.
Everything else is a malformed name without exception: the empty string, a withheld marker, a raw
pre-delimiter token, a bare numeric like 202, a four-character AL11. A malformed occurrence has
no name in this library's vocabulary and is identified by position instead.
Example
import { SEGMENT_IDENTIFIER_SHAPE } from "@cosyte/transform";
SEGMENT_IDENTIFIER_SHAPE.test("ZAL"); // true
SEGMENT_IDENTIFIER_SHAPE.test("202"); // false
SERVICE_REQUEST_PRIORITY_MAP
constSERVICE_REQUEST_PRIORITY_MAP:Readonly<Record<string,string>>
HL7 v2 Table 0485 (Extended Priority Codes) → FHIR request-priority (ServiceRequest.priority),
per the IG Table HL70485 to Request Priority ConceptMap (each is equivalent to; verified
firsthand against the published v1.0.0 ConceptMap). Only these three source codes carry a
target; every other v2-0485 code, namely P (Preop), C (Callback), T (Timing critical), the
T{S,M,H,D,W,L}<integer> timing-critical family, and PRN (As needed), sits in the IG's
(unmapped) group with no target, so an OBR-5 carrying one leaves priority absent + flagged.
All three targets (stat/asap/routine) are valid request-priority members.
SITE_VALUE_MAP
constSITE_VALUE_MAP:CodedValueMap
RXR-2 Administration Site: IG ConceptMap/table-hl70550-to-v2-0550. A single identity
group of 443 body-part codes (source v2-0550 → target v2-0550, each equivalent), transcribed
verbatim from the published STU1 ConceptMap, including its as-published data-quality artifacts
(CHESTÂ, a lone Â, KIDNÂ, where a stray U+00C2 leaked from the IG's source
encoding). They are preserved for source-fidelity; they are inert (a clean CHEST/KIDN simply
falls through to unmapped). A code not in the table is unmapped → raw coding preserved + flagged.
SPM_SHIPMENT_IDENTIFIER_TYPE
constSPM_SHIPMENT_IDENTIFIER_TYPE:"SHIP"="SHIP"
The Table 0203 identifier-type code the SPM-32 row assigns to the shipment identifier
(Specimen.identifier[3].type.coding.code = "SHIP", with the v2-0203 system beside it).
Example
import { SPM_SHIPMENT_IDENTIFIER_TYPE } from "@cosyte/transform";
SPM_SHIPMENT_IDENTIFIER_TYPE; // "SHIP"
SUBSTITUTION_VALUE_MAP
constSUBSTITUTION_VALUE_MAP:CodedValueMap
RXO-9 Allow Substitutions: IG ConceptMap/table-hl70161-to-v2-0161. A single identity
group of the three v2-0161 codes (N NOT authorized, G generic, T therapeutic → themselves,
each equivalent, source and target both v2-0161), the target for
MedicationRequest.substitution.allowedCodeableConcept. Any other code is unmapped → the
substitution is withheld + flagged, never a fabricated substitution permission.
TRANSFORM_ISSUE_SYSTEM
constTRANSFORM_ISSUE_SYSTEM:"https://cosyte.com/fhir/CodeSystem/transform-issue-codes"="https://cosyte.com/fhir/CodeSystem/transform-issue-codes"
The code system under which the transform's stable issue codes are carried in details.coding.
V2_0127_SYSTEM
constV2_0127_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0127"="http://terminology.hl7.org/CodeSystem/v2-0127"
HL7 v2 Table 0127 (Allergen Type) THO CodeSystem URI.
V2_0128_SYSTEM
constV2_0128_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0128"="http://terminology.hl7.org/CodeSystem/v2-0128"
HL7 v2 Table 0128 (Allergy Severity) THO CodeSystem URI.
V2_0161_SYSTEM
constV2_0161_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0161"="http://terminology.hl7.org/CodeSystem/v2-0161"
HL7 v2 Table 0161 (Allow Substitution) THO CodeSystem URI.
V2_0162_SYSTEM
constV2_0162_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0162"="http://terminology.hl7.org/CodeSystem/v2-0162"
HL7 v2 Table 0162 (Route of Administration) THO CodeSystem URI.
V2_0203_SYSTEM
constV2_0203_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0203"="http://terminology.hl7.org/CodeSystem/v2-0203"
The HL7 v2 Table 0203 identifier-type code system canonical URI: used to build Identifier.type.
(FHIR R4 terminologies-systems.html)
V2_0277_SYSTEM
constV2_0277_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0277"="http://terminology.hl7.org/CodeSystem/v2-0277"
HL7 v2 Table 0277 (Appointment Type Codes) THO CodeSystem URI.
V2_0550_SYSTEM
constV2_0550_SYSTEM:"http://terminology.hl7.org/CodeSystem/v2-0550"="http://terminology.hl7.org/CodeSystem/v2-0550"
HL7 v2 Table 0550 (Body Parts) THO CodeSystem URI.
V3_OBSERVATION_INTERPRETATION_SYSTEM
constV3_OBSERVATION_INTERPRETATION_SYSTEM:"http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation"="http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation"
The v3 ObservationInterpretation canonical system (FHIR Observation.interpretation binding).
Example
import { V3_OBSERVATION_INTERPRETATION_SYSTEM } from "@cosyte/transform";
V3_OBSERVATION_INTERPRETATION_SYSTEM.endsWith("v3-ObservationInterpretation"); // => true
V3_ROUTE_OF_ADMINISTRATION_SYSTEM
constV3_ROUTE_OF_ADMINISTRATION_SYSTEM:"http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration"="http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration"
HL7 v3 RouteOfAdministration CodeSystem URI (the IG's remap target for the six common routes).
VERSION
constVERSION:string="0.1.0"
Package version marker exported from the @cosyte/transform root.
Kept in lockstep with package.json by scripts/sync-version.mjs, which the version script
runs immediately after changeset version. The : string annotation is deliberate: without it
TypeScript infers the literal type (declare const VERSION = "0.0.0"), which leaks the current
release into consumers' types and makes an equality check against any other version a compile
error.
Example
import { VERSION } from "@cosyte/transform";
console.log(VERSION);
Functions
addMinutes()
addMinutes(
start,minutes):string|undefined
Add whole minutes to a FHIR dateTime that carries a time of day, preserving its stated offset and
its fractional seconds exactly. Returns undefined when the value is not a full zoned timestamp,
because a date is not a start a duration can be added to.
Parameters
start
string
The FHIR dateTime lexical value the conversion produced.
minutes
number
The number of minutes to add.
Returns
string | undefined
Example
import { addMinutes } from "@cosyte/transform";
addMinutes("2026-01-15T10:30:00-05:00", 45); // "2026-01-15T11:15:00-05:00"
addMinutes("2026-01-15", 45); // undefined
buildAnnotations()
buildAnnotations(
notes,ctx,issues):any
Every FHIR Annotation a run of NTE segments contributes, in message order: one per valued
NTE-3 repetition, each carrying that repetition's rendered text and the segment's NTE-6 time.
Returns undefined when the segments carry no comment text at all, so a caller adds no empty
note element. The diagnostics raised are value-free: no byte of a note ever reaches one.
Parameters
notes
readonly Segment[]
The NTE segments to read, in message order.
ctx
The transform context (naming-system registry + timezone policy).
issues
The issue sink for the deferred-row and timestamp diagnostics.
Returns
any
Example
import { parseHL7 } from "@cosyte/hl7";
// const nte = parseHL7(raw).segments("NTE");
// buildAnnotations(nte, {}, []); // a FHIR list of Annotation nodes, or undefined
buildCondition()
buildCondition(
dg1,patientFullUrl,ctx,v2Location):ConvertResult<FhirComplex>
Build a FHIR Condition resource node from one DG1 occurrence, wired to the bundle's Patient.
Always produces a Condition: a DG1 states a diagnosis, so an occurrence that grounds neither a
code nor a description is emitted with its empty code declared rather than withheld.
Parameters
dg1
Segment
The DG1 @cosyte/hl7 Segment.
patientFullUrl
string
The bundle's Patient fullUrl, for subject (required 1..1).
ctx
The transform context (naming-system registry + timezone policy).
v2Location
string
The occurrence's v2 location, for the codeless diagnostic (e.g. DG1[0]).
Returns
ConvertResult<FhirComplex>
Example
import { parseHL7 } from "@cosyte/hl7";
// const dg1 = parseHL7(raw).segments("DG1")[0];
// const { value } = buildCondition(dg1!, "urn:uuid:pat", {}, "DG1[0]");
buildCoverage()
buildCoverage(
in1,patientFullUrl,ctx,v2Location):ConvertResult<FhirComplex>
Build a FHIR Coverage resource node from one IN1 occurrence, wired to the bundle's Patient.
Returns { value: undefined } when IN1-4 names no insurance company, because payor is required
by R4 and no other row of the segment map grounds it.
Parameters
in1
Segment
The IN1 @cosyte/hl7 Segment.
patientFullUrl
string
The bundle's Patient fullUrl, for beneficiary (required 1..1).
ctx
The transform context (naming-system registry + timezone policy).
v2Location
string
The occurrence's v2 location, for the withholding diagnostic (e.g. IN1[0]).
Returns
ConvertResult<FhirComplex>
Example
import { parseHL7 } from "@cosyte/hl7";
// const in1 = parseHL7(raw).segments("IN1")[0];
// const { value } = buildCoverage(in1!, "urn:uuid:pat", {}, "IN1[0]");
buildProcedure()
buildProcedure(
pr1,patientFullUrl,ctx):ConvertResult<FhirComplex>
Build a FHIR Procedure resource node from one PR1 occurrence, wired to the bundle's Patient.
Always produces a Procedure: a PR1 states that a procedure happened, and status is grounded on
the map's own row rather than on the message, so nothing here can fail to be groundable.
Parameters
pr1
Segment
The PR1 @cosyte/hl7 Segment.
patientFullUrl
string
The bundle's Patient fullUrl, for subject (required 1..1).
ctx
The transform context (naming-system registry + timezone policy).
Returns
ConvertResult<FhirComplex>
Example
import { parseHL7 } from "@cosyte/hl7";
// const pr1 = parseHL7(raw).segments("PR1")[0];
// const { value } = buildProcedure(pr1!, "urn:uuid:pat", {});
buildSpecimen()
buildSpecimen(
spm,subjectFullUrl,ctx):ConvertResult<FhirComplex>
Build a FHIR Specimen resource node from one parsed HL7 v2 SPM segment. Returns
{ value: undefined } when the segment grounds no element of the map at all, because an empty
Specimen in a bundle is a claim that a sample was described when nothing about it was sent.
Parameters
spm
Segment
The SPM @cosyte/hl7 Segment.
subjectFullUrl
string | undefined
The urn:uuid: fullUrl of the bundle's Patient → Specimen.subject.
ctx
The transform context (naming-system registry + timezone policy).
Returns
ConvertResult<FhirComplex>
Example
import { parseHL7 } from "@cosyte/hl7";
// const spm = parseHL7(raw).segments("SPM")[0];
// const { value } = buildSpecimen(spm!, "urn:uuid:pat", {});
carriesLegacyOnsetDate()
carriesLegacyOnsetDate(
version):boolean
Whether a message's MSH-12 version identifier is readable and earlier than the version at which AL1-6 was withdrawn (AL1_ONSET_WITHDRAWN_AT).
Fails closed in both directions a version can be unusable: an absent MSH-12 and one this library
cannot compare (a vendor string, an empty component, anything outside the dotted-numeric shape)
both answer false, so a valued AL1-6 is dropped and flagged rather than read as an onset on a
message that may never have meant one.
Parameters
version
string | undefined
The MSH-12 version identifier exactly as the parser published it.
Returns
boolean
Example
import { carriesLegacyOnsetDate } from "@cosyte/transform";
carriesLegacyOnsetDate("2.5.1"); // true
carriesLegacyOnsetDate("2.7"); // false
carriesLegacyOnsetDate(undefined); // false
codeableConceptFromTarget()
codeableConceptFromTarget(
target,text?):FhirComplex
Build a FHIR CodeableConcept node for a CodedTarget: the single translated coding, with
an optional free-text. Used by translate-or-withhold callers (e.g. substitution) that build the
CodeableConcept only on a successful translation.
Parameters
target
The translated target coding.
text?
string
The original free text (CWE.9) to carry as CodeableConcept.text, if any.
Returns
FhirComplex
Example
import { codeableConceptFromTarget, V2_0161_SYSTEM } from "@cosyte/transform";
const cc = codeableConceptFromTarget({ system: V2_0161_SYSTEM, code: "G" });
void cc;
collectAllergies()
collectAllergies(
msg): readonlySegment[]
Every AL1 occurrence a message carries, in message order. One AllergyIntolerance is created per
occurrence, per the IG message map's 0..-1 cardinality on the AL1 row.
Parameters
msg
Hl7Message
The parsed @cosyte/hl7 message.
Returns
readonly Segment[]
Example
import { parseHL7 } from "@cosyte/hl7";
// collectAllergies(parseHL7(raw)).length; // one entry per AL1 in the message
collectCoverages()
collectCoverages(
msg): readonlySegment[]
Every IN1 occurrence a message carries, in message order. One Coverage is created per
occurrence, per the IG message map's INSURANCE group.
Parameters
msg
Hl7Message
The parsed @cosyte/hl7 message.
Returns
readonly Segment[]
Example
import { parseHL7 } from "@cosyte/hl7";
// collectCoverages(parseHL7(raw)).length; // one entry per IN1 in the message
collectDiagnoses()
collectDiagnoses(
msg): readonlySegment[]
Every DG1 occurrence a message carries, in message order. One Condition is created per
occurrence, per the IG message map's 0..-1 cardinality on the DG1 row.
Parameters
msg
Hl7Message
The parsed @cosyte/hl7 message.
Returns
readonly Segment[]
Example
import { parseHL7 } from "@cosyte/hl7";
// collectDiagnoses(parseHL7(raw)).length; // one entry per DG1 in the message
collectProcedures()
collectProcedures(
msg): readonlySegment[]
Every PR1 occurrence a message carries, in message order. One Procedure is created per
occurrence, per the IG message map's 0..-1 cardinality on the PROCEDURE group.
Parameters
msg
Hl7Message
The parsed @cosyte/hl7 message.
Returns
readonly Segment[]
Example
import { parseHL7 } from "@cosyte/hl7";
// collectProcedures(parseHL7(raw)).length; // one entry per PR1 in the message
createNamingSystem()
createNamingSystem(
seed?):NamingSystemRegistry
Create a NamingSystemRegistry. With no seed it resolves the built-in FHIR-core code systems and the two unambiguous HD auto-derivations (OID/UUID); a seed adds caller-vetted code systems and explicit assigning-authority URIs.
Parameters
seed?
NamingSystemSeed = {}
Returns
Example
import { createNamingSystem } from "@cosyte/transform";
const registry = createNamingSystem({
authorities: { HOSPMRN: "urn:oid:1.2.840.114350.1.13.1" },
});
registry.resolveCodeSystem("LN"); // => "http://loinc.org"
deferredCoverageIssues()
deferredCoverageIssues(
in1): readonlyTransformIssue[]
The value-free diagnostics for the IN1 rows this library reads and deliberately does not build: the payer address and the two policy-holder rows (each an Organization resource), the subscriber (a Patient or RelatedPerson reference), and the relationship, whose value translation needs a table this library does not carry.
Raised for the occurrence whether or not the Coverage itself is emitted, so a deferred row a message actually valued is in the issues list rather than silently absent.
Parameters
in1
Segment
The IN1 @cosyte/hl7 Segment.
Returns
readonly TransformIssue[]
Example
// deferredCoverageIssues(in1).length; // one per valued deferred row
deferredDiagnosisIssues()
deferredDiagnosisIssues(
dg1): readonlyTransformIssue[]
The value-free diagnostics for the DG1 rows this library reads and deliberately does not build: the diagnosing clinician (a Practitioner resource), and the parent diagnosis (a reference resolved by identifier rather than by bundle position).
Raised for the occurrence whether or not the Condition itself is emitted, so a deferred row a message actually valued is in the issues list rather than silently absent.
Parameters
dg1
Segment
The DG1 @cosyte/hl7 Segment.
Returns
readonly TransformIssue[]
Example
// deferredDiagnosisIssues(dg1).length; // one per valued deferred row
deferredProcedureIssues()
deferredProcedureIssues(
pr1): readonlyTransformIssue[]
The value-free diagnostics for the PR1 rows this library reads and deliberately does not build: the three practitioner roles, the treating organizational unit, the parent procedure, and the code modifier whose target is not an R4 element.
Raised for the occurrence whether or not the Procedure itself is emitted, so a deferred row a message actually valued is in the issues list rather than silently absent.
Parameters
pr1
Segment
The PR1 @cosyte/hl7 Segment.
Returns
readonly TransformIssue[]
Example
// deferredProcedureIssues(pr1).length; // one per valued deferred row
emitEncounterDiagnosis()
emitEncounterDiagnosis(
encounter,conditionFullUrls,gate):ConvertResult<FhirComplex>
The Encounter that should replace the emitted one once the message's diagnoses exist: the same resource carrying the back-references, put through the conservative-emit gate first. When the gate refuses the linked draft the ORIGINAL Encounter is returned unchanged and the link is declared ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED, so a detail never costs the visit.
The gate is a parameter rather than a call into the assembler, so what "the gate refuses this" means stays in one place and the refusal branch is reachable from a test without a hand-built invalid resource: the same shape the allergy emit path uses.
Parameters
encounter
FhirComplex
The Encounter node already in the bundle.
conditionFullUrls
readonly string[]
The fullUrls of the Conditions emitted for the same message, in order.
gate
(resource) => boolean
The conservative-emit predicate: true when the linked Encounter may replace it.
Returns
ConvertResult<FhirComplex>
Example
// emitEncounterDiagnosis(encounter, ["urn:uuid:cond-1"], () => true).value; // the linked one
enumerateSegmentOccurrences()
enumerateSegmentOccurrences(
msg): readonlySegmentOccurrence[]
Every segment occurrence of a parsed message, in message order.
A position that carries neither a name nor any field content is the parser's ordinal placeholder for a blank line: it is not a segment occurrence, it is left out, and it still advances the ordinal of everything after it. A position that carries field content is an occurrence even when its name is empty.
Parameters
msg
Hl7Message
The parsed message.
Returns
readonly SegmentOccurrence[]
Example
import { parseHL7 } from "@cosyte/hl7";
import { enumerateSegmentOccurrences } from "@cosyte/transform";
// enumerateSegmentOccurrences(parseHL7(raw))[0]?.name; // "MSH"
fhirIssueTypeFor()
fhirIssueTypeFor(
code):string
The FHIR issue-type code for an IssueCode: used by the OperationOutcome renderer.
Parameters
code
The stable IssueCode.
Returns
string
Example
import { fhirIssueTypeFor, ISSUE_CODES } from "@cosyte/transform";
fhirIssueTypeFor(ISSUE_CODES.TRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED); // "not-found"
insuranceCompanyName()
insuranceCompanyName(
in1):string
The insurance company name an IN1 carries, read from XON.1 of IN1-4, or "" when that component
carries nothing. The only row of the segment map that grounds the required payor.
Parameters
in1
Segment
The IN1 @cosyte/hl7 Segment.
Returns
string
Example
// insuranceCompanyName(in1); // the XON.1 organization name, verbatim
invertCodeMap()
invertCodeMap(
forward):Readonly<Record<string,string>>
Invert a forward v2-to-FHIR code map, keeping only the targets exactly one v2 code maps to.
This is the bijective-subset rule as code. Where several v2 codes are "equivalent to" one FHIR
concept (Table 0001 O/A/N all map to other), the inverse is ambiguous: the target is
dropped here, and its caller flags TRANSFORM_CODE_NOT_INVERTIBLE rather than picking one member
of the set.
Parameters
forward
Readonly<Record<string, string>>
A v2 code to FHIR code map, as published by the IG ConceptMap.
Returns
Readonly<Record<string, string>>
Example
import { invertCodeMap } from "@cosyte/transform";
invertCodeMap({ F: "female", O: "other", A: "other" }); // => { female: "F" }
isIgMappedSegmentName()
isIgMappedSegmentName(
name):boolean
Whether the guide publishes a segment map for name, decided against
IG_MAPPED_SEGMENT_NAMES and against nothing else.
The comparison is exact: a name this library could not classify is not in the set, and is reported as a standard gap for that reason rather than because the guide was consulted and published nothing. That conflation is deliberate and is documented on the code itself; the alternative would be re-deriving a name the parser refused to vouch for.
Parameters
name
string
A v2 segment name, exactly as the parser published it.
Returns
boolean
Example
import { isIgMappedSegmentName } from "@cosyte/transform";
isIgMappedSegmentName("DG1"); // true
isIgMappedSegmentName("ZAL"); // false
issue()
issue(
code,v2Location,fhirPath?):TransformIssue
Construct a value-free TransformIssue. The severity and message come from ISSUE_REGISTRY; the caller supplies only positional metadata, so an issue can carry no PHI.
Parameters
code
The stable IssueCode.
v2Location
string
The v2 source location (segment / field / component index), never a value.
fhirPath?
string
The FHIR path the issue concerns, when applicable.
Returns
Example
import { issue, ISSUE_CODES } from "@cosyte/transform";
const i = issue(ISSUE_CODES.TRANSFORM_TIMESTAMP_NO_TIMEZONE, "TS.1", "dateTime");
void i.severity; // "warning"
isWellFormedSegmentName()
isWellFormedSegmentName(
name):boolean
Whether a segment name may be rendered: the shape test of SEGMENT_IDENTIFIER_SHAPE applied to the value itself.
Deliberately NOT an exclusion of known-bad literals. An exclusion test admits any value it has not heard of, which is the wrong direction for a rule whose whole job is to keep message bytes out of a diagnostic, and it would silently couple this library to one release of the parser package.
Parameters
name
string
The value the parser published as the occurrence's segment type.
Returns
boolean
Example
import { isWellFormedSegmentName } from "@cosyte/transform";
isWellFormedSegmentName("ZAL"); // true
isWellFormedSegmentName("AL11"); // false
segmentOccurrenceLocation()
segmentOccurrenceLocation(
occurrence):string
The v2 location of an occurrence: NAME[k] for a name that passed the shape test, [#n] for one
that did not. Those are the only two shapes, and neither carries a field or component index.
Parameters
occurrence
The occurrence to locate.
Returns
string
Example
import { segmentOccurrenceLocation } from "@cosyte/transform";
// segmentOccurrenceLocation(occ); // "DG1[2]" or "[#4]"
toFhir()
toFhir(
msg,opts?):TransformResult
Transform a parsed HL7 v2 message into a FHIR R4 message Bundle. Never throws for a well-formed
Hl7Message; every ambiguity, unmapped code, dropped element, or withheld resource surfaces
as a value-free TransformIssue.
Parameters
msg
Hl7Message
A parsed @cosyte/hl7 message.
opts?
TransformOptions = {}
Transform options: the TransformOptions.namingSystem registry, the naked- timestamp TransformOptions.assumeTimezoneOffsetMinutes policy, and a TransformOptions.generateId allocator for reproducible fullUrls.
Returns
Example
import { parseHL7 } from "@cosyte/hl7";
import { toFhir, createNamingSystem } from "@cosyte/transform";
const { bundle, issues } = toFhir(parseHL7(raw), { namingSystem: createNamingSystem() });
void bundle;
void issues;
toFhirAddress()
toFhirAddress(
xad):ConvertResult<FhirComplex>
Convert a parsed HL7 v2 XAD to a FHIR Address node. Returns { value: undefined } when the
address carries no emittable part.
Parameters
xad
XAD
A parsed @cosyte/hl7 XAD.
Returns
ConvertResult<FhirComplex>
Example
import { toFhirAddress } from "@cosyte/transform";
const { value } = toFhirAddress({ street: "1 Main St", city: "Boston", stateOrProvince: "MA", addressType: "H" });
// value === Address { use: "home", line: ["1 Main St"], city: "Boston", state: "MA" }
void value;
toFhirCodeableConcept()
toFhirCodeableConcept(
cwe,ctx?):ConvertResult<FhirComplex>
Convert a parsed HL7 v2 CWE (or CE) to a FHIR CodeableConcept node, fail-safe on the coding
system and on unmapped codes. Returns { value: undefined } when the element is empty.
Parameters
cwe
A parsed @cosyte/hl7 CWE (a CE is accepted as its subset).
ctx?
TransformContext = {}
The transform context; ctx.namingSystem resolves the coding-system mnemonic.
Returns
ConvertResult<FhirComplex>
Example
import { toFhirCodeableConcept, createNamingSystem } from "@cosyte/transform";
const { value } = toFhirCodeableConcept(
{ identifier: "789-8", text: "Hemoglobin", nameOfCodingSystem: "LN" },
{ namingSystem: createNamingSystem() },
);
// coding[0] === { system: "http://loinc.org", code: "789-8", display: "Hemoglobin" }
void value;
toFhirCodeableConceptVia()
toFhirCodeableConceptVia(
cwe,map,ctx?):ConvertResult<FhirComplex>
Value-translate a coded v2 element to a FHIR CodeableConcept via a license-clean
CodedValueMap, additively and fail-safe, never mutating or discarding what the message
said:
- Primary code recognized as a bound-table code (translateBound: CWE.3 absent or names
the bound table, and the code is in the IG map's mapped group) → the primary coding is emitted
in the recognized source-table system (
map.sourceSystem, carryingCWE.7version) and the derived target coding is appended when it differs (a remap such asSC→SQ); the alternate triplet (CWE.4/5/6, via buildCoding, with its own system resolution + flags) and the originalCWE.9text are preserved. No primary unmapped flag: the value was faithfully recognized. - Otherwise: the primary declares a foreign coding system (not the bound table), the code is
empty, or it is in the IG's
(unmapped)group → this defers entirely to the structural toFhirCodeableConcept, which preserves the raw coding (and itsCWE.4/5/6alternate andCWE.7version) and flags it (ISSUE_CODES.TRANSFORM_CODE_UNMAPPED /TRANSFORM_CODE_SYSTEM_UNRESOLVED). A target is never fabricated, and a code that declares a foreign system is never asserted to be the standard concept.
Parameters
cwe
The parsed @cosyte/hl7 coded element (its identifier is the candidate table code).
map
The license-clean value map to apply (e.g. ROUTE_VALUE_MAP).
ctx?
TransformContext = {}
The transform context (threaded to the structural path + the alternate-triplet resolver).
Returns
ConvertResult<FhirComplex>
Example
import { toFhirCodeableConceptVia, ROUTE_VALUE_MAP } from "@cosyte/transform";
const { value } = toFhirCodeableConceptVia({ identifier: "IM" }, ROUTE_VALUE_MAP);
// coding === [{ system: ".../v2-0162", code: "IM" },
// { system: ".../v3-RouteOfAdministration", code: "IM", display: "Injection, intramuscular" }]
void value;
toFhirDateTime()
toFhirDateTime(
ts,options?):ConvertResult<string>
Convert a parsed HL7 v2 timestamp to a FHIR dateTime lexical string, fail-safe on timezone and
precision. Returns { value: undefined } only when the timestamp is unparseable.
Parameters
ts
TS
A parsed @cosyte/hl7 TS (DtmParts).
options?
TransformOptions = {}
Conversion policy; assumeTimezoneOffsetMinutes supplies a sender-asserted offset.
Returns
ConvertResult<string>
Example
import { parseDtm } from "@cosyte/hl7";
import { toFhirDateTime } from "@cosyte/transform";
const { value } = toFhirDateTime(parseDtm("20260721"));
// value === "2026-07-21"
void value;
toFhirEntityIdentifier()
toFhirEntityIdentifier(
field):EntityIdentifier
Read one EI (Entity Identifier) field as a FHIR Identifier, carrying EI.1 as
Identifier.value and nothing else. The same reading orderIdentifier applies to the
placer/filler order numbers, without the v2-0203 identifier type those rows assign.
Identifier.system is deliberately left absent even when EI.2 to EI.4 name an assigning
authority: a system URI is never synthesized from a bare namespace, because two senders reusing
one namespace would otherwise collide. The caller is told the authority went unused through
EntityIdentifier.authorityValued so it can raise its own value-free diagnostic.
Parameters
field
Field
The EI field, exactly as the parser published it.
Returns
Example
import { parseHL7 } from "@cosyte/hl7";
// const dg1 = parseHL7(raw).segments("DG1")[0];
// toFhirEntityIdentifier(dg1!.field(20)).identifier; // { value: "<EI.1>" } or undefined
toFhirHumanName()
toFhirHumanName(
xpn):ConvertResult<FhirComplex>
Convert a parsed HL7 v2 XPN to a FHIR HumanName node. Returns { value: undefined } when the
name carries no emittable part.
Parameters
xpn
XPN
A parsed @cosyte/hl7 XPN.
Returns
ConvertResult<FhirComplex>
Example
import { toFhirHumanName } from "@cosyte/transform";
const { value } = toFhirHumanName({ familyName: "Public", givenName: "Jane", nameTypeCode: "L" });
// value === HumanName { use: "official", family: "Public", given: ["Jane"] }
void value;
toFhirIdentifier()
toFhirIdentifier(
cx,ctx?):ConvertResult<FhirComplex>
Convert a parsed HL7 v2 CX to a FHIR Identifier node, fail-safe on the assigning authority.
Returns { value: undefined } when the CX carries no identifier value at all.
Parameters
cx
CX
A parsed @cosyte/hl7 CX.
ctx?
TransformContext = {}
The transform context; ctx.namingSystem resolves the assigning authority (HD).
Returns
ConvertResult<FhirComplex>
Example
import { toFhirIdentifier, createNamingSystem } from "@cosyte/transform";
const { value, issues } = toFhirIdentifier(
{ idNumber: "12345", assigningAuthority: { namespaceId: "HOSPMRN" } },
{ namingSystem: createNamingSystem() },
);
// no registry entry for a bare "HOSPMRN" namespace → value emitted, system absent, one issue
void value;
void issues;
toFhirQuantity()
toFhirQuantity(
value,units,ctx?):ConvertResult<FhirComplex>
Convert a parsed HL7 v2 numeric value plus its units to a FHIR Quantity node, fail-safe on the
unit. Returns { value: undefined } when the numeric magnitude is absent or non-numeric (a
Quantity without a value cannot be safely emitted).
Parameters
value
NM
A parsed @cosyte/hl7 NM (its .raw carries the exact lexical value).
units
CWE
The units component (an OBX-6 CWE); its CWE.1 is the candidate UCUM code.
ctx?
TransformContext = {}
The transform context; used to recognize the UCUM coding system.
Returns
ConvertResult<FhirComplex>
Example
import { toFhirQuantity } from "@cosyte/transform";
const { value } = toFhirQuantity(
{ raw: "5.4", value: 5.4 },
{ identifier: "mg/dL", nameOfCodingSystem: "UCUM" },
);
// value === Quantity { value: 5.4, unit: "mg/dL", system: "http://unitsofmeasure.org", code: "mg/dL" }
void value;
toOperationOutcome()
toOperationOutcome(
issues):FhirComplex
Build a FHIR OperationOutcome FhirComplex from the given issues. An empty list still
produces a structurally-valid OperationOutcome with a single information "all clear" issue
(FHIR requires OperationOutcome.issue to be non-empty).
Parameters
issues
readonly TransformIssue[]
The value-free diagnostics to render.
Returns
FhirComplex
Example
import { toOperationOutcome } from "@cosyte/transform";
const oo = toOperationOutcome([]);
// oo is a FhirComplex resource node with resourceType "OperationOutcome"
void oo;
toV2Observation()
toV2Observation(
resource,trigger,options?):ReverseResult
Convert a FHIR R4 Observation into a complete v2 message carrying an OBX segment, in the
result-report (ORU) shape.
The trigger argument is required and never inferred: no Observation element maps to a v2
message trigger, so the caller supplies it, and a missing, empty or non-string one returns
{ value: undefined } plus ISSUE_CODES.TRANSFORM_MISSING_TRIGGER without calling the
message builder at all. It is used verbatim as MSH-9.2 under the ORU message code this shape
fixes.
The message carries the OBX alone: this shape's input is an Observation, which names no
patient, and a subject segment assembled from a reference would be fabricated. Lossy by design and
never round-trip-safe.
An OBX field v2 requires (OBX-11 Observation Result Status) that this resource gives no source
for stays absent and is declared with ISSUE_CODES.TRANSFORM_V2_REQUIRED_FIELD_ABSENT,
rather than defaulted to F: a result reported as final that the sender never called final is the
confidently wrong value this library exists to refuse. An Observation that grounds no OBX
field at all yields no message and ISSUE_CODES.TRANSFORM_NO_V2_MESSAGE_EMITTED.
Parameters
resource
FhirNode
The FHIR Observation node.
trigger
string
The bare v2 trigger, e.g. "R01". Required; never derived from the resource.
options?
ReverseOptions = {}
Caller-vetted reverse context: code systems and the MSH envelope.
Returns
Example
import { parseResource } from "@cosyte/fhir";
import { toV2Observation } from "@cosyte/transform";
const { resource } = parseResource(
'{"resourceType":"Observation","status":"final","code":{"coding":[{"system":"http://loinc.org","code":"789-8"}]}}',
);
const { value, issues } = toV2Observation(resource, "R01");
// value.toString() carries "ORU^R01" in MSH-9, then an OBX whose OBX-3 is "789-8^^LN"
void value;
void issues;
toV2Patient()
toV2Patient(
resource,trigger,options?):ReverseResult
Convert a FHIR R4 Patient into a complete v2 message carrying a PID segment, for the
demographics-only trigger events (A28, A31, A29, ...) that carry a patient with no visit.
The trigger argument is required and never inferred: no Patient element maps to a v2
message trigger, so the caller supplies it, and a missing, empty or non-string one returns
{ value: undefined } plus ISSUE_CODES.TRANSFORM_MISSING_TRIGGER without calling the
message builder at all. It is used verbatim as MSH-9.2 under the ADT message code this shape
fixes; the caller never supplies the code and it never varies per call.
Lossy by design and never round-trip-safe: a value the inverse of the IG map cannot ground is flagged and left absent, never guessed, and a resource of another type is refused outright.
A PID field v2 requires (PID-3 Patient Identifier List, PID-5 Patient Name) that this resource
gives no source for stays absent and is declared with
ISSUE_CODES.TRANSFORM_V2_REQUIRED_FIELD_ABSENT: the emitted message is honest about what
it lacks rather than padded to look conformant. A Patient that grounds no PID field at all
yields no message and ISSUE_CODES.TRANSFORM_NO_V2_MESSAGE_EMITTED.
Parameters
resource
FhirNode
The FHIR Patient node (build one with @cosyte/fhir's parseResource).
trigger
string
The bare v2 trigger, e.g. "A28". Required; never derived from the resource.
options?
ReverseOptions = {}
Caller-vetted reverse context: assigning authorities, code systems, MSH envelope.
Returns
Example
import { parseResource } from "@cosyte/fhir";
import { toV2Patient } from "@cosyte/transform";
const { resource } = parseResource('{"resourceType":"Patient","gender":"female"}');
const { value, issues } = toV2Patient(resource, "A28");
// value.toString() starts "MSH|^~\\&|" and carries "ADT^A28" in MSH-9, then a PID segment
void value;
void issues;
translateBound()
translateBound(
cwe,map):CodedTarget|undefined
The bound-table target for a coded element's primary coding, or undefined when the map does
not faithfully apply, i.e. the primary declares a coding system that is not this map's bound
table (CWE.3 present and not in CodedValueMap.sourceMnemonics), the primary code is empty, or
the code is in the IG map's (unmapped) group. Never asserts a standard translation for a foreign
coding system, and never fabricates a target.
Parameters
cwe
The parsed coded element (its identifier is the candidate source-table code).
map
The license-clean value map to consider applying.
Returns
CodedTarget | undefined
Example
import { translateBound, ROUTE_VALUE_MAP } from "@cosyte/transform";
translateBound({ identifier: "IM" }, ROUTE_VALUE_MAP)?.code; // "IM" (v3 route)
translateBound({ identifier: "IM", nameOfCodingSystem: "99LOCAL" }, ROUTE_VALUE_MAP); // undefined
withCodeableText()
withCodeableText(
concept,textValue):FhirComplex
The same CodeableConcept with its text replaced by textValue, so a segment row that targets
code.text directly can override the original text the datatype map read out of the coded field.
Parameters
concept
FhirComplex
The CodeableConcept node the datatype converter produced.
textValue
string
The text the segment map's own row assigns.
Returns
FhirComplex
Example
// withCodeableText(concept, "Diabetes mellitus") -> the same codings, that text
withEncounterDiagnosis()
withEncounterDiagnosis(
encounter,conditionFullUrls):FhirComplex
The same Encounter carrying one diagnosis entry per Condition the bundle holds, per the ADT_A01
message map's Encounter[1].diagnosis.reference = Condition[1].id row. Each entry's condition
points at that Condition's fullUrl, so the link resolves inside the bundle.
Applied after the diagnoses are built, because the Encounter joins the bundle before them and the produced nodes are immutable: this returns a new node rather than mutating the emitted one.
Parameters
encounter
FhirComplex
The Encounter node already in the bundle.
conditionFullUrls
readonly string[]
The fullUrls of the Conditions emitted for the same message, in order.
Returns
FhirComplex
Example
// withEncounterDiagnosis(encounter, ["urn:uuid:cond-1"]); // adds one diagnosis entry