Skip to main content
Version: v0.0.6

@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). Terminology depth beyond these maps, profiles, and the reverse FHIR → v2 direction are not implemented.

Interfaces​

CodedTarget​

A translated FHIR target coding: the target CodeSystem URI + code, and the IG's target display.

Properties​

code​

readonly code: string

The FHIR target code.

display?​

readonly optional display?: string

The IG map's target display, when it carries one (absent for the identity table maps).

system​

readonly system: 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​

readonly name: string

The IG ConceptMap id this map transcribes (its citation).

sourceMnemonics​

readonly sourceMnemonics: 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​

readonly sourceSystem: string

The source table's canonical CodeSystem URI (what the raw v2 code is a member of when mapped).

translate​

readonly translate: (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​

readonly issues: readonly TransformIssue[]

The value-free diagnostics raised during the conversion, in emission order.

value​

readonly value: T | undefined

The produced FHIR value, or undefined when nothing could be safely emitted.


NamingSystemRegistry​

The resolver consulted by the identity- and code-conversion paths.

Properties​

resolveAssigningAuthority​

readonly resolveAssigningAuthority: (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​

readonly resolveCodeSystem: (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?​

readonly optional authorities?: 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?​

readonly optional codeSystems?: Readonly<Record<string, string>>

Extra v2 coding-system mnemonic → canonical URI entries (merged over the defaults).


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?​

readonly optional namingSystem?: NamingSystemRegistry

The registry used to resolve HD → system and v2 mnemonic → canonical URI.

options?​

readonly optional options?: 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​

readonly code: IssueCode

The stable code. One of ISSUE_CODES.

fhirPath?​

readonly optional fhirPath?: string

The FHIR path this issue concerns (e.g. Identifier.system), when applicable.

message​

readonly message: string

A static, value-free description drawn from ISSUE_REGISTRY.

severity​

readonly severity: TransformSeverity

The OperationOutcome-style severity, fixed per code.

v2Location​

readonly v2Location: 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?​

readonly optional assumeTimezoneOffsetMinutes?: number

The sender's UTC offset in minutes, asserted by the caller to resolve naked timestamps.

generateId?​

readonly optional generateId?: () => 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?​

readonly optional namingSystem?: 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​

readonly bundle: FhirComplex

The FHIR R4 Bundle resource node (a message Bundle: MessageHeader first, then focal resources).

issues​

readonly issues: readonly TransformIssue[]

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 typeof FATAL_CODES]

A value from FATAL_CODES - the type carried by a thrown fatal error.


IssueCode​

IssueCode = typeof ISSUE_CODES[keyof typeof ISSUE_CODES]

A value from ISSUE_CODES - the type consumers narrow issue.code against.


TransformSeverity​

TransformSeverity = "error" | "warning" | "information"

The severity a TransformIssue carries - an OperationOutcome.issue.severity value.

Variables​

ADDRESS_TYPE_MAP​

const ADDRESS_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​

const ADDRESS_USE_MAP: Readonly<Record<string, string>>

HL7 v2 Table 0190 address-type code → FHIR address-use, exactly per the IG HL70190→address-use map.


ADMINISTRATIVE_GENDER_MAP​

const ADMINISTRATIVE_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.


APPOINTMENT_STATUS_MAP​

const APPOINTMENT_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​

const APPOINTMENT_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.


DEFAULT_V2_CODE_SYSTEMS​

const DEFAULT_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.


DIAGNOSTIC_REPORT_STATUS_MAP​

const DIAGNOSTIC_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.


ENCOUNTER_CLASS_V3_MAP​

const ENCOUNTER_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​

const ENCOUNTER_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​

const FATAL_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​

readonly EMPTY_INPUT: "EMPTY_INPUT" = "EMPTY_INPUT"

The input carried nothing to transform.

TRANSFORM_UNSUPPORTED_INPUT​

readonly TRANSFORM_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;

HL70078_INTERPRETATION_CODES​

const HL70078_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_MAPPED_ADT_TRIGGERS​

const IG_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​

const IG_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​

const IG_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​

const IG_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​

const IG_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​

const IG_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.


IMMUNIZATION_STATUS_MAP​

const IMMUNIZATION_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.


ISSUE_CODES​

const ISSUE_CODES: object

Stable non-fatal issue codes - the typed diagnostics the fail-safe rule emits.

Type Declaration​

TRANSFORM_ADDRESS_USE_UNMAPPED​

readonly TRANSFORM_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_SYSTEM_UNRESOLVED​

readonly TRANSFORM_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​

readonly TRANSFORM_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​

readonly TRANSFORM_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​

readonly TRANSFORM_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_NAME_USE_UNMAPPED​

readonly TRANSFORM_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_QUANTITY_VALUE_INVALID​

readonly TRANSFORM_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​

readonly TRANSFORM_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​

readonly TRANSFORM_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_SEGMENT_ASSEMBLED​

readonly TRANSFORM_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_TIMESTAMP_INVALID​

readonly TRANSFORM_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​

readonly TRANSFORM_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​

readonly TRANSFORM_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.

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​

const ISSUE_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​

const NAME_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.


OBSERVATION_STATUS_MAP​

const OBSERVATION_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.


REQUEST_STATUS_MAP​

const REQUEST_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​

const ROUTE_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.


SERVICE_REQUEST_PRIORITY_MAP​

const SERVICE_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 - 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​

const SITE_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.


SUBSTITUTION_VALUE_MAP​

const SUBSTITUTION_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​

const TRANSFORM_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_0161_SYSTEM​

const V2_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​

const V2_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​

const V2_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​

const V2_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​

const V2_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_ROUTE_OF_ADMINISTRATION_SYSTEM​

const V3_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​

const VERSION: string = "0.0.6"

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​

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​

CodedTarget

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;

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​

NamingSystemRegistry

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"

fhirIssueTypeFor()​

fhirIssueTypeFor(code): string

The FHIR issue-type code for an IssueCode - used by the OperationOutcome renderer.

Parameters​

code​

IssueCode

The stable IssueCode.

Returns​

string

Example​

import { fhirIssueTypeFor, ISSUE_CODES } from "@cosyte/transform";
fhirIssueTypeFor(ISSUE_CODES.TRANSFORM_IDENTIFIER_SYSTEM_UNRESOLVED); // "not-found"

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​

IssueCode

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​

TransformIssue

Example​

import { issue, ISSUE_CODES } from "@cosyte/transform";
const i = issue(ISSUE_CODES.TRANSFORM_TIMESTAMP_NO_TIMEZONE, "TS.1", "dateTime");
void i.severity; // "warning"

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​

TransformResult

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​

CodedElement

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, carrying CWE.7 version) and the derived target coding is appended when it differs (a remap such as SC→SQ); the alternate triplet (CWE.4/5/6, via buildCoding, with its own system resolution + flags) and the original CWE.9 text 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 its CWE.4/5/6 alternate and CWE.7 version) 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​

CodedElement

The parsed @cosyte/hl7 coded element (its identifier is the candidate table code).

map​

CodedValueMap

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;

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;

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​

CodedElement

The parsed coded element (its identifier is the candidate source-table code).

map​

CodedValueMap

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