@cosyte/transform 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { FhirComplex } from '@cosyte/fhir';
2
- import { HD, TS, CX, CWE, XPN, XAD, NM, Hl7Message } from '@cosyte/hl7';
1
+ import { FhirComplex, FhirNode } from '@cosyte/fhir';
2
+ import { HD, TS, CX, CWE, XPN, XAD, NM, Hl7Message, Segment, Field, BuildMessageInit } from '@cosyte/hl7';
3
3
 
4
4
  /**
5
5
  * The stable code registries for the `@cosyte/transform` diagnostic channel.
@@ -17,6 +17,16 @@ import { HD, TS, CX, CWE, XPN, XAD, NM, Hl7Message } from '@cosyte/hl7';
17
17
  * entry points. **Nothing in this library throws one today**: the datatype converters and
18
18
  * `toFhir` alike fail safe to a value-free issue instead.
19
19
  *
20
+ * **The line between the two registries is structural, and it decides where a new code goes.** A
21
+ * `FatalCode` is the type carried by a *thrown* error; a `TransformIssue.code` is typed `IssueCode`
22
+ * and {@link ISSUE_REGISTRY} is exhaustive over {@link ISSUE_CODES} alone. So a condition that is
23
+ * *returned* on the non-throwing `{ value, issues }` channel is an {@link ISSUE_CODES} entry by
24
+ * construction, however severe it is: the missing-trigger refusal on the reverse
25
+ * (FHIR to v2) entry points is returned, never thrown, so it is
26
+ * {@link ISSUE_CODES.TRANSFORM_MISSING_TRIGGER} rather than a fatal code. Adding it to
27
+ * {@link FATAL_CODES} instead would have required widening `TransformIssue.code` to
28
+ * `IssueCode | FatalCode` and blurring exactly that split.
29
+ *
20
30
  * @packageDocumentation
21
31
  */
22
32
  /**
@@ -80,6 +90,62 @@ declare const ISSUE_CODES: {
80
90
  * emitted with a `data-absent-reason` extension (value `unknown`) rather than fabricated, e.g.
81
91
  * `MessageHeader.source.endpoint` from an MSH-3 application namespace that is not a URL. */
82
92
  readonly TRANSFORM_REQUIRED_ELEMENT_UNKNOWN: "TRANSFORM_REQUIRED_ELEMENT_UNKNOWN";
93
+ /** A reverse (FHIR to v2) conversion was called without the explicit message trigger it requires.
94
+ * No FHIR resource carries a v2 trigger, so it is never inferred from resource content and never
95
+ * defaulted: no message is built and no builder is called. */
96
+ readonly TRANSFORM_MISSING_TRIGGER: "TRANSFORM_MISSING_TRIGGER";
97
+ /** A reverse (FHIR to v2) conversion was handed a resource outside the narrow set of shapes it
98
+ * supports. No v2 message is emitted and no segment layout is guessed. */
99
+ readonly TRANSFORM_UNSUPPORTED_RESOURCE: "TRANSFORM_UNSUPPORTED_RESOURCE";
100
+ /** A resource handed to a reverse (FHIR to v2) conversion is not structurally a FHIR resource of
101
+ * its expected type (not an object, no `resourceType`, or an element carrying the wrong node
102
+ * kind). Nothing is emitted and nothing is thrown. */
103
+ readonly TRANSFORM_RESOURCE_MALFORMED: "TRANSFORM_RESOURCE_MALFORMED";
104
+ /** A populated FHIR element has no v2 field in the narrow reverse map that covers this shape
105
+ * (the IG map defines no source for it, or its inverse is not implemented here). The element is
106
+ * surfaced and left out, never approximated into a neighbouring v2 field. */
107
+ readonly TRANSFORM_NO_V2_TARGET: "TRANSFORM_NO_V2_TARGET";
108
+ /** A FHIR value cannot be carried into its v2 target without altering it (a lexical form v2 has
109
+ * no representation for, or content that exceeds the target's component structure). The v2 field
110
+ * is left absent rather than truncated, rounded, or coerced. */
111
+ readonly TRANSFORM_VALUE_NOT_REPRESENTABLE: "TRANSFORM_VALUE_NOT_REPRESENTABLE";
112
+ /** A FHIR code has no usable inverse in the IG ConceptMap that governs its field: either several
113
+ * v2 source codes map onto it (so the inverse is ambiguous) or the map has no row for it at all.
114
+ * The v2 field is left absent, never resolved to one arbitrary member of the ambiguous set. */
115
+ readonly TRANSFORM_CODE_NOT_INVERTIBLE: "TRANSFORM_CODE_NOT_INVERTIBLE";
116
+ /** A `Coding.system` is not a system this library can name with a v2 coding-system mnemonic, so
117
+ * the coding cannot be written into a v2 coded field. It is flagged rather than emitted with no
118
+ * table context or with a code from an unrelated table. */
119
+ readonly TRANSFORM_CODE_SYSTEM_NOT_V2: "TRANSFORM_CODE_SYSTEM_NOT_V2";
120
+ /** A v2 field the segment's own attribute table marks **required** (usage `R`) is absent from an
121
+ * emitted segment, because the FHIR resource carried no source this reverse map could ground it
122
+ * from, or the source it carried had no faithful v2 form. The field is left absent per v2
123
+ * optionality rules and **declared here**: a placeholder is never written to satisfy v2 structure,
124
+ * and the receiver is never left to discover the gap. Distinct from
125
+ * {@link ISSUE_CODES.TRANSFORM_REQUIRED_ELEMENT_UNKNOWN}, which is the forward direction's
126
+ * FHIR-required element. */
127
+ readonly TRANSFORM_V2_REQUIRED_FIELD_ABSENT: "TRANSFORM_V2_REQUIRED_FIELD_ABSENT";
128
+ /** A reverse (FHIR to v2) conversion produced **no message at all**: nothing in the resource
129
+ * grounded a single field of the target segment, and an empty segment is never emitted. Raised so
130
+ * that an empty-handed conversion is never indistinguishable from a successful one, and separate
131
+ * from the refusals that name their own cause (an absent trigger, an unsupported resource type, a
132
+ * structurally malformed resource). */
133
+ readonly TRANSFORM_NO_V2_MESSAGE_EMITTED: "TRANSFORM_NO_V2_MESSAGE_EMITTED";
134
+ /** A segment the message carried did **not** reach any resource in the returned bundle, and the IG
135
+ * *does* publish a segment map for its name: a **library gap**, fixable here. Raised once per
136
+ * occurrence, located `NAME[k]` with `k` counted 1-based among the occurrences of that name
137
+ * (`DG1[1]`, `DG1[2]`), so a consumer can tell how much of the message the bundle represents
138
+ * without diffing the two by hand. The occurrence may have been read and refused rather than never
139
+ * read: being counted, or already named by another issue, is not the same as reaching a resource. */
140
+ readonly TRANSFORM_SEGMENT_NOT_EMITTED: "TRANSFORM_SEGMENT_NOT_EMITTED";
141
+ /** A segment the message carried did **not** reach any resource in the returned bundle, and its
142
+ * name is **not** one the IG publishes a segment map for: a **standard gap**, not fixable here.
143
+ * Custom Z-segments and `RXE` land on this code, and so does a name this library could not
144
+ * classify at all, because a damaged segment identifier is never re-derived from the line: an
145
+ * `AL1` whose identifier arrived as `AL11` reads as unclassifiable, not as an IG omission. Such an
146
+ * occurrence is located `[#n]` by its 1-based position among the segments of the message, with no
147
+ * name part at all. */
148
+ readonly TRANSFORM_SEGMENT_NO_IG_MAP: "TRANSFORM_SEGMENT_NO_IG_MAP";
83
149
  };
84
150
  /** A value from {@link ISSUE_CODES}: the type consumers narrow `issue.code` against. */
85
151
  type IssueCode = (typeof ISSUE_CODES)[keyof typeof ISSUE_CODES];
@@ -605,9 +671,13 @@ declare function toFhirQuantity(value: NM, units: CWE, ctx?: TransformContext):
605
671
  * `toFhir`, the message-level entry point: assemble a parsed HL7 v2 message into a FHIR R4
606
672
  * **message Bundle** (a `MessageHeader` first, then the focal resources), grounded on the IG message
607
673
  * and segment maps. The **ADT** family becomes **Patient + Encounter** (+ `RelatedPerson`
608
- * from NK1); the **ORU^R01** results graph becomes `DiagnosticReport` + `Observation`; the
609
- * order-entry graph gives **ORM_O01 / OML_O21** ORC/OBR → `ServiceRequest` and **RXO** (+ RXR) →
610
- * `MedicationRequest`; and the thin IG singles give **VXU_V04** RXA/RXR/ORC → `Immunization`,
674
+ * from NK1, + one `AllergyIntolerance` per AL1, + one `Condition` per DG1, one `Procedure` per PR1
675
+ * and one `Coverage` per IN1); the **ORU^R01** results graph becomes
676
+ * `DiagnosticReport` + `Observation` (+ one `Specimen` per SPM of the report's SPECIMEN group,
677
+ * referenced from the report that scopes it); the
678
+ * order-entry graph gives **ORM_O01 / OML_O21** ORC/OBR → `ServiceRequest` and **RXO** (+ RXR, + the
679
+ * order's **TQ1** schedule) → `MedicationRequest`; and the thin IG singles give **VXU_V04**
680
+ * RXA/RXR/ORC → `Immunization`,
611
681
  * **SIU_S12** SCH/AIS/PID → `Appointment`, and **MDM_T02** TXA/OBX → `DocumentReference`.
612
682
  *
613
683
  * The fail-safe rule holds at the message level. Two message-level fail-safes join the datatype ones:
@@ -624,6 +694,12 @@ declare function toFhirQuantity(value: NM, units: CWE, ctx?: TransformContext):
624
694
  * {@link ISSUE_CODES.TRANSFORM_RESOURCE_INVALID} rather than shipped as silently-invalid FHIR. When
625
695
  * the Patient is withheld, the Encounter's `subject` and any RelatedPerson are dropped rather than
626
696
  * left dangling: references always resolve within the bundle.
697
+ * - **Segment-level completeness.** Every segment occurrence that contributed nothing to a resource
698
+ * the returned bundle contains raises one value-free issue naming it
699
+ * ({@link SegmentReachLedger}), so silence over an omitted segment can no longer read as
700
+ * completeness. The diagnostic OBSERVES this assembly and never steers it: the occurrences are
701
+ * marked where a resource clears the gate above, the issues are appended after every issue the
702
+ * assembly raised, and no resource, value or existing issue changes because of it.
627
703
  *
628
704
  * @packageDocumentation
629
705
  */
@@ -765,6 +841,41 @@ declare const ENCOUNTER_CLASS_V3_MAP: Readonly<Record<string, {
765
841
  * discharge sets `status = finished` per the PV1→Encounter map.
766
842
  */
767
843
  declare const ENCOUNTER_STATUS_MAP: Readonly<Record<string, string>>;
844
+ /**
845
+ * The same Encounter carrying one `diagnosis` entry per Condition the bundle holds, per the ADT_A01
846
+ * message map's `Encounter[1].diagnosis.reference = Condition[1].id` row. Each entry's `condition`
847
+ * points at that Condition's `fullUrl`, so the link resolves inside the bundle.
848
+ *
849
+ * Applied after the diagnoses are built, because the Encounter joins the bundle before them and the
850
+ * produced nodes are immutable: this returns a new node rather than mutating the emitted one.
851
+ *
852
+ * @param encounter - The Encounter node already in the bundle.
853
+ * @param conditionFullUrls - The fullUrls of the Conditions emitted for the same message, in order.
854
+ * @example
855
+ * ```ts
856
+ * // withEncounterDiagnosis(encounter, ["urn:uuid:cond-1"]); // adds one diagnosis entry
857
+ * ```
858
+ */
859
+ declare function withEncounterDiagnosis(encounter: FhirComplex, conditionFullUrls: readonly string[]): FhirComplex;
860
+ /**
861
+ * The Encounter that should replace the emitted one once the message's diagnoses exist: the same
862
+ * resource carrying the back-references, put through the conservative-emit gate first. When the
863
+ * gate refuses the linked draft the ORIGINAL Encounter is returned unchanged and the link is
864
+ * declared {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED}, so a detail never costs the visit.
865
+ *
866
+ * The gate is a parameter rather than a call into the assembler, so what "the gate refuses this"
867
+ * means stays in one place and the refusal branch is reachable from a test without a hand-built
868
+ * invalid resource: the same shape the allergy emit path uses.
869
+ *
870
+ * @param encounter - The Encounter node already in the bundle.
871
+ * @param conditionFullUrls - The fullUrls of the Conditions emitted for the same message, in order.
872
+ * @param gate - The conservative-emit predicate: `true` when the linked Encounter may replace it.
873
+ * @example
874
+ * ```ts
875
+ * // emitEncounterDiagnosis(encounter, ["urn:uuid:cond-1"], () => true).value; // the linked one
876
+ * ```
877
+ */
878
+ declare function emitEncounterDiagnosis(encounter: FhirComplex, conditionFullUrls: readonly string[], gate: (resource: FhirComplex) => boolean): ConvertResult<FhirComplex>;
768
879
 
769
880
  /**
770
881
  * OBX → FHIR `Observation`: the highest-clinical-stakes segment map,
@@ -783,13 +894,40 @@ declare const ENCOUNTER_STATUS_MAP: Readonly<Record<string, string>>;
783
894
  * | OBX-8 Abnormal Flags | `Observation.interpretation` | {@link HL70078_INTERPRETATION_CODES} |
784
895
  * | OBX-11 Result Status | `Observation.status` | {@link OBSERVATION_STATUS_MAP} (HL70085) |
785
896
  * | OBX-14 Date/Time of Observation | `Observation.effectiveDateTime` | {@link toFhirDateTime} |
897
+ * | (OBSERVATION-group NTE) | `Observation.note` | {@link buildAnnotations} (`NTE[ServiceRequest]`) |
898
+ *
899
+ * **What OBX-2 selects, row by row** (`ConceptMap-segment-obx-to-observation.html`, the OBX-5 rows):
900
+ *
901
+ * | OBX-2 | FHIR target | datatype map |
902
+ * |---|---|---|
903
+ * | `NM` | `valueQuantity` | `NM[Quantity]` |
904
+ * | `SN` | `valueQuantity` (with a comparator) / `valueRange` / `valueRatio` | the row's own conditions |
905
+ * | `CWE`/`CE`/`CF`/`CNE`/`IS` | `valueCodeableConcept` | `CWE[CodeableConcept]` |
906
+ * | `DT`/`DTM`/`TS` | `valueDateTime` | `DTM[DateTime]` |
907
+ * | `ST`/`TX`/`FT` | `valueString` | (direct) |
908
+ * | `DR` | `valuePeriod` | `DR[Period]` |
909
+ * | `NR` | `valueRange` | `NR[Range]` |
910
+ * | `TM` | `valueTime` | (direct, an R4 `time`) |
911
+ * | `NA` | `valueSampledData` | `NA[SampledData]` |
912
+ * | `ED` **and** OBX-5.4 = `Base64` | the {@link OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL} extension | `ED[Attachment]` |
913
+ * | `RP`, `ID`, anything else | `valueString` + flagged | (no settled target) |
786
914
  *
787
915
  * **The "never a confident wrong result" fail-safes:**
788
- * - **OBX-2 drives `value[x]`.** `NM`→`valueQuantity`, `CWE`/`CE`/`CF`/`CNE`/`IS`→`valueCodeableConcept`,
789
- * `SN`→structured (`valueQuantity` with a comparator / `valueRange` / `valueRatio`), `ST`/`TX`/`FT`→
790
- * `valueString`. A value type with no first-class target here (`NA`, `ED`, `DR`, `TM`, `NR`, unknown)
791
- * preserves the raw value as `valueString` and flags {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED}
792
- * (the richer FHIR type is deferred), never a fabricated `Quantity`.
916
+ * - **OBX-2 drives `value[x]`**, per the table above, and every row of it degrades to the raw OBX-5
917
+ * text as `valueString` + {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED} rather than emit a value
918
+ * the map cannot ground: a `DR` neither of whose bounds is a dateTime this library will emit, an
919
+ * `NR` neither of whose bounds is a faithful `decimal`, a `TM` carrying a UTC offset (an R4 `time`
920
+ * admits none, and discarding one would move the instant), an `NA` carrying a magnitude `decimal`
921
+ * cannot hold unaltered, an `ED` whose OBX-5.4 is not `Base64` (both ED rows are conditioned on
922
+ * it), and `RP`, whose extension target the guide's own comment marks unsettled.
923
+ * - **The published NA row spells its attribute `Observation.valueSampedData`.** That is a typo in
924
+ * the guide; the R4 element is `valueSampledData` and that is what is emitted.
925
+ * - **A SampledData asserts no origin and no period.** R4 makes both `1..1` and the NA map has no
926
+ * source row for either, so they ship value-absent with a `data-absent-reason` and
927
+ * {@link ISSUE_CODES.TRANSFORM_REQUIRED_ELEMENT_UNKNOWN}: an `origin` of 0 or a `period` of 1
928
+ * would be a magnitude this message never sent, on a waveform.
929
+ * - **An ED payload is carried, never read.** OBX-5.5 reaches `Attachment.data` byte-for-byte: no
930
+ * decode, no re-encode, no normalization, no validation, no truncation.
793
931
  * - **A corrected/cancelled result never emits as `final`.** OBX-11 `C`→`corrected`, `X`→`cancelled`,
794
932
  * `D`/`W`→`entered-in-error` (HL70085). A status code with **no** HL70085 target leaves
795
933
  * `Observation.status` absent (flagged {@link ISSUE_CODES.TRANSFORM_CODE_UNMAPPED}); the required-`status`
@@ -805,6 +943,16 @@ declare const ENCOUNTER_STATUS_MAP: Readonly<Record<string, string>>;
805
943
  * @packageDocumentation
806
944
  */
807
945
 
946
+ /**
947
+ * The v3 ObservationInterpretation canonical system (FHIR `Observation.interpretation` binding).
948
+ *
949
+ * @example
950
+ * ```ts
951
+ * import { V3_OBSERVATION_INTERPRETATION_SYSTEM } from "@cosyte/transform";
952
+ * V3_OBSERVATION_INTERPRETATION_SYSTEM.endsWith("v3-ObservationInterpretation"); // => true
953
+ * ```
954
+ */
955
+ declare const V3_OBSERVATION_INTERPRETATION_SYSTEM = "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation";
808
956
  /**
809
957
  * HL7 v2 Table 0078 (Abnormal Flags) → FHIR v3 ObservationInterpretation (`Observation.interpretation`),
810
958
  * per the IG **Table HL70078 to v3 ObservationInterpretation** ConceptMap. Every mapped row is
@@ -823,6 +971,54 @@ declare const HL70078_INTERPRETATION_CODES: ReadonlySet<string>;
823
971
  * **`C`→`corrected` and `X`→`cancelled` guarantee a corrected/cancelled result never emits as `final`.**
824
972
  */
825
973
  declare const OBSERVATION_STATUS_MAP: Readonly<Record<string, string>>;
974
+ /**
975
+ * The extension URL the OBX map **fixes** on the `IF OBX-2 EQUALS "ED" AND IF OBX-5.4 EQUALS
976
+ * "Base64"` rows, transcribed from the map's own `Observation.extension.url` assignment. R4 has no
977
+ * `Observation.valueAttachment`, so the guide carries the R5 element as this named extension.
978
+ *
979
+ * @example
980
+ * ```ts
981
+ * import { OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL } from "@cosyte/transform";
982
+ * OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL.endsWith("extension-Observation.valueAttachment"); // true
983
+ * ```
984
+ */
985
+ declare const OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL = "https://hl7.org/fhir/5.0/StructureDefinition/extension-Observation.valueAttachment";
986
+ /**
987
+ * The OBX-5.4 encoding the OBX map conditions **both** of its `ED` rows on. Any other encoding
988
+ * (`A`, `Hex`, `Ascii`, a local token) leaves those rows unapplied, so no attachment is built.
989
+ *
990
+ * @example
991
+ * ```ts
992
+ * import { ED_BASE64_ENCODING } from "@cosyte/transform";
993
+ * ED_BASE64_ENCODING; // "Base64"
994
+ * ```
995
+ */
996
+ declare const ED_BASE64_ENCODING = "Base64";
997
+ /**
998
+ * The `SampledData.data` token the Implementation Considerations chapter's own worked example
999
+ * directs for a data point a repetition did not carry (`"set .dimensions to 4 and use E for the
1000
+ * data points not present"`). It is the FHIR-defined "error" token, and it is written **only** for
1001
+ * an absent position, never for a value that arrived and could not be converted.
1002
+ *
1003
+ * @example
1004
+ * ```ts
1005
+ * import { SAMPLED_DATA_ABSENT_POINT } from "@cosyte/transform";
1006
+ * SAMPLED_DATA_ABSENT_POINT; // "E"
1007
+ * ```
1008
+ */
1009
+ declare const SAMPLED_DATA_ABSENT_POINT = "E";
1010
+ /**
1011
+ * The `data-absent-reason` code carried by `SampledData.origin` and `SampledData.period`, the two
1012
+ * R4-required elements of that datatype that **no row of the IG's NA map, and no line of the
1013
+ * Implementation Considerations chapter it points at, supplies a source for**.
1014
+ *
1015
+ * @example
1016
+ * ```ts
1017
+ * import { SAMPLED_DATA_UNGROUNDED } from "@cosyte/transform";
1018
+ * SAMPLED_DATA_UNGROUNDED; // "unknown"
1019
+ * ```
1020
+ */
1021
+ declare const SAMPLED_DATA_UNGROUNDED = "unknown";
826
1022
 
827
1023
  /**
828
1024
  * OBR → FHIR `DiagnosticReport`, the ORU results-report anchor, grounded firsthand
@@ -841,6 +1037,7 @@ declare const OBSERVATION_STATUS_MAP: Readonly<Record<string, string>>;
841
1037
  * | OBR-22 Results Rpt/Status Chng Date/Time | `DiagnosticReport.issued` (an `instant`) | {@link toFhirDateTime} |
842
1038
  * | OBR-24 Diagnostic Serv Sect ID | `DiagnosticReport.category` | v2-0074 coding |
843
1039
  * | OBR-25 Result Status | `DiagnosticReport.status` | {@link DIAGNOSTIC_REPORT_STATUS_MAP} (HL70123) |
1040
+ * | (SPM children) | `DiagnosticReport.specimen` | reference wiring from the assembler |
844
1041
  * | (OBX children) | `DiagnosticReport.result` | reference wiring from the assembler |
845
1042
  *
846
1043
  * **Fail-safes.** `DiagnosticReport.status` is required (R4 1..1) and the IG itself notes an unvalued
@@ -849,8 +1046,11 @@ declare const OBSERVATION_STATUS_MAP: Readonly<Record<string, string>>;
849
1046
  * required-`status` emit gate withholds the report rather than emitting an invalid one or guessing
850
1047
  * `final`. `OBR-25 = C`→`corrected` / `X`→`cancelled` are modelled exactly. OBR-22 becomes `issued`
851
1048
  * only when it is a fully-zoned instant; a date-only/naked OBR-22 is dropped + flagged (never a
852
- * fabricated UTC), mirroring `Bundle.timestamp`. Deferred and flagged elsewhere, not silently mapped:
853
- * OBR-32/34/35 performers (need PractitionerRole resources), specimen, and `basedOn` ServiceRequest.
1049
+ * fabricated UTC), mirroring `Bundle.timestamp`. `.specimen` carries only the Specimens the
1050
+ * assembler has already emitted into this bundle, so the reference never resolves to nothing.
1051
+ * Deferred and flagged elsewhere, not silently mapped: OBR-32/34/35 performers (need
1052
+ * PractitionerRole resources), the ORU map's own OBR-to-Specimen row (4.2.2, distinct from the SPM
1053
+ * one), and `basedOn` ServiceRequest.
854
1054
  *
855
1055
  * @packageDocumentation
856
1056
  */
@@ -867,6 +1067,125 @@ declare const OBSERVATION_STATUS_MAP: Readonly<Record<string, string>>;
867
1067
  */
868
1068
  declare const DIAGNOSTIC_REPORT_STATUS_MAP: Readonly<Record<string, string>>;
869
1069
 
1070
+ /**
1071
+ * SPM → FHIR `Specimen`: the sample a result was taken from, carried into the bundle instead of
1072
+ * lost between the lab feed and the FHIR record. Grounded firsthand on the IG **Segment SPM to
1073
+ * Specimen** ConceptMap and the **ORU_R01 to Bundle** message map (`hl7.fhir.uv.v2mappings`, STU1;
1074
+ * `ConceptMap-segment-spm-to-specimen.html`, `ConceptMap-message-oru-r01-to-bundle.html`), whose
1075
+ * row 4.2.7.1 creates one Specimen per SPM of an ORDER_OBSERVATION's SPECIMEN group and wires
1076
+ * `DiagnosticReport[1].specimen.reference` to it.
1077
+ *
1078
+ * | SPM field | FHIR target | via |
1079
+ * |---|---|---|
1080
+ * | SPM-2 Specimen ID (EIP) | `identifier` (placer, then filler) | EI.1 → `Identifier.value` |
1081
+ * | SPM-4 Specimen Type (CWE) | `Specimen.type` | {@link toFhirCodeableConcept} |
1082
+ * | SPM-6 Specimen Additives (CWE) | `container.additiveCodeableConcept` | {@link toFhirCodeableConcept} |
1083
+ * | SPM-7 Collection Method (CWE) | `collection.method` | {@link toFhirCodeableConcept} |
1084
+ * | SPM-8 Source Site (CWE) | `collection.bodySite` | {@link toFhirCodeableConcept} |
1085
+ * | SPM-14 Specimen Description (ST) | `note` (`Annotation.text`) | one annotation per repetition |
1086
+ * | SPM-17 Collection Date/Time (DR) | `collection.collectedPeriod` / `collectedDateTime` | `IF SPM-17.2 VALUED` |
1087
+ * | SPM-18 Received Date/Time (DTM) | `Specimen.receivedTime` | {@link toFhirDateTime} |
1088
+ * | SPM-24 Specimen Condition (CWE) | `Specimen.condition` | {@link toFhirCodeableConcept} |
1089
+ * | SPM-27 Container Type (CWE) | `container.type` | {@link toFhirCodeableConcept} |
1090
+ * | SPM-30 Accession ID (CX) | `Specimen.accessionIdentifier` | {@link toFhirIdentifier} |
1091
+ * | SPM-31 Other Specimen ID (CX) | `identifier` | {@link toFhirIdentifier} |
1092
+ * | SPM-32 Shipment ID (EI) | `identifier` (type `SHIP`, v2-0203) | the row's own fixed assignment |
1093
+ * | (message-map wiring) | referenced from `DiagnosticReport.specimen` | the assembler |
1094
+ *
1095
+ * **Fail-safes (never a confident wrong specimen).**
1096
+ * - **The status is never asserted.** `SPM-20` is the only row that targets `Specimen.status`, and
1097
+ * it reaches it through a **Table 0136 to specimen-status** value ConceptMap this library does not
1098
+ * carry. R4 binds that element `required`, and every member of the binding is a positive claim
1099
+ * about a sample a clinician may act on, so the element stays absent and the row is declared
1100
+ * {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED}. Unlike `Coverage.status`, `Specimen.status` is
1101
+ * `0..1`, so absence is the spec-clean shape and no `data-absent-reason` is needed to hold a slot.
1102
+ * - **A specimen never points at a specimen that is not there.** `SPM-3 Specimen Parent IDs` targets
1103
+ * `Specimen.parent`, a reference to another Specimen resource; none is built for a parent, so the
1104
+ * row is declared rather than emitted as a link that resolves to nothing.
1105
+ * - **A collection amount is not rebuilt from parts.** `SPM-12` reaches `collection.quantity`
1106
+ * through the `CQ[Quantity]` datatype map, which this library does not carry; assembling one from
1107
+ * CQ.1 and CQ.2 by hand would be a unit gate written twice, so the row is declared instead.
1108
+ * - **An unresolvable coding system costs the system URI, never the code**, and every date/time goes
1109
+ * through the one timezone-safe converter: the datatype converters own both rules and this module
1110
+ * only routes fields to them.
1111
+ *
1112
+ * @packageDocumentation
1113
+ */
1114
+
1115
+ /**
1116
+ * The Table 0203 identifier-type code the SPM-32 row **assigns** to the shipment identifier
1117
+ * (`Specimen.identifier[3].type.coding.code = "SHIP"`, with the v2-0203 system beside it).
1118
+ *
1119
+ * @example
1120
+ * ```ts
1121
+ * import { SPM_SHIPMENT_IDENTIFIER_TYPE } from "@cosyte/transform";
1122
+ * SPM_SHIPMENT_IDENTIFIER_TYPE; // "SHIP"
1123
+ * ```
1124
+ */
1125
+ declare const SPM_SHIPMENT_IDENTIFIER_TYPE = "SHIP";
1126
+ /**
1127
+ * Build a FHIR `Specimen` resource node from one parsed HL7 v2 SPM segment. Returns
1128
+ * `{ value: undefined }` when the segment grounds no element of the map at all, because an empty
1129
+ * `Specimen` in a bundle is a claim that a sample was described when nothing about it was sent.
1130
+ *
1131
+ * @param spm - The SPM `@cosyte/hl7` `Segment`.
1132
+ * @param subjectFullUrl - The `urn:uuid:` fullUrl of the bundle's Patient → `Specimen.subject`.
1133
+ * @param ctx - The transform context (naming-system registry + timezone policy).
1134
+ * @example
1135
+ * ```ts
1136
+ * import { parseHL7 } from "@cosyte/hl7";
1137
+ * // const spm = parseHL7(raw).segments("SPM")[0];
1138
+ * // const { value } = buildSpecimen(spm!, "urn:uuid:pat", {});
1139
+ * ```
1140
+ */
1141
+ declare function buildSpecimen(spm: Segment, subjectFullUrl: string | undefined, ctx: TransformContext): ConvertResult<FhirComplex>;
1142
+
1143
+ /**
1144
+ * NTE → a FHIR `Annotation`, grounded firsthand on the IG **Segment NTE to ServiceRequest**
1145
+ * ConceptMap (`hl7.fhir.uv.v2mappings`, STU1; `ConceptMap-segment-nte-to-servicerequest.html`),
1146
+ * which is the map the ORU_R01 message map files its `Observation.note` row against.
1147
+ *
1148
+ * | NTE field | FHIR target | via |
1149
+ * |---|---|---|
1150
+ * | NTE-3 Comment (FT, `0..-1`) | `Annotation.text` (`markdown`) | one annotation per repetition |
1151
+ * | NTE-6 Entered Date/Time (DTM) | `Annotation.time` | {@link toFhirDateTime} |
1152
+ *
1153
+ * `NTE-1`, `NTE-2`, `NTE-7`, `NTE-8` and `NTE-9` carry no target in the map at all. Two rows do
1154
+ * carry one and are deliberately **declared rather than built**: `NTE-5 Entered By` targets
1155
+ * `note.authorReference(Practitioner)`, and this library builds no Practitioner, so an author would
1156
+ * be a reference resolving to nothing; and `NTE-4 Comment Type` targets a **proposed** extension
1157
+ * the guide has not named yet (its own cell reads `extension??-noteType`), so there is no canonical
1158
+ * URL to write and one is never invented.
1159
+ *
1160
+ * **A note is text the sender wrote, so it is read as text.** `NTE-3` is `FT`: a v2 primitive with
1161
+ * no component structure, where a raw `^` or `&` is content. Each repetition is rendered through
1162
+ * the parser's own display projection, which resolves the v2 escape sequences (`\T\` to `&`,
1163
+ * `\.br\` to a line break) and preserves verbatim any sequence it cannot render. The repetitions
1164
+ * are **not** joined: a separator between them would be a character the wire never carried, and
1165
+ * `Observation.note` is `0..*` precisely so each can stand on its own.
1166
+ *
1167
+ * @packageDocumentation
1168
+ */
1169
+
1170
+ /**
1171
+ * Every FHIR `Annotation` a run of `NTE` segments contributes, in message order: one per valued
1172
+ * `NTE-3` repetition, each carrying that repetition's rendered text and the segment's `NTE-6` time.
1173
+ *
1174
+ * Returns `undefined` when the segments carry no comment text at all, so a caller adds no empty
1175
+ * `note` element. The diagnostics raised are value-free: no byte of a note ever reaches one.
1176
+ *
1177
+ * @param notes - The `NTE` segments to read, in message order.
1178
+ * @param ctx - The transform context (naming-system registry + timezone policy).
1179
+ * @param issues - The issue sink for the deferred-row and timestamp diagnostics.
1180
+ * @example
1181
+ * ```ts
1182
+ * import { parseHL7 } from "@cosyte/hl7";
1183
+ * // const nte = parseHL7(raw).segments("NTE");
1184
+ * // buildAnnotations(nte, {}, []); // a FHIR list of Annotation nodes, or undefined
1185
+ * ```
1186
+ */
1187
+ declare function buildAnnotations(notes: readonly Segment[], ctx: TransformContext, issues: TransformIssue[]): FhirNode | undefined;
1188
+
870
1189
  /**
871
1190
  * ORC + OBR → FHIR `ServiceRequest`: the order-entry request, grounded firsthand
872
1191
  * on the IG **Segment ORC to ServiceRequest** and **Segment OBR to ServiceRequest** ConceptMaps and
@@ -884,8 +1203,10 @@ declare const DIAGNOSTIC_REPORT_STATUS_MAP: Readonly<Record<string, string>>;
884
1203
  * | ORC-9 Date/Time of Order Event | `authoredOn` | {@link toFhirDateTime}, *IF ORC-1 = `NW`* |
885
1204
  * | OBR-4 Universal Service Identifier (CWE) | `ServiceRequest.code` | {@link toFhirCodeableConcept} |
886
1205
  * | OBR-5 Priority (v2-0485) | `ServiceRequest.priority` | {@link SERVICE_REQUEST_PRIORITY_MAP} (HL70485) |
887
- * | OBR-6 Requested Date/Time | `occurrenceDateTime` | {@link toFhirDateTime} |
1206
+ * | OBR-6 Requested Date/Time | `occurrenceDateTime` | {@link toFhirDateTime}, *IF no TQ1 timing* |
888
1207
  * | OBR-31 Reason for Study (CWE) | `reasonCode` | {@link toFhirCodeableConcept} |
1208
+ * | TQ1-3 Repeat Pattern (RPT) | `occurrenceTiming` | {@link readTq1} (RPT[Timing], all-or-nothing) |
1209
+ * | TQ1-7 / TQ1-8 Start / End date-time | `occurrenceTiming.repeat.boundsPeriod.start`/`.end` | {@link readTq1} |
889
1210
  * | (order message context) | `intent` = `order` | see below |
890
1211
  * | (message-map wiring) | `subject` / `encounter` | the bundle's Patient / Encounter |
891
1212
  *
@@ -906,6 +1227,13 @@ declare const DIAGNOSTIC_REPORT_STATUS_MAP: Readonly<Record<string, string>>;
906
1227
  * OBR-11-conditioned intent refinement is deferred.
907
1228
  * - **`subject` (required 1..1).** Wired to the bundle's Patient; a request with no resolvable Patient
908
1229
  * is withheld rather than emitted with a dangling/absent subject.
1230
+ * - **`occurrence[x]` is a choice, so exactly one member is ever emitted.** OBR-6 grounds an
1231
+ * `occurrenceDateTime` and a TQ1 grounds an `occurrenceTiming`; a group that would yield both
1232
+ * emits the **timing** (the richer statement, and the one the sender wrote a whole segment for)
1233
+ * and flags the dropped OBR-6. Emitting both would be structurally invalid FHIR, and silently
1234
+ * preferring the single instant would throw away the schedule. The timing itself is
1235
+ * all-or-nothing: see {@link readTq1}, whose every refusal leaves `occurrenceTiming` absent and
1236
+ * therefore hands the choice back to OBR-6 with no issue raised about it.
909
1237
  *
910
1238
  * - **`priority` (0..1), value-translated.** OBR-5 → `ServiceRequest.priority` via the IG
911
1239
  * **Table HL70485 to Request Priority** ConceptMap ({@link SERVICE_REQUEST_PRIORITY_MAP}): only
@@ -945,6 +1273,290 @@ declare const REQUEST_STATUS_MAP: Readonly<Record<string, string>>;
945
1273
  */
946
1274
  declare const SERVICE_REQUEST_PRIORITY_MAP: Readonly<Record<string, string>>;
947
1275
 
1276
+ /**
1277
+ * The message-level completeness diagnostic: which segment occurrences a message carried, which of
1278
+ * them contributed to a resource the returned bundle actually contains, and one value-free issue for
1279
+ * each one that did not.
1280
+ *
1281
+ * The library already refuses to produce a confident wrong FHIR value at the datatype and resource
1282
+ * levels. This is the same rule one level up. A message can carry an `IAM`, a `DG1` or an `IN1` that
1283
+ * nothing here reads, and until now the consumer got a bundle with nothing in it about the allergy
1284
+ * and an issues list with nothing in it about the omission: silence read as completeness, which is a
1285
+ * claim this library cannot make. After this, a consumer reads the issues list and learns which
1286
+ * segments did not reach the bundle, and whether each one is a **library gap**
1287
+ * ({@link ISSUE_CODES.TRANSFORM_SEGMENT_NOT_EMITTED}, the IG publishes a map and this library has
1288
+ * not built it) or a **standard gap** ({@link ISSUE_CODES.TRANSFORM_SEGMENT_NO_IG_MAP}, the IG
1289
+ * publishes no map, or the name could not be classified at all).
1290
+ *
1291
+ * Four rules carry the safety of this, and each one is enforced here rather than assumed upstream:
1292
+ *
1293
+ * - **Contribution, never inspection.** An occurrence "reached" a resource only if the assembly took
1294
+ * at least one of its values, or its identity, into a resource that is present in the returned
1295
+ * bundle. An occurrence that was counted, walked past, or already named by another issue did not
1296
+ * reach anything: the `RXE` and the orphan `OBX` this library counts and refuses are exactly the
1297
+ * omissions a consumer most needs told, so a "the walker touched it" reading would silence the
1298
+ * two cases the diagnostic exists for.
1299
+ * - **A name is rendered only if it passes the segment-identifier shape**
1300
+ * ({@link SEGMENT_IDENTIFIER_SHAPE}), applied by this library to the value the parser published,
1301
+ * as a positive test the value must pass. Not by excluding known markers, not by importing a
1302
+ * constant from the parser package, not by anything that depends on which parser version a
1303
+ * consumer resolved: this library declares a peer range that admits any of them, so a rule keyed
1304
+ * on a marker literal fails OPEN the moment that literal changes, promoting an unvouched value
1305
+ * into a rendering. A shape test fails CLOSED: whatever it does not recognize is located
1306
+ * positionally, and no byte of it is reproduced.
1307
+ * - **A position that carries no segment is not an occurrence.** The parser materializes an empty
1308
+ * position for a blank line so that ordinals stay stable. It carries no name AND no field content,
1309
+ * nothing was sent there, and reporting it would be a false claim of clinical omission at a
1310
+ * position the sender left empty. It is excluded wherever it sits, and it still counts toward the
1311
+ * `[#n]` ordinal of later occurrences so those keep matching the wire. A line that kept its field
1312
+ * separator still carries content and IS reported: the exclusion is for the absence of a segment,
1313
+ * never for the absence of a name.
1314
+ * - **One issue per occurrence, numbered among all occurrences of its name.** Never collapsed,
1315
+ * capped or deduplicated, and `[k]` is the occurrence's position among all occurrences of that
1316
+ * name, never among the reported ones: a message with two `NK1` of which only the second is
1317
+ * reported yields `NK1[2]`.
1318
+ *
1319
+ * @packageDocumentation
1320
+ */
1321
+
1322
+ /**
1323
+ * The HL7 v2 Chapter 2 segment-identifier shape: three characters, a leading letter, applied to the
1324
+ * name value ITSELF as a positive membership test that must pass before any name is rendered.
1325
+ *
1326
+ * Everything else is a malformed name without exception: the empty string, a withheld marker, a raw
1327
+ * pre-delimiter token, a bare numeric like `202`, a four-character `AL11`. A malformed occurrence has
1328
+ * no name in this library's vocabulary and is identified by position instead.
1329
+ *
1330
+ * @example
1331
+ * ```ts
1332
+ * import { SEGMENT_IDENTIFIER_SHAPE } from "@cosyte/transform";
1333
+ * SEGMENT_IDENTIFIER_SHAPE.test("ZAL"); // true
1334
+ * SEGMENT_IDENTIFIER_SHAPE.test("202"); // false
1335
+ * ```
1336
+ */
1337
+ declare const SEGMENT_IDENTIFIER_SHAPE: RegExp;
1338
+ /**
1339
+ * Whether a segment name may be rendered: the shape test of {@link SEGMENT_IDENTIFIER_SHAPE} applied
1340
+ * to the value itself.
1341
+ *
1342
+ * Deliberately NOT an exclusion of known-bad literals. An exclusion test admits any value it has not
1343
+ * heard of, which is the wrong direction for a rule whose whole job is to keep message bytes out of
1344
+ * a diagnostic, and it would silently couple this library to one release of the parser package.
1345
+ *
1346
+ * @param name - The value the parser published as the occurrence's segment type.
1347
+ * @example
1348
+ * ```ts
1349
+ * import { isWellFormedSegmentName } from "@cosyte/transform";
1350
+ * isWellFormedSegmentName("ZAL"); // true
1351
+ * isWellFormedSegmentName("AL11"); // false
1352
+ * ```
1353
+ */
1354
+ declare function isWellFormedSegmentName(name: string): boolean;
1355
+ /**
1356
+ * One segment occurrence of a parsed message: a segment as it appears in the message, in message
1357
+ * order, with everything needed to locate it in a value-free way and nothing else.
1358
+ */
1359
+ interface SegmentOccurrence {
1360
+ /** The parsed segment this occurrence wraps. */
1361
+ readonly segment: Segment;
1362
+ /** 1-based position among **all** parsed positions, empty ones included, so it matches the wire. */
1363
+ readonly ordinal: number;
1364
+ /** The renderable segment name, present only when it passed the shape test. */
1365
+ readonly name: string | undefined;
1366
+ /** 1-based position among the occurrences of {@link SegmentOccurrence.name}, when there is one. */
1367
+ readonly nameIndex: number | undefined;
1368
+ }
1369
+ /**
1370
+ * Every segment occurrence of a parsed message, in message order.
1371
+ *
1372
+ * A position that carries neither a name nor any field content is the parser's ordinal placeholder
1373
+ * for a blank line: it is not a segment occurrence, it is left out, and it still advances the
1374
+ * ordinal of everything after it. A position that carries field content is an occurrence even when
1375
+ * its name is empty.
1376
+ *
1377
+ * @param msg - The parsed message.
1378
+ * @example
1379
+ * ```ts
1380
+ * import { parseHL7 } from "@cosyte/hl7";
1381
+ * import { enumerateSegmentOccurrences } from "@cosyte/transform";
1382
+ * // enumerateSegmentOccurrences(parseHL7(raw))[0]?.name; // "MSH"
1383
+ * ```
1384
+ */
1385
+ declare function enumerateSegmentOccurrences(msg: Hl7Message): readonly SegmentOccurrence[];
1386
+ /**
1387
+ * The v2 location of an occurrence: `NAME[k]` for a name that passed the shape test, `[#n]` for one
1388
+ * that did not. Those are the only two shapes, and neither carries a field or component index.
1389
+ *
1390
+ * @param occurrence - The occurrence to locate.
1391
+ * @example
1392
+ * ```ts
1393
+ * import { segmentOccurrenceLocation } from "@cosyte/transform";
1394
+ * // segmentOccurrenceLocation(occ); // "DG1[2]" or "[#4]"
1395
+ * ```
1396
+ */
1397
+ declare function segmentOccurrenceLocation(occurrence: SegmentOccurrence): string;
1398
+ /**
1399
+ * Tracks, across one message-level assembly, which segment occurrences CONTRIBUTED to a resource the
1400
+ * returned bundle contains, and turns the rest into one value-free issue each.
1401
+ *
1402
+ * The assembly marks an occurrence only where a resource has just cleared the emit gate and joined
1403
+ * the bundle, so "reached" means contributed-and-present by construction: an occurrence that was
1404
+ * read and refused, or that built a resource the gate withheld, is never marked and is therefore
1405
+ * reported.
1406
+ *
1407
+ * @example
1408
+ * ```ts
1409
+ * import { parseHL7 } from "@cosyte/hl7";
1410
+ * import { SegmentReachLedger } from "@cosyte/transform";
1411
+ * // const ledger = new SegmentReachLedger(parseHL7(raw));
1412
+ * // ledger.markFirstOfType("MSH");
1413
+ * // ledger.issues(); // one issue per occurrence that reached nothing
1414
+ * ```
1415
+ */
1416
+ declare class SegmentReachLedger {
1417
+ private readonly occurrences;
1418
+ private readonly reached;
1419
+ /**
1420
+ * @param msg - The parsed message whose occurrences are being tracked.
1421
+ */
1422
+ constructor(msg: Hl7Message);
1423
+ /**
1424
+ * Record that each given segment contributed to a resource now present in the bundle. `undefined`
1425
+ * entries are ignored, so a call site can pass an optional part of a group without branching.
1426
+ */
1427
+ mark(...segments: readonly (Segment | undefined)[]): void;
1428
+ /**
1429
+ * Record that the FIRST occurrence of `type` contributed. The parser's derived views (`patient`,
1430
+ * `visit`, `meta`) are built from the first segment of their type, so this is how a resource built
1431
+ * from a view marks the occurrence it came from.
1432
+ */
1433
+ markFirstOfType(type: string): void;
1434
+ /**
1435
+ * Record that the `index`-th (0-based) occurrence of `type` contributed: the counterpart of
1436
+ * {@link SegmentReachLedger.markFirstOfType} for the repeating views (`nextOfKin()`), whose
1437
+ * entries are in document order.
1438
+ */
1439
+ markNthOfType(type: string, index: number): void;
1440
+ /** The occurrences that contributed to no resource present in the bundle, in message order. */
1441
+ reportable(): readonly SegmentOccurrence[];
1442
+ /**
1443
+ * One value-free issue per reportable occurrence, in message order: the library-gap code when the
1444
+ * IG publishes a segment map for the name, the standard-gap code otherwise, and the standard-gap
1445
+ * code for every name that could not be classified at all.
1446
+ */
1447
+ issues(): readonly TransformIssue[];
1448
+ }
1449
+
1450
+ /**
1451
+ * The set of HL7 v2 segment names the **HL7 Version 2 to FHIR** Implementation Guide publishes a
1452
+ * segment-to-resource map for, transcribed by hand from the guide's own Segment Maps index.
1453
+ *
1454
+ * This is the one fact the completeness diagnostic cannot derive from the message or from this
1455
+ * library's own code: whether a segment the transform did not carry into the Bundle is missing
1456
+ * because this library has not built the mapping yet, or because the standard publishes no mapping
1457
+ * to build. The two answers are different news for a consumer, so the set is recorded here with the
1458
+ * guide version and the retrieval date it was read at, and every entry is auditable against the
1459
+ * published index a reader can open themselves.
1460
+ *
1461
+ * **The set is the guide's, not this library's.** It says nothing about which of these segments the
1462
+ * transform actually reads: `IAM` is on it and is not transformed, `RXE` is off it and is read and
1463
+ * refused. Whether an occurrence is reported at all is decided elsewhere, by whether it reached an
1464
+ * emitted resource; this set only chooses which of the two codes the report carries.
1465
+ *
1466
+ * **Qualified rows collapse onto their segment name.** The index publishes several maps per name and
1467
+ * some of them carry a use qualifier (`MSH[Source]`, `PID[Patient]`, `PV1[EncounterHistory]`,
1468
+ * `OBX[Component]`, `NTE[Comment]`, `PD1[LivingWill]`, `PRT[Location]`, `ROL[GeneralPractitioner]`
1469
+ * and the rest). A qualifier selects a use of the same segment, so every one of them contributes its
1470
+ * base name and nothing else: what a message carries is an `MSH`, never an `MSH[Source]`.
1471
+ *
1472
+ * @packageDocumentation
1473
+ */
1474
+ /**
1475
+ * The published version of the HL7 Version 2 to FHIR Implementation Guide this set was read from.
1476
+ *
1477
+ * @example
1478
+ * ```ts
1479
+ * import { IG_SEGMENT_MAPS_VERSION } from "@cosyte/transform";
1480
+ * IG_SEGMENT_MAPS_VERSION; // "1.0.0"
1481
+ * ```
1482
+ */
1483
+ declare const IG_SEGMENT_MAPS_VERSION = "1.0.0";
1484
+ /**
1485
+ * The publication date of {@link IG_SEGMENT_MAPS_VERSION}, so a later release of the guide can be
1486
+ * told apart from a defect in this library.
1487
+ *
1488
+ * @example
1489
+ * ```ts
1490
+ * import { IG_SEGMENT_MAPS_PUBLISHED } from "@cosyte/transform";
1491
+ * IG_SEGMENT_MAPS_PUBLISHED; // "2025-10-07"
1492
+ * ```
1493
+ */
1494
+ declare const IG_SEGMENT_MAPS_PUBLISHED = "2025-10-07";
1495
+ /**
1496
+ * The date the Segment Maps index was retrieved and transcribed into {@link IG_MAPPED_SEGMENT_NAMES}.
1497
+ *
1498
+ * A classification that surprises a reader is answered by re-reading the index at this date: the set
1499
+ * is a transcription of a published document at a moment, not a live query.
1500
+ *
1501
+ * @example
1502
+ * ```ts
1503
+ * import { IG_SEGMENT_MAPS_RETRIEVED } from "@cosyte/transform";
1504
+ * IG_SEGMENT_MAPS_RETRIEVED; // "2026-08-22"
1505
+ * ```
1506
+ */
1507
+ declare const IG_SEGMENT_MAPS_RETRIEVED = "2026-08-22";
1508
+ /**
1509
+ * The Segment Maps index this set was transcribed from, so a reader can audit any entry.
1510
+ *
1511
+ * @example
1512
+ * ```ts
1513
+ * import { IG_SEGMENT_MAPS_SOURCE } from "@cosyte/transform";
1514
+ * IG_SEGMENT_MAPS_SOURCE.startsWith("https://"); // true
1515
+ * ```
1516
+ */
1517
+ declare const IG_SEGMENT_MAPS_SOURCE = "https://hl7.org/fhir/uv/v2mappings/segment_maps.html";
1518
+ /**
1519
+ * Every v2 segment name the guide publishes at least one segment-to-resource map for, at
1520
+ * {@link IG_SEGMENT_MAPS_VERSION}, as of {@link IG_SEGMENT_MAPS_RETRIEVED}.
1521
+ *
1522
+ * Thirty-three names, transcribed chapter by chapter from {@link IG_SEGMENT_MAPS_SOURCE}: Control
1523
+ * (`MSA`, `MSH`, `NTE`, `SFT`), Patient Administration (`AL1`, `EVN`, `IAM`, `MRG`, `NK1`, `PD1`,
1524
+ * `PID`, `PV1`, `PV2`), Order Entry (`OBR`, `ORC`, `TQ1`), Pharmacy and Vaccination (`RXA`, `RXO`,
1525
+ * `RXR`), Financial Management (`DG1`, `IN1`, `IN3`, `PR1`), Observation Reporting (`OBX`, `PRT`,
1526
+ * `SPM`), Medical Records (`TXA`), Scheduling (`AIG`, `AIL`, `AIP`, `AIS`, `SCH`) and Personnel
1527
+ * Management (`ROL`).
1528
+ *
1529
+ * Two absences a reader is most likely to check, because they look like oversights and are not:
1530
+ * **`RXE` is not on this set** (the guide publishes no map for it, which is why this library counts
1531
+ * an `RXE` and refuses to assemble one), and neither is **`GT1`**.
1532
+ *
1533
+ * @example
1534
+ * ```ts
1535
+ * import { IG_MAPPED_SEGMENT_NAMES } from "@cosyte/transform";
1536
+ * IG_MAPPED_SEGMENT_NAMES.has("IAM"); // true
1537
+ * IG_MAPPED_SEGMENT_NAMES.has("RXE"); // false
1538
+ * ```
1539
+ */
1540
+ declare const IG_MAPPED_SEGMENT_NAMES: ReadonlySet<string>;
1541
+ /**
1542
+ * Whether the guide publishes a segment map for `name`, decided against
1543
+ * {@link IG_MAPPED_SEGMENT_NAMES} and against nothing else.
1544
+ *
1545
+ * The comparison is exact: a name this library could not classify is not in the set, and is reported
1546
+ * as a standard gap for that reason rather than because the guide was consulted and published
1547
+ * nothing. That conflation is deliberate and is documented on the code itself; the alternative would
1548
+ * be re-deriving a name the parser refused to vouch for.
1549
+ *
1550
+ * @param name - A v2 segment name, exactly as the parser published it.
1551
+ * @example
1552
+ * ```ts
1553
+ * import { isIgMappedSegmentName } from "@cosyte/transform";
1554
+ * isIgMappedSegmentName("DG1"); // true
1555
+ * isIgMappedSegmentName("ZAL"); // false
1556
+ * ```
1557
+ */
1558
+ declare function isIgMappedSegmentName(name: string): boolean;
1559
+
948
1560
  /**
949
1561
  * VXU_V04 → FHIR `Immunization`: the thin IG single for immunization administration,
950
1562
  * grounded firsthand on the IG **VXU_V04 message map** and the **RXA/RXR/ORC → Immunization**
@@ -1075,76 +1687,655 @@ declare const IMMUNIZATION_STATUS_MAP: Readonly<Record<string, string>>;
1075
1687
  declare const APPOINTMENT_STATUS_MAP: Readonly<Record<string, string>>;
1076
1688
 
1077
1689
  /**
1078
- * The `$translate`-shaped ConceptMap-application engine + the **license-clean** v2-table → FHIR
1079
- * value maps it applies. This is the layer that value-**translates** a coded v2
1080
- * field, not merely carrying its code structurally, but mapping the source table code to the FHIR
1081
- * target coding the IG's segment-map `mappedVia` ConceptMap prescribes.
1082
- *
1083
- * **Grounded firsthand on the raw published IG ConceptMaps** (`hl7.fhir.uv.v2mappings`, STU1;
1084
- * `ConceptMap-table-*.json`). Each shipped map below cites the exact IG ConceptMap it transcribes and
1085
- * was verified against that resource's JSON (its `group.element[].target[]` rows and its `unmatched`
1086
- * `(unmapped)` group). The engine is **fail-safe by refusal**: a source code the IG map has **no
1087
- * target** for (its `(unmapped)` group) is never coerced to a plausible neighbor. The caller flags it
1088
- * and preserves the raw coding, or withholds the value, but a target is **never fabricated**.
1690
+ * AL1 to FHIR `AllergyIntolerance`: the allergy an ADT states, carried into the bundle instead of
1691
+ * lost between the v2 feed and the FHIR record. Grounded firsthand on the IG **AL1 to
1692
+ * AllergyIntolerance** segment map and the **ADT_A01 to Bundle** message map
1693
+ * (`hl7.fhir.uv.v2mappings`, STU1; `ConceptMap-segment-al1-to-allergyintolerance.html`,
1694
+ * `ConceptMap-message-adt-a01-to-bundle.html`), which wires
1695
+ * `AllergyIntolerance.patient.reference` to the bundle's Patient and creates one resource per AL1.
1089
1696
  *
1090
- * **License posture.** Only maps whose target CodeSystem is **freely redistributable** are
1091
- * shipped here: the HL7 THO v2 tables (`v2-0162`, `v2-0550`, `v2-0277`, `v2-0161`) and HL7 v3
1092
- * (`v3-RouteOfAdministration`) are HL7's own, license-clean. The IG's `*-to-sct` value maps,
1093
- * **RXR-4 method** (`table-hl70165-to-sct`) and **SCH-7 reason** (`table-hl70276-to-sct`), translate
1094
- * **into SNOMED CT**, which is **license-encumbered and is NOT bundled**; those fields stay
1095
- * structurally carried (BYO ConceptMap), never value-translated here (see their message modules).
1096
- *
1097
- * **Additive, never mutating.** A successful translation preserves the raw source coding
1098
- * (its code, display, version, and any `CWE.4/5/6` alternate triplet) and *adds* the derived target
1099
- * coding: recognition never overwrites or discards what the message said; it augments it with the
1100
- * IG-mapped equivalent. And it only fires when the field's primary coding is genuinely from the map's
1101
- * **bound source table** (CWE.3 absent, or naming that table): a field that declares a *foreign*
1102
- * coding system (a local `99…`, SNOMED, …) is carried structurally and flagged, and its code is **never**
1103
- * asserted to be the standard concept just because the string happens to collide with a table code.
1697
+ * | v2 field | FHIR target | via |
1698
+ * |---|---|---|
1699
+ * | AL1 (fixed) | `clinicalStatus` (`active`) | the IG's own assignment for constraint ait-1 |
1700
+ * | AL1-2 Allergen Type Code (CWE) | `category` (0..*) | {@link ALLERGY_CATEGORY_VALUE_MAP} (HL70127) |
1701
+ * | AL1-2 Allergen Type Code (CWE) | `category.extension` alternate-codes | {@link ALLERGY_ORIGINAL_CATEGORY_VALUE_MAP} (v2-0127 identity) |
1702
+ * | AL1-2 Allergen Type Code (CWE) | `type` (0..1) | {@link ALLERGY_TYPE_VALUE_MAP} (HL70127) |
1703
+ * | AL1-3 Allergen Code (CWE) | `code` | {@link toFhirCodeableConcept} (structural, no IG value map) |
1704
+ * | AL1-4 Allergy Severity Code (CWE) | `criticality` (0..1) | {@link ALLERGY_CRITICALITY_VALUE_MAP} (HL70128) |
1705
+ * | AL1-4 Allergy Severity Code (CWE) | `criticality.extension` alternate-codes | {@link ALLERGY_ORIGINAL_CRITICALITY_VALUE_MAP} (v2-0128 identity) |
1706
+ * | AL1-5 Allergy Reaction Code (ST) | `reaction.manifestation.text` | verbatim, one manifestation per repetition |
1707
+ * | AL1-6 Identification Date (DT) | `onsetDateTime` | {@link toFhirDateTime}, legacy versions only |
1708
+ * | (message-map wiring) | `patient` (required 1..1) | the bundle's Patient |
1709
+ *
1710
+ * **Fail-safes (never a confident wrong allergy).**
1711
+ * - **Two maps over one component, resolved independently.** The guide publishes a separate Table
1712
+ * 0127 map for `category` and for `type`, with different unmapped sets, so `MA` yields a type and
1713
+ * **no category**. Neither answer is ever borrowed from the other map or from a neighbouring code:
1714
+ * the element the map has no target for is omitted and flagged
1715
+ * {@link ISSUE_CODES.TRANSFORM_CODE_UNMAPPED}.
1716
+ * - **The original code survives whatever the map does.** The IG makes the `alternate-codes`
1717
+ * extension `1..1` wherever AL1-2 or AL1-4 is valued, so the code the sender wrote is carried in
1718
+ * its own v2 code system even when the translating map had no target for it. An unmapped category
1719
+ * is therefore a `category` element with the extension and no code value, not an absent one.
1720
+ * - **`criticality` is the only severity target.** `AllergyIntolerance.reaction.severity` is a LOCAL
1721
+ * VARIATION in the guide, conditioned on a severity that was not used equivalently to criticality,
1722
+ * which no message states. It is never populated here, so a `MO` or `U` severity leaves criticality
1723
+ * absent and flagged rather than reappearing as a reaction grading the source never asserted.
1724
+ * - **An allergy names what it is to.** AL1-3 is the allergen. An AL1 that grounds no allergen code
1725
+ * and no allergen text asserts an allergy without saying to what, so the resource is withheld and
1726
+ * flagged {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED} rather than emitted naming nothing.
1727
+ * - **AL1-6 is legacy input, never a live element.** The IG's own comment on that row reads
1728
+ * "Withdrawn as of 2.7", so `onsetDateTime` is carried only for a message whose MSH-12 is readable
1729
+ * and earlier than 2.7. A valued AL1-6 on any later, absent or unreadable version is dropped and
1730
+ * flagged, never read as an onset the sender may not have meant.
1731
+ * - **A rejected extension costs the extension, not the allergy.** If the alternate-codes extension
1732
+ * would make the resource fail the conservative-emit gate, the same resource is emitted without it
1733
+ * and the drop is flagged, so a consumer keeps the allergy rather than losing it to a detail.
1734
+ *
1735
+ * Deferred and flagged elsewhere, not silently mapped: `IAM` (the guide's other allergy segment),
1736
+ * AL1-1 (the guide states it does not warrant mapping), and `verificationStatus`, which no AL1
1737
+ * component grounds.
1104
1738
  *
1105
1739
  * @packageDocumentation
1106
1740
  */
1107
1741
 
1108
- /** HL7 v2 Table 0162 (Route of Administration) THO CodeSystem URI. */
1109
- declare const V2_0162_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0162";
1110
- /** HL7 v3 RouteOfAdministration CodeSystem URI (the IG's remap target for the six common routes). */
1111
- declare const V3_ROUTE_OF_ADMINISTRATION_SYSTEM = "http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration";
1112
- /** HL7 v2 Table 0550 (Body Parts) THO CodeSystem URI. */
1113
- declare const V2_0550_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0550";
1114
- /** HL7 v2 Table 0277 (Appointment Type Codes) THO CodeSystem URI. */
1115
- declare const V2_0277_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0277";
1116
- /** HL7 v2 Table 0161 (Allow Substitution) THO CodeSystem URI. */
1117
- declare const V2_0161_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0161";
1118
- /** A translated FHIR target coding: the target CodeSystem URI + code, and the IG's target display. */
1119
- interface CodedTarget {
1120
- /** The FHIR target CodeSystem canonical URI. */
1121
- readonly system: string;
1122
- /** The FHIR target code. */
1123
- readonly code: string;
1124
- /** The IG map's target display, when it carries one (absent for the identity table maps). */
1125
- readonly display?: string;
1126
- }
1127
1742
  /**
1128
- * A license-clean v2-table → FHIR value ConceptMap: it translates a **source table code** to its
1129
- * {@link CodedTarget}, or `undefined` when the code is not in the map's *mapped* group (the IG's
1130
- * `(unmapped)` group). Never fabricates a target.
1743
+ * The code system of the fixed `clinicalStatus` the IG assigns to every AllergyIntolerance built
1744
+ * from an AL1, transcribed from the segment map's own sort-order 0 row.
1745
+ *
1746
+ * @example
1747
+ * ```ts
1748
+ * import { ALLERGY_CLINICAL_STATUS_SYSTEM } from "@cosyte/transform";
1749
+ * ALLERGY_CLINICAL_STATUS_SYSTEM.endsWith("allergyintolerance-clinical"); // true
1750
+ * ```
1131
1751
  */
1132
- interface CodedValueMap {
1133
- /** The IG ConceptMap id this map transcribes (its citation). */
1134
- readonly name: string;
1135
- /** The source table's canonical CodeSystem URI (what the raw v2 code is a member of when mapped). */
1136
- readonly sourceSystem: string;
1137
- /**
1138
- * The CWE.3 (`nameOfCodingSystem`) mnemonics that denote this map's **bound source table**: the
1139
- * HL7 forms (`"HL70162"`, `"0162"`, …). Translation applies **only** when the field's primary
1140
- * coding is from the bound table: CWE.3 absent/empty (a positionally-bound bare code) **or** CWE.3 ∈
1141
- * this set. A CWE that declares a **different** coding system (a local `99…`, or SNOMED) is not a
1142
- * source-table code, so the map is not applied to it: the raw coding is carried structurally + its
1143
- * system flagged, never asserted as the standard concept.
1144
- */
1145
- readonly sourceMnemonics: ReadonlySet<string>;
1146
- /** Translate a source table code to its FHIR target, or `undefined` when the IG map has no target. */
1147
- readonly translate: (code: string) => CodedTarget | undefined;
1752
+ declare const ALLERGY_CLINICAL_STATUS_SYSTEM = "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical";
1753
+ /**
1754
+ * The fixed `clinicalStatus` code the IG assigns. The guide's own note explains why it is fixed
1755
+ * rather than derived: constraint ait-1 requires a clinicalStatus unless the verificationStatus is
1756
+ * `entered-in-error`, and no AL1 component can ground that retraction.
1757
+ *
1758
+ * @example
1759
+ * ```ts
1760
+ * import { ALLERGY_CLINICAL_STATUS_CODE } from "@cosyte/transform";
1761
+ * ALLERGY_CLINICAL_STATUS_CODE; // "active"
1762
+ * ```
1763
+ */
1764
+ declare const ALLERGY_CLINICAL_STATUS_CODE = "active";
1765
+ /**
1766
+ * The canonical URL of the FHIR `alternate-codes` extension, the IG's fixed assignment for the
1767
+ * `category.extension.url` and `criticality.extension.url` rows.
1768
+ *
1769
+ * @example
1770
+ * ```ts
1771
+ * import { ALTERNATE_CODES_EXTENSION_URL } from "@cosyte/transform";
1772
+ * ALTERNATE_CODES_EXTENSION_URL; // "http://hl7.org/fhir/StructureDefinition/alternate-codes"
1773
+ * ```
1774
+ */
1775
+ declare const ALTERNATE_CODES_EXTENSION_URL = "http://hl7.org/fhir/StructureDefinition/alternate-codes";
1776
+ /**
1777
+ * The HL7 v2 version at which AL1-6 Identification Date was withdrawn, per the IG map's own comment
1778
+ * on that row ("Withdrawn as of 2.7, Refer to IAM-11 Onset or IAM-13 Reported Date"). A message at
1779
+ * this version or later carries no AL1-6 that this library will read as an onset.
1780
+ *
1781
+ * @example
1782
+ * ```ts
1783
+ * import { AL1_ONSET_WITHDRAWN_AT } from "@cosyte/transform";
1784
+ * AL1_ONSET_WITHDRAWN_AT; // [2, 7]
1785
+ * ```
1786
+ */
1787
+ declare const AL1_ONSET_WITHDRAWN_AT: readonly number[];
1788
+ /**
1789
+ * Whether a message's MSH-12 version identifier is readable **and** earlier than the version at
1790
+ * which AL1-6 was withdrawn ({@link AL1_ONSET_WITHDRAWN_AT}).
1791
+ *
1792
+ * Fails closed in both directions a version can be unusable: an absent MSH-12 and one this library
1793
+ * cannot compare (a vendor string, an empty component, anything outside the dotted-numeric shape)
1794
+ * both answer `false`, so a valued AL1-6 is dropped and flagged rather than read as an onset on a
1795
+ * message that may never have meant one.
1796
+ *
1797
+ * @param version - The MSH-12 version identifier exactly as the parser published it.
1798
+ * @example
1799
+ * ```ts
1800
+ * import { carriesLegacyOnsetDate } from "@cosyte/transform";
1801
+ * carriesLegacyOnsetDate("2.5.1"); // true
1802
+ * carriesLegacyOnsetDate("2.7"); // false
1803
+ * carriesLegacyOnsetDate(undefined); // false
1804
+ * ```
1805
+ */
1806
+ declare function carriesLegacyOnsetDate(version: string | undefined): boolean;
1807
+ /**
1808
+ * Every `AL1` occurrence a message carries, in message order. One AllergyIntolerance is created per
1809
+ * occurrence, per the IG message map's `0..-1` cardinality on the AL1 row.
1810
+ *
1811
+ * @param msg - The parsed `@cosyte/hl7` message.
1812
+ * @example
1813
+ * ```ts
1814
+ * import { parseHL7 } from "@cosyte/hl7";
1815
+ * // collectAllergies(parseHL7(raw)).length; // one entry per AL1 in the message
1816
+ * ```
1817
+ */
1818
+ declare function collectAllergies(msg: Hl7Message): readonly Segment[];
1819
+ /** How much of the IG's AL1 mapping to carry: the alternate-codes extension is the one variable. */
1820
+ interface AllergyBuildOptions {
1821
+ /**
1822
+ * Whether to carry the IG's `alternate-codes` extension on `category` / `criticality`. Defaults to
1823
+ * `true`; the emit path builds a second draft with it off only when the first draft fails the
1824
+ * conservative-emit gate.
1825
+ */
1826
+ readonly carryAlternateCodes?: boolean;
1827
+ }
1828
+
1829
+ /**
1830
+ * DG1 to FHIR `Condition`: the diagnoses an admit states, carried into the bundle instead of lost
1831
+ * between the v2 feed and the FHIR record. Grounded firsthand on the IG **DG1 to Condition** segment
1832
+ * map and the **ADT_A01 to Bundle** message map (`hl7.fhir.uv.v2mappings`, STU1;
1833
+ * `ConceptMap-segment-dg1-to-condition.html`, `ConceptMap-message-adt-a01-to-bundle.html`), which
1834
+ * wires `Condition[1].subject.reference` to the bundle's Patient, creates one Condition per DG1, and
1835
+ * references it back from `Encounter[1].diagnosis`.
1836
+ *
1837
+ * | v2 field | FHIR target | via |
1838
+ * |---|---|---|
1839
+ * | DG1-3 Diagnosis Code (CWE) | `code` | {@link toFhirCodeableConcept} (structural, no IG value map) |
1840
+ * | DG1-4 Diagnosis Description (ST) | `code.text` | verbatim, overriding the coded field's own text |
1841
+ * | DG1-5 Diagnosis Date/Time (DTM) | `onsetDateTime` | {@link toFhirDateTime} |
1842
+ * | DG1-19 Attestation Date/Time (DTM) | `recordedDate` | {@link toFhirDateTime} |
1843
+ * | DG1-20 Diagnosis Identifier (EI) | `identifier` | {@link toFhirEntityIdentifier} |
1844
+ * | DG1-21 Diagnosis Action Code (ID) | `verificationStatus` | the map's fixed assignment for `D` |
1845
+ * | (message-map wiring) | `subject` (required 1..1) | the bundle's Patient |
1846
+ *
1847
+ * **Fail-safes (never a confident wrong diagnosis).**
1848
+ * - **One action code is mapped, and only one.** The DG1-21 row assigns the fixed value
1849
+ * `entered-in-error` and names no source code; its own comment reads "Other values (A and U) don't
1850
+ * map to anything", and Table 0206 publishes `A`, `D`, `S`, `U` and `X`. `D` (Delete) is therefore
1851
+ * the code the assignment covers: every other published action code leaves `verificationStatus`
1852
+ * absent and raises {@link ISSUE_CODES.TRANSFORM_CODE_UNMAPPED}, never a neighbouring status.
1853
+ * - **A diagnosis with no code and no text is visible, not silent.** Such a DG1 still becomes a
1854
+ * Condition (the message stated a diagnosis), and the empty `code` is declared
1855
+ * {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED} rather than read as an intentionally empty one.
1856
+ * - **`clinicalStatus` is absent because no row grounds it.** The map has no `Condition.clinicalStatus`
1857
+ * row and no DG1 component states one, so it is never filled. R4's `con-3` invariant expects it
1858
+ * wherever `verificationStatus` is not `entered-in-error`, so a Condition built here can fail that
1859
+ * invariant under a full profile validator: that is a declared gap, and filling the element from
1860
+ * nothing is the fabrication this library refuses.
1861
+ *
1862
+ * Deferred and flagged, never silently mapped: `DG1-16` (`asserter`, a Practitioner resource this
1863
+ * library does not build), `DG1-22` (the `condition-dueTo` extension, whose reference resolves by
1864
+ * identifier rather than by bundle position) and the map's `EpisodeOfCare` target, so a diagnosis
1865
+ * ties to an Encounter or to nothing.
1866
+ *
1867
+ * @packageDocumentation
1868
+ */
1869
+
1870
+ /**
1871
+ * The code system of the `verificationStatus` the DG1-21 row assigns, transcribed from the segment
1872
+ * map's own `Condition.verificationStatus.coding.system` assignment.
1873
+ *
1874
+ * @example
1875
+ * ```ts
1876
+ * import { CONDITION_VERIFICATION_STATUS_SYSTEM } from "@cosyte/transform";
1877
+ * CONDITION_VERIFICATION_STATUS_SYSTEM.endsWith("condition-ver-status"); // true
1878
+ * ```
1879
+ */
1880
+ declare const CONDITION_VERIFICATION_STATUS_SYSTEM = "http://terminology.hl7.org/CodeSystem/condition-ver-status";
1881
+ /**
1882
+ * The `verificationStatus` code the DG1-21 row assigns, transcribed from the segment map's own
1883
+ * `Condition.verificationStatus.coding.code` assignment.
1884
+ *
1885
+ * @example
1886
+ * ```ts
1887
+ * import { CONDITION_ENTERED_IN_ERROR } from "@cosyte/transform";
1888
+ * CONDITION_ENTERED_IN_ERROR; // "entered-in-error"
1889
+ * ```
1890
+ */
1891
+ declare const CONDITION_ENTERED_IN_ERROR = "entered-in-error";
1892
+ /**
1893
+ * The Table 0206 (Segment Action Code) code the DG1-21 assignment covers. The row assigns a
1894
+ * retraction and names no source code; `D` is Delete, and the row's own comment excludes the rest.
1895
+ *
1896
+ * @example
1897
+ * ```ts
1898
+ * import { DG1_RETRACTION_ACTION_CODE } from "@cosyte/transform";
1899
+ * DG1_RETRACTION_ACTION_CODE; // "D"
1900
+ * ```
1901
+ */
1902
+ declare const DG1_RETRACTION_ACTION_CODE = "D";
1903
+ /**
1904
+ * Every `DG1` occurrence a message carries, in message order. One Condition is created per
1905
+ * occurrence, per the IG message map's `0..-1` cardinality on the DG1 row.
1906
+ *
1907
+ * @param msg - The parsed `@cosyte/hl7` message.
1908
+ * @example
1909
+ * ```ts
1910
+ * import { parseHL7 } from "@cosyte/hl7";
1911
+ * // collectDiagnoses(parseHL7(raw)).length; // one entry per DG1 in the message
1912
+ * ```
1913
+ */
1914
+ declare function collectDiagnoses(msg: Hl7Message): readonly Segment[];
1915
+ /**
1916
+ * The value-free diagnostics for the DG1 rows this library reads and deliberately does not build:
1917
+ * the diagnosing clinician (a Practitioner resource), and the parent diagnosis (a reference resolved
1918
+ * by identifier rather than by bundle position).
1919
+ *
1920
+ * Raised for the occurrence whether or not the Condition itself is emitted, so a deferred row a
1921
+ * message actually valued is in the issues list rather than silently absent.
1922
+ *
1923
+ * @param dg1 - The `DG1` `@cosyte/hl7` `Segment`.
1924
+ * @example
1925
+ * ```ts
1926
+ * // deferredDiagnosisIssues(dg1).length; // one per valued deferred row
1927
+ * ```
1928
+ */
1929
+ declare function deferredDiagnosisIssues(dg1: Segment): readonly TransformIssue[];
1930
+ /**
1931
+ * Build a FHIR `Condition` resource node from one `DG1` occurrence, wired to the bundle's Patient.
1932
+ * Always produces a Condition: a DG1 states a diagnosis, so an occurrence that grounds neither a
1933
+ * code nor a description is emitted with its empty `code` declared rather than withheld.
1934
+ *
1935
+ * @param dg1 - The `DG1` `@cosyte/hl7` `Segment`.
1936
+ * @param patientFullUrl - The bundle's Patient fullUrl, for `subject` (required 1..1).
1937
+ * @param ctx - The transform context (naming-system registry + timezone policy).
1938
+ * @param v2Location - The occurrence's v2 location, for the codeless diagnostic (e.g. `DG1[0]`).
1939
+ * @example
1940
+ * ```ts
1941
+ * import { parseHL7 } from "@cosyte/hl7";
1942
+ * // const dg1 = parseHL7(raw).segments("DG1")[0];
1943
+ * // const { value } = buildCondition(dg1!, "urn:uuid:pat", {}, "DG1[0]");
1944
+ * ```
1945
+ */
1946
+ declare function buildCondition(dg1: Segment, patientFullUrl: string, ctx: TransformContext, v2Location: string): ConvertResult<FhirComplex>;
1947
+
1948
+ /**
1949
+ * PR1 to FHIR `Procedure`: the procedures an admit states, carried into the bundle instead of lost
1950
+ * between the v2 feed and the FHIR record. Grounded firsthand on the IG **PR1 to Procedure** segment
1951
+ * map and the **ADT_A01 to Bundle** message map (`hl7.fhir.uv.v2mappings`, STU1;
1952
+ * `ConceptMap-segment-pr1-to-procedure.html`, `ConceptMap-message-adt-a01-to-bundle.html`), which
1953
+ * wires `Procedure.subject.reference` to the bundle's Patient and creates one Procedure per PR1.
1954
+ *
1955
+ * | v2 field | FHIR target | via |
1956
+ * |---|---|---|
1957
+ * | PR1 (narrative row) | `status` (required 1..1) | the row's own `unknown`, the value it directs when the message context does not determine one |
1958
+ * | PR1-3 Procedure Code (CNE) | `code` | {@link toFhirCodeableConcept} (structural, no IG value map) |
1959
+ * | PR1-4 Procedure Description (ST) | `code.text` | verbatim, only `IF PR1-3.9 NOT VALUED` |
1960
+ * | PR1-5 Procedure Date/Time (DTM) | `performedDateTime` / `performedPeriod.start` | {@link toFhirDateTime}, branched on PR1-7 |
1961
+ * | PR1-6 Procedure Functional Type (CWE) | `category` | {@link toFhirCodeableConcept} |
1962
+ * | PR1-7 Procedure Minutes (NM) | `performedPeriod.end` | the period start plus that many minutes |
1963
+ * | PR1-15 Associated Diagnosis Code (CWE) | `reasonCode` | {@link toFhirCodeableConcept} |
1964
+ * | PR1-19 Procedure Identifier (EI) | `identifier` | {@link toFhirEntityIdentifier} |
1965
+ * | (message-map wiring) | `subject` (required 1..1) | the bundle's Patient |
1966
+ *
1967
+ * **Fail-safes (never a confident wrong procedure).**
1968
+ * - **The status is the one the map directs, never one the message did not state.** The map's own
1969
+ * sort-order 0 row reads "The value mapping depends on the message context where the PR1 is used
1970
+ * and to be determined by the implementer. If not clear, use `unknown`". No PR1 component states a
1971
+ * procedure status, so `unknown` is the answer, and `completed` or `in-progress` is never selected
1972
+ * from a message that did not say so.
1973
+ * - **A period needs a start precise enough to add minutes to.** PR1-7 is minutes, and the map's own
1974
+ * comment requires PR1-5 to reach at least minute granularity before a `performedPeriod` is built
1975
+ * from the pair. This library goes by what the conversion could actually carry: a PR1-5 that
1976
+ * reduces to date precision (a naked or partial-precision timestamp, per {@link toFhirDateTime})
1977
+ * is not a start a duration can be added to, so the value stays `performedDateTime` and the end is
1978
+ * declared {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED} rather than computed from a date.
1979
+ * - **The description defers to the coded field's own text.** The PR1-4 row is conditioned
1980
+ * `IF PR1-3.9 NOT VALUED`, so an original text the sender put in the coded field wins and PR1-4 is
1981
+ * dropped and declared rather than overwriting it.
1982
+ *
1983
+ * Deferred and flagged, never silently mapped: `PR1-8`, `PR1-11` and `PR1-12` (`performer.actor`, a
1984
+ * Practitioner resource this library does not build), `PR1-23` (`location`, likewise a Location),
1985
+ * `PR1-25` (`partOf`, a reference resolved by identifier rather than by bundle position) and
1986
+ * `PR1-16`, whose target `Procedure.code.value` is not an element of R4's `Procedure.code`.
1987
+ *
1988
+ * @packageDocumentation
1989
+ */
1990
+
1991
+ /**
1992
+ * The `Procedure.status` the PR1 map's own narrative row directs when the message context does not
1993
+ * determine one. No PR1 component carries a procedure status, so this is the value every Procedure
1994
+ * built from a PR1 carries.
1995
+ *
1996
+ * @example
1997
+ * ```ts
1998
+ * import { PROCEDURE_STATUS_UNKNOWN } from "@cosyte/transform";
1999
+ * PROCEDURE_STATUS_UNKNOWN; // "unknown"
2000
+ * ```
2001
+ */
2002
+ declare const PROCEDURE_STATUS_UNKNOWN = "unknown";
2003
+ /**
2004
+ * Every `PR1` occurrence a message carries, in message order. One Procedure is created per
2005
+ * occurrence, per the IG message map's `0..-1` cardinality on the PROCEDURE group.
2006
+ *
2007
+ * @param msg - The parsed `@cosyte/hl7` message.
2008
+ * @example
2009
+ * ```ts
2010
+ * import { parseHL7 } from "@cosyte/hl7";
2011
+ * // collectProcedures(parseHL7(raw)).length; // one entry per PR1 in the message
2012
+ * ```
2013
+ */
2014
+ declare function collectProcedures(msg: Hl7Message): readonly Segment[];
2015
+ /**
2016
+ * Add whole minutes to a FHIR `dateTime` that carries a time of day, preserving its stated offset and
2017
+ * its fractional seconds exactly. Returns `undefined` when the value is not a full zoned timestamp,
2018
+ * because a date is not a start a duration can be added to.
2019
+ *
2020
+ * @param start - The FHIR `dateTime` lexical value the conversion produced.
2021
+ * @param minutes - The number of minutes to add.
2022
+ * @example
2023
+ * ```ts
2024
+ * import { addMinutes } from "@cosyte/transform";
2025
+ * addMinutes("2026-01-15T10:30:00-05:00", 45); // "2026-01-15T11:15:00-05:00"
2026
+ * addMinutes("2026-01-15", 45); // undefined
2027
+ * ```
2028
+ */
2029
+ declare function addMinutes(start: string, minutes: number): string | undefined;
2030
+ /**
2031
+ * The value-free diagnostics for the PR1 rows this library reads and deliberately does not build:
2032
+ * the three practitioner roles, the treating organizational unit, the parent procedure, and the code
2033
+ * modifier whose target is not an R4 element.
2034
+ *
2035
+ * Raised for the occurrence whether or not the Procedure itself is emitted, so a deferred row a
2036
+ * message actually valued is in the issues list rather than silently absent.
2037
+ *
2038
+ * @param pr1 - The `PR1` `@cosyte/hl7` `Segment`.
2039
+ * @example
2040
+ * ```ts
2041
+ * // deferredProcedureIssues(pr1).length; // one per valued deferred row
2042
+ * ```
2043
+ */
2044
+ declare function deferredProcedureIssues(pr1: Segment): readonly TransformIssue[];
2045
+ /**
2046
+ * Build a FHIR `Procedure` resource node from one `PR1` occurrence, wired to the bundle's Patient.
2047
+ * Always produces a Procedure: a PR1 states that a procedure happened, and `status` is grounded on
2048
+ * the map's own row rather than on the message, so nothing here can fail to be groundable.
2049
+ *
2050
+ * @param pr1 - The `PR1` `@cosyte/hl7` `Segment`.
2051
+ * @param patientFullUrl - The bundle's Patient fullUrl, for `subject` (required 1..1).
2052
+ * @param ctx - The transform context (naming-system registry + timezone policy).
2053
+ * @example
2054
+ * ```ts
2055
+ * import { parseHL7 } from "@cosyte/hl7";
2056
+ * // const pr1 = parseHL7(raw).segments("PR1")[0];
2057
+ * // const { value } = buildProcedure(pr1!, "urn:uuid:pat", {});
2058
+ * ```
2059
+ */
2060
+ declare function buildProcedure(pr1: Segment, patientFullUrl: string, ctx: TransformContext): ConvertResult<FhirComplex>;
2061
+
2062
+ /**
2063
+ * IN1 to FHIR `Coverage`: the insurance an admit states, carried into the bundle instead of lost
2064
+ * between the v2 feed and the FHIR record. Grounded firsthand on the IG **IN1 to Coverage** segment
2065
+ * map and the **ADT_A01 to Bundle** message map (`hl7.fhir.uv.v2mappings`, STU1;
2066
+ * `ConceptMap-segment-in1-to-coverage.html`, `ConceptMap-message-adt-a01-to-bundle.html`), which
2067
+ * wires `Coverage.beneficiary.reference` to the bundle's Patient and creates one Coverage per IN1.
2068
+ *
2069
+ * | v2 field | FHIR target | via |
2070
+ * |---|---|---|
2071
+ * | IN1-2 Health Plan ID (CWE) | `identifier` | CWE.1 as the identifier value |
2072
+ * | IN1-4 Insurance Company Name (XON) | `payor` (required 1..*) | a reference carrying the name as `display` only |
2073
+ * | IN1-10 Insured's Group Emp ID (CX) | the subscriber-id extension, `IF CX.5 IS "SN"` | {@link toFhirIdentifier} |
2074
+ * | IN1-12 Plan Effective Date (DT) | `period.start` | {@link toFhirDateTime} |
2075
+ * | IN1-13 Plan Expiration Date (DT) | `period.end` | {@link toFhirDateTime} |
2076
+ * | IN1-15 Plan Type (CWE) | `type` | {@link toFhirCodeableConcept} |
2077
+ * | IN1-49 Insured's ID Number (CX) | the subscriber-id extension | {@link toFhirIdentifier} |
2078
+ * | (no row at all) | `status` (required 1..1) | a value-absent element, `data-absent-reason` `unknown` |
2079
+ * | (message-map wiring) | `beneficiary` (required 1..1) | the bundle's Patient |
2080
+ *
2081
+ * **Fail-safes (never a confident wrong coverage).**
2082
+ * - **The status is never asserted.** `Coverage.status` occurs nowhere in the segment map, and R4
2083
+ * makes the element required under a required binding whose members are all positive claims about
2084
+ * a policy. So it ships as a value-absent element carrying `data-absent-reason` `unknown`, plus
2085
+ * {@link ISSUE_CODES.TRANSFORM_REQUIRED_ELEMENT_UNKNOWN}: a consumer must read the status as
2086
+ * unknown, and `active` is never the answer this library gives to a message that did not say so.
2087
+ * - **A coverage names who pays.** `payor` is required 1..1 and IN1-4 is the only row that grounds
2088
+ * it, so an IN1 whose insurance company name is absent is **withheld** and declared
2089
+ * {@link ISSUE_CODES.TRANSFORM_ELEMENT_DROPPED} rather than emitted naming no payer.
2090
+ * - **The payer is named, not resolved.** No Organization resource is built here, so `payor` carries
2091
+ * the company name as a `display` and no literal reference, and the missing resource is declared
2092
+ * rather than left to look like a resolvable link.
2093
+ * - **A health plan id keeps its value, never a synthesized system.** IN1-2 is a coded element whose
2094
+ * coding system is a table mnemonic, not an identifier namespace, so only CWE.1 is carried as
2095
+ * `Identifier.value`; a valued CWE.3 is declared dropped rather than turned into an
2096
+ * `Identifier.system` this library would be inventing.
2097
+ *
2098
+ * Deferred and flagged, never silently mapped: `IN1-5` (the payer address, an Organization this
2099
+ * library does not build), `IN1-10` and `IN1-11` (`policyHolder`, likewise an Organization),
2100
+ * `IN1-16` (`subscriber`, a Patient or RelatedPerson reference the guide conditions on IN1-17) and
2101
+ * `IN1-17` (`relationship`, whose value translation needs a Table 0063 to v3 RoleCode ConceptMap
2102
+ * this library does not carry).
2103
+ *
2104
+ * @packageDocumentation
2105
+ */
2106
+
2107
+ /**
2108
+ * The canonical URL of the subscriber-id extension the IN1-10 and IN1-49 rows assign, transcribed
2109
+ * from the segment map's own `Coverage.extension.url` assignment.
2110
+ *
2111
+ * @example
2112
+ * ```ts
2113
+ * import { COVERAGE_SUBSCRIBER_ID_EXTENSION_URL } from "@cosyte/transform";
2114
+ * COVERAGE_SUBSCRIBER_ID_EXTENSION_URL.endsWith("extension-subscriberId"); // true
2115
+ * ```
2116
+ */
2117
+ declare const COVERAGE_SUBSCRIBER_ID_EXTENSION_URL = "http://hl7.org/fhir/5.0/StructureDefinition/extension-subscriberId";
2118
+ /**
2119
+ * The `data-absent-reason` code carried by `Coverage.status`, the one FHIR-required element of this
2120
+ * resource that no published row of the segment map grounds.
2121
+ *
2122
+ * @example
2123
+ * ```ts
2124
+ * import { COVERAGE_STATUS_UNKNOWN } from "@cosyte/transform";
2125
+ * COVERAGE_STATUS_UNKNOWN; // "unknown"
2126
+ * ```
2127
+ */
2128
+ declare const COVERAGE_STATUS_UNKNOWN = "unknown";
2129
+ /**
2130
+ * The Table 0203 identifier-type code the IN1-10 row conditions its subscriber-id assignment on
2131
+ * (`IF CX.5 IS "SN"`, Subscriber Number). Any other identifier type leaves that row unapplied.
2132
+ *
2133
+ * @example
2134
+ * ```ts
2135
+ * import { IN1_SUBSCRIBER_NUMBER_TYPE } from "@cosyte/transform";
2136
+ * IN1_SUBSCRIBER_NUMBER_TYPE; // "SN"
2137
+ * ```
2138
+ */
2139
+ declare const IN1_SUBSCRIBER_NUMBER_TYPE = "SN";
2140
+ /**
2141
+ * Every `IN1` occurrence a message carries, in message order. One Coverage is created per
2142
+ * occurrence, per the IG message map's INSURANCE group.
2143
+ *
2144
+ * @param msg - The parsed `@cosyte/hl7` message.
2145
+ * @example
2146
+ * ```ts
2147
+ * import { parseHL7 } from "@cosyte/hl7";
2148
+ * // collectCoverages(parseHL7(raw)).length; // one entry per IN1 in the message
2149
+ * ```
2150
+ */
2151
+ declare function collectCoverages(msg: Hl7Message): readonly Segment[];
2152
+ /**
2153
+ * The insurance company name an IN1 carries, read from XON.1 of IN1-4, or `""` when that component
2154
+ * carries nothing. The only row of the segment map that grounds the required `payor`.
2155
+ *
2156
+ * @param in1 - The `IN1` `@cosyte/hl7` `Segment`.
2157
+ * @example
2158
+ * ```ts
2159
+ * // insuranceCompanyName(in1); // the XON.1 organization name, verbatim
2160
+ * ```
2161
+ */
2162
+ declare function insuranceCompanyName(in1: Segment): string;
2163
+ /**
2164
+ * The value-free diagnostics for the IN1 rows this library reads and deliberately does not build:
2165
+ * the payer address and the two policy-holder rows (each an Organization resource), the subscriber
2166
+ * (a Patient or RelatedPerson reference), and the relationship, whose value translation needs a
2167
+ * table this library does not carry.
2168
+ *
2169
+ * Raised for the occurrence whether or not the Coverage itself is emitted, so a deferred row a
2170
+ * message actually valued is in the issues list rather than silently absent.
2171
+ *
2172
+ * @param in1 - The `IN1` `@cosyte/hl7` `Segment`.
2173
+ * @example
2174
+ * ```ts
2175
+ * // deferredCoverageIssues(in1).length; // one per valued deferred row
2176
+ * ```
2177
+ */
2178
+ declare function deferredCoverageIssues(in1: Segment): readonly TransformIssue[];
2179
+ /**
2180
+ * Build a FHIR `Coverage` resource node from one `IN1` occurrence, wired to the bundle's Patient.
2181
+ * Returns `{ value: undefined }` when IN1-4 names no insurance company, because `payor` is required
2182
+ * by R4 and no other row of the segment map grounds it.
2183
+ *
2184
+ * @param in1 - The `IN1` `@cosyte/hl7` `Segment`.
2185
+ * @param patientFullUrl - The bundle's Patient fullUrl, for `beneficiary` (required 1..1).
2186
+ * @param ctx - The transform context (naming-system registry + timezone policy).
2187
+ * @param v2Location - The occurrence's v2 location, for the withholding diagnostic (e.g. `IN1[0]`).
2188
+ * @example
2189
+ * ```ts
2190
+ * import { parseHL7 } from "@cosyte/hl7";
2191
+ * // const in1 = parseHL7(raw).segments("IN1")[0];
2192
+ * // const { value } = buildCoverage(in1!, "urn:uuid:pat", {}, "IN1[0]");
2193
+ * ```
2194
+ */
2195
+ declare function buildCoverage(in1: Segment, patientFullUrl: string, ctx: TransformContext, v2Location: string): ConvertResult<FhirComplex>;
2196
+
2197
+ /**
2198
+ * Bundle-assembly primitives shared by the segment→resource builders: fresh `urn:uuid:` identities,
2199
+ * FHIR `Reference` nodes, and the small coding/data-absent helpers the message maps need.
2200
+ *
2201
+ * The identities are the wiring of the resource graph: a produced resource is registered under a
2202
+ * `urn:uuid:` `fullUrl`, and every intra-bundle reference (Encounter→subject→Patient,
2203
+ * RelatedPerson→patient→Patient, MessageHeader→focus→…) points at that same `fullUrl` so references
2204
+ * always resolve **within** the bundle. Identities come from {@link TransformOptions.generateId}
2205
+ * (default `crypto.randomUUID`) so output can be made reproducible for golden fixtures.
2206
+ *
2207
+ * @packageDocumentation
2208
+ */
2209
+
2210
+ /** One EI field read as a FHIR `Identifier`: the value, and whether an authority went unused. */
2211
+ interface EntityIdentifier {
2212
+ /** The `Identifier` node built from EI.1, or `undefined` when EI.1 carries nothing. */
2213
+ readonly identifier: FhirComplex | undefined;
2214
+ /** Whether EI.2, EI.3 or EI.4 carried an assigning authority this library did not resolve. */
2215
+ readonly authorityValued: boolean;
2216
+ }
2217
+ /**
2218
+ * Read one EI (Entity Identifier) field as a FHIR `Identifier`, carrying EI.1 as
2219
+ * `Identifier.value` and nothing else. The same reading {@link orderIdentifier} applies to the
2220
+ * placer/filler order numbers, without the v2-0203 identifier type those rows assign.
2221
+ *
2222
+ * `Identifier.system` is deliberately left absent even when EI.2 to EI.4 name an assigning
2223
+ * authority: a system URI is never synthesized from a bare namespace, because two senders reusing
2224
+ * one namespace would otherwise collide. The caller is told the authority went unused through
2225
+ * {@link EntityIdentifier.authorityValued} so it can raise its own value-free diagnostic.
2226
+ *
2227
+ * @param field - The `EI` field, exactly as the parser published it.
2228
+ * @example
2229
+ * ```ts
2230
+ * import { parseHL7 } from "@cosyte/hl7";
2231
+ * // const dg1 = parseHL7(raw).segments("DG1")[0];
2232
+ * // toFhirEntityIdentifier(dg1!.field(20)).identifier; // { value: "<EI.1>" } or undefined
2233
+ * ```
2234
+ */
2235
+ declare function toFhirEntityIdentifier(field: Field): EntityIdentifier;
2236
+ /**
2237
+ * The same `CodeableConcept` with its `text` replaced by `textValue`, so a segment row that targets
2238
+ * `code.text` directly can override the original text the datatype map read out of the coded field.
2239
+ *
2240
+ * @param concept - The `CodeableConcept` node the datatype converter produced.
2241
+ * @param textValue - The text the segment map's own row assigns.
2242
+ * @example
2243
+ * ```ts
2244
+ * // withCodeableText(concept, "Diabetes mellitus") -> the same codings, that text
2245
+ * ```
2246
+ */
2247
+ declare function withCodeableText(concept: FhirComplex, textValue: string): FhirComplex;
2248
+
2249
+ /**
2250
+ * The `$translate`-shaped ConceptMap-application engine + the **license-clean** v2-table → FHIR
2251
+ * value maps it applies. This is the layer that value-**translates** a coded v2
2252
+ * field, not merely carrying its code structurally, but mapping the source table code to the FHIR
2253
+ * target coding the IG's segment-map `mappedVia` ConceptMap prescribes.
2254
+ *
2255
+ * **Grounded firsthand on the raw published IG ConceptMaps** (`hl7.fhir.uv.v2mappings`, STU1;
2256
+ * `ConceptMap-table-*.json`). Each shipped map below cites the exact IG ConceptMap it transcribes and
2257
+ * was verified against that resource's JSON (its `group.element[].target[]` rows and its `unmatched`
2258
+ * `(unmapped)` group). The engine is **fail-safe by refusal**: a source code the IG map has **no
2259
+ * target** for (its `(unmapped)` group) is never coerced to a plausible neighbor. The caller flags it
2260
+ * and preserves the raw coding, or withholds the value, but a target is **never fabricated**.
2261
+ *
2262
+ * Two of the maps below are consumed as **recognizers** rather than as translations, because their
2263
+ * IG rows are identity in the source code: {@link isRepeatPatternCode} (RPT.1 → `Timing.code`) and
2264
+ * {@link TIMING_EVENT_VALUE_MAP} (RPT.8 → `Timing.repeat.when`). What they decide is whether the
2265
+ * published map has a row at all, so the caller can carry the message's own code verbatim or
2266
+ * withhold the element; neither one ever rewrites a code into a different one.
2267
+ *
2268
+ * **License posture.** Only maps whose target CodeSystem is **freely redistributable** are
2269
+ * shipped here: the HL7 THO v2 tables (`v2-0162`, `v2-0550`, `v2-0277`, `v2-0161`, `v2-0127`,
2270
+ * `v2-0128`, `v2-0335`, `v2-0528`), the FHIR R4 core code systems (`allergy-intolerance-category`,
2271
+ * `allergy-intolerance-type`, `allergy-intolerance-criticality`) and HL7 v3
2272
+ * (`v3-RouteOfAdministration`, `v3-TimingEvent`) are HL7's own, license-clean. The IG's `*-to-sct`
2273
+ * value maps,
2274
+ * **RXR-4 method** (`table-hl70165-to-sct`) and **SCH-7 reason** (`table-hl70276-to-sct`), translate
2275
+ * **into SNOMED CT**, which is **license-encumbered and is NOT bundled**; those fields stay
2276
+ * structurally carried (BYO ConceptMap), never value-translated here (see their message modules).
2277
+ *
2278
+ * **Additive, never mutating.** A successful translation preserves the raw source coding
2279
+ * (its code, display, version, and any `CWE.4/5/6` alternate triplet) and *adds* the derived target
2280
+ * coding: recognition never overwrites or discards what the message said; it augments it with the
2281
+ * IG-mapped equivalent. And it only fires when the field's primary coding is genuinely from the map's
2282
+ * **bound source table** (CWE.3 absent, or naming that table): a field that declares a *foreign*
2283
+ * coding system (a local `99…`, SNOMED, …) is carried structurally and flagged, and its code is **never**
2284
+ * asserted to be the standard concept just because the string happens to collide with a table code.
2285
+ *
2286
+ * @packageDocumentation
2287
+ */
2288
+
2289
+ /** HL7 v2 Table 0162 (Route of Administration) THO CodeSystem URI. */
2290
+ declare const V2_0162_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0162";
2291
+ /** HL7 v3 RouteOfAdministration CodeSystem URI (the IG's remap target for the six common routes). */
2292
+ declare const V3_ROUTE_OF_ADMINISTRATION_SYSTEM = "http://terminology.hl7.org/CodeSystem/v3-RouteOfAdministration";
2293
+ /** HL7 v2 Table 0550 (Body Parts) THO CodeSystem URI. */
2294
+ declare const V2_0550_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0550";
2295
+ /** HL7 v2 Table 0277 (Appointment Type Codes) THO CodeSystem URI. */
2296
+ declare const V2_0277_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0277";
2297
+ /** HL7 v2 Table 0161 (Allow Substitution) THO CodeSystem URI. */
2298
+ declare const V2_0161_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0161";
2299
+ /** HL7 v2 Table 0127 (Allergen Type) THO CodeSystem URI. */
2300
+ declare const V2_0127_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0127";
2301
+ /** HL7 v2 Table 0128 (Allergy Severity) THO CodeSystem URI. */
2302
+ declare const V2_0128_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0128";
2303
+ /** FHIR R4 `AllergyIntoleranceCategory` CodeSystem URI (the IG's AL1-2 category target). */
2304
+ declare const ALLERGY_INTOLERANCE_CATEGORY_SYSTEM = "http://hl7.org/fhir/allergy-intolerance-category";
2305
+ /** FHIR R4 `AllergyIntoleranceType` CodeSystem URI (the IG's AL1-2 type target). */
2306
+ declare const ALLERGY_INTOLERANCE_TYPE_SYSTEM = "http://hl7.org/fhir/allergy-intolerance-type";
2307
+ /** FHIR R4 `AllergyIntoleranceCriticality` CodeSystem URI (the IG's AL1-4 criticality target). */
2308
+ declare const ALLERGY_INTOLERANCE_CRITICALITY_SYSTEM = "http://hl7.org/fhir/allergy-intolerance-criticality";
2309
+ /** A translated FHIR target coding: the target CodeSystem URI + code, and the IG's target display. */
2310
+ interface CodedTarget {
2311
+ /** The FHIR target CodeSystem canonical URI. */
2312
+ readonly system: string;
2313
+ /** The FHIR target code. */
2314
+ readonly code: string;
2315
+ /** The IG map's target display, when it carries one (absent for the identity table maps). */
2316
+ readonly display?: string;
2317
+ }
2318
+ /**
2319
+ * A license-clean v2-table → FHIR value ConceptMap: it translates a **source table code** to its
2320
+ * {@link CodedTarget}, or `undefined` when the code is not in the map's *mapped* group (the IG's
2321
+ * `(unmapped)` group). Never fabricates a target.
2322
+ */
2323
+ interface CodedValueMap {
2324
+ /** The IG ConceptMap id this map transcribes (its citation). */
2325
+ readonly name: string;
2326
+ /** The source table's canonical CodeSystem URI (what the raw v2 code is a member of when mapped). */
2327
+ readonly sourceSystem: string;
2328
+ /**
2329
+ * The CWE.3 (`nameOfCodingSystem`) mnemonics that denote this map's **bound source table**: the
2330
+ * HL7 forms (`"HL70162"`, `"0162"`, …). Translation applies **only** when the field's primary
2331
+ * coding is from the bound table: CWE.3 absent/empty (a positionally-bound bare code) **or** CWE.3 ∈
2332
+ * this set. A CWE that declares a **different** coding system (a local `99…`, or SNOMED) is not a
2333
+ * source-table code, so the map is not applied to it: the raw coding is carried structurally + its
2334
+ * system flagged, never asserted as the standard concept.
2335
+ */
2336
+ readonly sourceMnemonics: ReadonlySet<string>;
2337
+ /** Translate a source table code to its FHIR target, or `undefined` when the IG map has no target. */
2338
+ readonly translate: (code: string) => CodedTarget | undefined;
1148
2339
  }
1149
2340
  /**
1150
2341
  * **RXR-1 Route**: IG `ConceptMap/table-hl70162-to-v2-0162`. Two IG groups, transcribed verbatim:
@@ -1178,6 +2369,111 @@ declare const APPOINTMENT_TYPE_VALUE_MAP: CodedValueMap;
1178
2369
  * substitution is withheld + flagged, never a fabricated substitution permission.
1179
2370
  */
1180
2371
  declare const SUBSTITUTION_VALUE_MAP: CodedValueMap;
2372
+ /**
2373
+ * The published version of the HL7 Version 2 to FHIR Implementation Guide the five **AL1 allergy**
2374
+ * value maps below were transcribed from.
2375
+ *
2376
+ * Recorded per map family rather than once for the file, because the earlier value maps here were
2377
+ * transcribed on their own date and this constant must not backdate or forward-date them.
2378
+ *
2379
+ * @example
2380
+ * ```ts
2381
+ * import { IG_ALLERGY_VALUE_MAPS_VERSION } from "@cosyte/transform";
2382
+ * IG_ALLERGY_VALUE_MAPS_VERSION; // "1.0.0"
2383
+ * ```
2384
+ */
2385
+ declare const IG_ALLERGY_VALUE_MAPS_VERSION = "1.0.0";
2386
+ /**
2387
+ * The publication date of {@link IG_ALLERGY_VALUE_MAPS_VERSION}, so a later release of the guide can
2388
+ * be told apart from a defect in this library.
2389
+ *
2390
+ * @example
2391
+ * ```ts
2392
+ * import { IG_ALLERGY_VALUE_MAPS_PUBLISHED } from "@cosyte/transform";
2393
+ * IG_ALLERGY_VALUE_MAPS_PUBLISHED; // "2025-10-07"
2394
+ * ```
2395
+ */
2396
+ declare const IG_ALLERGY_VALUE_MAPS_PUBLISHED = "2025-10-07";
2397
+ /**
2398
+ * The date the five AL1 allergy ConceptMaps were retrieved and transcribed into the maps below. A
2399
+ * target that surprises a reader is answered by re-reading the guide at this date: each map is a
2400
+ * transcription of a published document at a moment, not a live query.
2401
+ *
2402
+ * @example
2403
+ * ```ts
2404
+ * import { IG_ALLERGY_VALUE_MAPS_RETRIEVED } from "@cosyte/transform";
2405
+ * IG_ALLERGY_VALUE_MAPS_RETRIEVED; // "2026-08-28"
2406
+ * ```
2407
+ */
2408
+ declare const IG_ALLERGY_VALUE_MAPS_RETRIEVED = "2026-08-28";
2409
+ /**
2410
+ * The IG segment map the five AL1 allergy value maps hang off, so a reader can audit any row: it is
2411
+ * the page that names which vocabulary map applies to which AL1 field.
2412
+ *
2413
+ * @example
2414
+ * ```ts
2415
+ * import { IG_ALLERGY_VALUE_MAPS_SOURCE } from "@cosyte/transform";
2416
+ * IG_ALLERGY_VALUE_MAPS_SOURCE.startsWith("https://"); // true
2417
+ * ```
2418
+ */
2419
+ declare const IG_ALLERGY_VALUE_MAPS_SOURCE = "https://hl7.org/fhir/uv/v2mappings/ConceptMap-segment-al1-to-allergyintolerance.html";
2420
+ /**
2421
+ * **AL1-2 Allergen Type to category**: IG `ConceptMap/table-hl70127-to-allergy-intolerance-category`.
2422
+ * One **mapped** group of six rows into the FHIR R4 `AllergyIntoleranceCategory` code system (`DA`
2423
+ * drug to `medication`, `FA` food to `food`, `EA` environmental to `environment`, `AA` animal to
2424
+ * `biologic`, `PA` plant to `environment`, `LA` pollen to `environment`, each `equivalent`, with the
2425
+ * IG target displays), and an `(unmapped)` group of two: **`MA` and `MC` have no category target**.
2426
+ *
2427
+ * The IG applies this map to `AllergyIntolerance.category` **only**; `AllergyIntolerance.type` has
2428
+ * its own map ({@link ALLERGY_TYPE_VALUE_MAP}) over the same source table, and the two are resolved
2429
+ * independently. `MA` therefore yields a type and no category, which is the guide's answer and not a
2430
+ * gap to be filled: a category is never borrowed from the type map or from a neighbouring code.
2431
+ */
2432
+ declare const ALLERGY_CATEGORY_VALUE_MAP: CodedValueMap;
2433
+ /**
2434
+ * **AL1-2 Allergen Type to type**: IG `ConceptMap/table-hl70127-to-allergy-intolerance-type`. One
2435
+ * **mapped** group of seven rows into the FHIR R4 `AllergyIntoleranceType` code system (`DA`, `FA`,
2436
+ * `MA`, `EA`, `AA`, `PA`, `LA` all to `allergy`, each `equivalent`, display `Allergy`), and an
2437
+ * `(unmapped)` group of one: **`MC` miscellaneous contraindication has no type target**.
2438
+ *
2439
+ * Read beside {@link ALLERGY_CATEGORY_VALUE_MAP}: the guide publishes two maps over Table 0127 with
2440
+ * different unmapped sets, so a code can be mapped by one and not the other. `MC` is the only code
2441
+ * neither map carries.
2442
+ */
2443
+ declare const ALLERGY_TYPE_VALUE_MAP: CodedValueMap;
2444
+ /**
2445
+ * **AL1-4 Allergy Severity to criticality**: IG
2446
+ * `ConceptMap/table-hl70128-to-allergy-intolerance-criticality`. One **mapped** group of two rows
2447
+ * into the FHIR R4 `AllergyIntoleranceCriticality` code system (`SV` severe to `high`, `MI` mild to
2448
+ * `low`, both `equivalent`, with the IG target displays), and an `(unmapped)` group of two: **`MO`
2449
+ * moderate and `U` unknown have no criticality target**.
2450
+ *
2451
+ * The unmapped pair is the whole reason this field fails safe. `criticality` is an overall risk
2452
+ * assessment a prescriber acts on, so a moderate severity is left absent and flagged rather than
2453
+ * rounded to `low` or `high`, and `AllergyIntolerance.reaction.severity` is never populated from the
2454
+ * same component instead: the IG offers that only as a local variation, conditioned on a severity
2455
+ * that was **not** used equivalently to criticality, which no v2 message states.
2456
+ */
2457
+ declare const ALLERGY_CRITICALITY_VALUE_MAP: CodedValueMap;
2458
+ /**
2459
+ * **AL1-2 original code**: IG `ConceptMap/table-hl70127-to-v2-0127`. A single **identity** group of
2460
+ * all eight Table 0127 codes (`DA`, `FA`, `MA`, `MC`, `EA`, `AA`, `PA`, `LA` to themselves, each
2461
+ * `equivalent`, source and target both `v2-0127`).
2462
+ *
2463
+ * This is the map behind the `alternate-codes` extension the IG puts on `category`: whatever the
2464
+ * category map does or does not translate, the code the sender actually wrote survives on the
2465
+ * resource in its own code system, so a consumer can always see what the message said.
2466
+ */
2467
+ declare const ALLERGY_ORIGINAL_CATEGORY_VALUE_MAP: CodedValueMap;
2468
+ /**
2469
+ * **AL1-4 original code**: IG `ConceptMap/table-hl70128-original-to-v2-0128`. A single **identity**
2470
+ * group of all four Table 0128 codes (`SV`, `MO`, `MI`, `U` to themselves, each `equivalent`, source
2471
+ * and target both `v2-0128`), the map behind the `alternate-codes` extension on `criticality`.
2472
+ *
2473
+ * Its four codes are a superset of the two {@link ALLERGY_CRITICALITY_VALUE_MAP} translates, which
2474
+ * is the point: a `MO` that yields no criticality still yields the original severity code here.
2475
+ */
2476
+ declare const ALLERGY_ORIGINAL_CRITICALITY_VALUE_MAP: CodedValueMap;
1181
2477
  /**
1182
2478
  * The bound-table target for a coded element's **primary** coding, or `undefined` when the map does
1183
2479
  * not faithfully apply, i.e. the primary declares a coding system that is **not** this map's bound
@@ -1242,6 +2538,308 @@ declare function codeableConceptFromTarget(target: CodedTarget, text?: string):
1242
2538
  */
1243
2539
  declare function toFhirCodeableConceptVia(cwe: CodedElement, map: CodedValueMap, ctx?: TransformContext): ConvertResult<FhirComplex>;
1244
2540
 
2541
+ /**
2542
+ * Writing HL7 v2 field content: the small, safe primitives the reverse (FHIR to v2) maps build on.
2543
+ *
2544
+ * Two disciplines live here.
2545
+ *
2546
+ * **Composite content is structured, never concatenated.** A typed composite (XPN, CX, CWE, XAD) is
2547
+ * handed to `@cosyte/hl7` as a `RawField` of components, so the serializer owns delimiter escaping:
2548
+ * a family name of `Do^e` emits as `Do\S\e` and reads back as `Do^e`, where a hand-built `"Do^e"`
2549
+ * string would have silently become two components. Nothing in this module writes a `^` or a `~`.
2550
+ *
2551
+ * **A lexical form v2 cannot carry is refused, never trimmed to fit.** {@link v2Timestamp} and
2552
+ * {@link v2Number} return `undefined` rather than an approximation, and their callers flag the value
2553
+ * and leave the v2 field absent.
2554
+ *
2555
+ * @packageDocumentation
2556
+ */
2557
+
2558
+ /**
2559
+ * Invert a forward v2-to-FHIR code map, keeping **only** the targets exactly one v2 code maps to.
2560
+ *
2561
+ * This is the bijective-subset rule as code. Where several v2 codes are "equivalent to" one FHIR
2562
+ * concept (Table 0001 `O`/`A`/`N` all map to `other`), the inverse is ambiguous: the target is
2563
+ * dropped here, and its caller flags `TRANSFORM_CODE_NOT_INVERTIBLE` rather than picking one member
2564
+ * of the set.
2565
+ *
2566
+ * @param forward - A v2 code to FHIR code map, as published by the IG ConceptMap.
2567
+ * @example
2568
+ * ```ts
2569
+ * import { invertCodeMap } from "@cosyte/transform";
2570
+ * invertCodeMap({ F: "female", O: "other", A: "other" }); // => { female: "F" }
2571
+ * ```
2572
+ */
2573
+ declare function invertCodeMap(forward: Readonly<Record<string, string>>): Readonly<Record<string, string>>;
2574
+
2575
+ /**
2576
+ * Codes and coding systems on the way out to v2, and the caller-supplied context that resolution
2577
+ * needs.
2578
+ *
2579
+ * A v2 coded field names its vocabulary with a Table 0396 mnemonic (`LN`, `SCT`, `UCUM`), so writing
2580
+ * a FHIR `Coding` into one means turning a canonical system URI back into that mnemonic. There is no
2581
+ * algorithm for that, only a registry, so this module inverts the same seed the forward direction
2582
+ * resolves through ({@link DEFAULT_V2_CODE_SYSTEMS} plus whatever the caller adds) and **refuses
2583
+ * everything else**: an unrecognized system is flagged, never written into a coded field with no
2584
+ * table context and never re-coded into a neighbouring table.
2585
+ *
2586
+ * The inversion keeps only URIs exactly one mnemonic names, for the same reason the code-map
2587
+ * inversion does: two mnemonics for one URI is an ambiguity, not a choice to make silently.
2588
+ *
2589
+ * @packageDocumentation
2590
+ */
2591
+
2592
+ /**
2593
+ * Caller context for a reverse (FHIR to v2) conversion. Every entry is **caller-vetted**: nothing
2594
+ * here is derived from resource content, and omitting all of it is safe (the conversion then flags
2595
+ * what it cannot resolve rather than guessing it).
2596
+ *
2597
+ * @example
2598
+ * ```ts
2599
+ * import { toV2Patient } from "@cosyte/transform";
2600
+ * const options = {
2601
+ * assigningAuthorities: { "urn:oid:1.2.840.114350": "HOSP" },
2602
+ * envelope: { sendingApp: "EHR", sendingFacility: "MAIN" },
2603
+ * };
2604
+ * void options;
2605
+ * void toV2Patient;
2606
+ * ```
2607
+ */
2608
+ interface ReverseOptions {
2609
+ /**
2610
+ * Extra v2 coding-system mnemonic to canonical URI entries, merged over
2611
+ * {@link DEFAULT_V2_CODE_SYSTEMS} and then inverted. Same shape and direction as the forward
2612
+ * registry's seed, so one declaration serves both directions.
2613
+ */
2614
+ readonly codeSystems?: Readonly<Record<string, string>>;
2615
+ /**
2616
+ * `Identifier.system` URI to the v2 assigning-authority namespace (HD.1) that stands for it. There
2617
+ * is no derivation from a URI to a namespace, so an identifier whose system is absent here is
2618
+ * emitted with its value and **no** assigning authority, flagged rather than invented.
2619
+ */
2620
+ readonly assigningAuthorities?: Readonly<Record<string, string>>;
2621
+ /**
2622
+ * MSH envelope fields for the emitted message (sending/receiving application and facility, control
2623
+ * id, timestamp, version, processing id). The message type is never taken from here: it is fixed
2624
+ * by the shape plus the caller's trigger argument.
2625
+ */
2626
+ readonly envelope?: Omit<BuildMessageInit, "type">;
2627
+ }
2628
+
2629
+ /**
2630
+ * The scaffolding every reverse (FHIR to v2) entry point shares: the required trigger, the resource
2631
+ * gate, and the message the mapped segment is carried in.
2632
+ *
2633
+ * **The trigger is always the caller's.** No FHIR resource carries an HL7 v2 message trigger: not
2634
+ * `Patient`, not `Observation`, not `Encounter`. So it is a required argument, and a missing, empty
2635
+ * or non-string one stops the conversion **before** any builder call, with
2636
+ * {@link ISSUE_CODES.TRANSFORM_MISSING_TRIGGER} on the ordinary `{ value, issues }` channel. It is
2637
+ * never defaulted, never derived from resource content, and never substituted with a placeholder.
2638
+ *
2639
+ * **What is emitted is a message, never a bare segment.** A segment on its own is not parseable HL7
2640
+ * (a v2 parser fatally rejects any input whose first segment is not `MSH`), so each shape builds a
2641
+ * complete message through `buildMessage` and appends its mapped segment to it. The trigger is used
2642
+ * verbatim as the trailing component of the fixed message code the shape itself owns.
2643
+ *
2644
+ * **What is missing is declared, not merely missing.** A FHIR resource carrying no source for a v2
2645
+ * field the segment's own attribute table marks *required* leaves that field absent, because the
2646
+ * alternative is inventing content for a clinical reader. Absent is the right wire; **silent** is
2647
+ * not, so each shape names its required fields ({@link ReverseShape.required}) and every one of them
2648
+ * that ends up unsourced raises {@link ISSUE_CODES.TRANSFORM_V2_REQUIRED_FIELD_ABSENT}. When nothing
2649
+ * at all grounded a field, there is no segment to be missing from and no message is built:
2650
+ * {@link ISSUE_CODES.TRANSFORM_NO_V2_MESSAGE_EMITTED} declares that outcome on its own, so an
2651
+ * empty-handed conversion never looks like a successful one.
2652
+ *
2653
+ * @packageDocumentation
2654
+ */
2655
+
2656
+ /**
2657
+ * What a reverse conversion returns: the complete `@cosyte/hl7` message it could faithfully build
2658
+ * (or `undefined` when it could not), plus the value-free diagnostics it raised. The same fail-safe
2659
+ * envelope the forward converters return, in the other direction.
2660
+ *
2661
+ * @example
2662
+ * ```ts
2663
+ * import { toV2Patient } from "@cosyte/transform";
2664
+ * // const { value, issues } = toV2Patient(patientNode, "A28");
2665
+ * // value?.toString() -> "MSH|^~\\&|...|ADT^A28|...\rPID|||MRN1\r"
2666
+ * void toV2Patient;
2667
+ * ```
2668
+ */
2669
+ type ReverseResult = ConvertResult<Hl7Message>;
2670
+
2671
+ /**
2672
+ * FHIR `Patient` to a v2 message carrying a `PID` segment: the inverse of the IG **Segment PID to
2673
+ * Patient** ConceptMap, over the rows whose inverse is defensible.
2674
+ *
2675
+ * | FHIR element | PID field | inverse |
2676
+ * |---|---|---|
2677
+ * | `Patient.identifier` | PID-3 (CX) | value to CX.1, caller-vetted authority to CX.4, Table 0203 type to CX.5 |
2678
+ * | `Patient.name` | PID-5 (XPN) | family/given/prefix/suffix to XPN.1-XPN.5, `use` to XPN.7 where the HL70200 map inverts |
2679
+ * | `Patient.birthDate` | PID-7 (DTM) | lexical date, precision preserved |
2680
+ * | `Patient.gender` | PID-8 | Table 0001 where the map inverts (`female`/`male`/`unknown`) |
2681
+ * | `Patient.address` | PID-11 (XAD) | line/city/state/postalCode/country/district, `use` to XAD.7 where HL70190 inverts |
2682
+ *
2683
+ * **This is the lossy direction, and it says so rather than papering over it.** The published map is
2684
+ * v2 to FHIR; several of its rows are many-to-one, so the inverse is ambiguous and is refused:
2685
+ * `gender` `other` (Table 0001 `O`, `A` and `N` all mean it), name use `official` (`L` and `R`) and
2686
+ * `temp` (`NAV` and `TEMP`), address use `work` (`B` and `O`), and every `Address.type`
2687
+ * (`M` and `SH` both mean `postal`). Each leaves its v2 field absent and raises
2688
+ * {@link ISSUE_CODES.TRANSFORM_CODE_NOT_INVERTIBLE}. Nothing here reconstructs a v2 message that was
2689
+ * transformed to FHIR: it writes what the FHIR resource itself supports, and flags the rest.
2690
+ *
2691
+ * @packageDocumentation
2692
+ */
2693
+
2694
+ /**
2695
+ * FHIR `administrative-gender` to HL7 v2 Table 0001, the invertible rows of the IG's **HL70001 to
2696
+ * Administrative Gender** map. `other` is absent on purpose: three source codes carry it.
2697
+ *
2698
+ * @example
2699
+ * ```ts
2700
+ * import { GENDER_TO_V2 } from "@cosyte/transform";
2701
+ * GENDER_TO_V2["female"]; // => "F"
2702
+ * GENDER_TO_V2["other"]; // => undefined (ambiguous inverse, flagged instead)
2703
+ * ```
2704
+ */
2705
+ declare const GENDER_TO_V2: Readonly<Record<string, string>>;
2706
+ /**
2707
+ * FHIR `name-use` to HL7 v2 Table 0200, the invertible rows of the IG's **HL70200 to name-use** map.
2708
+ * `official` and `temp` are absent on purpose: two source codes each.
2709
+ *
2710
+ * @example
2711
+ * ```ts
2712
+ * import { NAME_USE_TO_V2 } from "@cosyte/transform";
2713
+ * NAME_USE_TO_V2["maiden"]; // => "M"
2714
+ * ```
2715
+ */
2716
+ declare const NAME_USE_TO_V2: Readonly<Record<string, string>>;
2717
+ /**
2718
+ * FHIR `address-use` to HL7 v2 Table 0190, the invertible rows of the IG's **HL70190 to
2719
+ * address-use** map. `work` is absent on purpose (`B` and `O`), as is every `Address.type` row.
2720
+ *
2721
+ * @example
2722
+ * ```ts
2723
+ * import { ADDRESS_USE_TO_V2 } from "@cosyte/transform";
2724
+ * ADDRESS_USE_TO_V2["home"]; // => "H"
2725
+ * ```
2726
+ */
2727
+ declare const ADDRESS_USE_TO_V2: Readonly<Record<string, string>>;
2728
+ /**
2729
+ * Convert a FHIR R4 `Patient` into a **complete** v2 message carrying a `PID` segment, for the
2730
+ * demographics-only trigger events (`A28`, `A31`, `A29`, ...) that carry a patient with no visit.
2731
+ *
2732
+ * The `trigger` argument is **required and never inferred**: no `Patient` element maps to a v2
2733
+ * message trigger, so the caller supplies it, and a missing, empty or non-string one returns
2734
+ * `{ value: undefined }` plus {@link ISSUE_CODES.TRANSFORM_MISSING_TRIGGER} without calling the
2735
+ * message builder at all. It is used verbatim as MSH-9.2 under the `ADT` message code this shape
2736
+ * fixes; the caller never supplies the code and it never varies per call.
2737
+ *
2738
+ * Lossy by design and never round-trip-safe: a value the inverse of the IG map cannot ground is
2739
+ * flagged and left absent, never guessed, and a resource of another type is refused outright.
2740
+ *
2741
+ * A `PID` field v2 requires (PID-3 Patient Identifier List, PID-5 Patient Name) that this resource
2742
+ * gives no source for stays absent and is declared with
2743
+ * {@link ISSUE_CODES.TRANSFORM_V2_REQUIRED_FIELD_ABSENT}: the emitted message is honest about what
2744
+ * it lacks rather than padded to look conformant. A `Patient` that grounds no `PID` field at all
2745
+ * yields no message and {@link ISSUE_CODES.TRANSFORM_NO_V2_MESSAGE_EMITTED}.
2746
+ *
2747
+ * @param resource - The FHIR `Patient` node (build one with `@cosyte/fhir`'s `parseResource`).
2748
+ * @param trigger - The bare v2 trigger, e.g. `"A28"`. Required; never derived from the resource.
2749
+ * @param options - Caller-vetted reverse context: assigning authorities, code systems, MSH envelope.
2750
+ * @example
2751
+ * ```ts
2752
+ * import { parseResource } from "@cosyte/fhir";
2753
+ * import { toV2Patient } from "@cosyte/transform";
2754
+ *
2755
+ * const { resource } = parseResource('{"resourceType":"Patient","gender":"female"}');
2756
+ * const { value, issues } = toV2Patient(resource, "A28");
2757
+ * // value.toString() starts "MSH|^~\\&|" and carries "ADT^A28" in MSH-9, then a PID segment
2758
+ * void value;
2759
+ * void issues;
2760
+ * ```
2761
+ */
2762
+ declare function toV2Patient(resource: FhirNode, trigger: string, options?: ReverseOptions): ReverseResult;
2763
+
2764
+ /**
2765
+ * FHIR `Observation` to a v2 message carrying an `OBX` segment: the inverse of the IG **Segment OBX
2766
+ * to Observation** ConceptMap, over the rows whose inverse is defensible.
2767
+ *
2768
+ * | FHIR element | OBX field | inverse |
2769
+ * |---|---|---|
2770
+ * | `Observation.code` | OBX-3 (CWE) | coding to CWE.1/2/3 (+ one alternate triplet), `text` to CWE.9 |
2771
+ * | `Observation.value[x]` | OBX-2 + OBX-5 | the value type OBX-2 declares is derived from which `value[x]` is present |
2772
+ * | `Observation.valueQuantity` units | OBX-6 (CWE) | UCUM code/display, other systems flagged |
2773
+ * | `Observation.referenceRange.text` | OBX-7 | carried verbatim, never composed from `low`/`high` |
2774
+ * | `Observation.interpretation` | OBX-8 | v3 ObservationInterpretation codes the HL70078 map carries |
2775
+ * | `Observation.status` | OBX-11 | Table 0085 where the map inverts |
2776
+ * | `Observation.effectiveDateTime` | OBX-14 | lexical timestamp, precision preserved |
2777
+ *
2778
+ * **OBX-2 is derived, never assumed.** `valueQuantity` writes `NM` (or `SN` when the quantity
2779
+ * carries a comparator, which is the only OBX-2 type that can hold one), `valueCodeableConcept`
2780
+ * writes `CWE`, `valueString` writes `ST`, `valueDateTime` writes `DTM`. A `value[x]` with no
2781
+ * faithful OBX-5 form (`valueRange`, `valueRatio`, `valueBoolean`, ...) writes **nothing** and is
2782
+ * flagged: emitting the magnitude of a comparator-bearing or ranged value as a bare number would be
2783
+ * a confidently wrong result, which is the one thing this library never does.
2784
+ *
2785
+ * `Observation.subject` and `.encounter` are flagged rather than emitted: this shape's input is an
2786
+ * `Observation` alone, and a PID or PV1 assembled from a bare reference would be fabricated.
2787
+ *
2788
+ * @packageDocumentation
2789
+ */
2790
+
2791
+ /**
2792
+ * FHIR `observation-status` to HL7 v2 Table 0085, the invertible rows of the IG's **HL70085 to
2793
+ * Observation Status** map. `entered-in-error` is absent on purpose (`D` and `W` both carry it), as
2794
+ * are the FHIR statuses the map never targets (`registered`, `unknown`).
2795
+ *
2796
+ * @example
2797
+ * ```ts
2798
+ * import { OBSERVATION_STATUS_TO_V2 } from "@cosyte/transform";
2799
+ * OBSERVATION_STATUS_TO_V2["corrected"]; // => "C"
2800
+ * OBSERVATION_STATUS_TO_V2["entered-in-error"]; // => undefined (ambiguous inverse, flagged instead)
2801
+ * ```
2802
+ */
2803
+ declare const OBSERVATION_STATUS_TO_V2: Readonly<Record<string, string>>;
2804
+ /**
2805
+ * Convert a FHIR R4 `Observation` into a **complete** v2 message carrying an `OBX` segment, in the
2806
+ * result-report (`ORU`) shape.
2807
+ *
2808
+ * The `trigger` argument is **required and never inferred**: no `Observation` element maps to a v2
2809
+ * message trigger, so the caller supplies it, and a missing, empty or non-string one returns
2810
+ * `{ value: undefined }` plus {@link ISSUE_CODES.TRANSFORM_MISSING_TRIGGER} without calling the
2811
+ * message builder at all. It is used verbatim as MSH-9.2 under the `ORU` message code this shape
2812
+ * fixes.
2813
+ *
2814
+ * The message carries the `OBX` alone: this shape's input is an `Observation`, which names no
2815
+ * patient, and a subject segment assembled from a reference would be fabricated. Lossy by design and
2816
+ * never round-trip-safe.
2817
+ *
2818
+ * An `OBX` field v2 requires (OBX-11 Observation Result Status) that this resource gives no source
2819
+ * for stays absent and is declared with {@link ISSUE_CODES.TRANSFORM_V2_REQUIRED_FIELD_ABSENT},
2820
+ * rather than defaulted to `F`: a result reported as final that the sender never called final is the
2821
+ * confidently wrong value this library exists to refuse. An `Observation` that grounds no `OBX`
2822
+ * field at all yields no message and {@link ISSUE_CODES.TRANSFORM_NO_V2_MESSAGE_EMITTED}.
2823
+ *
2824
+ * @param resource - The FHIR `Observation` node.
2825
+ * @param trigger - The bare v2 trigger, e.g. `"R01"`. Required; never derived from the resource.
2826
+ * @param options - Caller-vetted reverse context: code systems and the MSH envelope.
2827
+ * @example
2828
+ * ```ts
2829
+ * import { parseResource } from "@cosyte/fhir";
2830
+ * import { toV2Observation } from "@cosyte/transform";
2831
+ *
2832
+ * const { resource } = parseResource(
2833
+ * '{"resourceType":"Observation","status":"final","code":{"coding":[{"system":"http://loinc.org","code":"789-8"}]}}',
2834
+ * );
2835
+ * const { value, issues } = toV2Observation(resource, "R01");
2836
+ * // value.toString() carries "ORU^R01" in MSH-9, then an OBX whose OBX-3 is "789-8^^LN"
2837
+ * void value;
2838
+ * void issues;
2839
+ * ```
2840
+ */
2841
+ declare function toV2Observation(resource: FhirNode, trigger: string, options?: ReverseOptions): ReverseResult;
2842
+
1245
2843
  /**
1246
2844
  * Public entry point for `@cosyte/transform`: the HL7 v2 → FHIR R4 transformation library.
1247
2845
  *
@@ -1260,8 +2858,15 @@ declare function toFhirCodeableConceptVia(cwe: CodedElement, map: CodedValueMap,
1260
2858
  * all through `toFhir(msg)`), and the **terminology value-translation** layer: a
1261
2859
  * `$translate`-shaped {@link toFhirCodeableConceptVia} engine applying the license-clean IG value
1262
2860
  * ConceptMaps to the previously structural-only coded fields (route/site, appointment type, order
1263
- * priority, substitution). Terminology **depth beyond these maps**, profiles, and the reverse
1264
- * FHIR → v2 direction are not implemented.
2861
+ * priority, substitution).
2862
+ *
2863
+ * It also ships a **narrow reverse path**, FHIR → v2: {@link toV2Patient} and
2864
+ * {@link toV2Observation} emit a complete v2 message carrying a `PID` or an `OBX` built from the
2865
+ * subset of the IG segment maps whose inverse is defensible. Each requires the caller to supply the
2866
+ * v2 trigger, because no FHIR resource carries one. It is **lossy by design and not a round-trip**:
2867
+ * a value the inverse of the IG map cannot ground is flagged and left absent, never guessed.
2868
+ * Terminology **depth beyond these maps**, profiles, and any wider FHIR → v2 conversion are not
2869
+ * implemented.
1265
2870
  *
1266
2871
  * @packageDocumentation
1267
2872
  */
@@ -1282,4 +2887,4 @@ declare function toFhirCodeableConceptVia(cwe: CodedElement, map: CodedValueMap,
1282
2887
  */
1283
2888
  declare const VERSION: string;
1284
2889
 
1285
- export { ADDRESS_TYPE_MAP, ADDRESS_USE_MAP, ADMINISTRATIVE_GENDER_MAP, APPOINTMENT_STATUS_MAP, APPOINTMENT_TYPE_VALUE_MAP, type CodedElement, type CodedTarget, type CodedValueMap, type ConvertResult, DEFAULT_V2_CODE_SYSTEMS, DIAGNOSTIC_REPORT_STATUS_MAP, ENCOUNTER_CLASS_V3_MAP, ENCOUNTER_STATUS_MAP, FATAL_CODES, type FatalCode, HL70078_INTERPRETATION_CODES, IG_MAPPED_ADT_TRIGGERS, IG_MAPPED_APPOINTMENT_TRIGGERS, IG_MAPPED_DOCUMENT_TRIGGERS, IG_MAPPED_IMMUNIZATION_TRIGGERS, IG_MAPPED_ORDER_TRIGGERS, IG_MAPPED_ORU_TRIGGERS, IMMUNIZATION_STATUS_MAP, ISSUE_CODES, ISSUE_REGISTRY, type IssueCode, NAME_USE_MAP, type NamingSystemRegistry, type NamingSystemSeed, OBSERVATION_STATUS_MAP, REQUEST_STATUS_MAP, ROUTE_VALUE_MAP, SERVICE_REQUEST_PRIORITY_MAP, SITE_VALUE_MAP, SUBSTITUTION_VALUE_MAP, TRANSFORM_ISSUE_SYSTEM, type TransformContext, type TransformIssue, type TransformOptions, type TransformResult, type TransformSeverity, V2_0161_SYSTEM, V2_0162_SYSTEM, V2_0203_SYSTEM, V2_0277_SYSTEM, V2_0550_SYSTEM, V3_ROUTE_OF_ADMINISTRATION_SYSTEM, VERSION, codeableConceptFromTarget, createNamingSystem, fhirIssueTypeFor, issue, toFhir, toFhirAddress, toFhirCodeableConcept, toFhirCodeableConceptVia, toFhirDateTime, toFhirHumanName, toFhirIdentifier, toFhirQuantity, toOperationOutcome, translateBound };
2890
+ export { ADDRESS_TYPE_MAP, ADDRESS_USE_MAP, ADDRESS_USE_TO_V2, ADMINISTRATIVE_GENDER_MAP, AL1_ONSET_WITHDRAWN_AT, ALLERGY_CATEGORY_VALUE_MAP, ALLERGY_CLINICAL_STATUS_CODE, ALLERGY_CLINICAL_STATUS_SYSTEM, ALLERGY_CRITICALITY_VALUE_MAP, ALLERGY_INTOLERANCE_CATEGORY_SYSTEM, ALLERGY_INTOLERANCE_CRITICALITY_SYSTEM, ALLERGY_INTOLERANCE_TYPE_SYSTEM, ALLERGY_ORIGINAL_CATEGORY_VALUE_MAP, ALLERGY_ORIGINAL_CRITICALITY_VALUE_MAP, ALLERGY_TYPE_VALUE_MAP, ALTERNATE_CODES_EXTENSION_URL, APPOINTMENT_STATUS_MAP, APPOINTMENT_TYPE_VALUE_MAP, type AllergyBuildOptions, CONDITION_ENTERED_IN_ERROR, CONDITION_VERIFICATION_STATUS_SYSTEM, COVERAGE_STATUS_UNKNOWN, COVERAGE_SUBSCRIBER_ID_EXTENSION_URL, type CodedElement, type CodedTarget, type CodedValueMap, type ConvertResult, DEFAULT_V2_CODE_SYSTEMS, DG1_RETRACTION_ACTION_CODE, DIAGNOSTIC_REPORT_STATUS_MAP, ED_BASE64_ENCODING, ENCOUNTER_CLASS_V3_MAP, ENCOUNTER_STATUS_MAP, type EntityIdentifier, FATAL_CODES, type FatalCode, GENDER_TO_V2, HL70078_INTERPRETATION_CODES, IG_ALLERGY_VALUE_MAPS_PUBLISHED, IG_ALLERGY_VALUE_MAPS_RETRIEVED, IG_ALLERGY_VALUE_MAPS_SOURCE, IG_ALLERGY_VALUE_MAPS_VERSION, IG_MAPPED_ADT_TRIGGERS, IG_MAPPED_APPOINTMENT_TRIGGERS, IG_MAPPED_DOCUMENT_TRIGGERS, IG_MAPPED_IMMUNIZATION_TRIGGERS, IG_MAPPED_ORDER_TRIGGERS, IG_MAPPED_ORU_TRIGGERS, IG_MAPPED_SEGMENT_NAMES, IG_SEGMENT_MAPS_PUBLISHED, IG_SEGMENT_MAPS_RETRIEVED, IG_SEGMENT_MAPS_SOURCE, IG_SEGMENT_MAPS_VERSION, IMMUNIZATION_STATUS_MAP, IN1_SUBSCRIBER_NUMBER_TYPE, ISSUE_CODES, ISSUE_REGISTRY, type IssueCode, NAME_USE_MAP, NAME_USE_TO_V2, type NamingSystemRegistry, type NamingSystemSeed, OBSERVATION_STATUS_MAP, OBSERVATION_STATUS_TO_V2, OBSERVATION_VALUE_ATTACHMENT_EXTENSION_URL, PROCEDURE_STATUS_UNKNOWN, REQUEST_STATUS_MAP, ROUTE_VALUE_MAP, type ReverseOptions, type ReverseResult, SAMPLED_DATA_ABSENT_POINT, SAMPLED_DATA_UNGROUNDED, SEGMENT_IDENTIFIER_SHAPE, SERVICE_REQUEST_PRIORITY_MAP, SITE_VALUE_MAP, SPM_SHIPMENT_IDENTIFIER_TYPE, SUBSTITUTION_VALUE_MAP, type SegmentOccurrence, SegmentReachLedger, TRANSFORM_ISSUE_SYSTEM, type TransformContext, type TransformIssue, type TransformOptions, type TransformResult, type TransformSeverity, V2_0127_SYSTEM, V2_0128_SYSTEM, V2_0161_SYSTEM, V2_0162_SYSTEM, V2_0203_SYSTEM, V2_0277_SYSTEM, V2_0550_SYSTEM, V3_OBSERVATION_INTERPRETATION_SYSTEM, V3_ROUTE_OF_ADMINISTRATION_SYSTEM, VERSION, addMinutes, buildAnnotations, buildCondition, buildCoverage, buildProcedure, buildSpecimen, carriesLegacyOnsetDate, codeableConceptFromTarget, collectAllergies, collectCoverages, collectDiagnoses, collectProcedures, createNamingSystem, deferredCoverageIssues, deferredDiagnosisIssues, deferredProcedureIssues, emitEncounterDiagnosis, enumerateSegmentOccurrences, fhirIssueTypeFor, insuranceCompanyName, invertCodeMap, isIgMappedSegmentName, isWellFormedSegmentName, issue, segmentOccurrenceLocation, toFhir, toFhirAddress, toFhirCodeableConcept, toFhirCodeableConceptVia, toFhirDateTime, toFhirEntityIdentifier, toFhirHumanName, toFhirIdentifier, toFhirQuantity, toOperationOutcome, toV2Observation, toV2Patient, translateBound, withCodeableText, withEncounterDiagnosis };