@cosyte/x12 0.0.14 → 0.0.16
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 +800 -5
- package/KNOWN-LIMITATIONS.md +553 -19
- package/README.md +1 -1
- package/dist/index.cjs +397 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +233 -52
- package/dist/index.d.ts +233 -52
- package/dist/index.mjs +397 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -47,6 +47,12 @@ var DELIMITER_POSITIONS = {
|
|
|
47
47
|
component: 104,
|
|
48
48
|
segment: 105
|
|
49
49
|
};
|
|
50
|
+
function isVisibleDelimiterChar(c) {
|
|
51
|
+
const code = c.charCodeAt(0);
|
|
52
|
+
if (code < 32 || code === 127) return false;
|
|
53
|
+
if (/\s/u.test(c)) return false;
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
50
56
|
function detectDelimiters(raw) {
|
|
51
57
|
const fatalPosition = { segmentIndex: 0, interchangeIndex: 0 };
|
|
52
58
|
const snip = snippet(raw);
|
|
@@ -70,19 +76,13 @@ function detectDelimiters(raw) {
|
|
|
70
76
|
const repetition = raw.charAt(DELIMITER_POSITIONS.repetition);
|
|
71
77
|
const component = raw.charAt(DELIMITER_POSITIONS.component);
|
|
72
78
|
const segment = raw.charAt(DELIMITER_POSITIONS.segment);
|
|
73
|
-
const isValidDelimiterChar = (c) => {
|
|
74
|
-
const code = c.charCodeAt(0);
|
|
75
|
-
if (code < 32 || code === 127) return false;
|
|
76
|
-
if (/\s/u.test(c)) return false;
|
|
77
|
-
return true;
|
|
78
|
-
};
|
|
79
79
|
for (const [name, ch] of [
|
|
80
80
|
["element", element],
|
|
81
81
|
["repetition", repetition],
|
|
82
82
|
["component", component],
|
|
83
83
|
["segment", segment]
|
|
84
84
|
]) {
|
|
85
|
-
if (!
|
|
85
|
+
if (!isVisibleDelimiterChar(ch)) {
|
|
86
86
|
throw new X12ParseError(
|
|
87
87
|
FATAL_CODES.X12_INVALID_DELIMITERS,
|
|
88
88
|
`Delimiter "${name}" at ISA byte ${String(DELIMITER_POSITIONS[name] + 1)} is whitespace, control, or empty.`,
|
|
@@ -224,7 +224,7 @@ var WARNING_MESSAGES = {
|
|
|
224
224
|
X12_MISSING_REQUIRED_LOOP_2000B: 'Missing required loop "2000B" (Subscriber HL): no Subscriber HL precedes the CLM.',
|
|
225
225
|
X12_MISSING_REQUIRED_LOOP_2010BA: 'Missing required loop "2010BA" (Subscriber Name): no Subscriber Name follows the Subscriber HL.',
|
|
226
226
|
X12_MISSING_REQUIRED_LOOP_2010BB: 'Missing required loop "2010BB" (Payer Name): no Payer Name follows the Subscriber HL.',
|
|
227
|
-
X12_837_UNKNOWN_VARIANT: "837 variant could not be resolved: ST-03's implementation convention reference is absent, empty, or not an 837 Technical Report Type 3 identifier this reader recognises, and no SVx service-line segment was present to fall back on. The set of references it recognises covers the professional, institutional and dental 837 guides HIPAA adopts at 45 CFR 162.1102 together with their published errata; it is NOT claimed to be exhaustive, and this message deliberately does not enumerate it, because a list here goes stale the moment a guide is added. A reference outside that set is not asserted to be invalid - all this code reports is that this reader could not turn it into a variant and had nothing to fall back on.
|
|
227
|
+
X12_837_UNKNOWN_VARIANT: "837 variant could not be resolved: ST-03's implementation convention reference is absent, empty, or not an 837 Technical Report Type 3 identifier this reader recognises, and no SVx service-line segment was present to fall back on. The set of references it recognises covers the professional, institutional and dental 837 guides HIPAA adopts at 45 CFR 162.1102 together with their published errata; it is NOT claimed to be exhaustive, and this message deliberately does not enumerate it, because a list here goes stale the moment a guide is added. A reference outside that set is not asserted to be invalid - all this code reports is that this reader could not turn it into a variant and had nothing to fall back on.",
|
|
228
228
|
X12_837_AMBIGUOUS_VARIANT: "837 variant resolved from a service segment while the transaction body carries service segments of more than one variant: no caller `type` option was supplied and ST-03's implementation convention reference is absent, empty, or not an 837 Technical Report Type 3 identifier this reader recognises, so this reader fell back to the FIRST SV1 / SV2 / SV3 in the body, and a later one names a different variant. `submission.variant` is therefore a guess between contradictory evidence, and every claim and service line in the submission was read against it. Which service segment is the stray one is NOT decided here and is not derivable from the TR3s: this reader cannot tell a stray service segment from a conformant one, and the fallback takes the first regardless of whether any Loop 2400 was open at it, so an orphan segment decides the variant like any other. Read the bound literally, as a property of the RESOLUTION rather than of the document: this reports the fallback's own ambiguity, so a caller-supplied `type`, or an ST-03 this reader does turn into a variant, means no guess was made and this code is NOT raised however mixed the body is. Whatever else this reader raised on a document that reaches this code, it still raises, at the same position, and this one is added beside them. It is NOT a list of what else you will see, and it does not promise that any particular loss on such a document is reported at all. Re-read with the `type` option to decode the document against a variant you trust. The verbatim segments are preserved on the transaction set; read them there before acting on the submission's type.",
|
|
229
229
|
X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "Unknown claim status category (CSCC): the STC composite's first component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
|
|
230
230
|
X12_UNKNOWN_CLAIM_STATUS: "Unknown claim status code (CSC): the STC composite's second component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
|
|
@@ -868,8 +868,11 @@ function boundSegmentId(first) {
|
|
|
868
868
|
return SEGMENT_ID_SHAPE_RE.test(first) ? first : NON_SPEC_SEGMENT_ID;
|
|
869
869
|
}
|
|
870
870
|
function decodeSegment(raw, delimiters, emit, position) {
|
|
871
|
-
const
|
|
872
|
-
|
|
871
|
+
const degenerate = delimiters.element === RELEASE_CHAR;
|
|
872
|
+
const elements = Object.freeze(
|
|
873
|
+
degenerate ? raw.split(delimiters.element) : splitWithRelease(raw, delimiters.element)
|
|
874
|
+
);
|
|
875
|
+
if (!degenerate && raw.length > 0 && raw.endsWith(RELEASE_CHAR)) {
|
|
873
876
|
let trailingRun = 0;
|
|
874
877
|
for (let j = raw.length - 1; j >= 0 && raw.charAt(j) === RELEASE_CHAR; j -= 1) trailingRun += 1;
|
|
875
878
|
if (trailingRun % 2 === 1) {
|
|
@@ -1097,7 +1100,10 @@ function splitSegments(text, start, delimiters) {
|
|
|
1097
1100
|
return { segments, endIndex: lastEnd };
|
|
1098
1101
|
}
|
|
1099
1102
|
function splitElements(segment, delimiters) {
|
|
1100
|
-
|
|
1103
|
+
if (delimiters.element === RELEASE_CHAR) {
|
|
1104
|
+
return Object.freeze(segment.split(delimiters.element));
|
|
1105
|
+
}
|
|
1106
|
+
return Object.freeze(splitWithRelease(segment, delimiters.element));
|
|
1101
1107
|
}
|
|
1102
1108
|
function el(elements, index) {
|
|
1103
1109
|
return elements[index] ?? "";
|
|
@@ -2703,10 +2709,70 @@ function requireCallerString(value, at, refuse) {
|
|
|
2703
2709
|
`${at}: every element value must be a string, but received ${describeCallerValue(value)}. Values are never coerced - a JavaScript number cannot carry a leading-zero identifier, so converting here could emit a different value than the caller sent. Convert at the call site.`
|
|
2704
2710
|
);
|
|
2705
2711
|
}
|
|
2712
|
+
var DELIMITER_ROLES = [
|
|
2713
|
+
["element", "element separator"],
|
|
2714
|
+
["repetition", "repetition separator"],
|
|
2715
|
+
["component", "component separator"],
|
|
2716
|
+
["segment", "segment terminator"]
|
|
2717
|
+
];
|
|
2718
|
+
function requireEscapableDelimiters(delimiters, at, refuse) {
|
|
2719
|
+
const degenerate = DELIMITER_ROLES.filter(([role]) => delimiters[role] === RELEASE_CHAR).map(
|
|
2720
|
+
([, name]) => name
|
|
2721
|
+
);
|
|
2722
|
+
if (degenerate.length === 0) return;
|
|
2723
|
+
const roles = degenerate.length === 1 ? `the ${degenerate[0] ?? ""}` : `the ${degenerate.slice(0, -1).join(", the ")} and the ${degenerate[degenerate.length - 1] ?? ""}`;
|
|
2724
|
+
refuse(
|
|
2725
|
+
`${at}: "${RELEASE_CHAR}" is the X12 release character and cannot also be ${roles}. An escape is written by prefixing "${RELEASE_CHAR}" to the byte it protects, so on this set the protection is emitted as structure; and a composite or a repetition joined with "${RELEASE_CHAR}" is emitted as an escape. Neither reads back, and no element value avoids it. Declare a delimiter set in which no role is "${RELEASE_CHAR}".`
|
|
2726
|
+
);
|
|
2727
|
+
}
|
|
2728
|
+
function requireWellShapedDelimiters(delimiters, at, refuse) {
|
|
2729
|
+
const REMEDY = `A delimiter occupies ONE fixed position of the ISA (ISA-11, ISA-16 and the position after it), so this set cannot be transmitted and this library's own parser would reject a document declaring it. Declare four distinct, visible, single-character delimiters.`;
|
|
2730
|
+
for (const [role, name] of DELIMITER_ROLES) {
|
|
2731
|
+
const value = delimiters[role];
|
|
2732
|
+
if (typeof value !== "string") {
|
|
2733
|
+
refuse(
|
|
2734
|
+
`${at}: the ${name} must be a string, but received ${describeCallerValue(value)}. Values are never coerced - a coerced delimiter frames the document while the release escape still compares against what you passed, so no element value is protected from it. ${REMEDY}`
|
|
2735
|
+
);
|
|
2736
|
+
}
|
|
2737
|
+
if (value.length !== 1) {
|
|
2738
|
+
refuse(
|
|
2739
|
+
`${at}: the ${name} must be exactly one character, but the declared value is ${value.length === 0 ? "empty" : `${String(value.length)} characters long`}. ${REMEDY}`
|
|
2740
|
+
);
|
|
2741
|
+
}
|
|
2742
|
+
if (!isVisibleDelimiterChar(value)) {
|
|
2743
|
+
refuse(
|
|
2744
|
+
`${at}: the ${name} must be a visible character, but the declared value is whitespace or a control character. ${REMEDY}`
|
|
2745
|
+
);
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
for (const [i, [role, name]] of DELIMITER_ROLES.entries()) {
|
|
2749
|
+
const earlier = DELIMITER_ROLES.slice(0, i).find(([r]) => delimiters[r] === delimiters[role]);
|
|
2750
|
+
if (earlier !== void 0) {
|
|
2751
|
+
refuse(
|
|
2752
|
+
`${at}: the ${name} and the ${earlier[1]} are the same character. A reader cannot tell which role a character is playing. ${REMEDY}`
|
|
2753
|
+
);
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2706
2757
|
function makeCallerEscaper(delimiters, at, refuse) {
|
|
2758
|
+
requireEscapableDelimiters(delimiters, at, refuse);
|
|
2759
|
+
requireWellShapedDelimiters(delimiters, at, refuse);
|
|
2707
2760
|
return (value) => escapeRelease(requireCallerString(value, at, refuse), delimiters);
|
|
2708
2761
|
}
|
|
2709
2762
|
|
|
2763
|
+
// src/builder/caller-control-number.ts
|
|
2764
|
+
function requireControlNumber(value, slot, field, at, refuse) {
|
|
2765
|
+
if (typeof value !== "string") {
|
|
2766
|
+
refuse(
|
|
2767
|
+
`${at}: ${field} must be a string, but received ${describeCallerValue(value)}. ${slot} is a required control number and this builder never coerces one, so nothing is emitted. Convert ${field} at the call site.`
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
if (value !== "") return value;
|
|
2771
|
+
refuse(
|
|
2772
|
+
`${at}: ${field} is empty. ${slot} is a required control number and this builder never invents one, so nothing is emitted. Supply ${field}.`
|
|
2773
|
+
);
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2710
2776
|
// src/transactions/remit/build-835.ts
|
|
2711
2777
|
function refuseSpec(message) {
|
|
2712
2778
|
throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
|
|
@@ -2751,6 +2817,27 @@ function build835(spec) {
|
|
|
2751
2817
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
2752
2818
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
2753
2819
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
2820
|
+
requireControlNumber(
|
|
2821
|
+
envelope.interchangeControlNumber,
|
|
2822
|
+
"ISA-13 / IEA-02",
|
|
2823
|
+
"interchangeControlNumber",
|
|
2824
|
+
"build835",
|
|
2825
|
+
refuseSpec
|
|
2826
|
+
);
|
|
2827
|
+
requireControlNumber(
|
|
2828
|
+
envelope.groupControlNumber,
|
|
2829
|
+
"GS-06 / GE-02",
|
|
2830
|
+
"groupControlNumber",
|
|
2831
|
+
"build835",
|
|
2832
|
+
refuseSpec
|
|
2833
|
+
);
|
|
2834
|
+
requireControlNumber(
|
|
2835
|
+
envelope.transactionSetControlNumber,
|
|
2836
|
+
"ST-02 / SE-02",
|
|
2837
|
+
"transactionSetControlNumber",
|
|
2838
|
+
"build835",
|
|
2839
|
+
refuseSpec
|
|
2840
|
+
);
|
|
2754
2841
|
const interchangeControlNumber = padControl(envelope.interchangeControlNumber, 9);
|
|
2755
2842
|
const isa = [
|
|
2756
2843
|
"ISA",
|
|
@@ -3328,6 +3415,14 @@ function wireLookup(entries) {
|
|
|
3328
3415
|
return Object.freeze(table);
|
|
3329
3416
|
}
|
|
3330
3417
|
|
|
3418
|
+
// src/transactions/shared/st03.ts
|
|
3419
|
+
var noopWarningSink = (_w) => {
|
|
3420
|
+
};
|
|
3421
|
+
function decodeSt03(raw, delimiters, position) {
|
|
3422
|
+
if (raw === void 0) return void 0;
|
|
3423
|
+
return unescapeRelease(raw, delimiters, noopWarningSink, position);
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3331
3426
|
// src/transactions/claim/address-segments.ts
|
|
3332
3427
|
function emitsStreetLines(address) {
|
|
3333
3428
|
return address.lines.length > 0;
|
|
@@ -3386,9 +3481,14 @@ function get837Claims(delimiters, tx, opts) {
|
|
|
3386
3481
|
if (tx.st.elements[1] !== "837") return void 0;
|
|
3387
3482
|
const warnings = [];
|
|
3388
3483
|
const body = tx.se === void 0 ? tx.segments.slice(1) : tx.segments.slice(1, -1);
|
|
3389
|
-
const
|
|
3484
|
+
const implementationConventionReferenceRaw = tx.st.elements[3];
|
|
3485
|
+
const implementationConventionReference = decodeSt03(
|
|
3486
|
+
implementationConventionReferenceRaw,
|
|
3487
|
+
delimiters,
|
|
3488
|
+
{ segmentIndex: 0, transactionIndex: 0 }
|
|
3489
|
+
);
|
|
3390
3490
|
const explicitType = opts?.type;
|
|
3391
|
-
const variantFromIcr =
|
|
3491
|
+
const variantFromIcr = implementationConventionReferenceRaw !== void 0 && implementationConventionReferenceRaw !== "" ? VARIANT_BY_ICR[implementationConventionReferenceRaw] : void 0;
|
|
3392
3492
|
let variantFromSegment;
|
|
3393
3493
|
let serviceSegmentVariantsConflict = false;
|
|
3394
3494
|
if (explicitType === void 0 && variantFromIcr === void 0) {
|
|
@@ -4569,6 +4669,29 @@ var VERSION_BY_VARIANT = {
|
|
|
4569
4669
|
I: "005010X223A3",
|
|
4570
4670
|
D: "005010X224A2"
|
|
4571
4671
|
};
|
|
4672
|
+
function resolveVersionRelease(variant, reference, esc) {
|
|
4673
|
+
if (reference === void 0) return VERSION_BY_VARIANT[variant];
|
|
4674
|
+
if (reference === "") {
|
|
4675
|
+
throw new Claim837BuildError(
|
|
4676
|
+
CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
|
|
4677
|
+
"build837: envelope.implementationConventionReference is empty. ST-03 and GS-08 are required elements and a trailing empty element is not emitted, so an empty reference would remove them rather than send them empty. Omit the field to take the builder's default."
|
|
4678
|
+
);
|
|
4679
|
+
}
|
|
4680
|
+
if (esc(reference) !== reference) {
|
|
4681
|
+
throw new Claim837BuildError(
|
|
4682
|
+
CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
|
|
4683
|
+
"build837: envelope.implementationConventionReference carries an active delimiter or the release character. Escaping does not make it safe here: the ST and GS segments are read by a splitter that is not release-aware, so a released delimiter still splits the segment and the declaration silently becomes two elements. State a reference that carries neither, or choose different delimiters."
|
|
4684
|
+
);
|
|
4685
|
+
}
|
|
4686
|
+
const named = Object.hasOwn(VARIANT_BY_ICR, reference) ? VARIANT_BY_ICR[reference] : void 0;
|
|
4687
|
+
if (named !== void 0 && named !== variant) {
|
|
4688
|
+
throw new Claim837BuildError(
|
|
4689
|
+
CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
|
|
4690
|
+
`build837: envelope.implementationConventionReference names an implementation guide this library reads as a DIFFERENT 837 variant, but this is build837${variant}. The emitted file would declare one variant and carry another's service segments, and this library's own reader would then decode none of its service lines. State a reference for the ${variant} 837, or build with the entry point that matches the reference.`
|
|
4691
|
+
);
|
|
4692
|
+
}
|
|
4693
|
+
return reference;
|
|
4694
|
+
}
|
|
4572
4695
|
var X12_837_FUNCTIONAL_ID = "HC";
|
|
4573
4696
|
var X12_AGENCY_CODE2 = "X";
|
|
4574
4697
|
var HL_LEVEL = { BILLING: "20", SUBSCRIBER: "22", PATIENT: "23" };
|
|
@@ -4583,7 +4706,6 @@ function build837D(spec) {
|
|
|
4583
4706
|
}
|
|
4584
4707
|
function buildClaim837(variant, spec) {
|
|
4585
4708
|
const { envelope } = spec;
|
|
4586
|
-
const versionRelease = VERSION_BY_VARIANT[variant];
|
|
4587
4709
|
enforceStructuralSpec2(variant, spec);
|
|
4588
4710
|
const elementSeparator = envelope.elementSeparator ?? "*";
|
|
4589
4711
|
const repetitionSeparator = envelope.repetitionSeparator ?? "^";
|
|
@@ -4609,9 +4731,35 @@ function buildClaim837(variant, spec) {
|
|
|
4609
4731
|
return escaped.slice(0, end).join(componentSeparator);
|
|
4610
4732
|
};
|
|
4611
4733
|
const ctx = { seg, esc, comp };
|
|
4734
|
+
const versionRelease = resolveVersionRelease(
|
|
4735
|
+
variant,
|
|
4736
|
+
envelope.implementationConventionReference,
|
|
4737
|
+
esc
|
|
4738
|
+
);
|
|
4612
4739
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
4613
4740
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
4614
4741
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
4742
|
+
requireControlNumber(
|
|
4743
|
+
envelope.interchangeControlNumber,
|
|
4744
|
+
"ISA-13 / IEA-02",
|
|
4745
|
+
"interchangeControlNumber",
|
|
4746
|
+
"build837",
|
|
4747
|
+
refuseSpec2
|
|
4748
|
+
);
|
|
4749
|
+
requireControlNumber(
|
|
4750
|
+
envelope.groupControlNumber,
|
|
4751
|
+
"GS-06 / GE-02",
|
|
4752
|
+
"groupControlNumber",
|
|
4753
|
+
"build837",
|
|
4754
|
+
refuseSpec2
|
|
4755
|
+
);
|
|
4756
|
+
requireControlNumber(
|
|
4757
|
+
envelope.transactionSetControlNumber,
|
|
4758
|
+
"ST-02 / SE-02",
|
|
4759
|
+
"transactionSetControlNumber",
|
|
4760
|
+
"build837",
|
|
4761
|
+
refuseSpec2
|
|
4762
|
+
);
|
|
4615
4763
|
const interchangeControlNumber = padControl2(envelope.interchangeControlNumber, 9);
|
|
4616
4764
|
const isa = [
|
|
4617
4765
|
"ISA",
|
|
@@ -5783,6 +5931,27 @@ function build271(spec) {
|
|
|
5783
5931
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
5784
5932
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
5785
5933
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
5934
|
+
requireControlNumber(
|
|
5935
|
+
envelope.interchangeControlNumber,
|
|
5936
|
+
"ISA-13 / IEA-02",
|
|
5937
|
+
"interchangeControlNumber",
|
|
5938
|
+
"build271",
|
|
5939
|
+
refuseSpec3
|
|
5940
|
+
);
|
|
5941
|
+
requireControlNumber(
|
|
5942
|
+
envelope.groupControlNumber,
|
|
5943
|
+
"GS-06 / GE-02",
|
|
5944
|
+
"groupControlNumber",
|
|
5945
|
+
"build271",
|
|
5946
|
+
refuseSpec3
|
|
5947
|
+
);
|
|
5948
|
+
requireControlNumber(
|
|
5949
|
+
envelope.transactionSetControlNumber,
|
|
5950
|
+
"ST-02 / SE-02",
|
|
5951
|
+
"transactionSetControlNumber",
|
|
5952
|
+
"build271",
|
|
5953
|
+
refuseSpec3
|
|
5954
|
+
);
|
|
5786
5955
|
const interchangeControlNumber = padControl3(envelope.interchangeControlNumber, 9);
|
|
5787
5956
|
const isa = [
|
|
5788
5957
|
"ISA",
|
|
@@ -6153,8 +6322,13 @@ function get277CADisposition(delimiters, tx) {
|
|
|
6153
6322
|
function walk277(delimiters, tx) {
|
|
6154
6323
|
const warnings = [];
|
|
6155
6324
|
const body = tx.se === void 0 ? tx.segments.slice(1) : tx.segments.slice(1, -1);
|
|
6156
|
-
const
|
|
6157
|
-
const
|
|
6325
|
+
const implementationConventionReferenceRaw = tx.st.elements[3];
|
|
6326
|
+
const implementationConventionReference = decodeSt03(
|
|
6327
|
+
implementationConventionReferenceRaw,
|
|
6328
|
+
delimiters,
|
|
6329
|
+
{ segmentIndex: 0, transactionIndex: 0 }
|
|
6330
|
+
);
|
|
6331
|
+
const transactionType = implementationConventionReferenceRaw === ICR_277CA ? "claim-acknowledgment" : "claim-status";
|
|
6158
6332
|
const hierarchies = [];
|
|
6159
6333
|
const hlIndex = /* @__PURE__ */ new Map();
|
|
6160
6334
|
const claims = [];
|
|
@@ -6509,6 +6683,27 @@ function buildClaimStatus(version, spec) {
|
|
|
6509
6683
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
6510
6684
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
6511
6685
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
6686
|
+
requireControlNumber(
|
|
6687
|
+
envelope.interchangeControlNumber,
|
|
6688
|
+
"ISA-13 / IEA-02",
|
|
6689
|
+
"interchangeControlNumber",
|
|
6690
|
+
"build277",
|
|
6691
|
+
refuseSpec4
|
|
6692
|
+
);
|
|
6693
|
+
requireControlNumber(
|
|
6694
|
+
envelope.groupControlNumber,
|
|
6695
|
+
"GS-06 / GE-02",
|
|
6696
|
+
"groupControlNumber",
|
|
6697
|
+
"build277",
|
|
6698
|
+
refuseSpec4
|
|
6699
|
+
);
|
|
6700
|
+
requireControlNumber(
|
|
6701
|
+
envelope.transactionSetControlNumber,
|
|
6702
|
+
"ST-02 / SE-02",
|
|
6703
|
+
"transactionSetControlNumber",
|
|
6704
|
+
"build277",
|
|
6705
|
+
refuseSpec4
|
|
6706
|
+
);
|
|
6512
6707
|
const interchangeControlNumber = padControl4(envelope.interchangeControlNumber, 9);
|
|
6513
6708
|
const isa = [
|
|
6514
6709
|
"ISA",
|
|
@@ -7300,6 +7495,27 @@ function build820(spec) {
|
|
|
7300
7495
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
7301
7496
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
7302
7497
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
7498
|
+
requireControlNumber(
|
|
7499
|
+
envelope.interchangeControlNumber,
|
|
7500
|
+
"ISA-13 / IEA-02",
|
|
7501
|
+
"interchangeControlNumber",
|
|
7502
|
+
"build820",
|
|
7503
|
+
refuseSpec5
|
|
7504
|
+
);
|
|
7505
|
+
requireControlNumber(
|
|
7506
|
+
envelope.groupControlNumber,
|
|
7507
|
+
"GS-06 / GE-02",
|
|
7508
|
+
"groupControlNumber",
|
|
7509
|
+
"build820",
|
|
7510
|
+
refuseSpec5
|
|
7511
|
+
);
|
|
7512
|
+
requireControlNumber(
|
|
7513
|
+
envelope.transactionSetControlNumber,
|
|
7514
|
+
"ST-02 / SE-02",
|
|
7515
|
+
"transactionSetControlNumber",
|
|
7516
|
+
"build820",
|
|
7517
|
+
refuseSpec5
|
|
7518
|
+
);
|
|
7303
7519
|
const interchangeControlNumber = padControl5(envelope.interchangeControlNumber, 9);
|
|
7304
7520
|
const isa = [
|
|
7305
7521
|
"ISA",
|
|
@@ -8007,6 +8223,27 @@ function build834(spec) {
|
|
|
8007
8223
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
8008
8224
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
8009
8225
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
8226
|
+
requireControlNumber(
|
|
8227
|
+
envelope.interchangeControlNumber,
|
|
8228
|
+
"ISA-13 / IEA-02",
|
|
8229
|
+
"interchangeControlNumber",
|
|
8230
|
+
"build834",
|
|
8231
|
+
refuseSpec6
|
|
8232
|
+
);
|
|
8233
|
+
requireControlNumber(
|
|
8234
|
+
envelope.groupControlNumber,
|
|
8235
|
+
"GS-06 / GE-02",
|
|
8236
|
+
"groupControlNumber",
|
|
8237
|
+
"build834",
|
|
8238
|
+
refuseSpec6
|
|
8239
|
+
);
|
|
8240
|
+
requireControlNumber(
|
|
8241
|
+
envelope.transactionSetControlNumber,
|
|
8242
|
+
"ST-02 / SE-02",
|
|
8243
|
+
"transactionSetControlNumber",
|
|
8244
|
+
"build834",
|
|
8245
|
+
refuseSpec6
|
|
8246
|
+
);
|
|
8010
8247
|
const interchangeControlNumber = padControl6(envelope.interchangeControlNumber, 9);
|
|
8011
8248
|
const isa = [
|
|
8012
8249
|
"ISA",
|
|
@@ -8459,7 +8696,10 @@ function walk278(delimiters, tx, direction) {
|
|
|
8459
8696
|
}
|
|
8460
8697
|
}
|
|
8461
8698
|
flushReview();
|
|
8462
|
-
const icr = tx.st.elements[3]
|
|
8699
|
+
const icr = decodeSt03(tx.st.elements[3], delimiters, {
|
|
8700
|
+
segmentIndex: 0,
|
|
8701
|
+
transactionIndex: 0
|
|
8702
|
+
});
|
|
8463
8703
|
return Object.freeze({
|
|
8464
8704
|
direction,
|
|
8465
8705
|
implementationConventionReference: icr === void 0 || icr === "" ? void 0 : icr,
|
|
@@ -8683,6 +8923,27 @@ function buildServicesReview(version, direction, spec) {
|
|
|
8683
8923
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
8684
8924
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
8685
8925
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
8926
|
+
requireControlNumber(
|
|
8927
|
+
envelope.interchangeControlNumber,
|
|
8928
|
+
"ISA-13 / IEA-02",
|
|
8929
|
+
"interchangeControlNumber",
|
|
8930
|
+
"build278",
|
|
8931
|
+
refuseSpec7
|
|
8932
|
+
);
|
|
8933
|
+
requireControlNumber(
|
|
8934
|
+
envelope.groupControlNumber,
|
|
8935
|
+
"GS-06 / GE-02",
|
|
8936
|
+
"groupControlNumber",
|
|
8937
|
+
"build278",
|
|
8938
|
+
refuseSpec7
|
|
8939
|
+
);
|
|
8940
|
+
requireControlNumber(
|
|
8941
|
+
envelope.transactionSetControlNumber,
|
|
8942
|
+
"ST-02 / SE-02",
|
|
8943
|
+
"transactionSetControlNumber",
|
|
8944
|
+
"build278",
|
|
8945
|
+
refuseSpec7
|
|
8946
|
+
);
|
|
8686
8947
|
const interchangeControlNumber = padControl7(envelope.interchangeControlNumber, 9);
|
|
8687
8948
|
const isa = [
|
|
8688
8949
|
"ISA",
|
|
@@ -9390,11 +9651,12 @@ function parseTA1(interchange) {
|
|
|
9390
9651
|
const ta1 = interchange.ta1Segments[0];
|
|
9391
9652
|
if (ta1 === void 0) return void 0;
|
|
9392
9653
|
const elements = ta1.elements;
|
|
9393
|
-
const
|
|
9394
|
-
const
|
|
9395
|
-
const
|
|
9396
|
-
const
|
|
9397
|
-
const
|
|
9654
|
+
const value = (index) => unescapeRelease(elements[index] ?? "", interchange.delimiters, noop3, { segmentIndex: 0 });
|
|
9655
|
+
const interchangeControlNumber = value(1);
|
|
9656
|
+
const interchangeDate = value(2);
|
|
9657
|
+
const interchangeTime = value(3);
|
|
9658
|
+
const ackCodeRaw = value(4);
|
|
9659
|
+
const noteCodeRaw = value(5);
|
|
9398
9660
|
const ackCode = narrowAckCode(ackCodeRaw) ?? TA1_ACK_CODES.R;
|
|
9399
9661
|
const noteCode = narrowNoteCode(noteCodeRaw);
|
|
9400
9662
|
return Object.freeze({
|
|
@@ -9407,6 +9669,8 @@ function parseTA1(interchange) {
|
|
|
9407
9669
|
raw: ta1
|
|
9408
9670
|
});
|
|
9409
9671
|
}
|
|
9672
|
+
var noop3 = (_w) => {
|
|
9673
|
+
};
|
|
9410
9674
|
function narrowAckCode(value) {
|
|
9411
9675
|
switch (value) {
|
|
9412
9676
|
case "A":
|
|
@@ -9448,6 +9712,27 @@ function build999(spec) {
|
|
|
9448
9712
|
const senderQualifier = envelope.senderQualifier ?? "ZZ";
|
|
9449
9713
|
const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
|
|
9450
9714
|
const usageIndicator = envelope.usageIndicator ?? "P";
|
|
9715
|
+
requireControlNumber(
|
|
9716
|
+
envelope.interchangeControlNumber,
|
|
9717
|
+
"ISA-13 / IEA-02",
|
|
9718
|
+
"interchangeControlNumber",
|
|
9719
|
+
"build999",
|
|
9720
|
+
refuseSpec8
|
|
9721
|
+
);
|
|
9722
|
+
requireControlNumber(
|
|
9723
|
+
envelope.groupControlNumber,
|
|
9724
|
+
"GS-06 / GE-02",
|
|
9725
|
+
"groupControlNumber",
|
|
9726
|
+
"build999",
|
|
9727
|
+
refuseSpec8
|
|
9728
|
+
);
|
|
9729
|
+
requireControlNumber(
|
|
9730
|
+
envelope.transactionSetControlNumber,
|
|
9731
|
+
"ST-02 / SE-02",
|
|
9732
|
+
"transactionSetControlNumber",
|
|
9733
|
+
"build999",
|
|
9734
|
+
refuseSpec8
|
|
9735
|
+
);
|
|
9451
9736
|
const interchangeControlNumber = padControl8(envelope.interchangeControlNumber, 9);
|
|
9452
9737
|
const isa = [
|
|
9453
9738
|
"ISA",
|
|
@@ -9516,6 +9801,13 @@ function build999(spec) {
|
|
|
9516
9801
|
elementSeparator,
|
|
9517
9802
|
segmentTerminator
|
|
9518
9803
|
);
|
|
9804
|
+
requireControlNumber(
|
|
9805
|
+
functionalGroup.groupControlNumber,
|
|
9806
|
+
"AK1-02",
|
|
9807
|
+
"functionalGroup.groupControlNumber",
|
|
9808
|
+
"build999",
|
|
9809
|
+
refuseSpec8
|
|
9810
|
+
);
|
|
9519
9811
|
const ak1 = joinSeg(
|
|
9520
9812
|
[
|
|
9521
9813
|
"AK1",
|
|
@@ -9622,6 +9914,13 @@ function responseHasAnyError(response) {
|
|
|
9622
9914
|
return false;
|
|
9623
9915
|
}
|
|
9624
9916
|
function buildAk2(response, esc, elementSeparator, segmentTerminator) {
|
|
9917
|
+
requireControlNumber(
|
|
9918
|
+
response.transactionSetControlNumber,
|
|
9919
|
+
"AK2-02",
|
|
9920
|
+
"transactionResponses[].transactionSetControlNumber",
|
|
9921
|
+
"build999",
|
|
9922
|
+
refuseSpec8
|
|
9923
|
+
);
|
|
9625
9924
|
const parts = [
|
|
9626
9925
|
"AK2",
|
|
9627
9926
|
esc(response.transactionSetIdCode),
|
|
@@ -9733,18 +10032,49 @@ function expandYY8(yymmdd) {
|
|
|
9733
10032
|
// src/transactions/ack/build-ta1.ts
|
|
9734
10033
|
function buildTA1(spec, options = {}) {
|
|
9735
10034
|
enforceAcceptIsClean2(spec);
|
|
9736
|
-
const
|
|
10035
|
+
const delimiters = {
|
|
10036
|
+
element: options.elementSeparator ?? "*",
|
|
10037
|
+
repetition: options.repetitionSeparator ?? "^",
|
|
10038
|
+
component: options.componentSeparator ?? ":",
|
|
10039
|
+
segment: options.segmentTerminator ?? "~"
|
|
10040
|
+
};
|
|
10041
|
+
const esc = makeCallerEscaper(delimiters, "buildTA1", refuseSpec9);
|
|
10042
|
+
requireControlNumber(
|
|
10043
|
+
spec.interchangeControlNumber,
|
|
10044
|
+
"TA1-01",
|
|
10045
|
+
"interchangeControlNumber",
|
|
10046
|
+
"buildTA1",
|
|
10047
|
+
refuseSpec9
|
|
10048
|
+
);
|
|
10049
|
+
const interchangeControlNumber = esc(spec.interchangeControlNumber);
|
|
10050
|
+
const interchangeDate = esc(spec.interchangeDate);
|
|
10051
|
+
const interchangeTime = esc(spec.interchangeTime);
|
|
10052
|
+
const ackCode = esc(spec.ackCode);
|
|
10053
|
+
const noteCode = esc(spec.noteCode);
|
|
10054
|
+
requireTa1Element(interchangeDate, "TA1-02", "interchangeDate");
|
|
10055
|
+
requireTa1Element(interchangeTime, "TA1-03", "interchangeTime");
|
|
10056
|
+
requireTa1Element(ackCode, "TA1-04", "ackCode");
|
|
10057
|
+
requireTa1Element(noteCode, "TA1-05", "noteCode");
|
|
9737
10058
|
const elements = Object.freeze([
|
|
9738
10059
|
"TA1",
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
10060
|
+
interchangeControlNumber,
|
|
10061
|
+
interchangeDate,
|
|
10062
|
+
interchangeTime,
|
|
10063
|
+
ackCode,
|
|
10064
|
+
noteCode
|
|
9744
10065
|
]);
|
|
9745
|
-
const raw = elements.join(
|
|
10066
|
+
const raw = elements.join(delimiters.element);
|
|
9746
10067
|
return Object.freeze({ raw, elements });
|
|
9747
10068
|
}
|
|
10069
|
+
function refuseSpec9(message) {
|
|
10070
|
+
throw new AckBuildError(ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC, message);
|
|
10071
|
+
}
|
|
10072
|
+
function requireTa1Element(emitted, slot, field) {
|
|
10073
|
+
if (emitted !== "") return;
|
|
10074
|
+
refuseSpec9(
|
|
10075
|
+
`buildTA1: ${field} is empty. ${slot} is a required element and this builder never invents one, so nothing is emitted. Supply ${field}.`
|
|
10076
|
+
);
|
|
10077
|
+
}
|
|
9748
10078
|
function enforceAcceptIsClean2(spec) {
|
|
9749
10079
|
if (spec.ackCode === TA1_ACK_CODES.A && spec.noteCode !== "000") {
|
|
9750
10080
|
throw new AckBuildError(
|
|
@@ -9933,7 +10263,7 @@ var X12BuildError = class extends Error {
|
|
|
9933
10263
|
};
|
|
9934
10264
|
|
|
9935
10265
|
// src/builder/build-interchange.ts
|
|
9936
|
-
function
|
|
10266
|
+
function refuseSpec10(message) {
|
|
9937
10267
|
throw new X12BuildError(X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC, message);
|
|
9938
10268
|
}
|
|
9939
10269
|
function buildInterchange(spec) {
|
|
@@ -9947,11 +10277,18 @@ function buildInterchange(spec) {
|
|
|
9947
10277
|
component: componentSeparator,
|
|
9948
10278
|
segment: segmentTerminator
|
|
9949
10279
|
};
|
|
9950
|
-
const esc = makeCallerEscaper(delimiters, "buildInterchange",
|
|
10280
|
+
const esc = makeCallerEscaper(delimiters, "buildInterchange", refuseSpec10);
|
|
9951
10281
|
const senderQualifier = spec.senderQualifier ?? "ZZ";
|
|
9952
10282
|
const receiverQualifier = spec.receiverQualifier ?? "ZZ";
|
|
9953
10283
|
const usageIndicator = spec.usageIndicator ?? "P";
|
|
9954
10284
|
const version = spec.version ?? "00501";
|
|
10285
|
+
requireControlNumber(
|
|
10286
|
+
spec.interchangeControlNumber,
|
|
10287
|
+
"ISA-13 / IEA-02",
|
|
10288
|
+
"interchangeControlNumber",
|
|
10289
|
+
"buildInterchange",
|
|
10290
|
+
refuseSpec10
|
|
10291
|
+
);
|
|
9955
10292
|
const interchangeControlNumber = padControl9(spec.interchangeControlNumber, 9);
|
|
9956
10293
|
const isa = [
|
|
9957
10294
|
"ISA",
|
|
@@ -10001,23 +10338,32 @@ function buildInterchange(spec) {
|
|
|
10001
10338
|
return parseX12(raw);
|
|
10002
10339
|
}
|
|
10003
10340
|
function buildGroup(group, spec, esc, elementSeparator, segmentTerminator) {
|
|
10341
|
+
requireControlNumber(
|
|
10342
|
+
group.groupControlNumber,
|
|
10343
|
+
"GS-06 / GE-02",
|
|
10344
|
+
"groupControlNumber",
|
|
10345
|
+
"buildInterchange",
|
|
10346
|
+
refuseSpec10
|
|
10347
|
+
);
|
|
10004
10348
|
const applicationSenderCode = group.applicationSenderCode ?? spec.senderId;
|
|
10005
10349
|
const applicationReceiverCode = group.applicationReceiverCode ?? spec.receiverId;
|
|
10006
10350
|
const groupDate = group.groupDate ?? expandYY9(spec.interchangeDate);
|
|
10007
10351
|
const groupTime = group.groupTime ?? spec.interchangeTime;
|
|
10008
10352
|
const responsibleAgencyCode = group.responsibleAgencyCode ?? "X";
|
|
10353
|
+
const gsParts = [
|
|
10354
|
+
"GS",
|
|
10355
|
+
group.functionalIdCode,
|
|
10356
|
+
applicationSenderCode,
|
|
10357
|
+
applicationReceiverCode,
|
|
10358
|
+
groupDate,
|
|
10359
|
+
groupTime,
|
|
10360
|
+
group.groupControlNumber,
|
|
10361
|
+
responsibleAgencyCode,
|
|
10362
|
+
group.versionRelease
|
|
10363
|
+
];
|
|
10364
|
+
requireCallerSegment(gsParts, "buildInterchange", refuseSpec10);
|
|
10009
10365
|
const gs = joinSeg2(
|
|
10010
|
-
|
|
10011
|
-
"GS",
|
|
10012
|
-
esc(group.functionalIdCode),
|
|
10013
|
-
esc(applicationSenderCode),
|
|
10014
|
-
esc(applicationReceiverCode),
|
|
10015
|
-
groupDate,
|
|
10016
|
-
groupTime,
|
|
10017
|
-
esc(group.groupControlNumber),
|
|
10018
|
-
responsibleAgencyCode,
|
|
10019
|
-
esc(group.versionRelease)
|
|
10020
|
-
],
|
|
10366
|
+
gsParts.map((value, index) => index === 0 ? value : esc(value)),
|
|
10021
10367
|
elementSeparator,
|
|
10022
10368
|
segmentTerminator
|
|
10023
10369
|
);
|
|
@@ -10033,6 +10379,13 @@ function buildGroup(group, spec, esc, elementSeparator, segmentTerminator) {
|
|
|
10033
10379
|
return gs + transactions + ge;
|
|
10034
10380
|
}
|
|
10035
10381
|
function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
|
|
10382
|
+
requireControlNumber(
|
|
10383
|
+
tx.transactionSetControlNumber,
|
|
10384
|
+
"ST-02 / SE-02",
|
|
10385
|
+
"transactionSetControlNumber",
|
|
10386
|
+
"buildInterchange",
|
|
10387
|
+
refuseSpec10
|
|
10388
|
+
);
|
|
10036
10389
|
const stParts = ["ST", esc(tx.transactionSetIdCode), esc(tx.transactionSetControlNumber)];
|
|
10037
10390
|
if (tx.implementationConventionReference !== void 0) {
|
|
10038
10391
|
stParts.push(esc(tx.implementationConventionReference));
|
|
@@ -10061,7 +10414,7 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
|
|
|
10061
10414
|
return st + bodySegments + se;
|
|
10062
10415
|
}
|
|
10063
10416
|
function joinSeg2(parts, elementSeparator, segmentTerminator) {
|
|
10064
|
-
requireCallerSegment(parts, "buildInterchange",
|
|
10417
|
+
requireCallerSegment(parts, "buildInterchange", refuseSpec10);
|
|
10065
10418
|
return parts.join(elementSeparator) + segmentTerminator;
|
|
10066
10419
|
}
|
|
10067
10420
|
function pad9(value, width) {
|
|
@@ -10370,7 +10723,7 @@ var profiles = Object.freeze({
|
|
|
10370
10723
|
});
|
|
10371
10724
|
|
|
10372
10725
|
// src/index.ts
|
|
10373
|
-
var VERSION = "0.0.
|
|
10726
|
+
var VERSION = "0.0.16";
|
|
10374
10727
|
|
|
10375
10728
|
exports.ACK_BUILD_ERROR_CODES = ACK_BUILD_ERROR_CODES;
|
|
10376
10729
|
exports.ALL_WARNING_MESSAGES = ALL_WARNING_MESSAGES;
|