@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
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.
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).
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.
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.
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.
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.
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.
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.
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;
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_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.
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.
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_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_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_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_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_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.
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.
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.
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.
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 - 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.
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_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_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:"0.0.0"="0.0.0"
The library version string, synced with package.json#version by the release tooling.
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
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
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
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
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"
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;
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
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