@cosyte/hl7 0.0.1 → 0.0.3

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.cjs CHANGED
@@ -3,6 +3,12 @@
3
3
  var crypto = require('crypto');
4
4
  var buffer = require('buffer');
5
5
 
6
+ var __defProp = Object.defineProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
6
12
  // src/parser/errors.ts
7
13
  var FATAL_CODES = {
8
14
  NO_MSH_SEGMENT: "NO_MSH_SEGMENT",
@@ -32,7 +38,7 @@ var ProfileDefinitionError = class extends Error {
32
38
  profileName;
33
39
  /**
34
40
  * Construct a new `ProfileDefinitionError`. `profileName` is optional so
35
- * Phase 6 callers may omit it when the offending profile cannot be named
41
+ * callers may omit it when the offending profile cannot be named
36
42
  * (e.g. during initial validation before a name is parsed).
37
43
  *
38
44
  * @internal
@@ -68,7 +74,7 @@ function readDelimiters(firstSegment) {
68
74
  if (firstSegment.length < 3 || firstSegment.slice(0, 3) !== "MSH") {
69
75
  throw new Hl7ParseError(
70
76
  FATAL_CODES.NO_MSH_SEGMENT,
71
- "First segment is not MSH \u2014 HL7 v2 messages must begin with an MSH segment.",
77
+ "First segment is not MSH: HL7 v2 messages must begin with an MSH segment.",
72
78
  fatalPosition,
73
79
  snip
74
80
  );
@@ -76,7 +82,7 @@ function readDelimiters(firstSegment) {
76
82
  if (firstSegment.length < 8) {
77
83
  throw new Hl7ParseError(
78
84
  FATAL_CODES.MSH_TOO_SHORT,
79
- "MSH segment is truncated \u2014 cannot read encoding characters.",
85
+ "MSH segment is truncated: cannot read encoding characters.",
80
86
  fatalPosition,
81
87
  snip
82
88
  );
@@ -85,7 +91,7 @@ function readDelimiters(firstSegment) {
85
91
  if (/\s/u.test(field)) {
86
92
  throw new Hl7ParseError(
87
93
  FATAL_CODES.INVALID_ENCODING_CHARACTERS,
88
- "MSH-1 field separator is whitespace \u2014 refusing to parse.",
94
+ "MSH-1 field separator is whitespace: refusing to parse.",
89
95
  fatalPosition,
90
96
  snip
91
97
  );
@@ -269,7 +275,8 @@ var WARNING_CODES = {
269
275
  ACK_NO_CORRELATION_ID: "ACK_NO_CORRELATION_ID",
270
276
  MERGE_MISSING_PRIOR_OR_SURVIVOR: "MERGE_MISSING_PRIOR_OR_SURVIVOR",
271
277
  BATCH_COUNT_MISMATCH: "BATCH_COUNT_MISMATCH",
272
- BATCH_MISSING_TRAILER: "BATCH_MISSING_TRAILER"
278
+ BATCH_MISSING_TRAILER: "BATCH_MISSING_TRAILER",
279
+ UNTERMINATED_STREAM_MESSAGE: "UNTERMINATED_STREAM_MESSAGE"
273
280
  };
274
281
  function mllpFramingStripped(position) {
275
282
  return {
@@ -347,7 +354,7 @@ function extraFields(position, segmentName2, extraCount) {
347
354
  function unknownSegment(position, segmentName2) {
348
355
  return {
349
356
  code: WARNING_CODES.UNKNOWN_SEGMENT,
350
- message: `Unknown segment "${segmentName2}" \u2014 not in HL7 spec and no profile claim.`,
357
+ message: `Unknown segment "${segmentName2}": not in HL7 spec and no profile claim.`,
351
358
  position
352
359
  };
353
360
  }
@@ -432,7 +439,14 @@ function batchCountMismatch(position, unit, declared, actual) {
432
439
  function batchMissingTrailer(position, header, expectedTrailer) {
433
440
  return {
434
441
  code: WARNING_CODES.BATCH_MISSING_TRAILER,
435
- message: `Batch envelope header "${header}" has no matching "${expectedTrailer}" trailer; splitBatch surfaces this but does not reject \u2014 a profile that mandates the full envelope may.`,
442
+ message: `Batch envelope header "${header}" has no matching "${expectedTrailer}" trailer; splitBatch surfaces this but does not reject: a profile that mandates the full envelope may.`,
443
+ position
444
+ };
445
+ }
446
+ function unterminatedStreamMessage(position) {
447
+ return {
448
+ code: WARNING_CODES.UNTERMINATED_STREAM_MESSAGE,
449
+ message: "The final message in the stream ended without a segment terminator; it is still yielded in full. If the source terminates every segment, this may indicate a truncated feed.",
436
450
  position
437
451
  };
438
452
  }
@@ -588,7 +602,7 @@ var RECOGNIZED_PRESERVED_SET = /* @__PURE__ */ new Set([
588
602
  "H",
589
603
  // begin highlighting (§2.7.1)
590
604
  "N",
591
- // normal text — end highlighting (§2.7.1)
605
+ // normal text: end highlighting (§2.7.1)
592
606
  ".sp",
593
607
  // vertical skip (§2.7.6)
594
608
  ".in",
@@ -775,7 +789,7 @@ function tokenizeComponent(raw, enc, emit, position) {
775
789
  var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
776
790
  // ── ADT (Ch. 3): patient identification (PID) + visit (PV1) are Required
777
791
  // for these admit/transfer/discharge/register/update/cancel events.
778
- // EVN is intentionally excluded — real senders omit it freely, making it
792
+ // EVN is intentionally excluded: real senders omit it freely, making it
779
793
  // a weak (false-positive-prone) signal.
780
794
  Object.freeze({
781
795
  messageCode: "ADT",
@@ -787,7 +801,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
787
801
  }),
788
802
  // ── ORU^R01 (Ch. 7): the OBR/OBX result group is the Required payload.
789
803
  // PID is excluded (the patient-result group's PID is R within the group,
790
- // but a result-only relay can legitimately omit it at the top — keep the
804
+ // but a result-only relay can legitimately omit it at the top: keep the
791
805
  // anchor on the result segments themselves, the true truncation signal).
792
806
  Object.freeze({
793
807
  messageCode: "ORU",
@@ -797,7 +811,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
797
811
  ])
798
812
  }),
799
813
  // ── Orders (Ch. 4): ORC is the Required common-order segment across the
800
- // order message family. OBR is excluded — it is Optional in several of
814
+ // order message family. OBR is excluded: it is Optional in several of
801
815
  // these (OML/OMG/OMI carry it inside an optional observation-request
802
816
  // group), so anchoring only on ORC avoids a false positive.
803
817
  Object.freeze({
@@ -860,7 +874,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
860
874
  Object.freeze({ name: "schedule", anchorSegments: Object.freeze(["SCH"]) })
861
875
  ])
862
876
  }),
863
- // ── MDM (Ch. 9): document management — PID + the TXA document header are
877
+ // ── MDM (Ch. 9): document management: PID + the TXA document header are
864
878
  // Required for T02 (original document) and T06 (document addendum).
865
879
  Object.freeze({
866
880
  messageCode: "MDM",
@@ -870,7 +884,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
870
884
  Object.freeze({ name: "document", anchorSegments: Object.freeze(["TXA"]) })
871
885
  ])
872
886
  }),
873
- // ── DFT^P03 (Ch. 6): financial transaction — PID + at least one FT1
887
+ // ── DFT^P03 (Ch. 6): financial transaction: PID + at least one FT1
874
888
  // financial-transaction segment are Required.
875
889
  Object.freeze({
876
890
  messageCode: "DFT",
@@ -880,7 +894,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
880
894
  Object.freeze({ name: "financial", anchorSegments: Object.freeze(["FT1"]) })
881
895
  ])
882
896
  }),
883
- // ── VXU^V04 (CDC IG): immunization update — PID is Required. RXA is
897
+ // ── VXU^V04 (CDC IG): immunization update: PID is Required. RXA is
884
898
  // excluded: it lives in the Optional order group of the CDC IG, so a
885
899
  // query-shaped VXU with no administered vaccine must not warn.
886
900
  Object.freeze({
@@ -890,7 +904,7 @@ var MESSAGE_STRUCTURE_DEFINITIONS = Object.freeze([
890
904
  Object.freeze({ name: "patient", anchorSegments: Object.freeze(["PID"]) })
891
905
  ])
892
906
  }),
893
- // ── ACK (Ch. 2): a general acknowledgment — MSA (message acknowledgment) is
907
+ // ── ACK (Ch. 2): a general acknowledgment: MSA (message acknowledgment) is
894
908
  // Required. Matched on message code alone (no trigger event in MSH-9.2).
895
909
  Object.freeze({
896
910
  messageCode: "ACK",
@@ -1020,7 +1034,7 @@ function parsePath(path) {
1020
1034
  }
1021
1035
  if (i !== path.length) {
1022
1036
  throw new TypeError(
1023
- `Invalid HL7 dot-path: "${path}" (trailing content at position ${String(i)} \u2014 too deep or malformed).`
1037
+ `Invalid HL7 dot-path: "${path}" (trailing content at position ${String(i)}: too deep or malformed).`
1024
1038
  );
1025
1039
  }
1026
1040
  return freezeDotPath(out);
@@ -1146,6 +1160,127 @@ function emitSegment(seg, enc) {
1146
1160
  return parts.join(enc.field);
1147
1161
  }
1148
1162
 
1163
+ // src/text/render.ts
1164
+ var FORMATTING_RE = /^\.(br|sp|in|ti|fi|nf|ce|sk)[ +]?([+-]?\d+)?$/u;
1165
+ var DEFAULT_TRUNCATION_CHAR2 = "#";
1166
+ var MAX_FORMAT_REPEAT = 100;
1167
+ function normalizeBreaks(s, newline) {
1168
+ return s.replace(/\r\n|\r|\n/gu, newline);
1169
+ }
1170
+ function clampCount(arg) {
1171
+ if (arg === void 0) return 1;
1172
+ const n = Math.trunc(Number(arg));
1173
+ if (!Number.isFinite(n) || n < 1) return 1;
1174
+ return Math.min(n, MAX_FORMAT_REPEAT);
1175
+ }
1176
+ function renderText(input, enc = DEFAULT_ENCODING_CHARACTERS, opts) {
1177
+ const esc = enc.escape;
1178
+ const newline = opts?.newline ?? "\n";
1179
+ const runs = [];
1180
+ const unrendered = [];
1181
+ let highlighted = false;
1182
+ let current = "";
1183
+ const flush = () => {
1184
+ if (current !== "") {
1185
+ runs.push({ text: current, highlighted });
1186
+ current = "";
1187
+ }
1188
+ };
1189
+ let i = 0;
1190
+ const len = input.length;
1191
+ while (i < len) {
1192
+ const ch = input.charAt(i);
1193
+ if (ch === "\r" || ch === "\n") {
1194
+ current += newline;
1195
+ i += ch === "\r" && input.charAt(i + 1) === "\n" ? 2 : 1;
1196
+ continue;
1197
+ }
1198
+ if (ch !== esc) {
1199
+ current += ch;
1200
+ i++;
1201
+ continue;
1202
+ }
1203
+ const close = input.indexOf(esc, i + 1);
1204
+ if (close === -1) {
1205
+ const tail = input.slice(i);
1206
+ current += tail;
1207
+ unrendered.push(tail);
1208
+ break;
1209
+ }
1210
+ const body = input.slice(i + 1, close);
1211
+ const literal = esc + body + esc;
1212
+ if (body === "H") {
1213
+ flush();
1214
+ highlighted = true;
1215
+ } else if (body === "N") {
1216
+ flush();
1217
+ highlighted = false;
1218
+ } else {
1219
+ const decoded = decodeBody(body, enc, newline);
1220
+ if (decoded !== null) {
1221
+ current += decoded;
1222
+ } else {
1223
+ current += literal;
1224
+ unrendered.push(literal);
1225
+ }
1226
+ }
1227
+ i = close + 1;
1228
+ }
1229
+ flush();
1230
+ const text = runs.reduce((acc, r) => acc + r.text, "");
1231
+ return { text, runs, unrenderedSequences: unrendered };
1232
+ }
1233
+ function decodeBody(body, enc, newline) {
1234
+ switch (body) {
1235
+ case "F":
1236
+ return enc.field;
1237
+ case "S":
1238
+ return enc.component;
1239
+ case "T":
1240
+ return enc.subcomponent;
1241
+ case "R":
1242
+ return enc.repetition;
1243
+ case "E":
1244
+ return enc.escape;
1245
+ case "P":
1246
+ return enc.truncation ?? DEFAULT_TRUNCATION_CHAR2;
1247
+ }
1248
+ if (body.charAt(0) === ".") {
1249
+ const m = FORMATTING_RE.exec(body);
1250
+ if (m !== null) return renderFormatting(m[1] ?? "", m[2], newline);
1251
+ return null;
1252
+ }
1253
+ if (body.charAt(0) === "X") {
1254
+ const hex = body.slice(1);
1255
+ if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9A-Fa-f]+$/u.test(hex)) {
1256
+ return null;
1257
+ }
1258
+ let out = "";
1259
+ for (let j = 0; j < hex.length; j += 2) {
1260
+ out += String.fromCharCode(parseInt(hex.slice(j, j + 2), 16));
1261
+ }
1262
+ return normalizeBreaks(out, newline);
1263
+ }
1264
+ return null;
1265
+ }
1266
+ function renderFormatting(cmd, arg, newline) {
1267
+ switch (cmd) {
1268
+ case "br":
1269
+ case "ce":
1270
+ return newline;
1271
+ case "sp":
1272
+ return newline.repeat(clampCount(arg));
1273
+ case "sk":
1274
+ return " ".repeat(clampCount(arg));
1275
+ case "in":
1276
+ case "ti":
1277
+ case "fi":
1278
+ case "nf":
1279
+ default:
1280
+ return "";
1281
+ }
1282
+ }
1283
+
1149
1284
  // src/model/types/_shared.ts
1150
1285
  function readSubcomponent(component, index, _enc) {
1151
1286
  if (component === void 0) return void 0;
@@ -1724,15 +1859,15 @@ function parseXtn(rep, enc) {
1724
1859
  // src/model/field.ts
1725
1860
  var DEFAULT_POSITION = { segmentIndex: 0 };
1726
1861
  var Field = class {
1727
- /** HL7 null indicator — `true` iff the underlying field was the two-char literal `""`. */
1862
+ /** HL7 null indicator: `true` iff the underlying field was the two-char literal `""`. */
1728
1863
  isNull;
1729
1864
  /** Reference to the underlying `RawField.repetitions` (no defensive copy). */
1730
1865
  repetitions;
1731
- /** The 5 encoding characters for this message. Exposed for composite parsers (Plan 04). @internal */
1866
+ /** The 5 encoding characters for this message. Exposed for composite parsers. @internal */
1732
1867
  enc;
1733
- /** Position of this field in the parent message — used for position-aware error messages. @internal */
1868
+ /** Position of this field in the parent message: used for position-aware error messages. @internal */
1734
1869
  position;
1735
- /** The full `RawField` this wrapper wraps. Exposed for composite parsers (Plan 02/03/04). @internal */
1870
+ /** The full `RawField` this wrapper wraps. Exposed for composite parsers. @internal */
1736
1871
  raw;
1737
1872
  /**
1738
1873
  * Construct a new `Field`. Called internally by `Segment.field(n)`; user
@@ -1748,8 +1883,8 @@ var Field = class {
1748
1883
  }
1749
1884
  /**
1750
1885
  * First-repetition, first-component, first-subcomponent value as a decoded
1751
- * string — unescaped ONCE by the tokenizer on parse, returned verbatim here
1752
- * (never re-unescaped, HL7-VALUE-REDECODE). Returns `""` when the field is
1886
+ * string: unescaped ONCE by the tokenizer on parse, returned verbatim here
1887
+ * (never re-unescaped). Returns `""` when the field is
1753
1888
  * empty or HL7 null. Equivalent to `msg.get('SEG.N')` for a top-level access.
1754
1889
  *
1755
1890
  * @example
@@ -1769,18 +1904,18 @@ var Field = class {
1769
1904
  return sub;
1770
1905
  }
1771
1906
  /**
1772
- * The field's **canonical wire text** — the full field re-serialized with
1907
+ * The field's **canonical wire text**: the full field re-serialized with
1773
1908
  * the active delimiters and re-escaped content (repetitions, components,
1774
1909
  * and subcomponents included). Contrast with {@link value}, which
1775
1910
  * returns only the first subcomponent of the first component of the first
1776
- * repetition (decoded once at parse — never re-unescaped).
1911
+ * repetition (decoded once at parse: never re-unescaped).
1777
1912
  *
1778
- * Use this when a field must be compared or echoed as a whole — e.g.
1913
+ * Use this when a field must be compared or echoed as a whole: e.g.
1779
1914
  * correlating an ACK's MSA-2 against the inbound MSH-10, where a
1780
1915
  * vendor-quirk control id containing an unescaped delimiter (`ID^X`) must
1781
1916
  * not be truncated to its first component.
1782
1917
  *
1783
- * **Byte-verbatim for parsed content (HL7-ESC).** The parse pipeline stores
1918
+ * **Byte-verbatim for parsed content.** The parse pipeline stores
1784
1919
  * *decoded* content, but also records the original wire bytes of any escape
1785
1920
  * whose decode is not byte-faithful (`RawComponent.rawSubcomponents`), so
1786
1921
  * re-serialization preserves the sender's exact escape bytes: hex escapes
@@ -1794,7 +1929,7 @@ var Field = class {
1794
1929
  *
1795
1930
  * **MSH-1/MSH-2 caveat.** Like {@link value}, calling this on MSH-1 or
1796
1931
  * MSH-2 (the delimiter-definition fields) re-escapes the encoding
1797
- * characters themselves and produces garbage — those two fields are only
1932
+ * characters themselves and produces garbage: those two fields are only
1798
1933
  * meaningful through `Hl7Message.encodingCharacters`.
1799
1934
  *
1800
1935
  * @example
@@ -1809,12 +1944,33 @@ var Field = class {
1809
1944
  return emitField(this.raw, this.enc);
1810
1945
  }
1811
1946
  /**
1812
- * Return a synthetic empty `Field` sentinel — used by `Segment.field(n)` to
1947
+ * Render this field's formatted text (HL7 v2 §2.7 highlight + formatting
1948
+ * escapes) into a normalized {@link RenderedText} display model: plain text
1949
+ * plus highlight-aware runs. A **read projection** over the field's
1950
+ * byte-verbatim wire {@link text}: it never mutates the raw value, and it
1951
+ * never fabricates (an unrenderable escape is preserved + flagged). Use this
1952
+ * to surface a clinical narrative (an NTE / OBX-5 note) to a human without
1953
+ * the raw `\.br\` / `\H\` sentinels.
1954
+ *
1955
+ * @param opts - see {@link RenderTextOptions} (e.g. a custom line-break string).
1956
+ * @returns the normalized display model.
1957
+ *
1958
+ * @example
1959
+ * ```ts
1960
+ * const note = msg.segments("OBX")[0]?.field(5);
1961
+ * note?.render().text; // "Specimen received.\nGross exam normal."
1962
+ * ```
1963
+ */
1964
+ render(opts) {
1965
+ return renderText(this.text, this.enc, opts);
1966
+ }
1967
+ /**
1968
+ * Return a synthetic empty `Field` sentinel: used by `Segment.field(n)` to
1813
1969
  * honor MODEL-05's "never throws on missing" contract. The returned Field
1814
1970
  * has `isNull === false`, `repetitions === []`, and `value === ""`.
1815
1971
  * Referentially stable across calls (same instance returned each time).
1816
1972
  *
1817
- * The `enc` argument is accepted for API symmetry but ignored — the
1973
+ * The `enc` argument is accepted for API symmetry but ignored: the
1818
1974
  * synthetic field carries no content, so unescape would be a no-op
1819
1975
  * regardless of the active encoding characters.
1820
1976
  *
@@ -1831,7 +1987,7 @@ var Field = class {
1831
1987
  /**
1832
1988
  * Coerce this field's first repetition to a typed `XPN` (Extended Person
1833
1989
  * Name). Absent components are OMITTED from the result
1834
- * (`exactOptionalPropertyTypes`). Not memoized in v1 — each call re-parses
1990
+ * (`exactOptionalPropertyTypes`). Not memoized in v1: each call re-parses
1835
1991
  * (D-09).
1836
1992
  *
1837
1993
  * @example
@@ -1921,7 +2077,7 @@ var Field = class {
1921
2077
  return parsePl(this.repetitions[0] ?? EMPTY_REP, this.enc);
1922
2078
  }
1923
2079
  /**
1924
- * Coerce this field's first repetition to a typed `TS` (Time Stamp) — the
2080
+ * Coerce this field's first repetition to a typed `TS` (Time Stamp): the
1925
2081
  * fidelity `DtmParts` (raw + parts + precision + timezone). `valid` is
1926
2082
  * `false` on unparseable input (no throw). Build an absolute instant only on
1927
2083
  * explicit request via `dtmToDate(ts)`.
@@ -1937,7 +2093,7 @@ var Field = class {
1937
2093
  }
1938
2094
  /**
1939
2095
  * Coerce this field's first repetition to a typed `NM` (Numeric).
1940
- * `{ raw, value }` — `value` is `undefined` on non-numeric input.
2096
+ * `{ raw, value }`: `value` is `undefined` on non-numeric input.
1941
2097
  *
1942
2098
  * @example
1943
2099
  * ```ts
@@ -2007,13 +2163,13 @@ var EMPTY_REP = Object.freeze({
2007
2163
  var Segment = class {
2008
2164
  /** Segment name (3 chars, e.g. `"PID"`, `"OBX"`, `"ZPI"`). */
2009
2165
  type;
2010
- /** Reference to the underlying `RawSegment.fields` — 1-indexed per HL7 convention. */
2166
+ /** Reference to the underlying `RawSegment.fields`: 1-indexed per HL7 convention. */
2011
2167
  fields;
2012
2168
  /** The 5 encoding characters for this message. Exposed for composite parsers. @internal */
2013
2169
  enc;
2014
2170
  /** Absolute index of this segment in `Hl7Message.rawSegments[]`. Used for position tracking. @internal */
2015
2171
  absoluteIndex;
2016
- /** The full `RawSegment` this wrapper wraps. Exposed for mutation methods (Plan 04). @internal */
2172
+ /** The full `RawSegment` this wrapper wraps. Exposed for mutation methods. @internal */
2017
2173
  raw;
2018
2174
  /**
2019
2175
  * Lookup map from profile-declared field name → 1-indexed HL7 position.
@@ -2023,14 +2179,14 @@ var Segment = class {
2023
2179
  * @internal
2024
2180
  */
2025
2181
  customFields;
2026
- /** Lazy cache of Field wrappers — one per fields[] position. @internal */
2182
+ /** Lazy cache of Field wrappers: one per fields[] position. @internal */
2027
2183
  _fieldWrappers;
2028
2184
  /**
2029
2185
  * Construct a new `Segment`. Called internally by `Hl7Message`; user code
2030
2186
  * should obtain `Segment` instances via `msg.segments(type)` or
2031
2187
  * `msg.allSegments()`.
2032
2188
  *
2033
- * The optional `customFields` parameter is the per-segment slice of the
2189
+ * The optional `customFields` parameter is the per-segment portion of the
2034
2190
  * applied profile's merged `customSegments` map (PROF-07 / D-16). When
2035
2191
  * supplied, `get(name)` resolves names against it; otherwise `get(name)`
2036
2192
  * always returns `undefined`.
@@ -2046,16 +2202,16 @@ var Segment = class {
2046
2202
  }
2047
2203
  /**
2048
2204
  * Return the `Field` wrapper at HL7 position `n`. Indexing follows the HL7
2049
- * 1-indexed convention — `seg.field(5)` on a PID segment maps to PID-5.
2205
+ * 1-indexed convention: `seg.field(5)` on a PID segment maps to PID-5.
2050
2206
  * MSH segments use the same user-facing convention: `msh.field(1)` returns
2051
2207
  * the field-separator (MSH-1), `msh.field(2)` returns encoding chars
2052
- * (MSH-2), `msh.field(3)` returns MSH-3, and so on — the internal
2208
+ * (MSH-2), `msh.field(3)` returns MSH-3, and so on: the internal
2053
2209
  * `fields[N-1]` offset for MSH segments is applied here (mirrors the
2054
2210
  * dot-path resolver in `dot-path.ts`, keeping `msg.segments('MSH')[0].field(3)`
2055
2211
  * and `msg.get('MSH.3')` in agreement).
2056
2212
  *
2057
2213
  * Returns a synthetic empty `Field` (`.isNull === false`, `.value === ""`)
2058
- * when `n` is out of range — never throws (MODEL-05). Successive calls with
2214
+ * when `n` is out of range: never throws (MODEL-05). Successive calls with
2059
2215
  * the same `n` return the same `Field` instance (D-12).
2060
2216
  *
2061
2217
  * @example
@@ -2082,13 +2238,13 @@ var Segment = class {
2082
2238
  /**
2083
2239
  * Return the `Field` at the profile-declared position for `name`, or
2084
2240
  * `undefined` when no custom mapping exists (PROF-07). Unlike `field(n)`,
2085
- * missing names return `undefined` — NOT a synthetic empty Field — so
2241
+ * missing names return `undefined`, NOT a synthetic empty Field, so
2086
2242
  * typos surface instead of silently resolving to an empty string (D-14).
2087
2243
  *
2088
2244
  * For segments without a profile-declared customSegments slice (most
2089
2245
  * non-Z segments, and any Z-segment whose host message had no profile
2090
2246
  * applied), this method always returns `undefined` (D-15 defense-in-depth
2091
- * — D-05 already rejects standard-segment overlays at `defineProfile()`
2247
+ *: D-05 already rejects standard-segment overlays at `defineProfile()`
2092
2248
  * time).
2093
2249
  *
2094
2250
  * When the declared position is out of range for the underlying
@@ -3136,8 +3292,8 @@ function buildMeta(msg) {
3136
3292
  const out = {};
3137
3293
  const msh = msg.segments("MSH")[0];
3138
3294
  if (msh !== void 0) {
3139
- const typeField = msh.field(9);
3140
- const firstRep = typeField.repetitions[0];
3295
+ const typeField2 = msh.field(9);
3296
+ const firstRep = typeField2.repetitions[0];
3141
3297
  if (firstRep !== void 0) {
3142
3298
  const parts = [];
3143
3299
  for (let i = 0; i < firstRep.components.length; i++) {
@@ -3456,7 +3612,7 @@ function emitJson(msg) {
3456
3612
  name: seg.name,
3457
3613
  fields: seg.fields.map((field) => ({
3458
3614
  // D-17 + Claude's-Discretion: `repetitions` is ALWAYS `[]` when the
3459
- // field has zero repetitions — shape-stable, no conditional omission.
3615
+ // field has zero repetitions: shape-stable, no conditional omission.
3460
3616
  repetitions: field.repetitions.map((rep) => ({
3461
3617
  components: rep.components.map((comp) => ({
3462
3618
  subcomponents: comp.subcomponents.slice()
@@ -3475,7 +3631,7 @@ function emitJson(msg) {
3475
3631
  },
3476
3632
  segments,
3477
3633
  // D-19: ALWAYS present, even when empty. `msg.warnings` is already frozen
3478
- // at Hl7Message construction (Phase 2) — pass-through is safe.
3634
+ // at Hl7Message construction (Phase 2): pass-through is safe.
3479
3635
  warnings: msg.warnings
3480
3636
  };
3481
3637
  if (msg.profile !== void 0) {
@@ -3516,6 +3672,205 @@ function emitMshSegment(seg, enc) {
3516
3672
  return "MSH" + enc.field + msh2 + enc.field + tail;
3517
3673
  }
3518
3674
 
3675
+ // src/builder/encode-composite.ts
3676
+ function sc(value) {
3677
+ return { subcomponents: [value ?? ""] };
3678
+ }
3679
+ function hdComponent(hd) {
3680
+ if (hd === void 0) return { subcomponents: [] };
3681
+ const subs = [hd.namespaceId ?? "", hd.universalId ?? "", hd.universalIdType ?? ""];
3682
+ while (subs.length > 0 && subs[subs.length - 1] === "") subs.pop();
3683
+ return { subcomponents: subs };
3684
+ }
3685
+ function isEmptyComponent(c) {
3686
+ return c.subcomponents.every((s) => s === "");
3687
+ }
3688
+ function toField(components) {
3689
+ const trimmed = components.slice();
3690
+ while (trimmed.length > 0) {
3691
+ const last = trimmed[trimmed.length - 1];
3692
+ if (last !== void 0 && isEmptyComponent(last)) trimmed.pop();
3693
+ else break;
3694
+ }
3695
+ if (trimmed.length === 0) return { repetitions: [], isNull: false };
3696
+ return { repetitions: [{ components: trimmed }], isNull: false };
3697
+ }
3698
+ function encodeXpn(v) {
3699
+ return toField([
3700
+ sc(v.familyName),
3701
+ sc(v.givenName),
3702
+ sc(v.secondName),
3703
+ sc(v.suffix),
3704
+ sc(v.prefix),
3705
+ sc(v.degree),
3706
+ sc(v.nameTypeCode),
3707
+ sc(v.nameRepresentationCode),
3708
+ sc(v.nameContext),
3709
+ sc(v.nameValidityRange),
3710
+ sc(v.nameAssemblyOrder),
3711
+ sc(v.effectiveDate),
3712
+ sc(v.expirationDate),
3713
+ sc(v.professionalSuffix)
3714
+ ]);
3715
+ }
3716
+ function encodeXad(v) {
3717
+ return toField([
3718
+ sc(v.street),
3719
+ sc(v.otherDesignation),
3720
+ sc(v.city),
3721
+ sc(v.stateOrProvince),
3722
+ sc(v.zipOrPostalCode),
3723
+ sc(v.country),
3724
+ sc(v.addressType),
3725
+ sc(v.otherGeographicDesignation),
3726
+ sc(v.countyParishCode),
3727
+ sc(v.censusTract),
3728
+ sc(v.addressRepresentationCode),
3729
+ sc(v.addressValidityRange)
3730
+ ]);
3731
+ }
3732
+ function encodeCx(v) {
3733
+ return toField([
3734
+ sc(v.idNumber),
3735
+ sc(v.checkDigit),
3736
+ sc(v.checkDigitScheme),
3737
+ hdComponent(v.assigningAuthority),
3738
+ sc(v.identifierTypeCode),
3739
+ sc(v.assigningFacility),
3740
+ sc(v.effectiveDate),
3741
+ sc(v.expirationDate),
3742
+ sc(v.assigningJurisdiction),
3743
+ sc(v.assigningAgencyOrDepartment)
3744
+ ]);
3745
+ }
3746
+ function encodeCwe(v) {
3747
+ const components = [
3748
+ sc(v.identifier),
3749
+ sc(v.text),
3750
+ sc(v.nameOfCodingSystem),
3751
+ sc(v.alternateIdentifier),
3752
+ sc(v.alternateText),
3753
+ sc(v.nameOfAlternateCodingSystem),
3754
+ sc(v.codingSystemVersionId),
3755
+ sc(v.alternateCodingSystemVersionId),
3756
+ sc(v.originalText)
3757
+ ];
3758
+ for (const extra of v.extraComponents ?? []) components.push(sc(extra));
3759
+ return toField(components);
3760
+ }
3761
+ function encodeCe(v) {
3762
+ const components = [
3763
+ sc(v.identifier),
3764
+ sc(v.text),
3765
+ sc(v.nameOfCodingSystem),
3766
+ sc(v.alternateIdentifier),
3767
+ sc(v.alternateText),
3768
+ sc(v.nameOfAlternateCodingSystem)
3769
+ ];
3770
+ for (const extra of v.extraComponents ?? []) components.push(sc(extra));
3771
+ return toField(components);
3772
+ }
3773
+ function encodeXtn(v) {
3774
+ return toField([
3775
+ sc(v.telephoneNumber),
3776
+ sc(v.telecommunicationUseCode),
3777
+ sc(v.telecommunicationEquipmentType),
3778
+ sc(v.emailAddress),
3779
+ sc(v.countryCode),
3780
+ sc(v.areaCityCode),
3781
+ sc(v.localNumber),
3782
+ sc(v.extension),
3783
+ sc(v.anyText),
3784
+ sc(v.extensionPrefix),
3785
+ sc(v.speedDialCode),
3786
+ sc(v.unformattedTelephoneNumber)
3787
+ ]);
3788
+ }
3789
+ function encodePl(v) {
3790
+ return toField([
3791
+ sc(v.pointOfCare),
3792
+ sc(v.room),
3793
+ sc(v.bed),
3794
+ hdComponent(v.facility),
3795
+ sc(v.locationStatus),
3796
+ sc(v.personLocationType),
3797
+ sc(v.building),
3798
+ sc(v.floor),
3799
+ sc(v.locationDescription),
3800
+ sc(v.comprehensiveLocationId),
3801
+ sc(v.assigningAuthorityForLocation)
3802
+ ]);
3803
+ }
3804
+ function encodeHd(v) {
3805
+ return toField([sc(v.namespaceId), sc(v.universalId), sc(v.universalIdType)]);
3806
+ }
3807
+ function encodeTs(v) {
3808
+ const raw = typeof v === "string" ? v : v.raw;
3809
+ return toField([sc(raw)]);
3810
+ }
3811
+ function encodeNm(v) {
3812
+ let raw;
3813
+ if (typeof v === "number") raw = String(v);
3814
+ else if (typeof v === "string") raw = v;
3815
+ else raw = v.raw;
3816
+ return toField([sc(raw)]);
3817
+ }
3818
+ function encodeXcn(v) {
3819
+ return toField([
3820
+ sc(v.idNumber),
3821
+ sc(v.familyName),
3822
+ sc(v.givenName),
3823
+ sc(v.secondName),
3824
+ sc(v.suffix),
3825
+ sc(v.prefix),
3826
+ sc(v.degree),
3827
+ sc(v.sourceTable),
3828
+ hdComponent(v.assigningAuthority),
3829
+ sc(v.nameTypeCode),
3830
+ sc(v.identifierCheckDigit),
3831
+ sc(v.checkDigitScheme),
3832
+ sc(v.identifierTypeCode)
3833
+ ]);
3834
+ }
3835
+ function encodeComposite(kind, value) {
3836
+ switch (kind) {
3837
+ case "XPN":
3838
+ return encodeXpn(value);
3839
+ case "XAD":
3840
+ return encodeXad(value);
3841
+ case "CX":
3842
+ return encodeCx(value);
3843
+ case "CWE":
3844
+ return encodeCwe(value);
3845
+ case "CE":
3846
+ return encodeCe(value);
3847
+ case "XTN":
3848
+ return encodeXtn(value);
3849
+ case "PL":
3850
+ return encodePl(value);
3851
+ case "TS":
3852
+ return encodeTs(value);
3853
+ case "NM":
3854
+ return encodeNm(value);
3855
+ case "HD":
3856
+ return encodeHd(value);
3857
+ case "XCN":
3858
+ return encodeXcn(value);
3859
+ default: {
3860
+ const never = kind;
3861
+ throw new TypeError(`encodeComposite: unknown composite kind ${JSON.stringify(never)}.`);
3862
+ }
3863
+ }
3864
+ }
3865
+ function encodeCompositeReps(kind, values) {
3866
+ const repetitions = [];
3867
+ for (const value of values) {
3868
+ const encoded = encodeComposite(kind, value);
3869
+ for (const rep of encoded.repetitions) repetitions.push(rep);
3870
+ }
3871
+ return { repetitions, isNull: false };
3872
+ }
3873
+
3519
3874
  // src/model/message.ts
3520
3875
  var SEGMENT_NAME_RE2 = /^[A-Z][A-Z0-9]{2}$/u;
3521
3876
  function toMutableArray(arr) {
@@ -3525,9 +3880,8 @@ var Hl7Message = class {
3525
3880
  /**
3526
3881
  * Raw positional tree produced by the parser. 1-indexed per HL7 convention
3527
3882
  * (`fields[0]` is the segment-name / MSH separator placeholder slot). Use
3528
- * `segments(type)` / `allSegments()` for typed wrapper access — this field
3529
- * is exposed for advanced callers that need the raw tree directly (e.g.
3530
- * future serialization phase 5).
3883
+ * `segments(type)` / `allSegments()` for typed wrapper access: this field
3884
+ * is exposed for advanced callers that need the raw tree directly.
3531
3885
  */
3532
3886
  rawSegments;
3533
3887
  encodingCharacters;
@@ -3535,7 +3889,7 @@ var Hl7Message = class {
3535
3889
  warnings;
3536
3890
  profile;
3537
3891
  /**
3538
- * Merged `dateFormats` list — `options.dateFormats ++ profile.dateFormats`
3892
+ * Merged `dateFormats` list: `options.dateFormats ++ profile.dateFormats`
3539
3893
  * deduped first-occurrence per D-21. Empty array when neither source
3540
3894
  * supplied any formats. Exposed publicly so helpers (`msg.meta.timestamp`)
3541
3895
  * and advanced callers can introspect the active cascade.
@@ -3543,7 +3897,7 @@ var Hl7Message = class {
3543
3897
  dateFormats;
3544
3898
  /**
3545
3899
  * Merged `customSegments` map from the applied profile, stored so
3546
- * `allSegments()` can hand per-segment slices to `Segment` constructors
3900
+ * `allSegments()` can hand per-segment portions to `Segment` constructors
3547
3901
  * (D-16). Undefined when no profile was applied.
3548
3902
  * @internal
3549
3903
  */
@@ -3552,40 +3906,40 @@ var Hl7Message = class {
3552
3906
  * Lazily built cache of Segment wrappers keyed by segment type. Built on
3553
3907
  * first `segments(type)` call and filtered from `_allSegments` so
3554
3908
  * individual Segment instances are identical across both caches (D-11).
3555
- * Plan 04 mutation methods drop this cache wholesale.
3909
+ * The mutation methods drop this cache wholesale.
3556
3910
  * @internal
3557
3911
  */
3558
3912
  _segmentsByType;
3559
3913
  /**
3560
3914
  * Lazily built cache of every Segment wrapper in document order. Built on
3561
- * first `segments(type)` / `allSegments()` call. Plan 04 mutation methods
3915
+ * first `segments(type)` / `allSegments()` call. The mutation methods
3562
3916
  * drop this cache wholesale.
3563
3917
  * @internal
3564
3918
  */
3565
3919
  _allSegments;
3566
3920
  /**
3567
- * Lazily built `Meta` view (Phase 4 D-02 memoization). Dropped wholesale
3568
- * by `invalidateCaches`. `Meta` is always defined (D-03 — MSH absence
3921
+ * Lazily built `Meta` view (memoized). Dropped wholesale
3922
+ * by `invalidateCaches`. `Meta` is always defined (D-03: MSH absence
3569
3923
  * throws `NO_MSH_SEGMENT` at parse time) so no null-sentinel is needed.
3570
3924
  * @internal
3571
3925
  */
3572
3926
  _meta;
3573
3927
  /**
3574
- * Lazily built `MessageStructure` view (Phase G). Dropped wholesale by
3575
- * `invalidateCaches`. Always defined — `analyzeMessageStructure` returns an
3928
+ * Lazily built `MessageStructure` view. Dropped wholesale by
3929
+ * `invalidateCaches`. Always defined: `analyzeMessageStructure` returns an
3576
3930
  * `recognized: false` summary for unmodelled types rather than absence.
3577
3931
  * @internal
3578
3932
  */
3579
3933
  _structure;
3580
3934
  /**
3581
- * Lazily built `Patient | undefined` view (Phase 4 D-02 memoization). Uses
3935
+ * Lazily built `Patient | undefined` view (memoized). Uses
3582
3936
  * a null-sentinel cache because `undefined` means "not yet computed" while
3583
3937
  * `null` means "computed, absent". D-04: no PID → public value `undefined`.
3584
3938
  * @internal
3585
3939
  */
3586
3940
  _patient;
3587
3941
  /**
3588
- * Lazily built `Visit | undefined` view (Phase 4 D-02 memoization). Same
3942
+ * Lazily built `Visit | undefined` view (memoized). Same
3589
3943
  * null-sentinel convention as `_patient`. HELPERS-03: no PV1 → public
3590
3944
  * value `undefined`.
3591
3945
  * @internal
@@ -3609,9 +3963,9 @@ var Hl7Message = class {
3609
3963
  }
3610
3964
  /**
3611
3965
  * Resolve a dot-path (e.g. `PID.5.1`, `OBX[2].5`, `PID.3[0].1`) to its
3612
- * decoded leaf string (unescaped once at parse — never re-unescaped on read,
3613
- * HL7-VALUE-REDECODE). Returns `undefined` when the path doesn't
3614
- * resolve — never throws on missing path (MODEL-05). Throws `TypeError`
3966
+ * decoded leaf string (unescaped once at parse: never re-unescaped on
3967
+ * read). Returns `undefined` when the path doesn't
3968
+ * resolve: never throws on missing path (MODEL-05). Throws `TypeError`
3615
3969
  * on malformed path syntax (e.g. `"pid.5"`, empty string).
3616
3970
  *
3617
3971
  * @example
@@ -3620,7 +3974,7 @@ var Hl7Message = class {
3620
3974
  * msg.get("PID.5.1"); // "Smith"
3621
3975
  * msg.get("OBX[2].5"); // third OBX's 5th field
3622
3976
  * msg.get("NOT.9.9"); // undefined
3623
- * msg.get("MSH.12"); // "2.5" — HL7 version string
3977
+ * msg.get("MSH.12"); // "2.5": HL7 version string
3624
3978
  * ```
3625
3979
  */
3626
3980
  get(path) {
@@ -3629,7 +3983,7 @@ var Hl7Message = class {
3629
3983
  /**
3630
3984
  * Return every `Segment` of `segmentType` in document order. Returns `[]`
3631
3985
  * (empty array, NEVER `undefined`) when no segment of that type exists
3632
- * (MODEL-02). Alias for `segments(segmentType)` — shares the same cache.
3986
+ * (MODEL-02). Alias for `segments(segmentType)`: shares the same cache.
3633
3987
  *
3634
3988
  * @example
3635
3989
  * ```ts
@@ -3645,7 +3999,7 @@ var Hl7Message = class {
3645
3999
  * Return the cached array of `Segment` wrappers for `segmentType` in
3646
4000
  * document order. The returned array identity and the individual Segment
3647
4001
  * instances are both stable across calls (D-11). Invalidated wholesale
3648
- * by Plan 04 mutation methods.
4002
+ * by the mutation methods.
3649
4003
  *
3650
4004
  * @example
3651
4005
  * ```ts
@@ -3668,7 +4022,7 @@ var Hl7Message = class {
3668
4022
  * Iterate every `Segment` in document order (MSH first, then every
3669
4023
  * subsequent segment). Cached per-message; same array reference and same
3670
4024
  * Segment instances on repeat calls (D-11). Invalidated wholesale by
3671
- * Plan 04 mutation methods.
4025
+ * the mutation methods.
3672
4026
  *
3673
4027
  * @example
3674
4028
  * ```ts
@@ -3695,14 +4049,14 @@ var Hl7Message = class {
3695
4049
  }
3696
4050
  /**
3697
4051
  * MSH-derived message metadata (type, controlId, timestamp, version, etc.).
3698
- * D-01: plain object. D-02: memoized — `msg.meta === msg.meta` across
4052
+ * D-01: plain object. D-02: memoized: `msg.meta === msg.meta` across
3699
4053
  * reads until mutation invalidates. D-03: always defined (MSH absence
3700
4054
  * throws `NO_MSH_SEGMENT` at parse time).
3701
4055
  *
3702
4056
  * @example
3703
4057
  * ```ts
3704
4058
  * console.log(msg.meta.type); // "ADT^A01"
3705
- * console.log(msg.meta.timestamp?.raw); // fidelity TS (Phase N)
4059
+ * console.log(msg.meta.timestamp?.raw); // fidelity TS
3706
4060
  * console.log(msg.meta.controlId); // "MSG001"
3707
4061
  * ```
3708
4062
  */
@@ -3710,11 +4064,11 @@ var Hl7Message = class {
3710
4064
  return this._meta ??= buildMeta(this);
3711
4065
  }
3712
4066
  /**
3713
- * Structural-conformance summary for the common message types (roadmap
3714
- * Phase G) — a misroute/truncation safety net, NOT a conformance validator.
4067
+ * Structural-conformance summary for the common message types: a
4068
+ * misroute/truncation safety net, NOT a conformance validator.
3715
4069
  * Reports, per the message's recognized (MSH-9.1, MSH-9.2) type, which
3716
4070
  * Required segment groups are present and which are entirely absent
3717
- * (`missingGroups` — the same set the parser flags as
4071
+ * (`missingGroups`: the same set the parser flags as
3718
4072
  * `MISSING_EXPECTED_GROUP` warnings). For an unmodelled type, `recognized`
3719
4073
  * is `false` and `missingGroups` is empty. D-02: memoized.
3720
4074
  *
@@ -3729,14 +4083,14 @@ var Hl7Message = class {
3729
4083
  }
3730
4084
  /**
3731
4085
  * PID-derived patient view, or `undefined` when no PID segment exists
3732
- * (D-04). D-02: memoized. HELPERS-07: never throws — absent fields
4086
+ * (D-04). D-02: memoized. HELPERS-07: never throws: absent fields
3733
4087
  * surface as `undefined` on the returned `Patient` object.
3734
4088
  *
3735
4089
  * @example
3736
4090
  * ```ts
3737
4091
  * console.log(msg.patient?.mrn);
3738
4092
  * console.log(msg.patient?.fullName);
3739
- * console.log(msg.patient?.dateOfBirth?.raw); // fidelity TS — e.g. "19800115"
4093
+ * console.log(msg.patient?.dateOfBirth?.raw); // fidelity TS: e.g. "19800115"
3740
4094
  * ```
3741
4095
  */
3742
4096
  get patient() {
@@ -3764,7 +4118,7 @@ var Hl7Message = class {
3764
4118
  }
3765
4119
  /**
3766
4120
  * Every OBX segment as a typed Observation in document order. D-05:
3767
- * returns `[]` when no OBX present. D-06: NOT memoized — each call
4121
+ * returns `[]` when no OBX present. D-06: NOT memoized: each call
3768
4122
  * re-walks `rawSegments`. Value type is discriminated per D-13.
3769
4123
  *
3770
4124
  * @example
@@ -3779,7 +4133,7 @@ var Hl7Message = class {
3779
4133
  }
3780
4134
  /**
3781
4135
  * Every OBR as an Order with its OBX children grouped positionally (D-12) and
3782
- * its TQ1 / legacy embedded-TQ (ORC-7) `timings` (Phase M — the repeat pattern
4136
+ * its TQ1 / legacy embedded-TQ (ORC-7) `timings` (the repeat pattern is
3783
4137
  * surfaced verbatim, never resolved to a schedule). D-05: returns `[]` when no
3784
4138
  * OBR present. D-06: not memoized.
3785
4139
  *
@@ -3787,7 +4141,7 @@ var Hl7Message = class {
3787
4141
  * ```ts
3788
4142
  * for (const order of msg.orders()) {
3789
4143
  * console.log(order.placerOrderNumber, order.observations.length);
3790
- * for (const t of order.timings) console.log(t.repeatPattern?.code); // e.g. "Q6H" — verbatim
4144
+ * for (const t of order.timings) console.log(t.repeatPattern?.code); // e.g. "Q6H": verbatim
3791
4145
  * }
3792
4146
  * ```
3793
4147
  */
@@ -3795,11 +4149,11 @@ var Hl7Message = class {
3795
4149
  return orders(this);
3796
4150
  }
3797
4151
  /**
3798
- * Message-level NTE notes (Phase P) — every NTE segment with no recognized
4152
+ * Message-level NTE notes: every NTE segment with no recognized
3799
4153
  * preceding parent (not immediately following a `PID`, `ORC`, `OBR`, or
3800
4154
  * `OBX`), surfaced verbatim in document order so nothing is dropped. Notes
3801
4155
  * that DO attach to a specific patient / order / result are exposed on those
3802
- * helper outputs (`msg.patient?.notes`, `order.notes`, `observation.notes`) —
4156
+ * helper outputs (`msg.patient?.notes`, `order.notes`, `observation.notes`),
3803
4157
  * not here. D-05: returns `[]` when there are none. D-06: NOT memoized.
3804
4158
  *
3805
4159
  * @example
@@ -3812,7 +4166,7 @@ var Hl7Message = class {
3812
4166
  }
3813
4167
  /**
3814
4168
  * Every recognized ADT patient-identity event (merge / move / link /
3815
- * unlink / person add/update — roadmap Phase K), with the MRG-sourced
4169
+ * unlink / person add/update), with the MRG-sourced
3816
4170
  * `prior` and PID/PV1-sourced `surviving` parties labelled by role and the
3817
4171
  * spec-constant `direction: "MRG_TO_PID"` on merge/move events. Returns
3818
4172
  * `[]` when the trigger event is not in the identity family. D-06: not
@@ -3833,13 +4187,13 @@ var Hl7Message = class {
3833
4187
  }
3834
4188
  /**
3835
4189
  * Every RXO/RXE/RXD/RXA as a typed `Medication`, with RXR (route) and RXC
3836
- * (component) segments grouped positionally under their parent (Phase D,
3837
- * P0 safety). D-05: returns `[]` when no RX* parent present. D-06: not
3838
- * memoized. The give *amount* and give *strength* are surfaced separately
3839
- * and never reconciled (Phase D §4).
4190
+ * (component) segments grouped positionally under their parent. D-05:
4191
+ * returns `[]` when no RX* parent present. D-06: not memoized. The give
4192
+ * *amount* and give *strength* are surfaced separately and never
4193
+ * reconciled.
3840
4194
  *
3841
4195
  * Each medication also carries its TQ1 / legacy embedded-TQ (RXE-1) `timings`
3842
- * (Phase M — repeat pattern verbatim, never resolved to a schedule).
4196
+ * (repeat pattern verbatim, never resolved to a schedule).
3843
4197
  *
3844
4198
  * @example
3845
4199
  * ```ts
@@ -3856,11 +4210,11 @@ var Hl7Message = class {
3856
4210
  /**
3857
4211
  * Every RXA of a VXU^V04 as a typed `Immunization`, with RXR (route/site)
3858
4212
  * and OBX children grouped positionally under the RXA and `orderControl`
3859
- * from the preceding ORC of the VXU order group (Phase E, P0 safety). D-05:
4213
+ * from the preceding ORC of the VXU order group. D-05:
3860
4214
  * returns `[]` when no RXA present. D-06: not memoized. The vaccine code
3861
4215
  * carries its own provenance; the action code (RXA-21) is surfaced verbatim
3862
4216
  * and `recordOrigin` (administered vs historical) is derived only from the
3863
- * well-known NIP001 RXA-9.1 codes — never guessed.
4217
+ * well-known NIP001 RXA-9.1 codes: never guessed.
3864
4218
  *
3865
4219
  * @example
3866
4220
  * ```ts
@@ -3924,13 +4278,13 @@ var Hl7Message = class {
3924
4278
  return insurance(this);
3925
4279
  }
3926
4280
  /**
3927
- * Every SCH of an SIU message as a typed `Appointment` (roadmap Phase Q), with
4281
+ * Every SCH of an SIU message as a typed `Appointment`, with
3928
4282
  * the AIS/AIG/AIL/AIP resource segments that follow it grouped positionally
3929
4283
  * under that SCH. Surfaces the placer/filler appointment ids, SCH-25 filler
3930
4284
  * status (Table 0278), SCH-11 start/end timing, and the resource groups
3931
4285
  * (service / general / location / personnel). D-05: returns `[]` when no SCH
3932
4286
  * is present. D-06: not memoized. Never throws (HELPERS-07). Not a
3933
- * scheduling-workflow state machine — see the package known-limitations.
4287
+ * scheduling-workflow state machine: see the package known-limitations.
3934
4288
  *
3935
4289
  * @example
3936
4290
  * ```ts
@@ -3944,10 +4298,10 @@ var Hl7Message = class {
3944
4298
  return appointments(this);
3945
4299
  }
3946
4300
  /**
3947
- * Every TXA of an MDM message as a typed `ClinicalDocument` (roadmap Phase Q),
4301
+ * Every TXA of an MDM message as a typed `ClinicalDocument`,
3948
4302
  * with the OBX narrative body grouped positionally under that TXA. The
3949
4303
  * completion status (TXA-17) and availability status (TXA-19) are surfaced as
3950
- * **distinct** fields and never conflated — a document can be available before
4304
+ * **distinct** fields and never conflated: a document can be available before
3951
4305
  * it is authenticated, and reading a preliminary document as final is the
3952
4306
  * harm. D-05: returns `[]` when no TXA is present. D-06: not memoized. Never
3953
4307
  * throws (HELPERS-07).
@@ -3964,10 +4318,10 @@ var Hl7Message = class {
3964
4318
  return documents(this);
3965
4319
  }
3966
4320
  /**
3967
- * Every FT1 of a DFT message as a typed `Charge` (roadmap Phase Q), one per
4321
+ * Every FT1 of a DFT message as a typed `Charge`, one per
3968
4322
  * FT1 in document order. Surfaces billing-critical fields (FT1-6 transaction
3969
4323
  * type, FT1-7 code, FT1-11/12 extended/unit amount, FT1-19 diagnosis linkage)
3970
- * with **no billing logic and no money-as-float** — amounts are the verbatim
4324
+ * with **no billing logic and no money-as-float**: amounts are the verbatim
3971
4325
  * CP wire text. D-05: returns `[]` when no FT1 is present. D-06: not memoized.
3972
4326
  * Never throws (HELPERS-07).
3973
4327
  *
@@ -3988,7 +4342,7 @@ var Hl7Message = class {
3988
4342
  * D-05; MSH-1 and MSH-2 are inlined verbatim from
3989
4343
  * `this.encodingCharacters` per D-06; every field string passes through
3990
4344
  * `reescape` per D-04. `RawField.isNull === true` is preserved as the
3991
- * HL7 literal `""` (D-02). Pure — never warns, never throws (D-07).
4345
+ * HL7 literal `""` (D-02). Pure: never warns, never throws (D-07).
3992
4346
  *
3993
4347
  * @example
3994
4348
  * ```ts
@@ -4006,7 +4360,7 @@ var Hl7Message = class {
4006
4360
  * Re-walks `rawSegments` on every call (D-30 no caching). Mirrors the
4007
4361
  * raw tree one-for-one, preserves `isNull`, always includes
4008
4362
  * `warnings: []`, and includes `profile: { name, lineage }` only when
4009
- * `this.profile` is truthy (D-19/D-20). Pure — never warns, never throws.
4363
+ * `this.profile` is truthy (D-19/D-20). Pure: never warns, never throws.
4010
4364
  *
4011
4365
  * @example
4012
4366
  * ```ts
@@ -4025,16 +4379,16 @@ var Hl7Message = class {
4025
4379
  * debugging (SER-04). Single opinionated format (D-22 no options):
4026
4380
  * header line with type / controlId / timestamp / segment count, then
4027
4381
  * one line per segment with labeled `[N]=value` fields (D-23). Composite
4028
- * values render as their raw HL7 string — depth stops at field level
4029
- * (D-24). Pure — never warns, never throws (D-26).
4382
+ * values render as their raw HL7 string: depth stops at field level
4383
+ * (D-24). Pure: never warns, never throws (D-26).
4030
4384
  *
4031
4385
  * **Field values render as their raw HL7 string representation.**
4032
- * Embedded delimiters in user data appear as escape sequences — e.g.
4386
+ * Embedded delimiters in user data appear as escape sequences: e.g.
4033
4387
  * a patient family name containing `|` renders as `Smith\F\Jones`
4034
4388
  * (NOT `Smith|Jones`). This preserves round-trip fidelity: copy-pasting
4035
4389
  * prettyPrint output into `parseHL7` yields a structurally equivalent
4036
4390
  * message. For un-escaped human display, parse the composite first via
4037
- * typed accessors (e.g. `msg.patient?.familyName`) — those return
4391
+ * typed accessors (e.g. `msg.patient?.familyName`): those return
4038
4392
  * already-decoded strings.
4039
4393
  *
4040
4394
  * @example
@@ -4054,13 +4408,13 @@ var Hl7Message = class {
4054
4408
  * Set the string value at a dot-path. Mutates the underlying tree and
4055
4409
  * returns `this` for chaining (D-15). Auto-creates missing repetitions,
4056
4410
  * components, and subcomponents WITHIN an existing field, but does NOT
4057
- * auto-create segments — callers must `addSegment` first (throws
4411
+ * auto-create segments: callers must `addSegment` first (throws
4058
4412
  * `TypeError` with an actionable message otherwise).
4059
4413
  *
4060
4414
  * The value is accepted verbatim: unescaped delimiter characters are NOT
4061
- * rejected on input (D-18). Re-escaping on serialize is Phase 5's concern.
4415
+ * rejected on input (D-18). Re-escaping is the serializer's concern.
4062
4416
  *
4063
- * MSH-1 / MSH-2 follow the user-facing HL7 convention — `setField("MSH.3", ...)`
4417
+ * MSH-1 / MSH-2 follow the user-facing HL7 convention: `setField("MSH.3", ...)`
4064
4418
  * targets MSH-3 (sending application), matching `msg.get("MSH.3")`.
4065
4419
  *
4066
4420
  * Segment/Field wrapper caches are invalidated wholesale on success (D-17).
@@ -4097,7 +4451,7 @@ var Hl7Message = class {
4097
4451
  const mutSegments = toMutableArray(this.rawSegments);
4098
4452
  const seg = mutSegments[segIdx];
4099
4453
  if (seg === void 0) {
4100
- throw new Error("setField: internal invariant \u2014 segment disappeared after lookup.");
4454
+ throw new Error("setField: internal invariant, segment disappeared after lookup.");
4101
4455
  }
4102
4456
  const mutFields = toMutableArray(seg.fields);
4103
4457
  while (mutFields.length <= rawFieldIndex) {
@@ -4105,7 +4459,7 @@ var Hl7Message = class {
4105
4459
  }
4106
4460
  const field = mutFields[rawFieldIndex];
4107
4461
  if (field === void 0) {
4108
- throw new Error("setField: internal invariant \u2014 field missing after growth.");
4462
+ throw new Error("setField: internal invariant, field missing after growth.");
4109
4463
  }
4110
4464
  const mutReps = toMutableArray(field.repetitions);
4111
4465
  const repIdx = parsed.repetitionIndex ?? 0;
@@ -4114,7 +4468,7 @@ var Hl7Message = class {
4114
4468
  }
4115
4469
  const rep = mutReps[repIdx];
4116
4470
  if (rep === void 0) {
4117
- throw new Error("setField: internal invariant \u2014 repetition missing after growth.");
4471
+ throw new Error("setField: internal invariant, repetition missing after growth.");
4118
4472
  }
4119
4473
  const mutComps = toMutableArray(rep.components);
4120
4474
  const compIdx = (parsed.componentIndex ?? 1) - 1;
@@ -4123,7 +4477,7 @@ var Hl7Message = class {
4123
4477
  }
4124
4478
  const comp = mutComps[compIdx];
4125
4479
  if (comp === void 0) {
4126
- throw new Error("setField: internal invariant \u2014 component missing after growth.");
4480
+ throw new Error("setField: internal invariant, component missing after growth.");
4127
4481
  }
4128
4482
  const mutSubs = toMutableArray(comp.subcomponents);
4129
4483
  const subIdx = (parsed.subcomponentIndex ?? 1) - 1;
@@ -4143,9 +4497,95 @@ var Hl7Message = class {
4143
4497
  this.invalidateCaches();
4144
4498
  return this;
4145
4499
  }
4500
+ /**
4501
+ * Set a **typed composite** at a field (or field-repetition) dot-path:
4502
+ * the conservative-emit mirror of the typed read accessors
4503
+ * (`asXpn`/`asCx`/…). The caller passes a structured value (an XPN name, a CX
4504
+ * identifier, a TS timestamp, …) by its {@link CompositeKind}, and the setter
4505
+ * encodes it into a spec-clean field using the encode-safe path: any
4506
+ * delimiter embedded in a component value is **escaped, never injected**, so
4507
+ * a `familyName` of `"Smith^Jr"` re-parses to exactly that string rather than
4508
+ * forging a component boundary. No hand-assembly of `^`/`&`/`~`.
4509
+ *
4510
+ * The path must resolve to a **field** (`"PID.5"`) or a specific
4511
+ * **repetition** of a field (`"PID.11[1]"`). A component/subcomponent-level
4512
+ * path (`"PID.5.1"`) is rejected with `TypeError`: a composite occupies a
4513
+ * whole field, not a single component. Like {@link setField}, the target
4514
+ * segment must already exist (`addSegment` first); the repetition defaults to
4515
+ * index 0 and other repetitions of the field are preserved.
4516
+ *
4517
+ * Never fabricates: an omitted optional composite field encodes to an
4518
+ * empty/absent component, never a defaulted value; an all-empty composite
4519
+ * clears the field. Segment/helper caches are invalidated on success; the
4520
+ * frozen `warnings` array is untouched.
4521
+ *
4522
+ * @example
4523
+ * ```ts
4524
+ * const msg = buildMessage({ type: "ADT^A01" }).addSegment("PID", [""]);
4525
+ * msg.setComposite("PID.5", "XPN", { familyName: "Smith", givenName: "Ann" });
4526
+ * msg.setComposite("PID.3", "CX", { idNumber: "MRN001", identifierTypeCode: "MR" });
4527
+ * msg.setComposite("PID.7", "TS", "19880705");
4528
+ * msg.get("PID.5.1"); // "Smith"
4529
+ * ```
4530
+ */
4531
+ setComposite(path, kind, value) {
4532
+ const parsed = parsePath(path);
4533
+ if (parsed.componentIndex !== void 0 || parsed.subcomponentIndex !== void 0) {
4534
+ throw new TypeError(
4535
+ `setComposite: path "${path}" targets a component/subcomponent, but a typed composite occupies a whole field. Use a field path (e.g. "PID.5") or a field-repetition path (e.g. "PID.11[1]").`
4536
+ );
4537
+ }
4538
+ let seen = 0;
4539
+ let segIdx = -1;
4540
+ for (let i = 0; i < this.rawSegments.length; i++) {
4541
+ const s = this.rawSegments[i];
4542
+ if (s === void 0) continue;
4543
+ if (s.name === parsed.segmentType) {
4544
+ if (seen === parsed.segmentIndex) {
4545
+ segIdx = i;
4546
+ break;
4547
+ }
4548
+ seen++;
4549
+ }
4550
+ }
4551
+ if (segIdx === -1) {
4552
+ throw new TypeError(
4553
+ `setComposite: segment "${parsed.segmentType}" (occurrence ${String(parsed.segmentIndex)}) not found. Add it first with addSegment("${parsed.segmentType}", [...]).`
4554
+ );
4555
+ }
4556
+ const encoded = encodeComposite(kind, value);
4557
+ const encodedRep = encoded.repetitions[0] ?? { components: [] };
4558
+ const rawFieldIndex = parsed.segmentType === "MSH" ? parsed.fieldIndex - 1 : parsed.fieldIndex;
4559
+ const mutSegments = toMutableArray(this.rawSegments);
4560
+ const seg = mutSegments[segIdx];
4561
+ if (seg === void 0) {
4562
+ throw new Error("setComposite: internal invariant, segment disappeared after lookup.");
4563
+ }
4564
+ const mutFields = toMutableArray(seg.fields);
4565
+ while (mutFields.length <= rawFieldIndex) {
4566
+ mutFields.push({ repetitions: [], isNull: false });
4567
+ }
4568
+ const field = mutFields[rawFieldIndex];
4569
+ if (field === void 0) {
4570
+ throw new Error("setComposite: internal invariant, field missing after growth.");
4571
+ }
4572
+ const mutReps = toMutableArray(field.repetitions);
4573
+ const repIdx = parsed.repetitionIndex ?? 0;
4574
+ while (mutReps.length <= repIdx) {
4575
+ mutReps.push({ components: [] });
4576
+ }
4577
+ mutReps[repIdx] = encodedRep;
4578
+ const newField = { repetitions: mutReps, isNull: false };
4579
+ mutFields[rawFieldIndex] = newField;
4580
+ const newSeg = { name: seg.name, fields: mutFields };
4581
+ mutSegments[segIdx] = newSeg;
4582
+ this.rawSegments = mutSegments;
4583
+ this.invalidateCaches();
4584
+ return this;
4585
+ }
4146
4586
  /**
4147
4587
  * Append a new segment to the end of the message. `name` must match
4148
- * `/^(?:[A-Z]{3}|Z[A-Z0-9]{2})$/u` — throws `TypeError` otherwise (D-19).
4588
+ * `/^(?:[A-Z]{3}|Z[A-Z0-9]{2})$/u`: throws `TypeError` otherwise (D-19).
4149
4589
  *
4150
4590
  * `fields` is interpreted in HL7 1-indexed terms: `addSegment("NTE", [a, b, c])`
4151
4591
  * produces a segment whose `NTE-1 = a`, `NTE-2 = b`, `NTE-3 = c`. The
@@ -4195,14 +4635,14 @@ var Hl7Message = class {
4195
4635
  /**
4196
4636
  * Remove segments by type + occurrence or by type + all. Call shapes:
4197
4637
  *
4198
- * - `removeSegment("NTE")` — remove the FIRST NTE (occurrence 0).
4199
- * - `removeSegment("OBX", 1)` — remove the SECOND OBX (0-indexed per D-01).
4200
- * - `removeSegment("OBX", { all: true })` — remove ALL OBX segments.
4638
+ * - `removeSegment("NTE")`: remove the FIRST NTE (occurrence 0).
4639
+ * - `removeSegment("OBX", 1)`: remove the SECOND OBX (0-indexed per D-01).
4640
+ * - `removeSegment("OBX", { all: true })`: remove ALL OBX segments.
4201
4641
  *
4202
- * `MSH` is protected — `removeSegment("MSH")` throws `TypeError` (every
4642
+ * `MSH` is protected: `removeSegment("MSH")` throws `TypeError` (every
4203
4643
  * HL7 message must retain its MSH segment). Unknown segment types are a
4204
4644
  * no-op (idempotent; no throw). Segment name must match the D-19 shape
4205
- * regex — invalid shapes throw `TypeError` for symmetry with `addSegment`.
4645
+ * regex: invalid shapes throw `TypeError` for symmetry with `addSegment`.
4206
4646
  *
4207
4647
  * Invalidates caches on return; warnings untouched (D-16).
4208
4648
  *
@@ -4253,8 +4693,8 @@ var Hl7Message = class {
4253
4693
  return this;
4254
4694
  }
4255
4695
  /**
4256
- * Drop every wrapper AND helper cache wholesale (Phase 3 D-17 + Phase 4
4257
- * D-02). Called by every mutation method so subsequent `segments(type)` /
4696
+ * Drop every wrapper AND helper cache wholesale (D-17 + D-02). Called by
4697
+ * every mutation method so subsequent `segments(type)` /
4258
4698
  * `allSegments()` / `meta` / `patient` / `visit` reads rebuild from the
4259
4699
  * mutated `rawSegments` tree.
4260
4700
  * @internal
@@ -4380,9 +4820,9 @@ function extractVersion(msh) {
4380
4820
  }
4381
4821
  function extractMessageType(msh) {
4382
4822
  if (msh === void 0 || msh.name !== "MSH") return { messageCode: "", triggerEvent: "" };
4383
- const typeField = msh.fields[8];
4384
- if (typeField === void 0) return { messageCode: "", triggerEvent: "" };
4385
- const firstRep = typeField.repetitions[0];
4823
+ const typeField2 = msh.fields[8];
4824
+ if (typeField2 === void 0) return { messageCode: "", triggerEvent: "" };
4825
+ const firstRep = typeField2.repetitions[0];
4386
4826
  if (firstRep === void 0) return { messageCode: "", triggerEvent: "" };
4387
4827
  const messageCode = firstRep.components[0]?.subcomponents[0] ?? "";
4388
4828
  const triggerEvent = firstRep.components[1]?.subcomponents[0] ?? "";
@@ -4514,6 +4954,24 @@ function parseHL7(raw, optionsOrProfile) {
4514
4954
  return new Hl7Message(init);
4515
4955
  }
4516
4956
 
4957
+ // src/text/codec.ts
4958
+ function ignore() {
4959
+ }
4960
+ function decodeText(input, enc = DEFAULT_ENCODING_CHARACTERS) {
4961
+ return unescape(input, enc, ignore, { segmentIndex: 0 });
4962
+ }
4963
+ function encodeText(input, enc = DEFAULT_ENCODING_CHARACTERS) {
4964
+ return reescape(input, enc);
4965
+ }
4966
+
4967
+ // src/text/index.ts
4968
+ var text_exports = {};
4969
+ __export(text_exports, {
4970
+ decode: () => decodeText,
4971
+ encode: () => encodeText,
4972
+ render: () => renderText
4973
+ });
4974
+
4517
4975
  // src/model/types/namespace.ts
4518
4976
  var namespace_exports = {};
4519
4977
  var ALNUM_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
@@ -4629,6 +5087,247 @@ function compositeField(typeString) {
4629
5087
  };
4630
5088
  }
4631
5089
 
5090
+ // src/builder/segment-fields.ts
5091
+ function scalarField2(value) {
5092
+ if (value === void 0 || value === "") return { repetitions: [], isNull: false };
5093
+ return { repetitions: [{ components: [{ subcomponents: [value] }] }], isNull: false };
5094
+ }
5095
+ function absentField2() {
5096
+ return { repetitions: [], isNull: false };
5097
+ }
5098
+ function typeField(typeString) {
5099
+ const components = typeString.split("^").map((p) => ({ subcomponents: [p] }));
5100
+ return { repetitions: [{ components }], isNull: false };
5101
+ }
5102
+ function resolveTimestamp2(ts) {
5103
+ if (ts === void 0) return formatHl7Timestamp(/* @__PURE__ */ new Date());
5104
+ if (typeof ts === "string") return ts;
5105
+ return formatHl7Timestamp(ts);
5106
+ }
5107
+ function buildMshSegment(type, envelope) {
5108
+ const enc = DEFAULT_ENCODING_CHARACTERS;
5109
+ const fields = [
5110
+ scalarField2(enc.field),
5111
+ // fields[0] MSH-1 field separator placeholder
5112
+ scalarField2(
5113
+ enc.component + enc.repetition + enc.escape + enc.subcomponent + (enc.truncation ?? "")
5114
+ ),
5115
+ // MSH-2 encoding characters
5116
+ scalarField2(envelope.sendingApp),
5117
+ // MSH-3
5118
+ scalarField2(envelope.sendingFacility),
5119
+ // MSH-4
5120
+ scalarField2(envelope.receivingApp),
5121
+ // MSH-5
5122
+ scalarField2(envelope.receivingFacility),
5123
+ // MSH-6
5124
+ scalarField2(resolveTimestamp2(envelope.timestamp)),
5125
+ // MSH-7
5126
+ absentField2(),
5127
+ // MSH-8
5128
+ typeField(type),
5129
+ // MSH-9
5130
+ scalarField2(envelope.controlId ?? generateControlId()),
5131
+ // MSH-10
5132
+ scalarField2(envelope.processingId ?? "P"),
5133
+ // MSH-11
5134
+ scalarField2(envelope.version ?? "2.5")
5135
+ // MSH-12
5136
+ ];
5137
+ return { name: "MSH", fields };
5138
+ }
5139
+ function assembleSegment(name, positions) {
5140
+ let max = 0;
5141
+ for (const [pos, field] of positions) {
5142
+ if (field !== void 0 && pos > max) max = pos;
5143
+ }
5144
+ const fields = [absentField2()];
5145
+ for (let i = 1; i <= max; i++) {
5146
+ fields.push(positions.get(i) ?? absentField2());
5147
+ }
5148
+ return { name, fields };
5149
+ }
5150
+
5151
+ // src/builder/build-adt.ts
5152
+ function repField(kind, value) {
5153
+ if (value === void 0) return { repetitions: [], isNull: false };
5154
+ if (Array.isArray(value)) {
5155
+ return encodeCompositeReps(kind, value);
5156
+ }
5157
+ return encodeComposite(kind, value);
5158
+ }
5159
+ function buildAdt(event, init) {
5160
+ if (typeof event !== "string" || event.trim().length === 0) {
5161
+ throw new TypeError(
5162
+ `buildAdt: \`event\` (the ADT trigger, e.g. "A01") is required and must be a non-empty string. Received: ${JSON.stringify(event)}.`
5163
+ );
5164
+ }
5165
+ if (init === null || init === void 0 || init.patient === void 0) {
5166
+ throw new TypeError(
5167
+ "buildAdt: `patient` is required. An ADT patient event is never emitted with a fabricated patient. Supply at least one identifier or a name."
5168
+ );
5169
+ }
5170
+ const enc = DEFAULT_ENCODING_CHARACTERS;
5171
+ const version = init.version ?? "2.5";
5172
+ const segments = [buildMshSegment(`ADT^${event}`, init)];
5173
+ const evn = init.event;
5174
+ segments.push(
5175
+ assembleSegment(
5176
+ "EVN",
5177
+ /* @__PURE__ */ new Map([
5178
+ [1, scalarField2(event)],
5179
+ [
5180
+ 2,
5181
+ evn?.recordedDateTime !== void 0 ? encodeComposite("TS", evn.recordedDateTime) : void 0
5182
+ ],
5183
+ [
5184
+ 6,
5185
+ evn?.eventOccurred !== void 0 ? encodeComposite("TS", evn.eventOccurred) : void 0
5186
+ ]
5187
+ ])
5188
+ )
5189
+ );
5190
+ const p = init.patient;
5191
+ segments.push(
5192
+ assembleSegment(
5193
+ "PID",
5194
+ /* @__PURE__ */ new Map([
5195
+ [1, p.setId !== void 0 ? scalarField2(p.setId) : void 0],
5196
+ [3, p.identifiers !== void 0 ? repField("CX", p.identifiers) : void 0],
5197
+ [5, p.name !== void 0 ? repField("XPN", p.name) : void 0],
5198
+ [
5199
+ 6,
5200
+ p.mothersMaidenName !== void 0 ? encodeComposite("XPN", p.mothersMaidenName) : void 0
5201
+ ],
5202
+ [7, p.birthDateTime !== void 0 ? encodeComposite("TS", p.birthDateTime) : void 0],
5203
+ [8, p.administrativeSex !== void 0 ? scalarField2(p.administrativeSex) : void 0],
5204
+ [11, p.address !== void 0 ? repField("XAD", p.address) : void 0],
5205
+ [13, p.phoneHome !== void 0 ? repField("XTN", p.phoneHome) : void 0],
5206
+ [18, p.accountNumber !== void 0 ? encodeComposite("CX", p.accountNumber) : void 0]
5207
+ ])
5208
+ )
5209
+ );
5210
+ const v = init.visit;
5211
+ segments.push(
5212
+ assembleSegment(
5213
+ "PV1",
5214
+ /* @__PURE__ */ new Map([
5215
+ [1, v?.setId !== void 0 ? scalarField2(v.setId) : void 0],
5216
+ [2, v?.patientClass !== void 0 ? scalarField2(v.patientClass) : void 0],
5217
+ [
5218
+ 3,
5219
+ v?.assignedLocation !== void 0 ? encodeComposite("PL", v.assignedLocation) : void 0
5220
+ ],
5221
+ [7, v?.attendingDoctor !== void 0 ? repField("XCN", v.attendingDoctor) : void 0],
5222
+ [8, v?.referringDoctor !== void 0 ? repField("XCN", v.referringDoctor) : void 0],
5223
+ [19, v?.visitNumber !== void 0 ? encodeComposite("CX", v.visitNumber) : void 0],
5224
+ [44, v?.admitDateTime !== void 0 ? encodeComposite("TS", v.admitDateTime) : void 0]
5225
+ ])
5226
+ )
5227
+ );
5228
+ return new Hl7Message({
5229
+ segments,
5230
+ encodingCharacters: enc,
5231
+ version,
5232
+ warnings: []
5233
+ });
5234
+ }
5235
+
5236
+ // src/builder/build-oru.ts
5237
+ function repField2(kind, value) {
5238
+ if (value === void 0) return { repetitions: [], isNull: false };
5239
+ if (Array.isArray(value)) {
5240
+ return encodeCompositeReps(kind, value);
5241
+ }
5242
+ return encodeComposite(kind, value);
5243
+ }
5244
+ function buildOru(init) {
5245
+ if (init === null || init === void 0 || init.patient === void 0) {
5246
+ throw new TypeError(
5247
+ "buildOru: `patient` is required. An ORU is never emitted with a fabricated subject."
5248
+ );
5249
+ }
5250
+ if (init.observations === void 0 || init.observations.length === 0) {
5251
+ throw new TypeError(
5252
+ "buildOru: at least one `observations` entry (OBX) is required. An ORU with no result is a typed error, never a fabricated observation."
5253
+ );
5254
+ }
5255
+ const enc = DEFAULT_ENCODING_CHARACTERS;
5256
+ const version = init.version ?? "2.5";
5257
+ const segments = [buildMshSegment("ORU^R01", init)];
5258
+ const p = init.patient;
5259
+ segments.push(
5260
+ assembleSegment(
5261
+ "PID",
5262
+ /* @__PURE__ */ new Map([
5263
+ [1, p.setId !== void 0 ? scalarField2(p.setId) : void 0],
5264
+ [3, p.identifiers !== void 0 ? repField2("CX", p.identifiers) : void 0],
5265
+ [5, p.name !== void 0 ? repField2("XPN", p.name) : void 0],
5266
+ [
5267
+ 6,
5268
+ p.mothersMaidenName !== void 0 ? encodeComposite("XPN", p.mothersMaidenName) : void 0
5269
+ ],
5270
+ [7, p.birthDateTime !== void 0 ? encodeComposite("TS", p.birthDateTime) : void 0],
5271
+ [8, p.administrativeSex !== void 0 ? scalarField2(p.administrativeSex) : void 0],
5272
+ [11, p.address !== void 0 ? repField2("XAD", p.address) : void 0],
5273
+ [13, p.phoneHome !== void 0 ? repField2("XTN", p.phoneHome) : void 0],
5274
+ [18, p.accountNumber !== void 0 ? encodeComposite("CX", p.accountNumber) : void 0]
5275
+ ])
5276
+ )
5277
+ );
5278
+ const o = init.order;
5279
+ segments.push(
5280
+ assembleSegment(
5281
+ "OBR",
5282
+ /* @__PURE__ */ new Map([
5283
+ [1, o?.setId !== void 0 ? scalarField2(o.setId) : void 0],
5284
+ [2, o?.placerOrderNumber !== void 0 ? scalarField2(o.placerOrderNumber) : void 0],
5285
+ [3, o?.fillerOrderNumber !== void 0 ? scalarField2(o.fillerOrderNumber) : void 0],
5286
+ [
5287
+ 4,
5288
+ o?.universalServiceId !== void 0 ? encodeComposite("CWE", o.universalServiceId) : void 0
5289
+ ],
5290
+ [
5291
+ 7,
5292
+ o?.observationDateTime !== void 0 ? encodeComposite("TS", o.observationDateTime) : void 0
5293
+ ],
5294
+ [16, o?.orderingProvider !== void 0 ? repField2("XCN", o.orderingProvider) : void 0],
5295
+ [25, o?.resultStatus !== void 0 ? scalarField2(o.resultStatus) : void 0]
5296
+ ])
5297
+ )
5298
+ );
5299
+ for (const obs of init.observations) {
5300
+ segments.push(
5301
+ assembleSegment(
5302
+ "OBX",
5303
+ /* @__PURE__ */ new Map([
5304
+ [1, obs.setId !== void 0 ? scalarField2(obs.setId) : void 0],
5305
+ [2, obs.valueType !== void 0 ? scalarField2(obs.valueType) : void 0],
5306
+ [3, obs.identifier !== void 0 ? encodeComposite("CWE", obs.identifier) : void 0],
5307
+ [5, obs.value !== void 0 ? scalarField2(obs.value) : void 0],
5308
+ [6, obs.units !== void 0 ? encodeComposite("CWE", obs.units) : void 0],
5309
+ [7, obs.referenceRange !== void 0 ? scalarField2(obs.referenceRange) : void 0],
5310
+ [8, obs.abnormalFlags !== void 0 ? scalarField2(obs.abnormalFlags) : void 0],
5311
+ [
5312
+ 11,
5313
+ obs.observationResultStatus !== void 0 ? scalarField2(obs.observationResultStatus) : void 0
5314
+ ],
5315
+ [
5316
+ 14,
5317
+ obs.observationDateTime !== void 0 ? encodeComposite("TS", obs.observationDateTime) : void 0
5318
+ ]
5319
+ ])
5320
+ )
5321
+ );
5322
+ }
5323
+ return new Hl7Message({
5324
+ segments,
5325
+ encodingCharacters: enc,
5326
+ version,
5327
+ warnings: []
5328
+ });
5329
+ }
5330
+
4632
5331
  // src/builder/ack-tables.ts
4633
5332
  var ACK_CODES = {
4634
5333
  AA: "AA",
@@ -4711,7 +5410,7 @@ function buildAck(inbound, options) {
4711
5410
  const enc = DEFAULT_ENCODING_CHARACTERS;
4712
5411
  const meta = inbound.meta;
4713
5412
  const msh = inbound.segments("MSH")[0];
4714
- const inboundMsh = (n) => msh?.field(n).raw ?? absentField2();
5413
+ const inboundMsh = (n) => msh?.field(n).raw ?? absentField3();
4715
5414
  const sameEnc = encodingsEqual(inbound.encodingCharacters, enc);
4716
5415
  const rawControlId = sameEnc ? inboundMsh(10) : stripEscapeOverlay(inboundMsh(10));
4717
5416
  const hasCorrelation = rawFieldHasContent(rawControlId);
@@ -4720,8 +5419,8 @@ function buildAck(inbound, options) {
4720
5419
  const version = meta.version ?? "2.5";
4721
5420
  const processingId = meta.processingId ?? "P";
4722
5421
  const mshFields = [
4723
- scalarField2(enc.field),
4724
- scalarField2(
5422
+ scalarField3(enc.field),
5423
+ scalarField3(
4725
5424
  enc.component + enc.repetition + enc.escape + enc.subcomponent + (enc.truncation ?? "")
4726
5425
  ),
4727
5426
  inboundMsh(5),
@@ -4732,26 +5431,26 @@ function buildAck(inbound, options) {
4732
5431
  // MSH-5 receivingApp = inbound MSH-3 (sendingApp)
4733
5432
  inboundMsh(4),
4734
5433
  // MSH-6 receivingFacility = inbound MSH-4 (sendingFacility)
4735
- scalarField2(formatHl7Timestamp(/* @__PURE__ */ new Date())),
5434
+ scalarField3(formatHl7Timestamp(/* @__PURE__ */ new Date())),
4736
5435
  // MSH-7
4737
- absentField2(),
5436
+ absentField3(),
4738
5437
  // MSH-8
4739
5438
  compositeField2(ackType),
4740
5439
  // MSH-9
4741
- scalarField2(generateControlId()),
5440
+ scalarField3(generateControlId()),
4742
5441
  // MSH-10
4743
- scalarField2(processingId),
5442
+ scalarField3(processingId),
4744
5443
  // MSH-11
4745
- scalarField2(version)
5444
+ scalarField3(version)
4746
5445
  // MSH-12
4747
5446
  ];
4748
5447
  const segments = [{ name: "MSH", fields: mshFields }];
4749
5448
  segments.push({
4750
5449
  name: "MSA",
4751
5450
  fields: [
4752
- absentField2(),
4753
- scalarField2(emittedCode),
4754
- hasCorrelation ? rawControlId : absentField2()
5451
+ absentField3(),
5452
+ scalarField3(emittedCode),
5453
+ hasCorrelation ? rawControlId : absentField3()
4755
5454
  ]
4756
5455
  });
4757
5456
  for (const detail of normalizeErrors(options.error)) {
@@ -4791,24 +5490,24 @@ function buildErrSegment(detail) {
4791
5490
  return {
4792
5491
  name: "ERR",
4793
5492
  fields: [
4794
- absentField2(),
4795
- // fields[0] — segment-name/separator placeholder slot
4796
- absentField2(),
5493
+ absentField3(),
5494
+ // fields[0]: segment-name/separator placeholder slot
5495
+ absentField3(),
4797
5496
  // ERR-1 (deprecated v2.4 / withdrawn v2.7)
4798
- detail.location !== void 0 ? compositeField2(detail.location) : absentField2(),
5497
+ detail.location !== void 0 ? compositeField2(detail.location) : absentField3(),
4799
5498
  // ERR-2 (ERL)
4800
5499
  err3,
4801
5500
  // ERR-3
4802
- scalarField2(severity)
5501
+ scalarField3(severity)
4803
5502
  // ERR-4
4804
5503
  ]
4805
5504
  };
4806
5505
  }
4807
- function scalarField2(value) {
5506
+ function scalarField3(value) {
4808
5507
  if (value === "") return { repetitions: [], isNull: false };
4809
5508
  return { repetitions: [{ components: [{ subcomponents: [value] }] }], isNull: false };
4810
5509
  }
4811
- function absentField2() {
5510
+ function absentField3() {
4812
5511
  return { repetitions: [], isNull: false };
4813
5512
  }
4814
5513
  function encodingsEqual(a, b) {
@@ -5068,7 +5767,7 @@ function validateCustomSegments(map, profileName) {
5068
5767
  for (const key of Object.keys(map)) {
5069
5768
  if (!Z_SEGMENT_RE.test(key)) {
5070
5769
  throw new ProfileDefinitionError(
5071
- `Profile '${profileName}' declares customSegments for '${key}' \u2014 only Z-segments (Z[A-Z0-9]{2}) are allowed in v1. Typed overlays are a v2 feature.`,
5770
+ `Profile '${profileName}' declares customSegments for '${key}': only Z-segments (Z[A-Z0-9]{2}) are allowed in v1. Typed overlays are a v2 feature.`,
5072
5771
  profileName
5073
5772
  );
5074
5773
  }
@@ -5095,7 +5794,7 @@ function validateDateFormats(formats, profileName) {
5095
5794
  const f = formats[i] ?? "";
5096
5795
  if (!TOKEN_MATCH_RE.test(f)) {
5097
5796
  throw new ProfileDefinitionError(
5098
- `Profile '${profileName}' dateFormats[${String(i)}] = ${JSON.stringify(f)} is malformed \u2014 must contain at least one of ${SUPPORTED_DATE_TOKENS.join("/")}.`,
5797
+ `Profile '${profileName}' dateFormats[${String(i)}] = ${JSON.stringify(f)} is malformed: must contain at least one of ${SUPPORTED_DATE_TOKENS.join("/")}.`,
5099
5798
  profileName
5100
5799
  );
5101
5800
  }
@@ -5153,7 +5852,7 @@ function defineProfile(opts) {
5153
5852
  // src/profiles/athena.ts
5154
5853
  var athena = defineProfile({
5155
5854
  name: "athena",
5156
- description: "athenahealth Interop \u2014 US-short-date format and care-team Z-segment",
5855
+ description: "athenahealth Interop: US-short-date format and care-team Z-segment",
5157
5856
  dateFormats: ["MM/DD/YYYY"],
5158
5857
  customSegments: {
5159
5858
  ZCA: { fields: { careTeamRole: 3, providerId: 5, providerName: 6 } }
@@ -5163,7 +5862,7 @@ var athena = defineProfile({
5163
5862
  // src/profiles/cerner.ts
5164
5863
  var cerner = defineProfile({
5165
5864
  name: "cerner",
5166
- description: "Cerner Millennium \u2014 ISO-style timestamps and common Z-segments",
5865
+ description: "Cerner Millennium: ISO-style timestamps and common Z-segments",
5167
5866
  dateFormats: ["YYYY-MM-DDTHH:mm:ss", "YYYY-MM-DD"],
5168
5867
  customSegments: {
5169
5868
  ZDS: { fields: { summaryText: 3 } },
@@ -5174,7 +5873,7 @@ var cerner = defineProfile({
5174
5873
  // src/profiles/epic.ts
5175
5874
  var epic = defineProfile({
5176
5875
  name: "epic",
5177
- description: "Epic Bridges Interconnect \u2014 ADT-style date formats and common Z-segments",
5876
+ description: "Epic Bridges Interconnect: ADT-style date formats and common Z-segments",
5178
5877
  dateFormats: ["MM/DD/YYYY HH:mm:ss", "MM/DD/YYYY"],
5179
5878
  customSegments: {
5180
5879
  ZDP: { fields: { departmentCode: 3, departmentName: 4 } },
@@ -5185,7 +5884,7 @@ var epic = defineProfile({
5185
5884
  // src/profiles/genericLab.ts
5186
5885
  var genericLab = defineProfile({
5187
5886
  name: "genericLab",
5188
- description: "Generic reference-laboratory \u2014 ASTM-era + ISO-date formats + lab Z-segments",
5887
+ description: "Generic reference-laboratory: ASTM-era + ISO-date formats + lab Z-segments",
5189
5888
  dateFormats: ["YYYYMMDD HHmm", "YYYY-MM-DD"],
5190
5889
  customSegments: {
5191
5890
  ZLB: { fields: { specimenOverride: 3, methodOverride: 5 } },
@@ -5196,10 +5895,122 @@ var genericLab = defineProfile({
5196
5895
  // src/profiles/meditech.ts
5197
5896
  var meditech = defineProfile({
5198
5897
  name: "meditech",
5199
- description: "Meditech MAGIC/Expanse \u2014 minute-precision timestamps and visit-info Z-segment",
5898
+ description: "MEDITECH MAGIC/6.x/Expanse: minute-precision timestamps and DFT charge Z-segments (ZF1/ZF2)",
5200
5899
  dateFormats: ["YYYYMMDDHHmm"],
5201
5900
  customSegments: {
5202
- ZVI: { fields: { visitReason: 3, admitSource: 5 } }
5901
+ ZF1: {
5902
+ fields: {
5903
+ providerEncounter: 1,
5904
+ misServiceGroup: 2,
5905
+ serviceGroupCopay: 3,
5906
+ visitCopay: 4,
5907
+ copayMinimum: 5,
5908
+ copayMaximum: 6
5909
+ }
5910
+ },
5911
+ ZF2: {
5912
+ fields: {
5913
+ setId: 1,
5914
+ providerEncounter: 2,
5915
+ encounterDate: 3,
5916
+ encounterProcedure: 4,
5917
+ encounterProcedureQuantity: 5,
5918
+ encounterProcedureCharge: 6,
5919
+ prvProcedureAmountPaid: 7,
5920
+ prvProcedureAmountDue: 8
5921
+ }
5922
+ }
5923
+ }
5924
+ });
5925
+
5926
+ // src/profiles/philips.ts
5927
+ var philips = defineProfile({
5928
+ name: "philips",
5929
+ description: "Philips Vue PACS (IS Link) imaging: ZDS/ZLK/ZAO/ZEB/ZAP/ZAV order/patient/visit-filler Z-segments",
5930
+ customSegments: {
5931
+ // §5.11 ZDS: Order Filler: DICOM Study Instance UID (RP, comp 1).
5932
+ ZDS: { fields: { studyInstanceUid: 1 } },
5933
+ // §5.12 ZLK: Order Filler: study/order linking ids.
5934
+ ZLK: { fields: { externalWorkitemId: 1, orderLinkId: 2 } },
5935
+ // §5.13 ZAO: Order Filler: order additional details (note: no field 7).
5936
+ ZAO: {
5937
+ fields: {
5938
+ orderAdditionalDetails: 1,
5939
+ orderWithNoImages: 2,
5940
+ modality: 3,
5941
+ bodyPart: 4,
5942
+ resultTransferStatus: 5,
5943
+ departmentId: 6,
5944
+ device: 8,
5945
+ section: 9,
5946
+ orderCustomString1: 10,
5947
+ orderCustomString2: 11,
5948
+ orderCustomString3: 12,
5949
+ orderCustomString4: 13,
5950
+ orderCustomString5: 14,
5951
+ orderCustomString6: 15,
5952
+ orderCustomString7: 16,
5953
+ orderCustomNumber1: 17,
5954
+ orderCustomNumber2: 18,
5955
+ orderCustomDate1: 19,
5956
+ orderCustomDate2: 20,
5957
+ orderCustomDate3: 21,
5958
+ technicianFamilyName: 22,
5959
+ technicianGivenName: 23,
5960
+ technicianMiddleName: 24,
5961
+ technicianId: 25,
5962
+ radiologistFamilyName: 26,
5963
+ radiologistGivenName: 27,
5964
+ radiologistMiddleName: 28,
5965
+ radiologistId: 29,
5966
+ orderCreatedBy: 30,
5967
+ orderUpdatedBy: 31,
5968
+ acquisitionStatus: 32
5969
+ }
5970
+ },
5971
+ // §5.14 ZEB: Patient Filler: encrypted patient-info blob (PHI-bearing).
5972
+ ZEB: { fields: { encryptedPatientInfo: 1 } },
5973
+ // §5.15 ZAP: Patient Filler: patient additional details (note: no field 2).
5974
+ ZAP: {
5975
+ fields: {
5976
+ patientAdditionalDetails: 1,
5977
+ patientCustomString1: 3,
5978
+ patientCustomString2: 4,
5979
+ patientCustomString3: 5,
5980
+ patientCustomString4: 6,
5981
+ patientCustomString5: 7,
5982
+ patientCustomString6: 8,
5983
+ patientCustomString7: 9,
5984
+ patientCustomNumber1: 10,
5985
+ patientCustomNumber2: 11,
5986
+ patientCustomDate1: 12,
5987
+ patientCustomDate2: 13,
5988
+ patientCustomDate3: 14
5989
+ }
5990
+ },
5991
+ // §5.16 ZAV: Visit Filler: visit additional details.
5992
+ ZAV: { fields: { visitAdditionalDetails: 1 } }
5993
+ }
5994
+ });
5995
+
5996
+ // src/profiles/va.ts
5997
+ var va = defineProfile({
5998
+ name: "va",
5999
+ description: "VA VistA Radiology/Nuclear Medicine imaging: ZDS DICOM Study Instance UID segment (ORM + ORU, IHE RAD)",
6000
+ customSegments: {
6001
+ // ZDS-1 = Study Instance UID (RP), UID in the first component (1.1 Pointer).
6002
+ // VA Radiology/Nuclear Medicine 5.0 HL7 IS v3.6 (June 2024): "ZDS Segment
6003
+ // Fields in ORU and ORM".
6004
+ ZDS: { fields: { studyInstanceUid: 1 } }
6005
+ }
6006
+ });
6007
+
6008
+ // src/profiles/visage.ts
6009
+ var visage = defineProfile({
6010
+ name: "visage",
6011
+ description: "Visage 7 imaging/PACS: ZDS DICOM Study Instance UID segment (IHE RAD)",
6012
+ customSegments: {
6013
+ ZDS: { fields: { studyInstanceUid: 1 } }
5203
6014
  }
5204
6015
  });
5205
6016
 
@@ -5209,7 +6020,10 @@ var profiles = Object.freeze({
5209
6020
  cerner,
5210
6021
  epic,
5211
6022
  genericLab,
5212
- meditech
6023
+ meditech,
6024
+ philips,
6025
+ va,
6026
+ visage
5213
6027
  });
5214
6028
 
5215
6029
  // src/model/coding-system.ts
@@ -5441,8 +6255,560 @@ function splitBatch(raw, optionsOrProfile) {
5441
6255
  return Object.freeze(result);
5442
6256
  }
5443
6257
 
6258
+ // src/conformance/types.ts
6259
+ var USAGE_CODES = Object.freeze(["R", "RE", "C", "CE", "O", "X"]);
6260
+ var FINDING_CODES = {
6261
+ /** A Required (`R`) segment or field is absent (or present-but-empty). */
6262
+ PROFILE_REQUIRED_ABSENT: "PROFILE_REQUIRED_ABSENT",
6263
+ /** A Not-permitted (`X`) segment or field is present. */
6264
+ PROFILE_NOT_PERMITTED: "PROFILE_NOT_PERMITTED",
6265
+ /** A segment-occurrence or field-repetition count is outside its cardinality. */
6266
+ PROFILE_CARDINALITY: "PROFILE_CARDINALITY",
6267
+ /** A checked component value exceeds the declared maximum length. */
6268
+ PROFILE_LENGTH: "PROFILE_LENGTH",
6269
+ /** A checked component value is not a member of the consumer-supplied value set. */
6270
+ PROFILE_VALUE_NOT_IN_SET: "PROFILE_VALUE_NOT_IN_SET",
6271
+ /** The profile ITSELF is structurally malformed (a diagnostic, not a message finding). */
6272
+ PROFILE_MALFORMED: "PROFILE_MALFORMED"
6273
+ };
6274
+
6275
+ // src/conformance/findings.ts
6276
+ function describeLocus(locus) {
6277
+ let s = locus.segment;
6278
+ if (locus.occurrence !== void 0 && locus.occurrence > 0) {
6279
+ s += `[occurrence ${String(locus.occurrence)}]`;
6280
+ }
6281
+ if (locus.field !== void 0) {
6282
+ s += `-${String(locus.field)}`;
6283
+ }
6284
+ if (locus.repetition !== void 0) {
6285
+ s += ` rep ${String(locus.repetition)}`;
6286
+ }
6287
+ if (locus.component !== void 0) {
6288
+ s += ` component ${String(locus.component)}`;
6289
+ }
6290
+ return s;
6291
+ }
6292
+ function requiredAbsent(locus, severity) {
6293
+ const kind = locus.field === void 0 ? "segment" : "field";
6294
+ return {
6295
+ code: FINDING_CODES.PROFILE_REQUIRED_ABSENT,
6296
+ severity,
6297
+ locus,
6298
+ message: `Required ${kind} ${describeLocus(locus)} is absent or empty (usage R).`
6299
+ };
6300
+ }
6301
+ function notPermitted(locus, severity) {
6302
+ const kind = locus.field === void 0 ? "segment" : "field";
6303
+ return {
6304
+ code: FINDING_CODES.PROFILE_NOT_PERMITTED,
6305
+ severity,
6306
+ locus,
6307
+ message: `${kind === "segment" ? "Segment" : "Field"} ${describeLocus(
6308
+ locus
6309
+ )} is present but the profile marks it not-permitted (usage X).`
6310
+ };
6311
+ }
6312
+ function cardinality(locus, actual, bound, unit, severity) {
6313
+ const parts = [];
6314
+ if (bound.min !== void 0) parts.push(`min ${String(bound.min)}`);
6315
+ if (bound.max !== void 0) parts.push(`max ${String(bound.max)}`);
6316
+ return {
6317
+ code: FINDING_CODES.PROFILE_CARDINALITY,
6318
+ severity,
6319
+ locus,
6320
+ message: `${describeLocus(locus)} has ${String(actual)} ${unit}(s), outside the declared cardinality (${parts.join(
6321
+ ", "
6322
+ )}).`
6323
+ };
6324
+ }
6325
+ function length(locus, actualLength, maxLength, severity) {
6326
+ return {
6327
+ code: FINDING_CODES.PROFILE_LENGTH,
6328
+ severity,
6329
+ locus,
6330
+ message: `${describeLocus(locus)} value length ${String(
6331
+ actualLength
6332
+ )} exceeds the declared maximum of ${String(maxLength)}.`
6333
+ };
6334
+ }
6335
+ function valueNotInSet(locus, valueSetSize, severity) {
6336
+ return {
6337
+ code: FINDING_CODES.PROFILE_VALUE_NOT_IN_SET,
6338
+ severity,
6339
+ locus,
6340
+ message: `${describeLocus(
6341
+ locus
6342
+ )} value is not in the profile value set (${String(valueSetSize)} permitted code(s)).`
6343
+ };
6344
+ }
6345
+ function malformed(locus, detail) {
6346
+ return {
6347
+ code: FINDING_CODES.PROFILE_MALFORMED,
6348
+ severity: "error",
6349
+ locus,
6350
+ message: `Malformed conformance profile: ${detail}`
6351
+ };
6352
+ }
6353
+
6354
+ // src/conformance/profile-shape.ts
6355
+ var SEGMENT_NAME_RE3 = /^[A-Z][A-Z0-9]{2}$/u;
6356
+ var SEVERITIES = ["error", "warning", "info"];
6357
+ function isObject(v) {
6358
+ return typeof v === "object" && v !== null && !Array.isArray(v);
6359
+ }
6360
+ function checkCardinality(card, locus, out) {
6361
+ if (card === void 0) return;
6362
+ if (!isObject(card)) {
6363
+ out.push({ locus, detail: `${describe(locus)} cardinality must be an object.` });
6364
+ return;
6365
+ }
6366
+ const min = card["min"];
6367
+ const max = card["max"];
6368
+ if (min !== void 0 && (typeof min !== "number" || !Number.isInteger(min) || min < 0)) {
6369
+ out.push({
6370
+ locus,
6371
+ detail: `${describe(locus)} cardinality.min must be a non-negative integer.`
6372
+ });
6373
+ }
6374
+ if (max !== void 0 && max !== "*" && (typeof max !== "number" || !Number.isInteger(max) || max < 0)) {
6375
+ out.push({
6376
+ locus,
6377
+ detail: `${describe(locus)} cardinality.max must be a non-negative integer or "*".`
6378
+ });
6379
+ }
6380
+ if (typeof min === "number" && typeof max === "number" && Number.isInteger(min) && Number.isInteger(max) && max < min) {
6381
+ out.push({
6382
+ locus,
6383
+ detail: `${describe(locus)} cardinality.max (${String(max)}) is less than min (${String(min)}).`
6384
+ });
6385
+ }
6386
+ }
6387
+ function describe(locus) {
6388
+ if (locus.segment === "(profile)") return "profile";
6389
+ let s = `segment "${locus.segment}"`;
6390
+ if (locus.field !== void 0) s += ` field ${String(locus.field)}`;
6391
+ return s;
6392
+ }
6393
+ function collectProfileDefects(profile) {
6394
+ const out = [];
6395
+ const root = { segment: "(profile)" };
6396
+ if (!isObject(profile)) {
6397
+ out.push({ locus: root, detail: "profile must be an object with `name` and `segments`." });
6398
+ return out;
6399
+ }
6400
+ if (typeof profile["name"] !== "string" || profile["name"].trim().length === 0) {
6401
+ out.push({ locus: root, detail: "profile.name must be a non-empty string." });
6402
+ }
6403
+ const segments = profile["segments"];
6404
+ if (!Array.isArray(segments)) {
6405
+ out.push({ locus: root, detail: "profile.segments must be an array of segment rules." });
6406
+ return out;
6407
+ }
6408
+ for (let i = 0; i < segments.length; i++) {
6409
+ const seg = segments[i];
6410
+ if (!isObject(seg)) {
6411
+ out.push({ locus: root, detail: `segments[${String(i)}] must be an object.` });
6412
+ continue;
6413
+ }
6414
+ const name = seg["segment"];
6415
+ if (typeof name !== "string" || !SEGMENT_NAME_RE3.test(name)) {
6416
+ out.push({
6417
+ locus: root,
6418
+ detail: `segments[${String(i)}].segment must be a valid segment name ([A-Z][A-Z0-9]{2}).`
6419
+ });
6420
+ continue;
6421
+ }
6422
+ const segLocus = { segment: name };
6423
+ checkUsage(seg["usage"], segLocus, out);
6424
+ checkSeverity(seg["severity"], segLocus, out);
6425
+ checkCardinality(seg["cardinality"], segLocus, out);
6426
+ const fields = seg["fields"];
6427
+ if (fields !== void 0) {
6428
+ if (!Array.isArray(fields)) {
6429
+ out.push({ locus: segLocus, detail: `segment "${name}" fields must be an array.` });
6430
+ continue;
6431
+ }
6432
+ for (let j = 0; j < fields.length; j++) {
6433
+ checkFieldRule(fields[j], name, j, out);
6434
+ }
6435
+ }
6436
+ }
6437
+ return out;
6438
+ }
6439
+ function checkUsage(usage, locus, out) {
6440
+ if (usage === void 0) return;
6441
+ if (typeof usage !== "string" || !USAGE_CODES.includes(usage)) {
6442
+ out.push({
6443
+ locus,
6444
+ detail: `${describe(locus)} usage must be one of ${USAGE_CODES.join("/")}.`
6445
+ });
6446
+ }
6447
+ }
6448
+ function checkSeverity(sev, locus, out) {
6449
+ if (sev === void 0) return;
6450
+ if (typeof sev !== "string" || !SEVERITIES.includes(sev)) {
6451
+ out.push({
6452
+ locus,
6453
+ detail: `${describe(locus)} severity must be one of ${SEVERITIES.join("/")}.`
6454
+ });
6455
+ }
6456
+ }
6457
+ function checkFieldRule(rule, segment, index, out) {
6458
+ const locus = { segment };
6459
+ if (!isObject(rule)) {
6460
+ out.push({ locus, detail: `segment "${segment}" fields[${String(index)}] must be an object.` });
6461
+ return;
6462
+ }
6463
+ const field = rule["field"];
6464
+ if (typeof field !== "number" || !Number.isInteger(field) || field < 1) {
6465
+ out.push({
6466
+ locus,
6467
+ detail: `segment "${segment}" fields[${String(index)}].field must be a positive (1-indexed) integer.`
6468
+ });
6469
+ return;
6470
+ }
6471
+ const fieldLocus = { segment, field };
6472
+ checkUsage(rule["usage"], fieldLocus, out);
6473
+ checkSeverity(rule["severity"], fieldLocus, out);
6474
+ checkCardinality(rule["cardinality"], fieldLocus, out);
6475
+ const len = rule["length"];
6476
+ if (len !== void 0 && (typeof len !== "number" || !Number.isInteger(len) || len < 0)) {
6477
+ out.push({
6478
+ locus: fieldLocus,
6479
+ detail: `${describe(fieldLocus)} length must be a non-negative integer.`
6480
+ });
6481
+ }
6482
+ const comp = rule["component"];
6483
+ if (comp !== void 0 && (typeof comp !== "number" || !Number.isInteger(comp) || comp < 1)) {
6484
+ out.push({
6485
+ locus: fieldLocus,
6486
+ detail: `${describe(fieldLocus)} component must be a positive (1-indexed) integer.`
6487
+ });
6488
+ }
6489
+ const vs = rule["valueSet"];
6490
+ if (vs !== void 0) {
6491
+ if (!Array.isArray(vs)) {
6492
+ out.push({
6493
+ locus: fieldLocus,
6494
+ detail: `${describe(fieldLocus)} valueSet must be an array of strings.`
6495
+ });
6496
+ } else if (!vs.every((c) => typeof c === "string")) {
6497
+ out.push({
6498
+ locus: fieldLocus,
6499
+ detail: `${describe(fieldLocus)} valueSet entries must all be strings.`
6500
+ });
6501
+ }
6502
+ }
6503
+ }
6504
+ function defineConformanceProfile(profile) {
6505
+ const defects = collectProfileDefects(profile);
6506
+ if (defects.length > 0) {
6507
+ const name = isObject(profile) && typeof profile["name"] === "string" ? profile["name"] : void 0;
6508
+ throw new ProfileDefinitionError(
6509
+ `Conformance profile has ${String(defects.length)} defect(s): ` + defects.map((d) => d.detail).join("; "),
6510
+ name
6511
+ );
6512
+ }
6513
+ return profile;
6514
+ }
6515
+
6516
+ // src/conformance/validate-against-profile.ts
6517
+ function safeName(profile) {
6518
+ if (typeof profile === "object" && profile !== null && !Array.isArray(profile)) {
6519
+ const n = profile["name"];
6520
+ if (typeof n === "string" && n.trim().length > 0) return n;
6521
+ }
6522
+ return "(unnamed profile)";
6523
+ }
6524
+ function componentValue(rep, component) {
6525
+ return rep.components[component - 1]?.subcomponents[0] ?? "";
6526
+ }
6527
+ function fieldHasValue(field) {
6528
+ return field.repetitions.some(
6529
+ (rep) => rep.components.some((comp) => comp.subcomponents.some((sub) => sub !== ""))
6530
+ );
6531
+ }
6532
+ function presenceVerdict(usage, present) {
6533
+ if (usage === "R" && !present) return "required-absent";
6534
+ if (usage === "X" && present) return "not-permitted";
6535
+ return null;
6536
+ }
6537
+ function checkCardinality2(count, card, locus, unit, severity, out) {
6538
+ if (card === void 0) return;
6539
+ const { min, max } = card;
6540
+ if (typeof max === "number" && count > max) {
6541
+ out.push(cardinality(locus, count, card, unit, severity));
6542
+ return;
6543
+ }
6544
+ if (typeof min === "number" && count > 0 && count < min) {
6545
+ out.push(cardinality(locus, count, card, unit, severity));
6546
+ }
6547
+ }
6548
+ function checkFields(seg, occurrence, fields, out) {
6549
+ for (const rule of fields) {
6550
+ const severity = rule.severity ?? "error";
6551
+ const field = seg.field(rule.field);
6552
+ const present = fieldHasValue(field);
6553
+ const baseLocus = { segment: seg.type, field: rule.field, occurrence };
6554
+ const verdict = presenceVerdict(rule.usage, present);
6555
+ if (verdict === "required-absent") {
6556
+ out.push(requiredAbsent(baseLocus, severity));
6557
+ continue;
6558
+ }
6559
+ if (verdict === "not-permitted") {
6560
+ out.push(notPermitted(baseLocus, severity));
6561
+ continue;
6562
+ }
6563
+ if (!present) continue;
6564
+ const reps = field.repetitions;
6565
+ checkCardinality2(reps.length, rule.cardinality, baseLocus, "repetition", severity, out);
6566
+ if (rule.length === void 0 && rule.valueSet === void 0) continue;
6567
+ const component = rule.component ?? 1;
6568
+ for (let r = 0; r < reps.length; r++) {
6569
+ const rep = reps[r];
6570
+ if (rep === void 0) continue;
6571
+ const value = componentValue(rep, component);
6572
+ const locus = {
6573
+ segment: seg.type,
6574
+ field: rule.field,
6575
+ component,
6576
+ repetition: r,
6577
+ occurrence
6578
+ };
6579
+ if (rule.length !== void 0 && value.length > rule.length) {
6580
+ out.push(length(locus, value.length, rule.length, severity));
6581
+ }
6582
+ if (rule.valueSet !== void 0 && value !== "" && !rule.valueSet.includes(value)) {
6583
+ out.push(valueNotInSet(locus, rule.valueSet.length, severity));
6584
+ }
6585
+ }
6586
+ }
6587
+ }
6588
+ function checkSegment(message, rule, out) {
6589
+ const severity = rule.severity ?? "error";
6590
+ const occurrences = message.segments(rule.segment);
6591
+ const count = occurrences.length;
6592
+ const present = count > 0;
6593
+ const segLocus = { segment: rule.segment };
6594
+ const verdict = presenceVerdict(rule.usage, present);
6595
+ if (verdict === "required-absent") {
6596
+ out.push(requiredAbsent(segLocus, severity));
6597
+ return;
6598
+ }
6599
+ if (verdict === "not-permitted") {
6600
+ out.push(notPermitted(segLocus, severity));
6601
+ return;
6602
+ }
6603
+ checkCardinality2(count, rule.cardinality, segLocus, "occurrence", severity, out);
6604
+ if (!present || rule.fields === void 0) return;
6605
+ for (let occ = 0; occ < occurrences.length; occ++) {
6606
+ const seg = occurrences[occ];
6607
+ if (seg === void 0) continue;
6608
+ checkFields(seg, occ, rule.fields, out);
6609
+ }
6610
+ }
6611
+ function validateAgainstProfile(message, profile) {
6612
+ const defects = collectProfileDefects(profile);
6613
+ if (defects.length > 0) {
6614
+ const findings = defects.map((d) => malformed(d.locus, d.detail));
6615
+ return Object.freeze({ profileName: safeName(profile), findings: Object.freeze(findings) });
6616
+ }
6617
+ const out = [];
6618
+ for (const rule of profile.segments) {
6619
+ checkSegment(message, rule, out);
6620
+ }
6621
+ return Object.freeze({ profileName: profile.name, findings: Object.freeze(out) });
6622
+ }
6623
+
6624
+ // src/conformance/index.ts
6625
+ var conformance_exports = {};
6626
+ __export(conformance_exports, {
6627
+ FINDING_CODES: () => FINDING_CODES,
6628
+ USAGE_CODES: () => USAGE_CODES,
6629
+ collectProfileDefects: () => collectProfileDefects,
6630
+ defineConformanceProfile: () => defineConformanceProfile,
6631
+ validateAgainstProfile: () => validateAgainstProfile
6632
+ });
6633
+ function isEnvelopeName2(name) {
6634
+ return name === "FHS" || name === "BHS" || name === "BTS" || name === "FTS";
6635
+ }
6636
+ function decodeChunk(chunk) {
6637
+ if (typeof chunk === "string") return { text: chunk, wasBuffer: false };
6638
+ if (chunk instanceof Uint8Array) {
6639
+ return { text: buffer.Buffer.from(chunk).toString("latin1"), wasBuffer: true };
6640
+ }
6641
+ throw new TypeError(
6642
+ `parseStream: each chunk must be a string, Buffer, or Uint8Array; received ${chunk === null ? "null" : typeof chunk}.`
6643
+ );
6644
+ }
6645
+ async function* iterateChunks(source) {
6646
+ if (source === null || source === void 0) {
6647
+ throw new TypeError("parseStream: source must be an async-iterable or iterable of chunks.");
6648
+ }
6649
+ const asAsync = source[Symbol.asyncIterator];
6650
+ if (typeof asAsync === "function") {
6651
+ for await (const chunk of source) yield chunk;
6652
+ return;
6653
+ }
6654
+ const asSync = source[Symbol.iterator];
6655
+ if (typeof asSync === "function") {
6656
+ for (const chunk of source) yield chunk;
6657
+ return;
6658
+ }
6659
+ throw new TypeError(
6660
+ "parseStream: source must be an async-iterable or iterable of chunks (e.g. a Node Readable)."
6661
+ );
6662
+ }
6663
+ function nextSegment(buf, cursor, final) {
6664
+ if (cursor >= buf.length) return null;
6665
+ const r = buf.indexOf("\r", cursor);
6666
+ const n = buf.indexOf("\n", cursor);
6667
+ let idx;
6668
+ let isCr;
6669
+ if (r === -1 && n === -1) return null;
6670
+ else if (r === -1) {
6671
+ idx = n;
6672
+ isCr = false;
6673
+ } else if (n === -1) {
6674
+ idx = r;
6675
+ isCr = true;
6676
+ } else if (r < n) {
6677
+ idx = r;
6678
+ isCr = true;
6679
+ } else {
6680
+ idx = n;
6681
+ isCr = false;
6682
+ }
6683
+ if (isCr && idx === buf.length - 1 && !final) return null;
6684
+ let termLen = 1;
6685
+ if (isCr && idx + 1 < buf.length && buf.charCodeAt(idx + 1) === 10) termLen = 2;
6686
+ return { seg: buf.slice(cursor, idx), next: idx + termLen };
6687
+ }
6688
+ function parseStreamEntry(rawMessage, position, wasBuffer, optionsOrProfile, streamWarnings) {
6689
+ const input = wasBuffer ? buffer.Buffer.from(rawMessage, "latin1") : rawMessage;
6690
+ try {
6691
+ const message = optionsOrProfile === void 0 ? parseHL7(input) : parseHL7(input, optionsOrProfile);
6692
+ return Object.freeze({ ok: true, message, raw: rawMessage, position, streamWarnings });
6693
+ } catch (error) {
6694
+ if (error instanceof Hl7ParseError) {
6695
+ return Object.freeze({ ok: false, error, raw: rawMessage, position, streamWarnings });
6696
+ }
6697
+ throw error;
6698
+ }
6699
+ }
6700
+ async function* parseStream(source, optionsOrProfile) {
6701
+ if (typeof source === "string" || source instanceof Uint8Array) {
6702
+ throw new TypeError(
6703
+ "parseStream expects a stream of chunks (a Node Readable, an async-iterable, or an iterable of string/Buffer chunks), not a single string or Buffer. For one message use parseHL7; to stream a whole buffer, wrap it: parseStream([buffer])."
6704
+ );
6705
+ }
6706
+ let pending = "";
6707
+ let currentLines = [];
6708
+ let messageStartIndex = -1;
6709
+ let globalSegmentIndex = 0;
6710
+ let wasBuffer = false;
6711
+ let firstChunkSeen = false;
6712
+ let bomStripped = false;
6713
+ const flush = (finalUnterminated2) => {
6714
+ while (currentLines.length > 0 && currentLines[currentLines.length - 1] === "") {
6715
+ currentLines.pop();
6716
+ }
6717
+ if (currentLines.length === 0) {
6718
+ messageStartIndex = -1;
6719
+ return null;
6720
+ }
6721
+ const position = Object.freeze({ segmentIndex: messageStartIndex });
6722
+ const streamWarnings = finalUnterminated2 ? Object.freeze([unterminatedStreamMessage(position)]) : Object.freeze([]);
6723
+ const entry = parseStreamEntry(
6724
+ currentLines.join("\r"),
6725
+ position,
6726
+ wasBuffer,
6727
+ optionsOrProfile,
6728
+ streamWarnings
6729
+ );
6730
+ currentLines = [];
6731
+ messageStartIndex = -1;
6732
+ return entry;
6733
+ };
6734
+ const processSegment = (seg) => {
6735
+ const thisIndex = globalSegmentIndex;
6736
+ globalSegmentIndex += 1;
6737
+ const name = seg.slice(0, 3);
6738
+ if (isEnvelopeName2(name)) {
6739
+ return flush(false);
6740
+ }
6741
+ if (name === "MSH") {
6742
+ const flushed = flush(false);
6743
+ currentLines = [seg];
6744
+ messageStartIndex = thisIndex;
6745
+ return flushed;
6746
+ }
6747
+ if (currentLines.length === 0) {
6748
+ if (seg.trim() === "") return null;
6749
+ messageStartIndex = thisIndex;
6750
+ }
6751
+ currentLines.push(seg);
6752
+ return null;
6753
+ };
6754
+ const tryStripBom = (final) => {
6755
+ if (bomStripped || pending.length === 0) return;
6756
+ if (pending.charCodeAt(0) === 65279) {
6757
+ pending = pending.slice(1);
6758
+ bomStripped = true;
6759
+ } else if (pending.startsWith("\xEF\xBB\xBF")) {
6760
+ pending = pending.slice(3);
6761
+ bomStripped = true;
6762
+ } else if (final || !"\xEF\xBB\xBF".startsWith(pending)) {
6763
+ bomStripped = true;
6764
+ }
6765
+ };
6766
+ for await (const rawChunk of iterateChunks(source)) {
6767
+ const { text, wasBuffer: chunkWasBuffer } = decodeChunk(rawChunk);
6768
+ if (!firstChunkSeen) {
6769
+ wasBuffer = chunkWasBuffer;
6770
+ firstChunkSeen = true;
6771
+ }
6772
+ if (text.length === 0) continue;
6773
+ pending += text;
6774
+ tryStripBom(false);
6775
+ if (!bomStripped) continue;
6776
+ let cursor = 0;
6777
+ for (; ; ) {
6778
+ const res = nextSegment(pending, cursor, false);
6779
+ if (res === null) break;
6780
+ cursor = res.next;
6781
+ const entry = processSegment(res.seg);
6782
+ if (entry !== null) yield entry;
6783
+ }
6784
+ pending = pending.slice(cursor);
6785
+ }
6786
+ tryStripBom(true);
6787
+ {
6788
+ let cursor = 0;
6789
+ for (; ; ) {
6790
+ const res = nextSegment(pending, cursor, true);
6791
+ if (res === null) break;
6792
+ cursor = res.next;
6793
+ const entry = processSegment(res.seg);
6794
+ if (entry !== null) yield entry;
6795
+ }
6796
+ pending = pending.slice(cursor);
6797
+ }
6798
+ const tail = pending;
6799
+ pending = "";
6800
+ let finalUnterminated = false;
6801
+ if (tail.length > 0) {
6802
+ const flushed = processSegment(tail);
6803
+ if (flushed !== null) yield flushed;
6804
+ finalUnterminated = currentLines.length > 0 && tail.trim() !== "";
6805
+ }
6806
+ const finalEntry = flush(finalUnterminated);
6807
+ if (finalEntry !== null) yield finalEntry;
6808
+ }
6809
+
5444
6810
  // src/index.ts
5445
- var VERSION = "0.0.1";
6811
+ var VERSION = "0.0.3";
5446
6812
 
5447
6813
  exports.ACK_CODES = ACK_CODES;
5448
6814
  exports.ACK_CONDITIONS = ACK_CONDITIONS;
@@ -5452,6 +6818,7 @@ exports.ERR_CONDITION_CODES = ERR_CONDITION_CODES;
5452
6818
  exports.ERR_CONDITION_CODE_SYSTEM = ERR_CONDITION_CODE_SYSTEM;
5453
6819
  exports.ERR_SEVERITIES = ERR_SEVERITIES;
5454
6820
  exports.FATAL_CODES = FATAL_CODES;
6821
+ exports.FINDING_CODES = FINDING_CODES;
5455
6822
  exports.Field = Field;
5456
6823
  exports.HL7 = namespace_exports;
5457
6824
  exports.Hl7Message = Hl7Message;
@@ -5462,6 +6829,7 @@ exports.MESSAGE_STRUCTURE_DEFINITIONS = MESSAGE_STRUCTURE_DEFINITIONS;
5462
6829
  exports.ProfileDefinitionError = ProfileDefinitionError;
5463
6830
  exports.SUPPORTED_DATE_TOKENS = SUPPORTED_DATE_TOKENS;
5464
6831
  exports.Segment = Segment;
6832
+ exports.USAGE_CODES = USAGE_CODES;
5465
6833
  exports.VERSION = VERSION;
5466
6834
  exports.WARNING_CODES = WARNING_CODES;
5467
6835
  exports.ackNoCorrelationId = ackNoCorrelationId;
@@ -5470,15 +6838,34 @@ exports.analyzeMessageStructure = analyzeMessageStructure;
5470
6838
  exports.batchCountMismatch = batchCountMismatch;
5471
6839
  exports.batchMissingTrailer = batchMissingTrailer;
5472
6840
  exports.buildAck = buildAck;
6841
+ exports.buildAdt = buildAdt;
5473
6842
  exports.buildMessage = buildMessage;
6843
+ exports.buildOru = buildOru;
5474
6844
  exports.canonicalCharset = canonicalCharset;
5475
6845
  exports.codingSystem = codingSystem;
5476
6846
  exports.codingSystemOf = codingSystemOf;
6847
+ exports.conformance = conformance_exports;
6848
+ exports.decodeText = decodeText;
6849
+ exports.defineConformanceProfile = defineConformanceProfile;
5477
6850
  exports.defineProfile = defineProfile;
5478
6851
  exports.detectAckMode = detectAckMode;
5479
6852
  exports.downgradePositiveAck = downgradePositiveAck;
5480
6853
  exports.dtmToDate = dtmToDate;
5481
6854
  exports.duplicateRequiredSegment = duplicateRequiredSegment;
6855
+ exports.encodeCe = encodeCe;
6856
+ exports.encodeComposite = encodeComposite;
6857
+ exports.encodeCompositeReps = encodeCompositeReps;
6858
+ exports.encodeCwe = encodeCwe;
6859
+ exports.encodeCx = encodeCx;
6860
+ exports.encodeHd = encodeHd;
6861
+ exports.encodeNm = encodeNm;
6862
+ exports.encodePl = encodePl;
6863
+ exports.encodeText = encodeText;
6864
+ exports.encodeTs = encodeTs;
6865
+ exports.encodeXad = encodeXad;
6866
+ exports.encodeXcn = encodeXcn;
6867
+ exports.encodeXpn = encodeXpn;
6868
+ exports.encodeXtn = encodeXtn;
5482
6869
  exports.encodingMismatch = encodingMismatch;
5483
6870
  exports.extraFields = extraFields;
5484
6871
  exports.fieldWhitespaceTrimmed = fieldWhitespaceTrimmed;
@@ -5501,6 +6888,7 @@ exports.parseNm = parseNm;
5501
6888
  exports.parsePath = parsePath;
5502
6889
  exports.parsePl = parsePl;
5503
6890
  exports.parseSn = parseSn;
6891
+ exports.parseStream = parseStream;
5504
6892
  exports.parseTs = parseTs;
5505
6893
  exports.parseXad = parseXad;
5506
6894
  exports.parseXcn = parseXcn;
@@ -5509,11 +6897,13 @@ exports.parseXtn = parseXtn;
5509
6897
  exports.pickMrn = pickMrn;
5510
6898
  exports.profiles = profiles;
5511
6899
  exports.reescape = reescape;
6900
+ exports.renderText = renderText;
5512
6901
  exports.resolveCharset = resolveCharset;
5513
6902
  exports.resolvePath = resolvePath;
5514
6903
  exports.segmentCase = segmentCase;
5515
6904
  exports.setDefaultProfile = setDefaultProfile;
5516
6905
  exports.splitBatch = splitBatch;
6906
+ exports.text = text_exports;
5517
6907
  exports.timestampFallbackFormat = timestampFallbackFormat;
5518
6908
  exports.unescape = unescape;
5519
6909
  exports.unknownCharset = unknownCharset;
@@ -5521,6 +6911,8 @@ exports.unknownEscapeSequence = unknownEscapeSequence;
5521
6911
  exports.unknownSegment = unknownSegment;
5522
6912
  exports.unsupportedCharset = unsupportedCharset;
5523
6913
  exports.unterminatedEscapeSequence = unterminatedEscapeSequence;
6914
+ exports.unterminatedStreamMessage = unterminatedStreamMessage;
6915
+ exports.validateAgainstProfile = validateAgainstProfile;
5524
6916
  exports.versionMismatch = versionMismatch;
5525
6917
  //# sourceMappingURL=index.cjs.map
5526
6918
  //# sourceMappingURL=index.cjs.map