@cosyte/x12 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -12,12 +12,35 @@ import { Buffer } from 'node:buffer';
12
12
  * (see `test/warning-codes.snapshot.test.ts`). Phase 2+ extends, never
13
13
  * renames.
14
14
  *
15
- * Warning messages NEVER echo field VALUES (matches the hl7 H-PHI invariant
16
- * locked in 2026-06). They carry positional context plus bounded metadata
17
- * (e.g. counts, expected-vs-actual control numbers) - never the raw bytes
18
- * the warning describes. The `snippet` on a fatal {@link
19
- * "./errors.js".X12ParseError} is the documented consumer-redaction
20
- * boundary; warnings have no snippet.
15
+ * ## A warning message is built from this registry, never from the document
16
+ *
17
+ * This is the load-bearing PHI invariant of the library, and it is enforced
18
+ * structurally rather than by review: **no factory in this file takes a
19
+ * value parameter.** Every factory takes an {@link X12Position} plus, where
20
+ * one code covers more than one situation, a library-owned discriminant
21
+ * ({@link X12ControlNumberPair}, {@link X12UnexpectedSegmentContext},
22
+ * {@link X12BalanceInvariant}, {@link X12RequiredLoop}). `message` is a
23
+ * lookup into a frozen table, so it cannot interpolate anything a sender
24
+ * controls no matter what the input contains.
25
+ *
26
+ * That is a deliberate change of shape. Earlier versions shape-validated an
27
+ * echoed value against a spec grammar and substituted `(non-spec)` when it
28
+ * did not match. That held for the code-list slots and did NOT hold for the
29
+ * six envelope control numbers, whose grammar is "whatever the trading
30
+ * partner sent": a `X12_CONTROL_NUMBER_MISMATCH` echoed both sides verbatim
31
+ * and unbounded. A shape test is a filter somebody has to remember to
32
+ * apply; taking no value at all is a property of the type signature.
33
+ *
34
+ * The values themselves are never discarded. Every one of them is preserved
35
+ * verbatim on the model (`isa.elements`, `seg.raw`,
36
+ * `adjustment.reasonCode`, and so on), which is where a consumer that has
37
+ * decided it may handle PHI goes to read them. The diagnostic says *what*
38
+ * is wrong and *where*; the model says what the bytes were.
39
+ *
40
+ * `X12ParseError.snippet` on a **Tier-3 fatal** is the one deliberate
41
+ * exception in the library, and it is bounded to 64 characters. Warnings
42
+ * have no `snippet`, and a strict-mode escalation of a warning carries none
43
+ * either. See `KNOWN-LIMITATIONS.md`.
21
44
  */
22
45
 
23
46
  /**
@@ -79,20 +102,163 @@ declare const WARNING_CODES: {
79
102
  * ```
80
103
  */
81
104
  type X12WarningCode = (typeof WARNING_CODES)[keyof typeof WARNING_CODES];
105
+ /**
106
+ * Which header/trailer control-number pair disagreed. A library-owned
107
+ * discriminant, NOT a value read out of the document: the useful part of
108
+ * the diagnostic is that the two disagree and where each one sits, never
109
+ * what either one says.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * import { controlNumberMismatch, CONTROL_NUMBER_PAIRS } from "@cosyte/x12";
114
+ * const w = controlNumberMismatch({ segmentIndex: 6 }, CONTROL_NUMBER_PAIRS.INTERCHANGE);
115
+ * ```
116
+ */
117
+ declare const CONTROL_NUMBER_PAIRS: {
118
+ /** ISA-13 against IEA-02. */
119
+ readonly INTERCHANGE: "interchange";
120
+ /** GS-06 against GE-02. */
121
+ readonly GROUP: "group";
122
+ /** ST-02 against SE-02. */
123
+ readonly TRANSACTION: "transaction";
124
+ };
125
+ /**
126
+ * String-literal union over {@link CONTROL_NUMBER_PAIRS}.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * import type { X12ControlNumberPair } from "@cosyte/x12";
131
+ * const pair: X12ControlNumberPair = "group";
132
+ * ```
133
+ */
134
+ type X12ControlNumberPair = (typeof CONTROL_NUMBER_PAIRS)[keyof typeof CONTROL_NUMBER_PAIRS];
135
+ /**
136
+ * Which structural rule an out-of-place segment broke. A closed,
137
+ * library-owned set. The segment's own id is deliberately NOT part of it:
138
+ * a segment that is not where it belongs is exactly the case where its
139
+ * first element is arbitrary sender bytes rather than a spec name.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * import { unexpectedSegment, UNEXPECTED_SEGMENT_CONTEXTS } from "@cosyte/x12";
144
+ * const w = unexpectedSegment({ segmentIndex: 12 }, UNEXPECTED_SEGMENT_CONTEXTS.GE_WITHOUT_GS);
145
+ * ```
146
+ */
147
+ declare const UNEXPECTED_SEGMENT_CONTEXTS: {
148
+ /** A `TA1` (envelope-level by spec) appeared inside an open functional group. */
149
+ readonly TA1_INSIDE_GROUP: "ta1-inside-group";
150
+ /** A `GE` appeared with no open `GS`. */
151
+ readonly GE_WITHOUT_GS: "ge-without-gs";
152
+ /** An `ST` appeared with no open functional group. */
153
+ readonly ST_WITHOUT_GS: "st-without-gs";
154
+ /** An `SE` appeared with no open transaction set. */
155
+ readonly SE_WITHOUT_ST: "se-without-st";
156
+ /** A body segment appeared outside any open transaction set. */
157
+ readonly BODY_OUTSIDE_TRANSACTION: "body-outside-transaction";
158
+ };
159
+ /**
160
+ * String-literal union over {@link UNEXPECTED_SEGMENT_CONTEXTS}.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import type { X12UnexpectedSegmentContext } from "@cosyte/x12";
165
+ * const ctx: X12UnexpectedSegmentContext = "se-without-st";
166
+ * ```
167
+ */
168
+ type X12UnexpectedSegmentContext = (typeof UNEXPECTED_SEGMENT_CONTEXTS)[keyof typeof UNEXPECTED_SEGMENT_CONTEXTS];
169
+ /**
170
+ * Which 835 balance invariant failed. A library-owned discriminant naming
171
+ * the TR3 equation. The amounts on either side stay on the model as
172
+ * `X12Decimal` and are never rendered into the message: an EDI amount is a
173
+ * consumer-controlled element like any other, and a 300,000-digit "amount"
174
+ * would otherwise become a 300,000-byte diagnostic.
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * import { remitBalanceMismatch, BALANCE_INVARIANTS } from "@cosyte/x12";
179
+ * const w = remitBalanceMismatch({ segmentIndex: 12 }, BALANCE_INVARIANTS.CLAIM);
180
+ * ```
181
+ */
182
+ declare const BALANCE_INVARIANTS: {
183
+ /** `CLP-04 + Σ(claim CAS + line CAS) == CLP-03`. */
184
+ readonly CLAIM: "claim";
185
+ /** `SVC-03 + Σ(line CAS) == SVC-02`. */
186
+ readonly SERVICE_LINE: "service-line";
187
+ /** `Σ(CLP-04) - Σ(PLB amounts) == BPR-02`. */
188
+ readonly REMIT_TOTAL: "remit-total";
189
+ };
190
+ /**
191
+ * String-literal union over {@link BALANCE_INVARIANTS}.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * import type { X12BalanceInvariant } from "@cosyte/x12";
196
+ * const which: X12BalanceInvariant = "service-line";
197
+ * ```
198
+ */
199
+ type X12BalanceInvariant = (typeof BALANCE_INVARIANTS)[keyof typeof BALANCE_INVARIANTS];
200
+ /**
201
+ * The TR3-required loops the parser reports as structurally absent. A
202
+ * closed set owned by the loop specs under `src/transactions/`, so both the
203
+ * loop id and its rationale are library constants rather than anything read
204
+ * out of the document.
205
+ *
206
+ * @example
207
+ * ```ts
208
+ * import { missingRequiredLoop, REQUIRED_LOOPS } from "@cosyte/x12";
209
+ * const w = missingRequiredLoop({ segmentIndex: 12 }, REQUIRED_LOOPS.PAYER_NAME_2010BB);
210
+ * ```
211
+ */
212
+ declare const REQUIRED_LOOPS: {
213
+ /** Loop 2000A, Billing Provider HL. */
214
+ readonly BILLING_PROVIDER_2000A: "2000A";
215
+ /** Loop 2000B, Subscriber HL. */
216
+ readonly SUBSCRIBER_2000B: "2000B";
217
+ /** Loop 2010BA, Subscriber Name. */
218
+ readonly SUBSCRIBER_NAME_2010BA: "2010BA";
219
+ /** Loop 2010BB, Payer Name. */
220
+ readonly PAYER_NAME_2010BB: "2010BB";
221
+ };
222
+ /**
223
+ * String-literal union over {@link REQUIRED_LOOPS}.
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * import type { X12RequiredLoop } from "@cosyte/x12";
228
+ * const loop: X12RequiredLoop = "2010BB";
229
+ * ```
230
+ */
231
+ type X12RequiredLoop = (typeof REQUIRED_LOOPS)[keyof typeof REQUIRED_LOOPS];
232
+ /**
233
+ * Every message string this library can put on a warning. Exported so a
234
+ * consumer, or a conformance gate, can assert set membership: if
235
+ * `ALL_WARNING_MESSAGES.has(w.message)` is ever false, something
236
+ * interpolated document bytes into a diagnostic.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * import { parseX12, ALL_WARNING_MESSAGES } from "@cosyte/x12";
241
+ * const ix = parseX12(raw);
242
+ * ix.warnings.every((w) => ALL_WARNING_MESSAGES.has(w.message)); // true, always
243
+ * ```
244
+ */
245
+ declare const ALL_WARNING_MESSAGES: ReadonlySet<string>;
82
246
  /**
83
247
  * Data shape for every Tier-2 warning emitted by the parser. Warnings are
84
248
  * plain data (distinct from `X12ParseError`, which is a thrown `Error`
85
249
  * subclass) so they can be safely accumulated on `X12Interchange.warnings`
86
250
  * and passed to `onWarning` callbacks.
87
251
  *
252
+ * `message` is always a member of {@link ALL_WARNING_MESSAGES}: it names
253
+ * the deviation, never the bytes that caused it. `position` says where to
254
+ * look and the bytes stay on the model. A warning has no `snippet`.
255
+ *
88
256
  * @example
89
257
  * ```ts
90
258
  * import type { X12ParseWarning } from "@cosyte/x12";
91
- * const w: X12ParseWarning = {
92
- * code: "X12_PRE_005010",
93
- * message: "ISA-12 declares pre-005010 version.",
94
- * position: { segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 },
95
- * };
259
+ * declare const w: X12ParseWarning;
260
+ * w.code; // "X12_PRE_005010"
261
+ * w.position; // { segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 }
96
262
  * ```
97
263
  */
98
264
  interface X12ParseWarning {
@@ -102,111 +268,101 @@ interface X12ParseWarning {
102
268
  }
103
269
  /**
104
270
  * Build an `X12_CONTROL_NUMBER_MISMATCH` warning. Emitted when an
105
- * envelope-trailer control number does not match its matching header -
106
- * ISA-13 ↔ IEA-02, GS-06 ↔ GE-02, or ST-02 ↔ SE-02. Message carries the
107
- * field pair label and the expected-vs-actual values bounded to the 9-char
108
- * (interchange) / variable (group/transaction) numeric forms - these are
109
- * control numbers, not PHI.
271
+ * envelope-trailer control number does not match its matching header:
272
+ * ISA-13 ↔ IEA-02, GS-06 ↔ GE-02, or ST-02 ↔ SE-02.
273
+ *
274
+ * Neither side is echoed, not truncated and not hashed. A control number is
275
+ * free-form trading-partner text on five of the six slots (only ISA-13 is
276
+ * fixed-width), routinely carries a batch or patient-account identifier in
277
+ * the field, and is entirely sender-controlled. Read `isa.elements[13]`,
278
+ * `iea.elements[2]`, `gs.elements[6]`, `ge.elements[2]`, `st.elements[2]`
279
+ * and `se.elements[2]` off the model when you need the values.
110
280
  *
111
281
  * @example
112
282
  * ```ts
113
- * import { controlNumberMismatch } from "@cosyte/x12";
283
+ * import { controlNumberMismatch, CONTROL_NUMBER_PAIRS } from "@cosyte/x12";
114
284
  * const w = controlNumberMismatch(
115
- * { segmentIndex: 1, interchangeIndex: 0, elementIndex: 2 },
116
- * "ISA-13/IEA-02",
117
- * "000000001",
118
- * "000000002",
285
+ * { segmentIndex: 6, interchangeIndex: 0, elementIndex: 2 },
286
+ * CONTROL_NUMBER_PAIRS.INTERCHANGE,
119
287
  * );
120
288
  * ```
121
289
  */
122
- declare function controlNumberMismatch(position: X12Position, pair: string, header: string, trailer: string): X12ParseWarning;
290
+ declare function controlNumberMismatch(position: X12Position, pair: X12ControlNumberPair): X12ParseWarning;
123
291
  /**
124
- * Build an `X12_PRE_005010` warning. Emitted when ISA-12 declares a version
125
- * earlier than `00501` - the HIPAA-mandated baseline. The parser still
292
+ * Build an `X12_PRE_005010` warning. Emitted when ISA-12 declares any version
293
+ * other than `00501`, the HIPAA-mandated baseline. The code name reads as a
294
+ * "pre-005010" test and the guard is an inequality, so a LATER family
295
+ * (`00602`, `00700`) raises it too. The parser still
126
296
  * accepts the input (Postel's Law: lenient on parse) but flags the
127
297
  * mismatch so consumers know the input may diverge from 005010 semantics.
298
+ * The declared version stays on `isa.elements[12]`.
128
299
  *
129
300
  * @example
130
301
  * ```ts
131
302
  * import { pre005010 } from "@cosyte/x12";
132
- * const w = pre005010({ segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 }, "00401");
303
+ * const w = pre005010({ segmentIndex: 0, interchangeIndex: 0, elementIndex: 12 });
133
304
  * ```
134
305
  */
135
- declare function pre005010(position: X12Position, declared: string): X12ParseWarning;
306
+ declare function pre005010(position: X12Position): X12ParseWarning;
136
307
  /**
137
308
  * Build an `X12_GROUP_COUNT_MISMATCH` warning. Emitted when IEA-01 does not
138
309
  * equal the actual number of GS..GE groups present in the interchange.
139
- * Trading partners use this to detect transmission truncation; the parser
140
- * surfaces both values verbatim and never silently corrects them.
310
+ * Trading partners use this to detect transmission truncation. Both numbers
311
+ * stay on the model (`iea.elements[1]` and `ix.groups.length`) and neither
312
+ * is silently corrected.
141
313
  *
142
314
  * @example
143
315
  * ```ts
144
316
  * import { groupCountMismatch } from "@cosyte/x12";
145
- * const w = groupCountMismatch(
146
- * { segmentIndex: 5, interchangeIndex: 0, elementIndex: 1 },
147
- * "2",
148
- * 1,
149
- * );
317
+ * const w = groupCountMismatch({ segmentIndex: 5, interchangeIndex: 0, elementIndex: 1 });
150
318
  * ```
151
319
  */
152
- declare function groupCountMismatch(position: X12Position, declared: string, actual: number): X12ParseWarning;
320
+ declare function groupCountMismatch(position: X12Position): X12ParseWarning;
153
321
  /**
154
322
  * Build an `X12_TRANSACTION_COUNT_MISMATCH` warning. Emitted when GE-01
155
323
  * does not equal the actual number of ST..SE transaction sets present in
156
- * the group. As with group counts, the parser surfaces both values
157
- * verbatim and never silently corrects them.
324
+ * the group. Both numbers stay on the model (`ge.elements[1]` and
325
+ * `group.transactions.length`).
158
326
  *
159
327
  * @example
160
328
  * ```ts
161
329
  * import { transactionCountMismatch } from "@cosyte/x12";
162
- * const w = transactionCountMismatch(
163
- * { segmentIndex: 4, interchangeIndex: 0, groupIndex: 0, elementIndex: 1 },
164
- * "3",
165
- * 2,
166
- * );
330
+ * const w = transactionCountMismatch({ segmentIndex: 4, groupIndex: 0, elementIndex: 1 });
167
331
  * ```
168
332
  */
169
- declare function transactionCountMismatch(position: X12Position, declared: string, actual: number): X12ParseWarning;
333
+ declare function transactionCountMismatch(position: X12Position): X12ParseWarning;
170
334
  /**
171
335
  * Build an `X12_SEGMENT_COUNT_MISMATCH` warning. Emitted by the spec-clean
172
336
  * serializer when an SE-01 value does not equal the actual number of
173
- * segments in the transaction set it closes (ST through SE inclusive). Like
174
- * the group/transaction count factories, the serializer surfaces both values
175
- * verbatim and NEVER silently corrects them - corrected counts are emitted
176
- * only on `serializeX12(ix, { recomputeCounts: true })`. The parser does not
177
- * emit this code (it leaves SE-01 reconciliation to the emit half); it is a
178
- * Phase-8 serializer diagnostic.
337
+ * segments in the transaction set it closes (ST through SE inclusive).
338
+ * Corrected counts are emitted only on `serializeX12(ix, { specClean: true,
339
+ * recomputeCounts: true })`. The parser does not emit this code (it leaves
340
+ * SE-01 reconciliation to the emit half); it is a Phase-8 serializer
341
+ * diagnostic.
179
342
  *
180
343
  * @example
181
344
  * ```ts
182
345
  * import { segmentCountMismatch } from "@cosyte/x12";
183
- * const w = segmentCountMismatch(
184
- * { segmentIndex: 2, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0, elementIndex: 1 },
185
- * "6",
186
- * 7,
187
- * );
346
+ * const w = segmentCountMismatch({ segmentIndex: 2, transactionIndex: 0, elementIndex: 1 });
188
347
  * ```
189
348
  */
190
- declare function segmentCountMismatch(position: X12Position, declared: string, actual: number): X12ParseWarning;
349
+ declare function segmentCountMismatch(position: X12Position): X12ParseWarning;
191
350
  /**
192
351
  * Build an `X12_TRAILING_GARBAGE` warning. Emitted when non-empty bytes
193
352
  * appear after the IEA segment terminator and any optional CRLF. The bytes
194
353
  * are preserved verbatim on {@link
195
- * "./types.js".X12Interchange}.`trailingBytes` so consumers can inspect or
196
- * re-emit them. Common cause: a second interchange concatenated into the
197
- * same file (multi-ISA - out of v1 scope; only the first interchange is
198
- * decoded).
354
+ * "./types.js".X12Interchange}.`trailingBytes` so consumers can inspect,
355
+ * measure, or re-emit them. Common cause: a second interchange concatenated
356
+ * into the same file (multi-ISA, out of v1 scope; only the first
357
+ * interchange is decoded).
199
358
  *
200
359
  * @example
201
360
  * ```ts
202
361
  * import { trailingGarbage } from "@cosyte/x12";
203
- * const w = trailingGarbage(
204
- * { segmentIndex: 6, interchangeIndex: 0 },
205
- * 42,
206
- * );
362
+ * const w = trailingGarbage({ segmentIndex: 6, interchangeIndex: 0 });
207
363
  * ```
208
364
  */
209
- declare function trailingGarbage(position: X12Position, byteCount: number): X12ParseWarning;
365
+ declare function trailingGarbage(position: X12Position): X12ParseWarning;
210
366
  /**
211
367
  * Build an `X12_MISSING_IEA` warning. Emitted when the input opened a
212
368
  * valid ISA but EOF arrived before any IEA segment. The parser returns the
@@ -242,12 +398,7 @@ declare function missingGe(position: X12Position): X12ParseWarning;
242
398
  * @example
243
399
  * ```ts
244
400
  * import { missingSe } from "@cosyte/x12";
245
- * const w = missingSe({
246
- * segmentIndex: 2,
247
- * interchangeIndex: 0,
248
- * groupIndex: 0,
249
- * transactionIndex: 0,
250
- * });
401
+ * const w = missingSe({ segmentIndex: 2, groupIndex: 0, transactionIndex: 0 });
251
402
  * ```
252
403
  */
253
404
  declare function missingSe(position: X12Position): X12ParseWarning;
@@ -268,249 +419,197 @@ declare function missingSe(position: X12Position): X12ParseWarning;
268
419
  declare function danglingReleaseChar(position: X12Position): X12ParseWarning;
269
420
  /**
270
421
  * Build an `X12_UNEXPECTED_SEGMENT` warning. Emitted when a structurally
271
- * meaningful envelope segment (`GE`, `SE`, body segments) appears outside
272
- * its expected parent - e.g. a `GE` with no open `GS`, an `SE` with no open
273
- * `ST`, or any body segment before the first `ST`. The parser preserves
274
- * lenient-never-throw and continues; the warning carries the segment id (if
275
- * it matches the X12 segment-id grammar - otherwise the literal
276
- * `(non-spec)` is substituted to avoid echoing arbitrary bytes / PHI) and
277
- * its global segment index so a consumer can locate the deviation.
422
+ * meaningful segment (`GE`, `SE`, `ST`, `TA1`, or a body segment) appears
423
+ * outside its expected parent. The parser preserves lenient-never-throw and
424
+ * continues; `context` names which structural rule broke and `position`
425
+ * locates the segment.
278
426
  *
279
- * Message NEVER echoes element values - only a SHAPE-VALIDATED 2-or-3-
280
- * letter segment id (the spec name, not user data) and the structural
281
- * context, mirroring the H-PHI invariant locked for `@cosyte/hl7`. A
282
- * hostile input that puts PHI in the first slot of a malformed "segment"
283
- * still has its bytes preserved on the parent container - they are simply
284
- * not echoed in the diagnostic message.
427
+ * The segment's own id is deliberately not a parameter. Note that a segment
428
+ * in one of these positions is NOT retained on the model at all (it has no
429
+ * open container to belong to), so `position.segmentIndex` against the input
430
+ * is the only way back to its bytes. For a segment that IS retained, the
431
+ * `X12Segment.id` a consumer reads is bounded to the X12 segment-id grammar
432
+ * (see {@link "./segment.js".decodeSegment}) while `seg.raw` and
433
+ * `seg.elements[0]` stay verbatim.
285
434
  *
286
435
  * @example
287
436
  * ```ts
288
- * import { unexpectedSegment } from "@cosyte/x12";
437
+ * import { unexpectedSegment, UNEXPECTED_SEGMENT_CONTEXTS } from "@cosyte/x12";
289
438
  * const w = unexpectedSegment(
290
439
  * { segmentIndex: 12, interchangeIndex: 0 },
291
- * "GE",
292
- * "no open functional group",
440
+ * UNEXPECTED_SEGMENT_CONTEXTS.GE_WITHOUT_GS,
293
441
  * );
294
442
  * ```
295
443
  */
296
- declare function unexpectedSegment(position: X12Position, segmentId: string, context: string): X12ParseWarning;
444
+ declare function unexpectedSegment(position: X12Position, context: X12UnexpectedSegmentContext): X12ParseWarning;
297
445
  /**
298
446
  * Build an `X12_835_REMIT_BALANCE_MISMATCH` warning. Emitted by the 835
299
- * helper when a balance invariant fails - typically `CLP-04 + CLP-05 +
300
- * Σ(claim-level CAS amounts) !== CLP-03`, or `Σ(SVC paid) + Σ(line CAS)
301
- * !== CLP-04`, or `Σ(claim CLP-04) + Σ(PLB adjustments) !== BPR-02`.
447
+ * helper when a TR3 X221A1 §1.10.2 balance invariant fails. `invariant`
448
+ * names which equation broke; the spec'd, computed and delta amounts stay
449
+ * on the model as {@link "../decimal.js".X12Decimal} values and are never
450
+ * rendered into the message.
302
451
  *
303
- * The message carries the invariant label, the spec'd value, the
304
- * computed value, and the side-by-side diff - all numeric strings (the
305
- * outputs of {@link "../decimal.js".X12Decimal} `toString()`). It NEVER
306
- * echoes patient identifiers, member ids, names, account numbers, or any
307
- * other PHI-shaped value - mirrors the H-PHI invariant from `@cosyte/hl7`.
308
- * The parser ALWAYS surfaces this and NEVER silently rebalances.
452
+ * The parser ALWAYS surfaces this and NEVER silently rebalances. To report
453
+ * the numbers, recompute them from the model: `claim.totalChargeAmount`,
454
+ * `claim.totalPaymentAmount` and the CAS adjustments are all present.
309
455
  *
310
456
  * @example
311
457
  * ```ts
312
- * import { remitBalanceMismatch } from "@cosyte/x12";
458
+ * import { remitBalanceMismatch, BALANCE_INVARIANTS } from "@cosyte/x12";
313
459
  * const w = remitBalanceMismatch(
314
- * { segmentIndex: 12, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
315
- * "CLP-04 + CLP-05 + ΣCAS == CLP-03",
316
- * "500.00",
317
- * "499.99",
318
- * "0.01",
460
+ * { segmentIndex: 12, groupIndex: 0, transactionIndex: 0 },
461
+ * BALANCE_INVARIANTS.CLAIM,
319
462
  * );
320
463
  * ```
321
464
  */
322
- declare function remitBalanceMismatch(position: X12Position, invariant: string, spec: string, computed: string, delta: string): X12ParseWarning;
465
+ declare function remitBalanceMismatch(position: X12Position, invariant: X12BalanceInvariant): X12ParseWarning;
323
466
  /**
324
467
  * Build an `X12_UNKNOWN_CARC` warning. Emitted when a CAS adjustment
325
468
  * carries a CARC code outside the bundled snapshot (see
326
- * {@link "../code-lists/carc.js".CARC}). The verbatim code is still
327
- * preserved on the parsed adjustment - only the description is missing.
328
- * The code value is shape-validated against `[A-Z0-9]{1,5}` before
329
- * echoing in the message; a hostile non-conformant value collapses to
330
- * the literal `(non-spec)` so the parser never echoes arbitrary bytes
331
- * (H-PHI invariant).
469
+ * {@link "../code-lists/carc.js".CARC}). The verbatim code is preserved on
470
+ * the parsed adjustment (`adjustment.reasonCode`); only the description is
471
+ * missing.
332
472
  *
333
473
  * @example
334
474
  * ```ts
335
475
  * import { unknownCarc } from "@cosyte/x12";
336
- * const w = unknownCarc(
337
- * { segmentIndex: 14, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
338
- * "9999",
339
- * );
476
+ * const w = unknownCarc({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
340
477
  * ```
341
478
  */
342
- declare function unknownCarc(position: X12Position, code: string): X12ParseWarning;
479
+ declare function unknownCarc(position: X12Position): X12ParseWarning;
343
480
  /**
344
481
  * Build an `X12_UNKNOWN_RARC` warning. Companion to {@link unknownCarc}
345
- * for RARC codes on `MIA` / `MOA` / `LQ` / `NTE`. Same shape-validation
346
- * + verbatim-preserve posture.
482
+ * for RARC codes on `MIA` / `MOA` / `LQ` / `NTE`. Same verbatim-preserve
483
+ * posture; the code lives on the parsed remark.
347
484
  *
348
485
  * @example
349
486
  * ```ts
350
487
  * import { unknownRarc } from "@cosyte/x12";
351
- * const w = unknownRarc(
352
- * { segmentIndex: 16, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
353
- * "ZZZZZ",
354
- * );
488
+ * const w = unknownRarc({ segmentIndex: 16, groupIndex: 0, transactionIndex: 0 });
355
489
  * ```
356
490
  */
357
- declare function unknownRarc(position: X12Position, code: string): X12ParseWarning;
491
+ declare function unknownRarc(position: X12Position): X12ParseWarning;
358
492
  /**
359
- * Build an `X12_HL_PARENT_MISMATCH` warning. Emitted by the 837 helper
360
- * when an HL segment's HL-02 (parent id) does not match any earlier-
361
- * emitted HL-01 in the same transaction. The walker NEVER silently
362
- * re-numbers the hierarchy - the safety primitive of the 837 is HL
363
- * parent-pointer integrity. The reported ids are shape-validated against
364
- * the HL-id grammar before echoing.
493
+ * Build an `X12_HL_PARENT_MISMATCH` warning. Emitted when an HL segment's
494
+ * HL-02 (parent id) does not match any earlier-emitted HL-01 in the same
495
+ * transaction. The walker NEVER silently re-numbers the hierarchy (HL
496
+ * parent-pointer integrity is the safety primitive of the 837), so the
497
+ * declared pointer stays verbatim on `hierarchy.parentHlId` and the warning
498
+ * reports only that the pointer is dangling, and where.
365
499
  *
366
500
  * @example
367
501
  * ```ts
368
502
  * import { hlParentMismatch } from "@cosyte/x12";
369
- * const w = hlParentMismatch(
370
- * { segmentIndex: 14, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
371
- * "3",
372
- * "9",
373
- * );
503
+ * const w = hlParentMismatch({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
374
504
  * ```
375
505
  */
376
- declare function hlParentMismatch(position: X12Position, hlId: string, declaredParentId: string): X12ParseWarning;
506
+ declare function hlParentMismatch(position: X12Position): X12ParseWarning;
377
507
  /**
378
508
  * Build an `X12_HL_PARENT_LEVEL_INVALID` warning. Emitted when an HL's
379
- * level code (HL-03) is inconsistent with its declared parent's level
380
- * code per the 837 TR3 (e.g. a `22` Subscriber claiming a `22`
381
- * Subscriber as its parent - the parent must be `20` Information
382
- * Source). The verbatim level codes are shape-validated before echoing.
509
+ * level code (HL-03) is inconsistent with its declared parent's level code
510
+ * per the TR3 (e.g. a `22` Subscriber claiming a `22` Subscriber as its
511
+ * parent, where the parent must be `20` Information Source). Both level
512
+ * codes stay verbatim on the model.
383
513
  *
384
514
  * @example
385
515
  * ```ts
386
516
  * import { hlParentLevelInvalid } from "@cosyte/x12";
387
- * const w = hlParentLevelInvalid(
388
- * { segmentIndex: 14, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
389
- * "3",
390
- * "23",
391
- * "2",
392
- * "22",
393
- * "20",
394
- * );
517
+ * const w = hlParentLevelInvalid({ segmentIndex: 14, groupIndex: 0, transactionIndex: 0 });
395
518
  * ```
396
519
  */
397
- declare function hlParentLevelInvalid(position: X12Position, hlId: string, hlLevel: string, parentHlId: string, parentLevel: string, expectedParentLevel: string): X12ParseWarning;
520
+ declare function hlParentLevelInvalid(position: X12Position): X12ParseWarning;
398
521
  /**
399
- * Build an `X12_UNKNOWN_HI_QUALIFIER` warning. Emitted by the 837 helper
400
- * when an HI composite's qualifier (first component) is outside the
522
+ * Build an `X12_UNKNOWN_HI_QUALIFIER` warning. Emitted by the 837 / 278
523
+ * helpers when an HI composite's qualifier (first component) is outside the
401
524
  * bundled snapshot at {@link "../code-lists/hi-qualifiers.js".
402
- * HI_QUALIFIERS}. The verbatim code is preserved on the parsed
403
- * diagnosis/procedure with `codeSystem: "unknown"` so consumers can
404
- * still react. Qualifier is shape-validated before echoing - the H-PHI
405
- * invariant.
525
+ * HI_QUALIFIERS}. The verbatim qualifier and code are preserved on the
526
+ * parsed diagnosis / procedure with `codeSystem: "unknown"` so consumers
527
+ * can still react.
406
528
  *
407
529
  * @example
408
530
  * ```ts
409
531
  * import { unknownHiQualifier } from "@cosyte/x12";
410
- * const w = unknownHiQualifier(
411
- * { segmentIndex: 25, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
412
- * "ZZZ",
413
- * );
532
+ * const w = unknownHiQualifier({ segmentIndex: 25, groupIndex: 0, transactionIndex: 0 });
414
533
  * ```
415
534
  */
416
- declare function unknownHiQualifier(position: X12Position, qualifier: string): X12ParseWarning;
535
+ declare function unknownHiQualifier(position: X12Position): X12ParseWarning;
417
536
  /**
418
537
  * Build an `X12_MISSING_REQUIRED_LOOP` warning. Emitted when a TR3-required
419
538
  * loop is structurally absent (e.g. no Loop 2010BB Payer Name inside a
420
- * Subscriber HL). The parser does not enforce situational rules - only
421
- * loops marked `usage: "required"` in the loop spec fire this warning.
422
- * The loop id is shape-validated before echoing.
539
+ * Subscriber HL). The parser does not enforce situational rules: only loops
540
+ * marked `usage: "required"` in the loop spec fire this warning, so the
541
+ * loop id and its rationale are both library constants.
423
542
  *
424
543
  * @example
425
544
  * ```ts
426
- * import { missingRequiredLoop } from "@cosyte/x12";
545
+ * import { missingRequiredLoop, REQUIRED_LOOPS } from "@cosyte/x12";
427
546
  * const w = missingRequiredLoop(
428
- * { segmentIndex: 12, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
429
- * "2010BB",
430
- * "Loop 2010BB Payer Name required when Loop 2000B (Subscriber HL) is present",
547
+ * { segmentIndex: 12, groupIndex: 0, transactionIndex: 0 },
548
+ * REQUIRED_LOOPS.PAYER_NAME_2010BB,
431
549
  * );
432
550
  * ```
433
551
  */
434
- declare function missingRequiredLoop(position: X12Position, loopId: string, rationale: string): X12ParseWarning;
552
+ declare function missingRequiredLoop(position: X12Position, loop: X12RequiredLoop): X12ParseWarning;
435
553
  /**
436
554
  * Build an `X12_837_UNKNOWN_VARIANT` warning. Emitted when the 837 helper
437
555
  * cannot resolve the variant from ST-03's implementation-convention
438
556
  * reference AND no SVx service-line segment is present to fall back on.
439
- * The parsed submission still ships with `variant: "unknown"`; the walker
440
- * does its best on shared structure (envelope, HL, claim header) and
441
- * skips variant-specific service-line decoding. The implementation-
442
- * convention reference is shape-validated before echoing.
557
+ * The parsed submission still ships with `variant: "unknown"` and the
558
+ * verbatim reference on `submission.implementationConventionReference`; the
559
+ * walker does its best on shared structure (envelope, HL, claim header) and
560
+ * skips variant-specific service-line decoding.
443
561
  *
444
562
  * @example
445
563
  * ```ts
446
564
  * import { unknown837Variant } from "@cosyte/x12";
447
- * const w = unknown837Variant(
448
- * { segmentIndex: 1, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
449
- * "005010X999",
450
- * );
565
+ * const w = unknown837Variant({ segmentIndex: 1, groupIndex: 0, transactionIndex: 0 });
451
566
  * ```
452
567
  */
453
- declare function unknown837Variant(position: X12Position, implementationConventionReference: string | undefined): X12ParseWarning;
568
+ declare function unknown837Variant(position: X12Position): X12ParseWarning;
454
569
  /**
455
570
  * Build an `X12_UNKNOWN_CLAIM_STATUS_CATEGORY` warning. Emitted by the 277
456
571
  * / 277CA helpers when an STC composite's Claim Status Category Code
457
- * (CSCC, first component) is outside the bundled snapshot (see
458
- * {@link "../code-lists/claim-status-category.js".
459
- * CLAIM_STATUS_CATEGORY_CODES}). The verbatim CSCC is still preserved on
460
- * the parsed status - only the description is missing. The code value is
461
- * shape-validated against the CSCC grammar before echoing; a hostile
462
- * non-conformant value collapses to the literal `(non-spec)` so the
463
- * parser never echoes arbitrary bytes (H-PHI invariant).
572
+ * (CSCC, first component; X12 code source 507) is outside the bundled
573
+ * snapshot. The verbatim CSCC is preserved on the parsed status; only the
574
+ * description is missing.
464
575
  *
465
576
  * @example
466
577
  * ```ts
467
578
  * import { unknownClaimStatusCategory } from "@cosyte/x12";
468
- * const w = unknownClaimStatusCategory(
469
- * { segmentIndex: 18, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
470
- * "Z9",
471
- * );
579
+ * const w = unknownClaimStatusCategory({ segmentIndex: 18, transactionIndex: 0 });
472
580
  * ```
473
581
  */
474
- declare function unknownClaimStatusCategory(position: X12Position, code: string): X12ParseWarning;
582
+ declare function unknownClaimStatusCategory(position: X12Position): X12ParseWarning;
475
583
  /**
476
584
  * Build an `X12_UNKNOWN_CLAIM_STATUS` warning. Companion to
477
585
  * {@link unknownClaimStatusCategory} for the Claim Status Code (CSC, the
478
586
  * second component of an STC composite; X12 code source 508). Same
479
- * shape-validation + verbatim-preserve posture; reuses the CARC/RARC
480
- * `[A-Z0-9]{1,5}` value grammar (CSCs are short numeric tokens).
587
+ * verbatim-preserve posture.
481
588
  *
482
589
  * @example
483
590
  * ```ts
484
591
  * import { unknownClaimStatus } from "@cosyte/x12";
485
- * const w = unknownClaimStatus(
486
- * { segmentIndex: 18, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
487
- * "99999",
488
- * );
592
+ * const w = unknownClaimStatus({ segmentIndex: 18, transactionIndex: 0 });
489
593
  * ```
490
594
  */
491
- declare function unknownClaimStatus(position: X12Position, code: string): X12ParseWarning;
595
+ declare function unknownClaimStatus(position: X12Position): X12ParseWarning;
492
596
  /**
493
597
  * Build an `X12_834_UNKNOWN_MAINTENANCE_TYPE` warning. Emitted by the 834
494
598
  * helper when a member-level `INS-03` (or a health-coverage `HD-01`)
495
599
  * maintenance type code falls outside the bundled snapshot (see
496
600
  * {@link "../code-lists/maintenance-type.js".MAINTENANCE_TYPE_CODES}).
497
- * Maintenance type is the 834's safety-critical field - an unknown action
601
+ * Maintenance type is the 834's safety-critical field: an unknown action
498
602
  * code must NEVER be silently coerced to add / change / terminate, so the
499
603
  * verbatim code is preserved on the parsed enrollment and this warning
500
- * flags the gap. The code value is shape-validated against `[0-9]{3}`
501
- * before echoing; a hostile non-conformant value collapses to the literal
502
- * `(non-spec)` (H-PHI invariant).
604
+ * flags the gap.
503
605
  *
504
606
  * @example
505
607
  * ```ts
506
608
  * import { unknownMaintenanceType } from "@cosyte/x12";
507
- * const w = unknownMaintenanceType(
508
- * { segmentIndex: 9, interchangeIndex: 0, groupIndex: 0, transactionIndex: 0 },
509
- * "999",
510
- * );
609
+ * const w = unknownMaintenanceType({ segmentIndex: 9, transactionIndex: 0 });
511
610
  * ```
512
611
  */
513
- declare function unknownMaintenanceType(position: X12Position, code: string): X12ParseWarning;
612
+ declare function unknownMaintenanceType(position: X12Position): X12ParseWarning;
514
613
 
515
614
  /**
516
615
  * Type definitions for the `@cosyte/x12` profile subsystem (Phase 9).
@@ -961,6 +1060,21 @@ interface X12Segment {
961
1060
  readonly raw: string;
962
1061
  readonly elements: readonly string[];
963
1062
  }
1063
+ /**
1064
+ * The value {@link X12Segment.id} takes when the first element does not
1065
+ * match the X12 segment-id grammar. Not a valid segment id, so it can
1066
+ * never collide with a real one in a `seg.id === "NM1"` comparison.
1067
+ *
1068
+ * @example
1069
+ * ```ts
1070
+ * import { parseX12, NON_SPEC_SEGMENT_ID } from "@cosyte/x12";
1071
+ * const seg = parseX12(raw).groups[0]?.transactions[0]?.segments[1];
1072
+ * if (seg?.id === NON_SPEC_SEGMENT_ID) {
1073
+ * // the sender's "segment" name is not a spec segment id; its bytes are on seg.raw
1074
+ * }
1075
+ * ```
1076
+ */
1077
+ declare const NON_SPEC_SEGMENT_ID = "(non-spec)";
964
1078
  /**
965
1079
  * Decode a raw segment string into an {@link X12Segment}. Splits on the
966
1080
  * detected element separator (honouring the `?`-release-character escape),
@@ -1378,14 +1492,173 @@ interface X12FunctionalGroup {
1378
1492
  readonly ge: GeSegment | undefined;
1379
1493
  readonly transactions: readonly X12TransactionSet[];
1380
1494
  }
1495
+ /**
1496
+ * Where an orphan sat in the STRUCTURE of the interchange, as opposed to
1497
+ * where it sat in the input byte stream. This is what lets `serializeX12`
1498
+ * put an orphan back without guessing.
1499
+ *
1500
+ * `X12OrphanSegment.segmentIndex` cannot do that job. It indexes the INPUT
1501
+ * stream, and the emit is not in input order: `ta1Segments` are hoisted ahead
1502
+ * of the groups, and a doubled terminator's zero-length segment occupies an
1503
+ * input index that is never emitted. Either one shifts the output's indices
1504
+ * away from the input's, so replaying by index splices the orphan into
1505
+ * whatever occupies that slot - measurably, into an 835's `ST..SE` body,
1506
+ * where a re-parse reports nothing. An anchor names a slot in the typed tree
1507
+ * instead, which survives both reorderings because it does not mention bytes.
1508
+ *
1509
+ * Three kinds, one per structural level:
1510
+ *
1511
+ * - **`"interchange"`** - between the ISA and the IEA but outside every
1512
+ * functional group. `groupIndex` is the number of groups that had already
1513
+ * closed, so the orphan is emitted immediately before `ix.groups[groupIndex]`
1514
+ * (or before the IEA when `groupIndex === ix.groups.length`).
1515
+ * - **`"group"`** - inside `ix.groups[groupIndex]` but outside every
1516
+ * transaction set in it. `transactionIndex` is the number of transactions
1517
+ * that had already closed, so the orphan is emitted immediately before that
1518
+ * group's `transactions[transactionIndex]` (or before its `GE` when
1519
+ * `transactionIndex === transactions.length`).
1520
+ * - **`"transaction"`** - inside an open `ST..SE`, which only a `TA1` can be,
1521
+ * since every other segment arriving there is body content. `segmentOffset`
1522
+ * is the number of `rawSegments` already collected, so the orphan is emitted
1523
+ * immediately before `rawSegments[segmentOffset]`. It is never `0` (the `ST`
1524
+ * is always `rawSegments[0]`) and never exceeds `rawSegments.length`. Such an
1525
+ * orphan is written back BETWEEN the `ST` and the `SE`, so `serializeX12`
1526
+ * counts it toward SE-01 in spec-clean mode even though it is not on
1527
+ * `tx.rawSegments` - it is a segment of that transaction set per X12.6.
1528
+ *
1529
+ * **An anchor is a POSITION, so reshaping the model invalidates it.** The
1530
+ * indices address `ix.groups`, that group's `transactions`, and that
1531
+ * transaction's `rawSegments` as they stand on the interchange you pass to
1532
+ * `serializeX12`. Filter or reorder any of those and an orphan's anchor may
1533
+ * still resolve while naming a different slot, and it will be emitted there
1534
+ * with no warning. An anchor that resolves to nothing is emitted at
1535
+ * interchange level before the IEA rather than dropped. Re-parse rather than
1536
+ * hand-edit if you need anchors to stay meaningful.
1537
+ *
1538
+ * @example
1539
+ * ```ts
1540
+ * import { parseX12 } from "@cosyte/x12";
1541
+ * const ix = parseX12(raw);
1542
+ * for (const o of ix.orphanSegments) {
1543
+ * if (o.anchor.kind === "group") console.warn(o.anchor.groupIndex);
1544
+ * }
1545
+ * ```
1546
+ */
1547
+ type X12OrphanAnchor = {
1548
+ readonly kind: "interchange";
1549
+ /** How many functional groups had closed before this segment arrived. */
1550
+ readonly groupIndex: number;
1551
+ } | {
1552
+ readonly kind: "group";
1553
+ /** Index into `ix.groups` of the group that was open. */
1554
+ readonly groupIndex: number;
1555
+ /** How many transaction sets in that group had closed. */
1556
+ readonly transactionIndex: number;
1557
+ } | {
1558
+ readonly kind: "transaction";
1559
+ /** Index into `ix.groups` of the group that was open. */
1560
+ readonly groupIndex: number;
1561
+ /** Index into that group's `transactions` of the set that was open. */
1562
+ readonly transactionIndex: number;
1563
+ /** How many of that set's `rawSegments` had been collected. */
1564
+ readonly segmentOffset: number;
1565
+ };
1566
+ /**
1567
+ * String-literal union over the `kind` discriminant of {@link X12OrphanAnchor}.
1568
+ *
1569
+ * @example
1570
+ * ```ts
1571
+ * import type { X12OrphanAnchorKind } from "@cosyte/x12";
1572
+ * const kind: X12OrphanAnchorKind = "transaction";
1573
+ * ```
1574
+ */
1575
+ type X12OrphanAnchorKind = X12OrphanAnchor["kind"];
1576
+ /**
1577
+ * A segment the envelope grammar has no place for, captured verbatim rather
1578
+ * than discarded. Every segment recorded here also raised exactly one
1579
+ * `X12_UNEXPECTED_SEGMENT` warning whose `position.segmentIndex` equals
1580
+ * {@link segmentIndex}, and `context` is that warning's library-owned
1581
+ * discriminant, so the two surfaces can be joined without string matching.
1582
+ *
1583
+ * These are structural anomalies, not a normal shape: a stray segment
1584
+ * between `GE` and `IEA`, a body segment between an `SE` and its group's
1585
+ * `GE`, a body segment between `GS` and the first `ST`, an `ST` with no open
1586
+ * group, an `SE` closing nothing, a `GE` closing nothing, or a `TA1` inside
1587
+ * an open functional group. The parser cannot place any of them in the typed
1588
+ * tree, but it no longer drops them either, so a segment that used to vanish
1589
+ * is now readable here.
1590
+ *
1591
+ * **Most of these sit outside every ST..SE transaction set, but the `TA1`
1592
+ * case does not.** `TA1` is envelope-level by spec, so a `TA1` anywhere
1593
+ * inside an open group is routed here even when it arrives BETWEEN an `ST`
1594
+ * and its `SE` - in which case it is lifted out of that transaction's
1595
+ * `segments` / `rawSegments` and appears only on this array. That is
1596
+ * long-standing behaviour (it predates this array; the segment simply used
1597
+ * to be discarded), and it is the one case where `ix.groups` is not the whole
1598
+ * typed model.
1599
+ *
1600
+ * **`serializeX12` re-emits these, at {@link anchor}**, so an orphan and its
1601
+ * `X12_UNEXPECTED_SEGMENT` warning both survive a round trip. Placement is by
1602
+ * the structural anchor and NEVER by {@link segmentIndex}: that index is an
1603
+ * index into the INPUT stream, and the emit is not in input order (it hoists
1604
+ * `ta1Segments` ahead of the groups and skips the zero-length segment a
1605
+ * doubled terminator produces), so replaying by index splices an orphan into
1606
+ * whatever occupies that slot - measurably, into an 835's `ST..SE` body,
1607
+ * where a re-parse reports nothing at all. Use {@link segmentIndex} to join
1608
+ * back to the warning, not to place the segment. See `KNOWN-LIMITATIONS.md`.
1609
+ *
1610
+ * Two things are NOT recorded here. A doubled segment terminator delimits a
1611
+ * zero-length segment carrying no elements, so there is nothing to retain.
1612
+ * A segment whose first element is empty (`*A*B~`) has no id for the
1613
+ * envelope walker to dispatch on and is skipped without a warning; that is
1614
+ * long-standing behaviour this array does not change.
1615
+ *
1616
+ * **This is document content, so treat it as PHI.** Unlike an
1617
+ * `X12ParseWarning`, whose `message` is a lookup into a frozen registry and
1618
+ * whose metadata is positional only, an orphan carries the sender's bytes
1619
+ * verbatim, exactly as `X12TransactionSet.rawSegments` and `isa.raw` do. A
1620
+ * segment outside a transaction is not required to be PHI-free, so do NOT
1621
+ * log this array wholesale when triaging; log `context` and `segmentIndex`,
1622
+ * which name the structural rule and the location without echoing content.
1623
+ *
1624
+ * @example
1625
+ * ```ts
1626
+ * import { parseX12 } from "@cosyte/x12";
1627
+ * const ix = parseX12(raw);
1628
+ * for (const o of ix.orphanSegments) {
1629
+ * console.warn(o.context, o.segmentIndex, o.segment.id);
1630
+ * }
1631
+ * ```
1632
+ */
1633
+ interface X12OrphanSegment {
1634
+ /** The verbatim segment text, segment terminator stripped. */
1635
+ readonly raw: string;
1636
+ /** The decoded segment (id + 1-indexed elements), as for any body segment. */
1637
+ readonly segment: X12Segment;
1638
+ /**
1639
+ * Global segment index in the post-ISA stream (ISA itself is index 0) -
1640
+ * identical to the `position.segmentIndex` of the segment's
1641
+ * `X12_UNEXPECTED_SEGMENT` warning.
1642
+ */
1643
+ readonly segmentIndex: number;
1644
+ /** Which structural rule the segment broke. */
1645
+ readonly context: X12UnexpectedSegmentContext;
1646
+ /**
1647
+ * Where the segment sat in the typed tree - the slot `serializeX12` puts it
1648
+ * back into. See {@link X12OrphanAnchor} for why a structural anchor and not
1649
+ * {@link segmentIndex} is what makes re-emission sound.
1650
+ */
1651
+ readonly anchor: X12OrphanAnchor;
1652
+ }
1381
1653
  /**
1382
1654
  * The top-level X12 interchange returned by `parseX12`. `isa` carries the
1383
1655
  * envelope header verbatim; `delimiters` is the four-class delimiter set
1384
1656
  * detected from fixed positions inside `isa.raw`; `groups` is the ordered
1385
- * GS..GE list; `warnings` accumulates every Tier-2 deviation observed
1386
- * during the parse (lenient mode); `trailingBytes` (when present) is any
1387
- * non-empty content after IEA - preserved verbatim so a consumer can
1388
- * inspect or re-emit it.
1657
+ * GS..GE list; `orphanSegments` holds any segment that fell outside every
1658
+ * transaction set (empty for a well-formed interchange); `warnings`
1659
+ * accumulates every Tier-2 deviation observed during the parse (lenient
1660
+ * mode); `trailingBytes` (when present) is any non-empty content after IEA -
1661
+ * preserved verbatim so a consumer can inspect or re-emit it.
1389
1662
  *
1390
1663
  * @example
1391
1664
  * ```ts
@@ -1400,6 +1673,14 @@ interface X12Interchange {
1400
1673
  readonly delimiters: Delimiters;
1401
1674
  readonly groups: readonly X12FunctionalGroup[];
1402
1675
  readonly ta1Segments: readonly Ta1Segment[];
1676
+ /**
1677
+ * Segments the envelope grammar could not place, in input order - almost
1678
+ * always because they fell outside every ST..SE transaction set, plus the
1679
+ * `TA1`-inside-a-group case, which is lifted out of the transaction it
1680
+ * arrived in. Empty for a well-formed interchange. See
1681
+ * {@link X12OrphanSegment}.
1682
+ */
1683
+ readonly orphanSegments: readonly X12OrphanSegment[];
1403
1684
  readonly warnings: readonly X12ParseWarning[];
1404
1685
  readonly trailingBytes?: string;
1405
1686
  /**
@@ -1432,7 +1713,9 @@ interface X12Interchange {
1432
1713
  * throw {@link X12ParseError}: `X12_EMPTY_INPUT`, `X12_NO_ISA_HEADER`,
1433
1714
  * `X12_ISA_TOO_SHORT`, `X12_INVALID_DELIMITERS`. Opt into strict mode with
1434
1715
  * `{ strict: true }` to escalate every Tier-2 warning into an
1435
- * `X12ParseError` carrying the warning's code.
1716
+ * `X12ParseError` carrying the warning's code. A strict-mode escalation
1717
+ * carries an empty `snippet`: the warning it wraps is registry-built and
1718
+ * fully located by `position`, so there is nothing to redact.
1436
1719
  *
1437
1720
  * Phase 1 decodes the envelope (ISA / GS / ST / SE / GE / IEA) and
1438
1721
  * detects the four delimiters from fixed ISA byte positions. Transaction-
@@ -1610,11 +1893,19 @@ type X12FatalCode = (typeof FATAL_CODES)[keyof typeof FATAL_CODES];
1610
1893
  * snippet of the offending input so consumers can log actionable errors.
1611
1894
  *
1612
1895
  * @remarks
1613
- * Snippets may contain PHI/PII when parsing real interchanges (member IDs
1614
- * appear in ISA-06/08 only as trading-partner IDs, not patient identity -
1615
- * but real claim/eligibility bodies elsewhere in the input can carry PHI).
1616
- * Redact at the call site if required by your compliance posture. The
1617
- * library does not redact snippets itself.
1896
+ * `snippet` is the library's ONE deliberate PHI exception, and it exists for
1897
+ * the four Tier-3 structural fatals only. Those are raised before the
1898
+ * envelope is readable and are undebuggable without a few bytes of context.
1899
+ * It may contain PHI/PII when parsing real interchanges (member IDs appear in
1900
+ * ISA-06/08 only as trading-partner IDs, not patient identity, but a real
1901
+ * claim / eligibility body elsewhere in the input can carry PHI). Redact at
1902
+ * the call site if required by your compliance posture; the library does not
1903
+ * redact snippets itself.
1904
+ *
1905
+ * A strict-mode escalation of a Tier-2 warning carries `snippet: ""`. That
1906
+ * error's `message` is the same frozen-registry entry the warning carried and
1907
+ * `position` locates it, so there is nothing to attach and nothing to
1908
+ * redact.
1618
1909
  *
1619
1910
  * @example
1620
1911
  * ```ts
@@ -3931,8 +4222,12 @@ declare const REMIT_835_LOOP_1000B: LoopSpec;
3931
4222
  * cash to the wrong dollar. These checks NEVER silently rebalance: a
3932
4223
  * failed invariant emits an {@link
3933
4224
  * "../../parser/warnings.js".WARNING_CODES.X12_835_REMIT_BALANCE_MISMATCH}
3934
- * carrying the side-by-side spec'd vs computed values + delta, and the
3935
- * model still resolves with the verbatim inbound amounts.
4225
+ * naming which TR3 equation broke, and the model still resolves with the
4226
+ * verbatim inbound amounts. The amounts themselves are NOT rendered into
4227
+ * the message: an EDI amount is a consumer-controlled element like any
4228
+ * other, and the spec'd / computed / delta trio used to be interpolated
4229
+ * unbounded. Recompute them from the model, which carries every one of
4230
+ * them as an `X12Decimal`.
3936
4231
  *
3937
4232
  * Three invariants per TR3 005010X221A1 §1.10.2 ("Balancing"):
3938
4233
  *
@@ -3960,11 +4255,33 @@ declare const REMIT_835_LOOP_1000B: LoopSpec;
3960
4255
  * > slice with a forward-pointer to this module so the contract stays
3961
4256
  * > consistent.
3962
4257
  *
3963
- * **PHI discipline:** mismatch messages echo only the invariant label +
3964
- * the X12Decimal text values (numeric - no PHI by shape). Patient
3965
- * control numbers / member ids are NOT in the message - consumers
3966
- * locate the offending claim via the warning's `position` + the claim's
3967
- * sequence in `remit.claims`.
4258
+ * **PHI discipline: the message names the equation and carries no value at
4259
+ * all**, not even an amount. An EDI amount is a consumer-controlled element
4260
+ * like any other: `CLP-03` is whatever the payer sent, so the spec'd /
4261
+ * computed / delta trio these messages used to interpolate was an unbounded
4262
+ * echo of sender bytes. Recompute the numbers from the model, which carries
4263
+ * every one of them as an `X12Decimal`.
4264
+ *
4265
+ * **Which claim, then?** Three different answers, one per invariant.
4266
+ *
4267
+ * - **Claim-level** ({@link checkClaimBalance}): `position.segmentIndex` is
4268
+ * the CLP segment's own 1-based index inside the transaction body, so
4269
+ * `tx.segments[position.segmentIndex]` is that exact CLP.
4270
+ * - **Service-line** ({@link checkServiceLineBalance}): that CLP index plus
4271
+ * the line's zero-based ordinal plus one, which is a **unique locator, not
4272
+ * a pointer at the SVC**. The segment sitting at that index is usually
4273
+ * something else in the claim's loop. Read it as "the claim whose CLP is at
4274
+ * `segmentIndex - (ordinal + 1)`, service line `ordinal`", or match against
4275
+ * `remit.claims` and `claim.serviceLines`, which carry the decoded model.
4276
+ * What the offset guarantees is non-collision across claims: a claim with
4277
+ * `n` service lines spans at least `n + 1` body segments, so the next CLP
4278
+ * always sits past the previous claim's last line position.
4279
+ * - **Remit-level** ({@link checkRemitTotalBalance}): `segmentIndex` is
4280
+ * **`0`**, not a CLP and not the BPR. The top-of-remit equation spans the
4281
+ * whole transaction set and has no single offending segment, and there is
4282
+ * at most one such warning per transaction, so it needs no locator to stay
4283
+ * distinct. Read it as "this transaction set", and take the amounts from
4284
+ * `remit.paymentAmount` and `remit.claims`.
3968
4285
  */
3969
4286
 
3970
4287
  /**
@@ -3978,7 +4295,8 @@ declare const REMIT_835_LOOP_1000B: LoopSpec;
3978
4295
  * declare const claim: X12RemitClaim;
3979
4296
  * const w = checkClaimBalance(claim, { segmentIndex: 12 });
3980
4297
  * if (w !== undefined) {
3981
- * // not balanced - w.message names invariant + spec + computed + delta
4298
+ * // not balanced - w.message names the TR3 equation; the amounts are on `claim`,
4299
+ * // and w.position.segmentIndex is the CLP's own index in the transaction body
3982
4300
  * }
3983
4301
  * ```
3984
4302
  */
@@ -11873,14 +12191,71 @@ interface BuildTA1Options {
11873
12191
  * - **Byte-faithful (default).** Reconstructs the interchange purely from the
11874
12192
  * verbatim `.raw` strings the parser preserved (ISA + terminator, then each
11875
12193
  * GS / transaction segment / GE / IEA terminator-joined, then any
11876
- * `trailingBytes`). For a Tier-1 (spec-clean, no-CRLF) input this is exactly
11877
- * the source bytes - the idempotency fixed point `serialize(parse(s)) === s`.
11878
- * Inter-segment CRLF and a trailing newline are NOT reproduced: the parser
11879
- * silently normalizes them away (they are not in the model), so a
11880
- * pretty-printed source round-trips to its compact spec-clean form.
12194
+ * `trailingBytes`). "Byte-faithful" is a statement about SEGMENTS ON THE
12195
+ * MODEL, and the distinction matters to anyone diffing output against input.
12196
+ *
12197
+ * Every segment the parser recorded comes back verbatim, including element
12198
+ * padding, composite structure and `?`-release escapes, but it comes back in
12199
+ * the ORDER the model holds it, which is not always the input order. SIX
12200
+ * constructs are known not to survive, and line breaks are only the most
12201
+ * common:
12202
+ *
12203
+ * 1. **Line breaks between segments.** The parser absorbs any run of CR /
12204
+ * LF bytes between segments and the model has nowhere to record it, so a
12205
+ * pretty-printed or double-spaced source emits as its compact form.
12206
+ * Silent.
12207
+ * 2. **A doubled segment terminator** outside a transaction. It delimits a
12208
+ * zero-length segment carrying no elements, so there is nothing to
12209
+ * retain. Silent.
12210
+ * 3. **A missing final terminator**, which the emit supplies. Silent.
12211
+ * 4. **Post-IEA `trailingBytes`**, re-joined from segment slices rather than
12212
+ * preserved verbatim.
12213
+ * 5. **TA1 position.** A TA1 that appeared AFTER a functional group is
12214
+ * collected onto `ix.ta1Segments` and emitted immediately after the ISA,
12215
+ * so the emit reorders it. Silent, and unlike the others nothing is
12216
+ * dropped: the model and the warning stream both round-trip identically.
12217
+ * This is also the only construct that can move something ELSE - a
12218
+ * segment outside a transaction is placed correctly relative to the
12219
+ * groups but not relative to a TA1 that was hoisted past it. This library
12220
+ * takes no position here on where ASC X12 requires a TA1 to sit.
12221
+ * 6. **A segment whose first element is empty** (`*A*B~`), outside a
12222
+ * transaction. It has no id for the envelope walker to dispatch on, so it
12223
+ * is skipped: absent from the model, absent from the emit, and it does
12224
+ * not even raise `X12_UNEXPECTED_SEGMENT`. Silent, and the only case here
12225
+ * that loses a value with no diagnostic at all. Inside an open
12226
+ * transaction the same segment is kept and re-emitted normally.
12227
+ *
12228
+ * **A segment outside a transaction is no longer on that list.** It is
12229
+ * retained on `ix.orphanSegments` with a structural `anchor`, and this
12230
+ * function re-emits it at that anchor, so the segment, its value and its
12231
+ * `X12_UNEXPECTED_SEGMENT` warning all survive the round trip. See the
12232
+ * `orphans` block below for why placement is by anchor and never by
12233
+ * `segmentIndex`.
12234
+ *
12235
+ * So `serialize(parse(s)) === s` is still NOT guaranteed in general, and the
12236
+ * absence of line breaks is still not sufficient to make it hold: cases 2 to
12237
+ * 6 all break it on inputs that contain none. Five of the six (1, 2, 3, 5, 6)
12238
+ * produce no warning at all, so the warning stream is not a reliable signal
12239
+ * that a round trip will be byte-exact - only case 4 warns.
12240
+ *
12241
+ * What IS measured, across the 56 committed fixtures: all 56 emits are fixed
12242
+ * points (serializing again is a byte-level no-op), all 56 re-parse to an
12243
+ * identical model with an identical warning stream, the 14 fixtures carrying
12244
+ * no line breaks return byte-identical, and the 42 that are pretty-printed
12245
+ * differ from their source by line breaks and nothing else. Two caveats on
12246
+ * that corpus: it contains no instance of cases 2 to 6 and no orphan at all,
12247
+ * and 13 of the 14 byte-identical fixtures are `golden/*.edi`, which are
12248
+ * serializer output by construction, so `envelope/no-trailing-crlf.edi` is
12249
+ * the only independent witness. `test/serialize.test.ts` covers the corpus
12250
+ * sweep, the orphan round trip, and cases 1 to 6 separately.
11881
12251
  *
11882
12252
  * - **Spec-clean (`{ specClean: true }`).** Same byte-faithful structure, but
11883
- * the serializer ALSO reconciles the envelope counts and control numbers:
12253
+ * the serializer ALSO reconciles the envelope counts and control numbers.
12254
+ * Every count is taken from the bytes this function WRITES, which for SE-01
12255
+ * is `tx.rawSegments` PLUS any orphan re-emitted between the `ST` and the
12256
+ * `SE` - a lifted `TA1` is off the model's transaction but is still a
12257
+ * segment of that transaction set per X12.6, and counting the model alone
12258
+ * made `recomputeCounts` shrink a correct SE-01. The pairs reconciled are
11884
12259
  * SE-01 (segment count) vs the actual ST..SE segment count, GE-01
11885
12260
  * (transaction count) vs the actual ST count, IEA-01 (group count) vs the
11886
12261
  * actual group count, plus the ISA-13↔IEA-02 / GS-06↔GE-02 / ST-02↔SE-02
@@ -11891,9 +12266,12 @@ interface BuildTA1Options {
11891
12266
  * segments. Control numbers are identity, not derived, so they are NEVER
11892
12267
  * rewritten - only flagged.
11893
12268
  *
11894
- * Warning messages carry positional context + bounded numeric metadata only;
11895
- * they never echo element VALUES (the H-PHI invariant shared across the
11896
- * `@cosyte/x12` warning factories).
12269
+ * Every warning it emits is built by the same value-free factories the parser
12270
+ * uses: `message` is a frozen-registry lookup and `position` locates the
12271
+ * control segment, so a declared count or control number can never reach a
12272
+ * diagnostic. Read the declared and actual values off the model
12273
+ * (`se.elements[1]` against `tx.rawSegments.length`, `ge.elements[1]` against
12274
+ * `group.transactions.length`, `iea.elements[1]` against `ix.groups.length`).
11897
12275
  */
11898
12276
 
11899
12277
  /**
@@ -11943,7 +12321,10 @@ interface SerializeOptions {
11943
12321
  * ```ts
11944
12322
  * import { parseX12, serializeX12 } from "@cosyte/x12";
11945
12323
  * const ix = parseX12(raw);
11946
- * const bytes = serializeX12(ix); // byte-faithful for a Tier-1 input
12324
+ * // Segments on the model come back verbatim, orphans included. Anything the
12325
+ * // parser did not record (line breaks, a doubled terminator, ...) does not,
12326
+ * // so this is not guaranteed to equal `raw`. See the module header.
12327
+ * const bytes = serializeX12(ix);
11947
12328
  * ```
11948
12329
  */
11949
12330
  declare function serializeX12(interchange: X12Interchange, opts?: SerializeOptions): string;
@@ -12479,4 +12860,4 @@ declare const profiles: {
12479
12860
  */
12480
12861
  declare const VERSION: string;
12481
12862
 
12482
- export { ACK_BUILD_ERROR_CODES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, type AckBuildErrorCode, type Build271AddressSpec, type Build271BenefitSpec, type Build271DateSpec, type Build271DependentSpec, type Build271EntitySpec, type Build271EnvelopeSpec, type Build271InformationReceiverSpec, type Build271InformationSourceSpec, type Build271MemberSpec, type Build271ReferenceSpec, type Build271ServiceTypeSpec, type Build271Spec, type Build271SubscriberSpec, type Build271TraceSpec, type Build277ClaimSpec, type Build277DateSpec, type Build277DependentSpec, type Build277EntitySpec, type Build277EnvelopeSpec, type Build277InformationReceiverSpec, type Build277InformationSourceSpec, type Build277MemberSpec, type Build277ProviderSpec, type Build277ReferenceSpec, type Build277ServiceLineSpec, type Build277Spec, type Build277StatusCodeSpec, type Build277StatusSpec, type Build277SubscriberSpec, type Build277TraceSpec, type Build278DateSpec, type Build278DecisionSpec, type Build278DependentSpec, type Build278DiagnosisSpec, type Build278EntitySpec, type Build278EnvelopeSpec, type Build278HeaderSpec, type Build278MemberSpec, type Build278ReferenceSpec, type Build278ReviewSpec, type Build278Spec, type Build278SubscriberSpec, type Build278TraceSpec, type Build820AddressSpec, type Build820AdjustmentSpec, type Build820DateSpec, type Build820EntitySpec, type Build820EnvelopeSpec, type Build820OpenItemSpec, type Build820PartySpec, type Build820PaymentSpec, type Build820PersonSpec, type Build820ReferenceSpec, type Build820RemittanceSpec, type Build820Spec, type Build820TraceSpec, type Build834AddressSpec, type Build834AmountSpec, type Build834CoordinationOfBenefitsSpec, type Build834CoverageSpec, type Build834DateSpec, type Build834EnvelopeSpec, type Build834HeaderSpec, type Build834MemberNameSpec, type Build834MemberSpec, type Build834PartySpec, type Build834ReferenceSpec, type Build834Spec, type Build835AddressSpec, type Build835AdjustmentSpec, type Build835AmountSpec, type Build835ClaimSpec, type Build835ContactSpec, type Build835EnvelopeSpec, type Build835PartySpec, type Build835PaymentSpec, type Build835PersonSpec, type Build835ProviderAdjustmentSpec, type Build835ProviderSpec, type Build835ReferenceSpec, type Build835RemarkSpec, type Build835ServiceLineSpec, type Build835Spec, type Build835TraceSpec, type Build837AddressSpec, type Build837AdjudicationSpec, type Build837AdjustmentSpec, type Build837AmountSpec, type Build837BillingProviderSpec, type Build837ClaimSpec, type Build837ContactSpec, type Build837DateSpec, type Build837DrugSpec, type Build837EntitySpec, type Build837EnvelopeSpec, type Build837HiCodeSpec, type Build837NoteSpec, type Build837OtherSubscriberSpec, type Build837PatientSpec, type Build837ReferenceSpec, type Build837ServiceLineBaseSpec, type Build837ServiceLineDentalSpec, type Build837ServiceLineInstitutionalSpec, type Build837ServiceLineProfessionalSpec, type Build837ServiceLineSpec, type Build837Spec, type Build837SubscriberInfoSpec, type Build837SubscriberSpec, type Build837ToothSpec, type Build999ElementErrorSpec, type Build999EnvelopeSpec, type Build999FunctionalGroupSpec, type Build999SegmentErrorSpec, type Build999Spec, type Build999TransactionResponseSpec, type BuildTA1Options, type BuildTA1Spec, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, Claim837BuildError, type Claim837BuildErrorCode, type ClaimAdjustmentGroupCode, ClaimStatus277BuildError, type ClaimStatus277BuildErrorCode, type CodeListEntry, type CodeListMeta, type CodeListSnapshot, DELIMITER_POSITIONS, type DefineLoopSpecInput, type Delimiters, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, type Eligibility271BuildErrorCode, Enrollment834BuildError, type Enrollment834BuildErrorCode, FATAL_CODES, type FunctionalGroupSpec, type GeSegment, type GsSegment, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, type IeaSegment, type Ik304Code, type Ik403Code, type InterchangeSpec, type IsaSegment, type LoopMax, type LoopSegmentSpec, type LoopSpec, LoopSpecDefinitionError, type LoopUsage, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, type OnWarningCallback, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, type Premium820BuildErrorCode, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, Remit835BuildError, type Remit835BuildErrorCode, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, type SegmentSpec, type SerializeOptions, ServicesReview278BuildError, type ServicesReview278BuildErrorCode, TA1_ACK_CODES, TA1_NOTE_CODES, type Ta1AckCode, type Ta1NoteCode, type Ta1Segment, type TransactionSetSpec, VERSION, WARNING_CODES, type X12Ack999, type X12Ack999Ak1, type X12Ack999Ak2, type X12Ack999Ak9, type X12Ack999ElementNote, type X12Ack999Ik3, type X12Ack999Ik4, type X12Ack999Ik4Position, type X12Ack999Ik5, type X12Ack999SegmentNote, type X12Ack999TransactionResponse, type X12AckDispositionCode, type X12AckTA1, type X12AuthDate, type X12AuthDiagnosis, type X12AuthEntity, type X12AuthHeader, type X12AuthMember, type X12AuthReference, type X12AuthTrace, X12BuildError, type X12BuildErrorCode, type X12Claim, type X12Claim837Variant, type X12ClaimAddress, type X12ClaimAmount, type X12ClaimContact, type X12ClaimDate, type X12ClaimEntity, type X12ClaimHiCode, type X12ClaimMember, type X12ClaimNote, type X12ClaimReference, type X12ClaimStatus, type X12ClaimStatusResponse, type X12CoordinationOfBenefits, X12Decimal, type X12Eligibility, type X12EligibilityAddress, type X12EligibilityBenefit, type X12EligibilityDate, type X12EligibilityDependent, type X12EligibilityEntity, type X12EligibilityMember, type X12EligibilityReference, type X12EligibilityServiceType, type X12EligibilitySubscriber, type X12EligibilityTrace, type X12Enrollment, type X12EnrollmentAddress, type X12EnrollmentAmount, type X12EnrollmentDate, type X12EnrollmentHeader, type X12EnrollmentMember, type X12EnrollmentParty, type X12EnrollmentReference, type X12FatalCode, type X12FunctionalGroup, type X12HealthCoverage, type X12HiCategory, type X12HiCodeSystem, type X12HiQualifier, type X12HierarchicalLevel, type X12Hl, type X12Interchange, type X12LineAdjudication, type X12LineDrug, type X12OtherSubscriber, X12ParseError, type X12ParseOptions, type X12ParseWarning, type X12Position, type X12PremiumAddress, type X12PremiumAdjustment, type X12PremiumDate, type X12PremiumEntity, type X12PremiumOpenItem, type X12PremiumParty, type X12PremiumPaymentHeader, type X12PremiumPayments, type X12PremiumPerson, type X12PremiumReference, type X12PremiumRemittance, type X12PremiumTrace, type X12Profile, type X12ProfileDescription, type X12ProfileEffect, X12ProfileError, type X12ProfileQuirk, type X12ProfileSpec, type X12RemitAddress, type X12RemitAdjustment, type X12RemitAmount, type X12RemitClaim, type X12RemitContact, type X12RemitParty, type X12RemitPaymentHeader, type X12RemitPerson, type X12RemitProvider, type X12RemitProviderAdjustment, type X12RemitReference, type X12RemitRemark, type X12RemitServiceLine, type X12RemitTrace, type X12Remittance, type X12ReviewDecision, type X12Segment, type X12ServiceLineStatus, type X12ServiceReview, type X12ServicesReview, type X12StatusCode, type X12StatusDate, type X12StatusEntity, type X12StatusInfo, type X12StatusMember, type X12StatusReference, type X12StatusTrace, type X12SubscriberInfo, type X12ToothInformation, type X12TransactionSet, type X12WarningCode, type X12WarningPartition, type X12_837ServiceLine, type X12_837ServiceLineDental, type X12_837ServiceLineInstitutional, type X12_837ServiceLineProfessional, type X12_837Submission, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, remitBalanceMismatch, resolveHiQualifier, segmentCountMismatch, serializeX12, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc };
12863
+ export { ACK_BUILD_ERROR_CODES, ALL_WARNING_MESSAGES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, type AckBuildErrorCode, BALANCE_INVARIANTS, type Build271AddressSpec, type Build271BenefitSpec, type Build271DateSpec, type Build271DependentSpec, type Build271EntitySpec, type Build271EnvelopeSpec, type Build271InformationReceiverSpec, type Build271InformationSourceSpec, type Build271MemberSpec, type Build271ReferenceSpec, type Build271ServiceTypeSpec, type Build271Spec, type Build271SubscriberSpec, type Build271TraceSpec, type Build277ClaimSpec, type Build277DateSpec, type Build277DependentSpec, type Build277EntitySpec, type Build277EnvelopeSpec, type Build277InformationReceiverSpec, type Build277InformationSourceSpec, type Build277MemberSpec, type Build277ProviderSpec, type Build277ReferenceSpec, type Build277ServiceLineSpec, type Build277Spec, type Build277StatusCodeSpec, type Build277StatusSpec, type Build277SubscriberSpec, type Build277TraceSpec, type Build278DateSpec, type Build278DecisionSpec, type Build278DependentSpec, type Build278DiagnosisSpec, type Build278EntitySpec, type Build278EnvelopeSpec, type Build278HeaderSpec, type Build278MemberSpec, type Build278ReferenceSpec, type Build278ReviewSpec, type Build278Spec, type Build278SubscriberSpec, type Build278TraceSpec, type Build820AddressSpec, type Build820AdjustmentSpec, type Build820DateSpec, type Build820EntitySpec, type Build820EnvelopeSpec, type Build820OpenItemSpec, type Build820PartySpec, type Build820PaymentSpec, type Build820PersonSpec, type Build820ReferenceSpec, type Build820RemittanceSpec, type Build820Spec, type Build820TraceSpec, type Build834AddressSpec, type Build834AmountSpec, type Build834CoordinationOfBenefitsSpec, type Build834CoverageSpec, type Build834DateSpec, type Build834EnvelopeSpec, type Build834HeaderSpec, type Build834MemberNameSpec, type Build834MemberSpec, type Build834PartySpec, type Build834ReferenceSpec, type Build834Spec, type Build835AddressSpec, type Build835AdjustmentSpec, type Build835AmountSpec, type Build835ClaimSpec, type Build835ContactSpec, type Build835EnvelopeSpec, type Build835PartySpec, type Build835PaymentSpec, type Build835PersonSpec, type Build835ProviderAdjustmentSpec, type Build835ProviderSpec, type Build835ReferenceSpec, type Build835RemarkSpec, type Build835ServiceLineSpec, type Build835Spec, type Build835TraceSpec, type Build837AddressSpec, type Build837AdjudicationSpec, type Build837AdjustmentSpec, type Build837AmountSpec, type Build837BillingProviderSpec, type Build837ClaimSpec, type Build837ContactSpec, type Build837DateSpec, type Build837DrugSpec, type Build837EntitySpec, type Build837EnvelopeSpec, type Build837HiCodeSpec, type Build837NoteSpec, type Build837OtherSubscriberSpec, type Build837PatientSpec, type Build837ReferenceSpec, type Build837ServiceLineBaseSpec, type Build837ServiceLineDentalSpec, type Build837ServiceLineInstitutionalSpec, type Build837ServiceLineProfessionalSpec, type Build837ServiceLineSpec, type Build837Spec, type Build837SubscriberInfoSpec, type Build837SubscriberSpec, type Build837ToothSpec, type Build999ElementErrorSpec, type Build999EnvelopeSpec, type Build999FunctionalGroupSpec, type Build999SegmentErrorSpec, type Build999Spec, type Build999TransactionResponseSpec, type BuildTA1Options, type BuildTA1Spec, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, CONTROL_NUMBER_PAIRS, Claim837BuildError, type Claim837BuildErrorCode, type ClaimAdjustmentGroupCode, ClaimStatus277BuildError, type ClaimStatus277BuildErrorCode, type CodeListEntry, type CodeListMeta, type CodeListSnapshot, DELIMITER_POSITIONS, type DefineLoopSpecInput, type Delimiters, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, type Eligibility271BuildErrorCode, Enrollment834BuildError, type Enrollment834BuildErrorCode, FATAL_CODES, type FunctionalGroupSpec, type GeSegment, type GsSegment, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, type IeaSegment, type Ik304Code, type Ik403Code, type InterchangeSpec, type IsaSegment, type LoopMax, type LoopSegmentSpec, type LoopSpec, LoopSpecDefinitionError, type LoopUsage, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, type OnWarningCallback, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, type Premium820BuildErrorCode, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, REQUIRED_LOOPS, Remit835BuildError, type Remit835BuildErrorCode, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, type SegmentSpec, type SerializeOptions, ServicesReview278BuildError, type ServicesReview278BuildErrorCode, TA1_ACK_CODES, TA1_NOTE_CODES, type Ta1AckCode, type Ta1NoteCode, type Ta1Segment, type TransactionSetSpec, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, type X12Ack999, type X12Ack999Ak1, type X12Ack999Ak2, type X12Ack999Ak9, type X12Ack999ElementNote, type X12Ack999Ik3, type X12Ack999Ik4, type X12Ack999Ik4Position, type X12Ack999Ik5, type X12Ack999SegmentNote, type X12Ack999TransactionResponse, type X12AckDispositionCode, type X12AckTA1, type X12AuthDate, type X12AuthDiagnosis, type X12AuthEntity, type X12AuthHeader, type X12AuthMember, type X12AuthReference, type X12AuthTrace, type X12BalanceInvariant, X12BuildError, type X12BuildErrorCode, type X12Claim, type X12Claim837Variant, type X12ClaimAddress, type X12ClaimAmount, type X12ClaimContact, type X12ClaimDate, type X12ClaimEntity, type X12ClaimHiCode, type X12ClaimMember, type X12ClaimNote, type X12ClaimReference, type X12ClaimStatus, type X12ClaimStatusResponse, type X12ControlNumberPair, type X12CoordinationOfBenefits, X12Decimal, type X12Eligibility, type X12EligibilityAddress, type X12EligibilityBenefit, type X12EligibilityDate, type X12EligibilityDependent, type X12EligibilityEntity, type X12EligibilityMember, type X12EligibilityReference, type X12EligibilityServiceType, type X12EligibilitySubscriber, type X12EligibilityTrace, type X12Enrollment, type X12EnrollmentAddress, type X12EnrollmentAmount, type X12EnrollmentDate, type X12EnrollmentHeader, type X12EnrollmentMember, type X12EnrollmentParty, type X12EnrollmentReference, type X12FatalCode, type X12FunctionalGroup, type X12HealthCoverage, type X12HiCategory, type X12HiCodeSystem, type X12HiQualifier, type X12HierarchicalLevel, type X12Hl, type X12Interchange, type X12LineAdjudication, type X12LineDrug, type X12OrphanAnchor, type X12OrphanAnchorKind, type X12OrphanSegment, type X12OtherSubscriber, X12ParseError, type X12ParseOptions, type X12ParseWarning, type X12Position, type X12PremiumAddress, type X12PremiumAdjustment, type X12PremiumDate, type X12PremiumEntity, type X12PremiumOpenItem, type X12PremiumParty, type X12PremiumPaymentHeader, type X12PremiumPayments, type X12PremiumPerson, type X12PremiumReference, type X12PremiumRemittance, type X12PremiumTrace, type X12Profile, type X12ProfileDescription, type X12ProfileEffect, X12ProfileError, type X12ProfileQuirk, type X12ProfileSpec, type X12RemitAddress, type X12RemitAdjustment, type X12RemitAmount, type X12RemitClaim, type X12RemitContact, type X12RemitParty, type X12RemitPaymentHeader, type X12RemitPerson, type X12RemitProvider, type X12RemitProviderAdjustment, type X12RemitReference, type X12RemitRemark, type X12RemitServiceLine, type X12RemitTrace, type X12Remittance, type X12RequiredLoop, type X12ReviewDecision, type X12Segment, type X12ServiceLineStatus, type X12ServiceReview, type X12ServicesReview, type X12StatusCode, type X12StatusDate, type X12StatusEntity, type X12StatusInfo, type X12StatusMember, type X12StatusReference, type X12StatusTrace, type X12SubscriberInfo, type X12ToothInformation, type X12TransactionSet, type X12UnexpectedSegmentContext, type X12WarningCode, type X12WarningPartition, type X12_837ServiceLine, type X12_837ServiceLineDental, type X12_837ServiceLineInstitutional, type X12_837ServiceLineProfessional, type X12_837Submission, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, remitBalanceMismatch, resolveHiQualifier, segmentCountMismatch, serializeX12, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc };