@cosyte/x12 0.0.14 → 0.0.15
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/CHANGELOG.md +209 -0
- package/KNOWN-LIMITATIONS.md +203 -13
- package/dist/index.cjs +52 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +179 -30
- package/dist/index.d.ts +179 -30
- package/dist/index.mjs +52 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2483,9 +2483,10 @@ declare function unescapeRelease(input: string, delimiters: Delimiters, emit: (w
|
|
|
2483
2483
|
* the untyped-refusal defect this package has fixed elsewhere. This is a pure
|
|
2484
2484
|
* text utility with no spec, no element and no caller context to name, so
|
|
2485
2485
|
* `TypeError` is the accurate answer for a wrong-typed argument. **Nothing
|
|
2486
|
-
* inside this library can reach it**:
|
|
2486
|
+
* inside this library can reach it**: every builder routes its elements
|
|
2487
2487
|
* through `src/builder/caller-string.ts`, which refuses first with the calling
|
|
2488
|
-
* builder's own typed, code-tagged error.
|
|
2488
|
+
* builder's own typed, code-tagged error. (No count: it is asserted by
|
|
2489
|
+
* `test/builder-string-type.test.ts` and was stale here.) This throw is the backstop for a
|
|
2489
2490
|
* consumer calling the export directly, where the alternative was silent data
|
|
2490
2491
|
* loss.
|
|
2491
2492
|
*
|
|
@@ -5720,22 +5721,23 @@ declare function get837Claims(delimiters: Delimiters, tx: X12TransactionSet, opt
|
|
|
5720
5721
|
|
|
5721
5722
|
/**
|
|
5722
5723
|
* Interchange + group + transaction identity for the built 837. The builder
|
|
5723
|
-
* fixes GS-01 to `"HC"
|
|
5724
|
-
* (`005010X222A2` / `X223A3` / `X224A2`) so the caller never
|
|
5725
|
-
*
|
|
5726
|
-
*
|
|
5727
|
-
*
|
|
5728
|
-
*
|
|
5729
|
-
*
|
|
5730
|
-
*
|
|
5731
|
-
*
|
|
5732
|
-
*
|
|
5733
|
-
*
|
|
5734
|
-
*
|
|
5735
|
-
*
|
|
5736
|
-
*
|
|
5737
|
-
*
|
|
5738
|
-
*
|
|
5724
|
+
* fixes GS-01 to `"HC"`, and defaults the ST-03 / GS-08 reference to the
|
|
5725
|
+
* variant's TR3 (`005010X222A2` / `X223A3` / `X224A2`) so the caller never
|
|
5726
|
+
* has to hand-code it.
|
|
5727
|
+
*
|
|
5728
|
+
* **🩺 That default is not what every trading partner accepts, so
|
|
5729
|
+
* {@link Build837EnvelopeSpec.implementationConventionReference} overrides
|
|
5730
|
+
* it.** The three defaults are published errata guides, but they are
|
|
5731
|
+
* neither the identifiers HIPAA adopts at 45 CFR 162.1102 nor the ones
|
|
5732
|
+
* payer companion guides commonly require in ST-03 / GS-08 (CMS and several
|
|
5733
|
+
* state Medicaid guides state `005010X222A1` for Professional and
|
|
5734
|
+
* `005010X223A2` for Institutional). **A partner that requires one of those
|
|
5735
|
+
* will reject a Professional or Institutional 837 built on the default**,
|
|
5736
|
+
* and the override is how you send what your partner asked for. The default
|
|
5737
|
+
* itself was deliberately NOT re-stamped: which published guide identifier
|
|
5738
|
+
* a partner accepts is a partner fact rather than a spec fact, and changing
|
|
5739
|
+
* bytes this library already emitted would break the partners it works with
|
|
5740
|
+
* today. The READ side is unaffected - `get837Claims` recognises all of
|
|
5739
5741
|
* these references.
|
|
5740
5742
|
*
|
|
5741
5743
|
* @example
|
|
@@ -5764,6 +5766,44 @@ interface Build837EnvelopeSpec {
|
|
|
5764
5766
|
readonly groupControlNumber: string;
|
|
5765
5767
|
/** ST-02 / SE-02 - transaction set control number. */
|
|
5766
5768
|
readonly transactionSetControlNumber: string;
|
|
5769
|
+
/**
|
|
5770
|
+
* 🩺 ST-03 **and** GS-08 - the implementation convention reference this
|
|
5771
|
+
* 837 declares. Default: the variant's TR3 (`005010X222A2` Professional,
|
|
5772
|
+
* `005010X223A3` Institutional, `005010X224A2` Dental).
|
|
5773
|
+
*
|
|
5774
|
+
* **Set it to whatever your trading partner's companion guide requires**,
|
|
5775
|
+
* for example `005010X222A1` on a professional claim to a payer that asks
|
|
5776
|
+
* for it. Which published identifier a partner accepts is a partner fact,
|
|
5777
|
+
* so this library will not choose for you: it defaults to a real published
|
|
5778
|
+
* guide and gets out of the way. **One value is written to both elements**,
|
|
5779
|
+
* because this builder has always written the same reference to ST-03 and
|
|
5780
|
+
* GS-08 and nothing grounds a caller making them differ. That is a statement
|
|
5781
|
+
* about the bytes this field emits, not about what each element may legally
|
|
5782
|
+
* hold: GS-08 is data element 480 (`AN 1/12`) and ST-03 is element 1705
|
|
5783
|
+
* (`AN 1/35`), and nothing here bounds the length.
|
|
5784
|
+
*
|
|
5785
|
+
* Refused, all `X12_837_BUILD_INVALID_SPEC`. An **empty** string, because a
|
|
5786
|
+
* trailing empty element is dropped on emit, so it would delete ST-03 and
|
|
5787
|
+
* GS-08 rather than send them empty. One carrying an **active delimiter or
|
|
5788
|
+
* the release character**, because these two elements cannot carry it even
|
|
5789
|
+
* escaped: the ST and GS segments are read by a splitter that is not
|
|
5790
|
+
* release-aware, so the declaration would silently become two elements. And
|
|
5791
|
+
* one **this library's own reader resolves to a different variant**
|
|
5792
|
+
* (`005010X223A2` handed to `build837P`): the file would declare one variant
|
|
5793
|
+
* and carry another's service segments, and `get837Claims` would then decode
|
|
5794
|
+
* none of its service lines. Those are what this field adds, on top of the
|
|
5795
|
+
* element-type guard every string slot already has, which refuses a
|
|
5796
|
+
* non-string with the same code - no total is published. **Anything else is
|
|
5797
|
+
* emitted as given** - the set of published errata is not provably
|
|
5798
|
+
* exhaustive, so an identifier this library does not carry is the caller's
|
|
5799
|
+
* call, not an error.
|
|
5800
|
+
*
|
|
5801
|
+
* 🩺 A guard on this element cannot make the element trustworthy. An active
|
|
5802
|
+
* delimiter in a DIFFERENT envelope field splits its own segment and shifts
|
|
5803
|
+
* every element after it, so ST-03 / GS-08 are then read out of a
|
|
5804
|
+
* neighbour's slot. `KNOWN-LIMITATIONS.md` carries the measurement.
|
|
5805
|
+
*/
|
|
5806
|
+
readonly implementationConventionReference?: string;
|
|
5767
5807
|
/** ISA-05 - interchange sender qualifier. Default `"ZZ"`. */
|
|
5768
5808
|
readonly senderQualifier?: string;
|
|
5769
5809
|
/** ISA-07 - interchange receiver qualifier. Default `"ZZ"`. */
|
|
@@ -6475,8 +6515,9 @@ interface Build837Spec {
|
|
|
6475
6515
|
|
|
6476
6516
|
/**
|
|
6477
6517
|
* `build837P` / `build837I` / `build837D` - pure-function builders for a
|
|
6478
|
-
* 005010 837 Healthcare Claim (Professional
|
|
6479
|
-
*
|
|
6518
|
+
* 005010 837 Healthcare Claim (Professional, Institutional, Dental; the
|
|
6519
|
+
* ST-03 / GS-08 guide reference defaults to `X222A2` / `X223A3` / `X224A2`
|
|
6520
|
+
* and the caller may state another). NEVER auto-sends, NEVER opens a socket, NEVER
|
|
6480
6521
|
* touches the filesystem. The library mechanically emits the claim it is
|
|
6481
6522
|
* told; a spec whose billing-provider → subscriber → (claims | patient)
|
|
6482
6523
|
* tree cannot form a valid HL hierarchy is REFUSED via {@link
|
|
@@ -6505,7 +6546,9 @@ interface Build837Spec {
|
|
|
6505
6546
|
*/
|
|
6506
6547
|
|
|
6507
6548
|
/**
|
|
6508
|
-
* `build837P` - assemble a
|
|
6549
|
+
* `build837P` - assemble a Professional 837 around the spec, declaring
|
|
6550
|
+
* `005010X222A2` unless `envelope.implementationConventionReference` states
|
|
6551
|
+
* the guide your trading partner requires.
|
|
6509
6552
|
*
|
|
6510
6553
|
* @example
|
|
6511
6554
|
* ```ts
|
|
@@ -6537,8 +6580,10 @@ interface Build837Spec {
|
|
|
6537
6580
|
*/
|
|
6538
6581
|
declare function build837P(spec: Build837Spec): X12Interchange;
|
|
6539
6582
|
/**
|
|
6540
|
-
* `build837I` - assemble
|
|
6541
|
-
*
|
|
6583
|
+
* `build837I` - assemble an Institutional 837 around the spec, declaring
|
|
6584
|
+
* `005010X223A3` unless `envelope.implementationConventionReference` states
|
|
6585
|
+
* the guide your trading partner requires. Service lines must be
|
|
6586
|
+
* `variant: "I"` (SV2).
|
|
6542
6587
|
*
|
|
6543
6588
|
* @example
|
|
6544
6589
|
* ```ts
|
|
@@ -6549,8 +6594,10 @@ declare function build837P(spec: Build837Spec): X12Interchange;
|
|
|
6549
6594
|
*/
|
|
6550
6595
|
declare function build837I(spec: Build837Spec): X12Interchange;
|
|
6551
6596
|
/**
|
|
6552
|
-
* `build837D` - assemble a
|
|
6553
|
-
*
|
|
6597
|
+
* `build837D` - assemble a Dental 837 around the spec, declaring
|
|
6598
|
+
* `005010X224A2` unless `envelope.implementationConventionReference` states
|
|
6599
|
+
* the guide your trading partner requires. Service lines must be
|
|
6600
|
+
* `variant: "D"` (SV3); per-line tooth detail rides on TOO.
|
|
6554
6601
|
*
|
|
6555
6602
|
* @example
|
|
6556
6603
|
* ```ts
|
|
@@ -12862,6 +12909,82 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12862
12909
|
* library does NOT silently invent envelope bytes around it - the caller's
|
|
12863
12910
|
* application boundary owns whether the TA1 is embedded in an outbound
|
|
12864
12911
|
* interchange or sent as a standalone TA1-only interchange.
|
|
12912
|
+
*
|
|
12913
|
+
* ## 🩺 Why every element is released, and what that changed
|
|
12914
|
+
*
|
|
12915
|
+
* `raw` used to be `[...five caller values].join(elementSeparator)` with
|
|
12916
|
+
* nothing in between, so a caller value carrying an active delimiter took
|
|
12917
|
+
* a slot of its own and shifted every element after it down one. TA1-04 is
|
|
12918
|
+
* the disposition and TA1-05 the note, so the shift landed the read on the
|
|
12919
|
+
* wrong pair, and `parseTA1` narrows an out-of-enum TA1-04 to `R`:
|
|
12920
|
+
* **an Accept this library emitted read back as a Reject**, with the TA1-01
|
|
12921
|
+
* reassociation key merged into TA1-02 and `warnings: []` on every channel.
|
|
12922
|
+
* The inverse is the less safe one and also existed: a `noteCode` of
|
|
12923
|
+
* literally `"A"` (a value the type forbids and nothing checks at run time)
|
|
12924
|
+
* shifted onto TA1-04 and made a **Reject read back as an Accept**, which a
|
|
12925
|
+
* sender never resubmits against.
|
|
12926
|
+
*
|
|
12927
|
+
* The grounding is inside the package, not in a spec clause, which is the
|
|
12928
|
+
* same tiebreak `X12-ENVELOPE-SPLITTER-NOT-RELEASE-AWARE` recorded: one
|
|
12929
|
+
* function disagreed with itself. This module emitted bytes that this
|
|
12930
|
+
* package's own reader decoded into a different disposition than the one
|
|
12931
|
+
* the caller asked for, and every other builder already released the same
|
|
12932
|
+
* class of element through the same helper.
|
|
12933
|
+
*
|
|
12934
|
+
* **It changes bytes, and that is the cost that kept it open for a slice.**
|
|
12935
|
+
* A value containing none of the four delimiters or the release character
|
|
12936
|
+
* is emitted byte-for-byte as before, which is every conformant TA1. A
|
|
12937
|
+
* value containing one is now released, so its bytes differ from the ones
|
|
12938
|
+
* `0.0.14` and earlier put on the wire. What that costs is stated outright
|
|
12939
|
+
* below rather than argued away, and **without a total**: two drafts of this
|
|
12940
|
+
* account published a closed one and both were refuted.
|
|
12941
|
+
*
|
|
12942
|
+
* - **The consumer predicate moves in BOTH directions.** Read the property
|
|
12943
|
+
* rather than a direction list: `parseTA1` of a `buildTA1` output now
|
|
12944
|
+
* reports the disposition and note the CALLER passed, where before it
|
|
12945
|
+
* reported whatever element the shift left in TA1-04. So
|
|
12946
|
+
* `ackCode === "R"` stops firing where an Accept had been shifted onto
|
|
12947
|
+
* it, and starts firing where a Reject had been shifted off it -
|
|
12948
|
+
* `interchangeTime: "12*A"` with `ackCode: "R"` read `"A"` before and
|
|
12949
|
+
* reads `"R"` here, every field a valid member of its union. What is
|
|
12950
|
+
* one-directional is the safety, which is a different statement.
|
|
12951
|
+
* - **Only three values in the escaped set ever shifted the segment's own
|
|
12952
|
+
* element framing**: the element separator, the segment terminator, and
|
|
12953
|
+
* a `?` immediately before the separator. **`^` and `:` moved the
|
|
12954
|
+
* dot-path reader instead, and releasing them is a GAIN there.**
|
|
12955
|
+
* `getSegmentValue(ta1, "01")` answered `"0000"` before for a control
|
|
12956
|
+
* number of `"0000^0001"`, truncating the reassociation key to the first
|
|
12957
|
+
* repetition, and answers `"0000^0001"` here; the composite read `"01-1"`
|
|
12958
|
+
* answered `"0000"` for `"0000:0001"`. **The measured pure cost is a
|
|
12959
|
+
* MID-STRING `?`, and only on the surfaces documented as raw**: `raw`,
|
|
12960
|
+
* `elements` and `parseTA1`'s fields read `"0000??0001"` where they read
|
|
12961
|
+
* `"0000?0001"`, while the dot-path read of THAT value unescapes and
|
|
12962
|
+
* answered `"0000?0001"` on both. Read the clause as scoped to the
|
|
12963
|
+
* mid-string `?`, because it is not true of `^` or `:` three sentences
|
|
12964
|
+
* up. **`getSegmentValue` takes an `X12Segment` and `Ta1Segment` carries
|
|
12965
|
+
* no `id`, so add one to read a TA1 through it.** No total is published:
|
|
12966
|
+
* that is what was measured, not a closed account.
|
|
12967
|
+
* - **`parseTA1` reads elements RAW, pre-`?`-unescape**, exactly as
|
|
12968
|
+
* `X12Segment.elements` has always documented. So a control number of
|
|
12969
|
+
* `"00000001?"` now reads back as `"00000001??"` rather than as
|
|
12970
|
+
* `"00000001?*260601"`. The disposition is correct where it was
|
|
12971
|
+
* inverted; the key still needs `unescapeRelease` applied by the reader.
|
|
12972
|
+
* That is a property of the read half and is not changed here.
|
|
12973
|
+
* - **A caller who was pre-releasing the value themselves** (the remedy
|
|
12974
|
+
* `KNOWN-LIMITATIONS.md` named while this was open) is now escaping
|
|
12975
|
+
* twice: `"00000001??"` in, `"00000001????"` out. The framing and the
|
|
12976
|
+
* disposition stay correct, and this one regresses on BOTH kinds of
|
|
12977
|
+
* surface - the dot-path read answers `"00000001??"` where it answered
|
|
12978
|
+
* `"00000001?"`. Drop the hand-rolled escape.
|
|
12979
|
+
*
|
|
12980
|
+
* **And an EMPTY control number is still not refused.** `escapeRelease`
|
|
12981
|
+
* early-returns on `""` and this module has no required-field guard, so
|
|
12982
|
+
* `interchangeControlNumber: ""` emits `TA1**260601*1200*A*000` with no
|
|
12983
|
+
* error, here and at every earlier release. Only a NON-string refuses.
|
|
12984
|
+
*
|
|
12985
|
+
* And the release is scoped to the delimiter set the caller states through
|
|
12986
|
+
* {@link BuildTA1Options} - see that interface for why guessing one is a
|
|
12987
|
+
* value corruption rather than a safe default.
|
|
12865
12988
|
*/
|
|
12866
12989
|
|
|
12867
12990
|
/**
|
|
@@ -12876,7 +12999,18 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12876
12999
|
* - `ackCode === "A"` paired with `noteCode !== "000"` →
|
|
12877
13000
|
* {@link "./errors.js".ACK_BUILD_ERROR_CODES.X12_TA1_ACCEPT_WITH_NOTE}.
|
|
12878
13001
|
* Accept must mean accept. Use `E` (accept with errors) when the
|
|
12879
|
-
* inbound had structural defects you elected to ignore.
|
|
13002
|
+
* inbound had structural defects you elected to ignore. This one runs
|
|
13003
|
+
* FIRST and its precedence is unchanged.
|
|
13004
|
+
* - Any of the five element values that is not a `string` →
|
|
13005
|
+
* {@link "./errors.js".ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC}. This
|
|
13006
|
+
* is not a bonus guard: releasing a value means routing it through
|
|
13007
|
+
* {@link "../../builder/caller-string.js".makeCallerEscaper}, and the
|
|
13008
|
+
* bare `escapeRelease` underneath it returns its empty accumulator for a
|
|
13009
|
+
* `number`, so escaping without the type check would have replaced the
|
|
13010
|
+
* shifted-element defect with a silently VANISHED TA1-01. **A number or
|
|
13011
|
+
* an `undefined` control number used to emit as `TA1*12345*…` (the
|
|
13012
|
+
* number surviving onto `elements`, in a `readonly string[]`) or
|
|
13013
|
+
* `TA1**250101*…`; both now refuse.**
|
|
12880
13014
|
*
|
|
12881
13015
|
* @param spec - The TA1 fields. `interchangeControlNumber` echoes the
|
|
12882
13016
|
* inbound ISA-13; `interchangeDate` / `interchangeTime` echo
|
|
@@ -12914,13 +13048,28 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12914
13048
|
*/
|
|
12915
13049
|
declare function buildTA1(spec: BuildTA1Spec, options?: BuildTA1Options): Ta1Segment;
|
|
12916
13050
|
/**
|
|
12917
|
-
* Options accepted by {@link buildTA1}
|
|
12918
|
-
*
|
|
12919
|
-
*
|
|
12920
|
-
*
|
|
13051
|
+
* Options accepted by {@link buildTA1}: the delimiter set the returned
|
|
13052
|
+
* segment will be read against. Every field is optional and defaults to the
|
|
13053
|
+
* cosyte parser archetype (`*` element, `^` repetition, `:` component, `~`
|
|
13054
|
+
* segment), which is the same four `build999` takes on
|
|
13055
|
+
* {@link "./types.js".Build999EnvelopeSpec}.
|
|
13056
|
+
*
|
|
13057
|
+
* **The three non-element fields exist for ESCAPING and nothing else.**
|
|
13058
|
+
* `buildTA1` still emits no segment terminator, no repetition and no
|
|
13059
|
+
* composite. It has to know them because a caller value carrying one of
|
|
13060
|
+
* them has to be released, and because escaping a byte that is NOT a
|
|
13061
|
+
* delimiter where the segment lands corrupts the value: `unescapeRelease`
|
|
13062
|
+
* preserves `?X` verbatim for any `X` outside the declared set, so a value
|
|
13063
|
+
* released against a guessed delimiter comes back carrying a stray `?`.
|
|
13064
|
+
* **If you embed a TA1 in an envelope whose delimiters are not the
|
|
13065
|
+
* archetype, state them here** - the defaults are an assumption this
|
|
13066
|
+
* function cannot verify, exactly as they were before it escaped anything.
|
|
12921
13067
|
*/
|
|
12922
13068
|
interface BuildTA1Options {
|
|
12923
13069
|
readonly elementSeparator?: string;
|
|
13070
|
+
readonly repetitionSeparator?: string;
|
|
13071
|
+
readonly componentSeparator?: string;
|
|
13072
|
+
readonly segmentTerminator?: string;
|
|
12924
13073
|
}
|
|
12925
13074
|
|
|
12926
13075
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2483,9 +2483,10 @@ declare function unescapeRelease(input: string, delimiters: Delimiters, emit: (w
|
|
|
2483
2483
|
* the untyped-refusal defect this package has fixed elsewhere. This is a pure
|
|
2484
2484
|
* text utility with no spec, no element and no caller context to name, so
|
|
2485
2485
|
* `TypeError` is the accurate answer for a wrong-typed argument. **Nothing
|
|
2486
|
-
* inside this library can reach it**:
|
|
2486
|
+
* inside this library can reach it**: every builder routes its elements
|
|
2487
2487
|
* through `src/builder/caller-string.ts`, which refuses first with the calling
|
|
2488
|
-
* builder's own typed, code-tagged error.
|
|
2488
|
+
* builder's own typed, code-tagged error. (No count: it is asserted by
|
|
2489
|
+
* `test/builder-string-type.test.ts` and was stale here.) This throw is the backstop for a
|
|
2489
2490
|
* consumer calling the export directly, where the alternative was silent data
|
|
2490
2491
|
* loss.
|
|
2491
2492
|
*
|
|
@@ -5720,22 +5721,23 @@ declare function get837Claims(delimiters: Delimiters, tx: X12TransactionSet, opt
|
|
|
5720
5721
|
|
|
5721
5722
|
/**
|
|
5722
5723
|
* Interchange + group + transaction identity for the built 837. The builder
|
|
5723
|
-
* fixes GS-01 to `"HC"
|
|
5724
|
-
* (`005010X222A2` / `X223A3` / `X224A2`) so the caller never
|
|
5725
|
-
*
|
|
5726
|
-
*
|
|
5727
|
-
*
|
|
5728
|
-
*
|
|
5729
|
-
*
|
|
5730
|
-
*
|
|
5731
|
-
*
|
|
5732
|
-
*
|
|
5733
|
-
*
|
|
5734
|
-
*
|
|
5735
|
-
*
|
|
5736
|
-
*
|
|
5737
|
-
*
|
|
5738
|
-
*
|
|
5724
|
+
* fixes GS-01 to `"HC"`, and defaults the ST-03 / GS-08 reference to the
|
|
5725
|
+
* variant's TR3 (`005010X222A2` / `X223A3` / `X224A2`) so the caller never
|
|
5726
|
+
* has to hand-code it.
|
|
5727
|
+
*
|
|
5728
|
+
* **🩺 That default is not what every trading partner accepts, so
|
|
5729
|
+
* {@link Build837EnvelopeSpec.implementationConventionReference} overrides
|
|
5730
|
+
* it.** The three defaults are published errata guides, but they are
|
|
5731
|
+
* neither the identifiers HIPAA adopts at 45 CFR 162.1102 nor the ones
|
|
5732
|
+
* payer companion guides commonly require in ST-03 / GS-08 (CMS and several
|
|
5733
|
+
* state Medicaid guides state `005010X222A1` for Professional and
|
|
5734
|
+
* `005010X223A2` for Institutional). **A partner that requires one of those
|
|
5735
|
+
* will reject a Professional or Institutional 837 built on the default**,
|
|
5736
|
+
* and the override is how you send what your partner asked for. The default
|
|
5737
|
+
* itself was deliberately NOT re-stamped: which published guide identifier
|
|
5738
|
+
* a partner accepts is a partner fact rather than a spec fact, and changing
|
|
5739
|
+
* bytes this library already emitted would break the partners it works with
|
|
5740
|
+
* today. The READ side is unaffected - `get837Claims` recognises all of
|
|
5739
5741
|
* these references.
|
|
5740
5742
|
*
|
|
5741
5743
|
* @example
|
|
@@ -5764,6 +5766,44 @@ interface Build837EnvelopeSpec {
|
|
|
5764
5766
|
readonly groupControlNumber: string;
|
|
5765
5767
|
/** ST-02 / SE-02 - transaction set control number. */
|
|
5766
5768
|
readonly transactionSetControlNumber: string;
|
|
5769
|
+
/**
|
|
5770
|
+
* 🩺 ST-03 **and** GS-08 - the implementation convention reference this
|
|
5771
|
+
* 837 declares. Default: the variant's TR3 (`005010X222A2` Professional,
|
|
5772
|
+
* `005010X223A3` Institutional, `005010X224A2` Dental).
|
|
5773
|
+
*
|
|
5774
|
+
* **Set it to whatever your trading partner's companion guide requires**,
|
|
5775
|
+
* for example `005010X222A1` on a professional claim to a payer that asks
|
|
5776
|
+
* for it. Which published identifier a partner accepts is a partner fact,
|
|
5777
|
+
* so this library will not choose for you: it defaults to a real published
|
|
5778
|
+
* guide and gets out of the way. **One value is written to both elements**,
|
|
5779
|
+
* because this builder has always written the same reference to ST-03 and
|
|
5780
|
+
* GS-08 and nothing grounds a caller making them differ. That is a statement
|
|
5781
|
+
* about the bytes this field emits, not about what each element may legally
|
|
5782
|
+
* hold: GS-08 is data element 480 (`AN 1/12`) and ST-03 is element 1705
|
|
5783
|
+
* (`AN 1/35`), and nothing here bounds the length.
|
|
5784
|
+
*
|
|
5785
|
+
* Refused, all `X12_837_BUILD_INVALID_SPEC`. An **empty** string, because a
|
|
5786
|
+
* trailing empty element is dropped on emit, so it would delete ST-03 and
|
|
5787
|
+
* GS-08 rather than send them empty. One carrying an **active delimiter or
|
|
5788
|
+
* the release character**, because these two elements cannot carry it even
|
|
5789
|
+
* escaped: the ST and GS segments are read by a splitter that is not
|
|
5790
|
+
* release-aware, so the declaration would silently become two elements. And
|
|
5791
|
+
* one **this library's own reader resolves to a different variant**
|
|
5792
|
+
* (`005010X223A2` handed to `build837P`): the file would declare one variant
|
|
5793
|
+
* and carry another's service segments, and `get837Claims` would then decode
|
|
5794
|
+
* none of its service lines. Those are what this field adds, on top of the
|
|
5795
|
+
* element-type guard every string slot already has, which refuses a
|
|
5796
|
+
* non-string with the same code - no total is published. **Anything else is
|
|
5797
|
+
* emitted as given** - the set of published errata is not provably
|
|
5798
|
+
* exhaustive, so an identifier this library does not carry is the caller's
|
|
5799
|
+
* call, not an error.
|
|
5800
|
+
*
|
|
5801
|
+
* 🩺 A guard on this element cannot make the element trustworthy. An active
|
|
5802
|
+
* delimiter in a DIFFERENT envelope field splits its own segment and shifts
|
|
5803
|
+
* every element after it, so ST-03 / GS-08 are then read out of a
|
|
5804
|
+
* neighbour's slot. `KNOWN-LIMITATIONS.md` carries the measurement.
|
|
5805
|
+
*/
|
|
5806
|
+
readonly implementationConventionReference?: string;
|
|
5767
5807
|
/** ISA-05 - interchange sender qualifier. Default `"ZZ"`. */
|
|
5768
5808
|
readonly senderQualifier?: string;
|
|
5769
5809
|
/** ISA-07 - interchange receiver qualifier. Default `"ZZ"`. */
|
|
@@ -6475,8 +6515,9 @@ interface Build837Spec {
|
|
|
6475
6515
|
|
|
6476
6516
|
/**
|
|
6477
6517
|
* `build837P` / `build837I` / `build837D` - pure-function builders for a
|
|
6478
|
-
* 005010 837 Healthcare Claim (Professional
|
|
6479
|
-
*
|
|
6518
|
+
* 005010 837 Healthcare Claim (Professional, Institutional, Dental; the
|
|
6519
|
+
* ST-03 / GS-08 guide reference defaults to `X222A2` / `X223A3` / `X224A2`
|
|
6520
|
+
* and the caller may state another). NEVER auto-sends, NEVER opens a socket, NEVER
|
|
6480
6521
|
* touches the filesystem. The library mechanically emits the claim it is
|
|
6481
6522
|
* told; a spec whose billing-provider → subscriber → (claims | patient)
|
|
6482
6523
|
* tree cannot form a valid HL hierarchy is REFUSED via {@link
|
|
@@ -6505,7 +6546,9 @@ interface Build837Spec {
|
|
|
6505
6546
|
*/
|
|
6506
6547
|
|
|
6507
6548
|
/**
|
|
6508
|
-
* `build837P` - assemble a
|
|
6549
|
+
* `build837P` - assemble a Professional 837 around the spec, declaring
|
|
6550
|
+
* `005010X222A2` unless `envelope.implementationConventionReference` states
|
|
6551
|
+
* the guide your trading partner requires.
|
|
6509
6552
|
*
|
|
6510
6553
|
* @example
|
|
6511
6554
|
* ```ts
|
|
@@ -6537,8 +6580,10 @@ interface Build837Spec {
|
|
|
6537
6580
|
*/
|
|
6538
6581
|
declare function build837P(spec: Build837Spec): X12Interchange;
|
|
6539
6582
|
/**
|
|
6540
|
-
* `build837I` - assemble
|
|
6541
|
-
*
|
|
6583
|
+
* `build837I` - assemble an Institutional 837 around the spec, declaring
|
|
6584
|
+
* `005010X223A3` unless `envelope.implementationConventionReference` states
|
|
6585
|
+
* the guide your trading partner requires. Service lines must be
|
|
6586
|
+
* `variant: "I"` (SV2).
|
|
6542
6587
|
*
|
|
6543
6588
|
* @example
|
|
6544
6589
|
* ```ts
|
|
@@ -6549,8 +6594,10 @@ declare function build837P(spec: Build837Spec): X12Interchange;
|
|
|
6549
6594
|
*/
|
|
6550
6595
|
declare function build837I(spec: Build837Spec): X12Interchange;
|
|
6551
6596
|
/**
|
|
6552
|
-
* `build837D` - assemble a
|
|
6553
|
-
*
|
|
6597
|
+
* `build837D` - assemble a Dental 837 around the spec, declaring
|
|
6598
|
+
* `005010X224A2` unless `envelope.implementationConventionReference` states
|
|
6599
|
+
* the guide your trading partner requires. Service lines must be
|
|
6600
|
+
* `variant: "D"` (SV3); per-line tooth detail rides on TOO.
|
|
6554
6601
|
*
|
|
6555
6602
|
* @example
|
|
6556
6603
|
* ```ts
|
|
@@ -12862,6 +12909,82 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12862
12909
|
* library does NOT silently invent envelope bytes around it - the caller's
|
|
12863
12910
|
* application boundary owns whether the TA1 is embedded in an outbound
|
|
12864
12911
|
* interchange or sent as a standalone TA1-only interchange.
|
|
12912
|
+
*
|
|
12913
|
+
* ## 🩺 Why every element is released, and what that changed
|
|
12914
|
+
*
|
|
12915
|
+
* `raw` used to be `[...five caller values].join(elementSeparator)` with
|
|
12916
|
+
* nothing in between, so a caller value carrying an active delimiter took
|
|
12917
|
+
* a slot of its own and shifted every element after it down one. TA1-04 is
|
|
12918
|
+
* the disposition and TA1-05 the note, so the shift landed the read on the
|
|
12919
|
+
* wrong pair, and `parseTA1` narrows an out-of-enum TA1-04 to `R`:
|
|
12920
|
+
* **an Accept this library emitted read back as a Reject**, with the TA1-01
|
|
12921
|
+
* reassociation key merged into TA1-02 and `warnings: []` on every channel.
|
|
12922
|
+
* The inverse is the less safe one and also existed: a `noteCode` of
|
|
12923
|
+
* literally `"A"` (a value the type forbids and nothing checks at run time)
|
|
12924
|
+
* shifted onto TA1-04 and made a **Reject read back as an Accept**, which a
|
|
12925
|
+
* sender never resubmits against.
|
|
12926
|
+
*
|
|
12927
|
+
* The grounding is inside the package, not in a spec clause, which is the
|
|
12928
|
+
* same tiebreak `X12-ENVELOPE-SPLITTER-NOT-RELEASE-AWARE` recorded: one
|
|
12929
|
+
* function disagreed with itself. This module emitted bytes that this
|
|
12930
|
+
* package's own reader decoded into a different disposition than the one
|
|
12931
|
+
* the caller asked for, and every other builder already released the same
|
|
12932
|
+
* class of element through the same helper.
|
|
12933
|
+
*
|
|
12934
|
+
* **It changes bytes, and that is the cost that kept it open for a slice.**
|
|
12935
|
+
* A value containing none of the four delimiters or the release character
|
|
12936
|
+
* is emitted byte-for-byte as before, which is every conformant TA1. A
|
|
12937
|
+
* value containing one is now released, so its bytes differ from the ones
|
|
12938
|
+
* `0.0.14` and earlier put on the wire. What that costs is stated outright
|
|
12939
|
+
* below rather than argued away, and **without a total**: two drafts of this
|
|
12940
|
+
* account published a closed one and both were refuted.
|
|
12941
|
+
*
|
|
12942
|
+
* - **The consumer predicate moves in BOTH directions.** Read the property
|
|
12943
|
+
* rather than a direction list: `parseTA1` of a `buildTA1` output now
|
|
12944
|
+
* reports the disposition and note the CALLER passed, where before it
|
|
12945
|
+
* reported whatever element the shift left in TA1-04. So
|
|
12946
|
+
* `ackCode === "R"` stops firing where an Accept had been shifted onto
|
|
12947
|
+
* it, and starts firing where a Reject had been shifted off it -
|
|
12948
|
+
* `interchangeTime: "12*A"` with `ackCode: "R"` read `"A"` before and
|
|
12949
|
+
* reads `"R"` here, every field a valid member of its union. What is
|
|
12950
|
+
* one-directional is the safety, which is a different statement.
|
|
12951
|
+
* - **Only three values in the escaped set ever shifted the segment's own
|
|
12952
|
+
* element framing**: the element separator, the segment terminator, and
|
|
12953
|
+
* a `?` immediately before the separator. **`^` and `:` moved the
|
|
12954
|
+
* dot-path reader instead, and releasing them is a GAIN there.**
|
|
12955
|
+
* `getSegmentValue(ta1, "01")` answered `"0000"` before for a control
|
|
12956
|
+
* number of `"0000^0001"`, truncating the reassociation key to the first
|
|
12957
|
+
* repetition, and answers `"0000^0001"` here; the composite read `"01-1"`
|
|
12958
|
+
* answered `"0000"` for `"0000:0001"`. **The measured pure cost is a
|
|
12959
|
+
* MID-STRING `?`, and only on the surfaces documented as raw**: `raw`,
|
|
12960
|
+
* `elements` and `parseTA1`'s fields read `"0000??0001"` where they read
|
|
12961
|
+
* `"0000?0001"`, while the dot-path read of THAT value unescapes and
|
|
12962
|
+
* answered `"0000?0001"` on both. Read the clause as scoped to the
|
|
12963
|
+
* mid-string `?`, because it is not true of `^` or `:` three sentences
|
|
12964
|
+
* up. **`getSegmentValue` takes an `X12Segment` and `Ta1Segment` carries
|
|
12965
|
+
* no `id`, so add one to read a TA1 through it.** No total is published:
|
|
12966
|
+
* that is what was measured, not a closed account.
|
|
12967
|
+
* - **`parseTA1` reads elements RAW, pre-`?`-unescape**, exactly as
|
|
12968
|
+
* `X12Segment.elements` has always documented. So a control number of
|
|
12969
|
+
* `"00000001?"` now reads back as `"00000001??"` rather than as
|
|
12970
|
+
* `"00000001?*260601"`. The disposition is correct where it was
|
|
12971
|
+
* inverted; the key still needs `unescapeRelease` applied by the reader.
|
|
12972
|
+
* That is a property of the read half and is not changed here.
|
|
12973
|
+
* - **A caller who was pre-releasing the value themselves** (the remedy
|
|
12974
|
+
* `KNOWN-LIMITATIONS.md` named while this was open) is now escaping
|
|
12975
|
+
* twice: `"00000001??"` in, `"00000001????"` out. The framing and the
|
|
12976
|
+
* disposition stay correct, and this one regresses on BOTH kinds of
|
|
12977
|
+
* surface - the dot-path read answers `"00000001??"` where it answered
|
|
12978
|
+
* `"00000001?"`. Drop the hand-rolled escape.
|
|
12979
|
+
*
|
|
12980
|
+
* **And an EMPTY control number is still not refused.** `escapeRelease`
|
|
12981
|
+
* early-returns on `""` and this module has no required-field guard, so
|
|
12982
|
+
* `interchangeControlNumber: ""` emits `TA1**260601*1200*A*000` with no
|
|
12983
|
+
* error, here and at every earlier release. Only a NON-string refuses.
|
|
12984
|
+
*
|
|
12985
|
+
* And the release is scoped to the delimiter set the caller states through
|
|
12986
|
+
* {@link BuildTA1Options} - see that interface for why guessing one is a
|
|
12987
|
+
* value corruption rather than a safe default.
|
|
12865
12988
|
*/
|
|
12866
12989
|
|
|
12867
12990
|
/**
|
|
@@ -12876,7 +12999,18 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12876
12999
|
* - `ackCode === "A"` paired with `noteCode !== "000"` →
|
|
12877
13000
|
* {@link "./errors.js".ACK_BUILD_ERROR_CODES.X12_TA1_ACCEPT_WITH_NOTE}.
|
|
12878
13001
|
* Accept must mean accept. Use `E` (accept with errors) when the
|
|
12879
|
-
* inbound had structural defects you elected to ignore.
|
|
13002
|
+
* inbound had structural defects you elected to ignore. This one runs
|
|
13003
|
+
* FIRST and its precedence is unchanged.
|
|
13004
|
+
* - Any of the five element values that is not a `string` →
|
|
13005
|
+
* {@link "./errors.js".ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC}. This
|
|
13006
|
+
* is not a bonus guard: releasing a value means routing it through
|
|
13007
|
+
* {@link "../../builder/caller-string.js".makeCallerEscaper}, and the
|
|
13008
|
+
* bare `escapeRelease` underneath it returns its empty accumulator for a
|
|
13009
|
+
* `number`, so escaping without the type check would have replaced the
|
|
13010
|
+
* shifted-element defect with a silently VANISHED TA1-01. **A number or
|
|
13011
|
+
* an `undefined` control number used to emit as `TA1*12345*…` (the
|
|
13012
|
+
* number surviving onto `elements`, in a `readonly string[]`) or
|
|
13013
|
+
* `TA1**250101*…`; both now refuse.**
|
|
12880
13014
|
*
|
|
12881
13015
|
* @param spec - The TA1 fields. `interchangeControlNumber` echoes the
|
|
12882
13016
|
* inbound ISA-13; `interchangeDate` / `interchangeTime` echo
|
|
@@ -12914,13 +13048,28 @@ declare function build999(spec: Build999Spec): X12Interchange;
|
|
|
12914
13048
|
*/
|
|
12915
13049
|
declare function buildTA1(spec: BuildTA1Spec, options?: BuildTA1Options): Ta1Segment;
|
|
12916
13050
|
/**
|
|
12917
|
-
* Options accepted by {@link buildTA1}
|
|
12918
|
-
*
|
|
12919
|
-
*
|
|
12920
|
-
*
|
|
13051
|
+
* Options accepted by {@link buildTA1}: the delimiter set the returned
|
|
13052
|
+
* segment will be read against. Every field is optional and defaults to the
|
|
13053
|
+
* cosyte parser archetype (`*` element, `^` repetition, `:` component, `~`
|
|
13054
|
+
* segment), which is the same four `build999` takes on
|
|
13055
|
+
* {@link "./types.js".Build999EnvelopeSpec}.
|
|
13056
|
+
*
|
|
13057
|
+
* **The three non-element fields exist for ESCAPING and nothing else.**
|
|
13058
|
+
* `buildTA1` still emits no segment terminator, no repetition and no
|
|
13059
|
+
* composite. It has to know them because a caller value carrying one of
|
|
13060
|
+
* them has to be released, and because escaping a byte that is NOT a
|
|
13061
|
+
* delimiter where the segment lands corrupts the value: `unescapeRelease`
|
|
13062
|
+
* preserves `?X` verbatim for any `X` outside the declared set, so a value
|
|
13063
|
+
* released against a guessed delimiter comes back carrying a stray `?`.
|
|
13064
|
+
* **If you embed a TA1 in an envelope whose delimiters are not the
|
|
13065
|
+
* archetype, state them here** - the defaults are an assumption this
|
|
13066
|
+
* function cannot verify, exactly as they were before it escaped anything.
|
|
12921
13067
|
*/
|
|
12922
13068
|
interface BuildTA1Options {
|
|
12923
13069
|
readonly elementSeparator?: string;
|
|
13070
|
+
readonly repetitionSeparator?: string;
|
|
13071
|
+
readonly componentSeparator?: string;
|
|
13072
|
+
readonly segmentTerminator?: string;
|
|
12924
13073
|
}
|
|
12925
13074
|
|
|
12926
13075
|
/**
|