@cosyte/x12 0.0.4 → 0.0.6

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.mjs CHANGED
@@ -1886,6 +1886,7 @@ function get835(delimiters, tx) {
1886
1886
  const warnings = [];
1887
1887
  const body = tx.se === void 0 ? tx.segments.slice(1) : tx.segments.slice(1, -1);
1888
1888
  let payment = EMPTY_HEADER;
1889
+ let bprSegmentIndex = 0;
1889
1890
  const traces = [];
1890
1891
  let payer;
1891
1892
  let payee;
@@ -1914,6 +1915,7 @@ function get835(delimiters, tx) {
1914
1915
  switch (seg.id) {
1915
1916
  case "BPR": {
1916
1917
  payment = decodeBpr(seg, delimiters);
1918
+ bprSegmentIndex = position.segmentIndex;
1917
1919
  break;
1918
1920
  }
1919
1921
  case "TRN": {
@@ -2081,7 +2083,7 @@ function get835(delimiters, tx) {
2081
2083
  payment.totalActualPayment,
2082
2084
  finalClaims,
2083
2085
  providerAdjustments,
2084
- { segmentIndex: 0, transactionIndex: 0 }
2086
+ { segmentIndex: bprSegmentIndex, transactionIndex: 0 }
2085
2087
  );
2086
2088
  if (remitTotalWarn !== void 0) warnings.push(remitTotalWarn);
2087
2089
  return Object.freeze({
@@ -2442,10 +2444,79 @@ var Remit835BuildError = class extends Error {
2442
2444
  }
2443
2445
  };
2444
2446
 
2447
+ // src/builder/caller-value.ts
2448
+ var BUILD_REFUSAL_VALUE_MAX_LENGTH = 63;
2449
+ var MAX_LENGTH_DIGITS = 10;
2450
+ var BUILD_REFUSAL_VALUE_MAX_RENDERED = BUILD_REFUSAL_VALUE_MAX_LENGTH + 2 + 1 + " ( characters)".length + MAX_LENGTH_DIGITS;
2451
+ function renderCallerValue(value) {
2452
+ const text = coerce(value);
2453
+ if (text.length <= BUILD_REFUSAL_VALUE_MAX_LENGTH) return `"${text}"`;
2454
+ return `"${text.slice(0, BUILD_REFUSAL_VALUE_MAX_LENGTH)}\u2026" (${String(text.length)} characters)`;
2455
+ }
2456
+ function coerce(value) {
2457
+ if (typeof value === "string") return value;
2458
+ try {
2459
+ return String(value);
2460
+ } catch {
2461
+ return "[unrenderable value]";
2462
+ }
2463
+ }
2464
+ function renderCallerJson(value) {
2465
+ let text;
2466
+ try {
2467
+ text = JSON.stringify(value) ?? "undefined";
2468
+ } catch {
2469
+ return "[unrenderable value]";
2470
+ }
2471
+ if (text.length <= BUILD_REFUSAL_VALUE_MAX_LENGTH) return text;
2472
+ return `${text.slice(0, BUILD_REFUSAL_VALUE_MAX_LENGTH)}\u2026 (${String(text.length)} characters)`;
2473
+ }
2474
+
2475
+ // src/builder/caller-array.ts
2476
+ var NONE = Object.freeze([]);
2477
+ function describeShape(value) {
2478
+ if (typeof value !== "object") {
2479
+ return `a ${typeof value} (${renderCallerValue(value)})`;
2480
+ }
2481
+ let length;
2482
+ try {
2483
+ length = value.length;
2484
+ } catch {
2485
+ return "an object whose 'length' getter threw";
2486
+ }
2487
+ if (length !== void 0) {
2488
+ return `an array-like object with length ${renderCallerValue(length)}`;
2489
+ }
2490
+ let tag;
2491
+ try {
2492
+ tag = Object.prototype.toString.call(value);
2493
+ } catch {
2494
+ tag = "[object Unknown]";
2495
+ }
2496
+ return `a non-array ${renderCallerValue(tag)}`;
2497
+ }
2498
+ function requireCallerArray(value, at, refuse) {
2499
+ if (value === void 0 || value === null) return NONE;
2500
+ if (!isRealArray(value)) {
2501
+ refuse(`${at} must be an array. Received ${describeShape(value)}.`);
2502
+ }
2503
+ return value;
2504
+ }
2505
+ function isRealArray(value) {
2506
+ return Array.isArray(value);
2507
+ }
2508
+
2445
2509
  // src/transactions/remit/build-835.ts
2510
+ function refuseSpec(message) {
2511
+ throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
2512
+ }
2446
2513
  var X221A1_VERSION_RELEASE = "005010X221A1";
2447
2514
  var X12_835_FUNCTIONAL_ID = "HP";
2448
2515
  var X12_AGENCY_CODE = "X";
2516
+ var UNANCHORED_BUILD_POSITION = Object.freeze({
2517
+ segmentIndex: 0,
2518
+ transactionIndex: 0
2519
+ });
2449
2520
  function build835(spec) {
2450
2521
  const { envelope } = spec;
2451
2522
  enforceStructuralSpec(spec);
@@ -2592,7 +2663,14 @@ function build835(spec) {
2592
2663
  emitClaim(claim, body, seg, esc, comp);
2593
2664
  }
2594
2665
  }
2595
- emitProviderAdjustments(spec.providerAdjustments ?? [], body, seg, esc, comp);
2666
+ emitProviderAdjustments(
2667
+ spec.providerAdjustments,
2668
+ "build835: spec.providerAdjustments",
2669
+ body,
2670
+ seg,
2671
+ esc,
2672
+ comp
2673
+ );
2596
2674
  const seCount = body.length + 2;
2597
2675
  const se = seg(["SE", String(seCount), esc(stControlNumber)]);
2598
2676
  const ge = seg(["GE", "1", esc(envelope.groupControlNumber)]);
@@ -2601,14 +2679,16 @@ function build835(spec) {
2601
2679
  return parseX12(raw);
2602
2680
  }
2603
2681
  function enforceStructuralSpec(spec) {
2604
- if (spec.traces.length === 0) {
2682
+ const traces = requireCallerArray(spec.traces, "build835: spec.traces", refuseSpec);
2683
+ if (traces.length === 0) {
2605
2684
  throw new Remit835BuildError(
2606
2685
  REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
2607
2686
  "build835: at least one TRN trace is required (TR3 005010X221A1 Loop header)."
2608
2687
  );
2609
2688
  }
2610
- for (let i = 0; i < spec.claims.length; i += 1) {
2611
- const claim = spec.claims[i];
2689
+ const claims = requireCallerArray(spec.claims, "build835: spec.claims", refuseSpec);
2690
+ for (let i = 0; i < claims.length; i += 1) {
2691
+ const claim = claims[i];
2612
2692
  if (claim === void 0) continue;
2613
2693
  if (claim.patientControlNumber === "") {
2614
2694
  throw new Remit835BuildError(
@@ -2619,7 +2699,7 @@ function enforceStructuralSpec(spec) {
2619
2699
  }
2620
2700
  }
2621
2701
  function enforceBalance(spec) {
2622
- const position = { segmentIndex: 0, transactionIndex: 0 };
2702
+ const position = UNANCHORED_BUILD_POSITION;
2623
2703
  const claims = spec.claims.map(materializeClaim);
2624
2704
  for (const claim of claims) {
2625
2705
  const claimWarn = checkClaimBalance(claim, position);
@@ -2770,7 +2850,7 @@ function emitClaim(claim, body, seg, esc, comp) {
2770
2850
  comp([claim.facilityTypeCode ?? "", "", claim.claimFrequencyCode ?? ""])
2771
2851
  ])
2772
2852
  );
2773
- emitCasGroup(claim.adjustments ?? [], body, seg, esc);
2853
+ emitCasGroup(claim.adjustments, "build835: claim.adjustments", body, seg, esc);
2774
2854
  if (claim.patient !== void 0) body.push(emitPerson(claim.patient, seg, esc));
2775
2855
  if (claim.subscriber !== void 0) body.push(emitPerson(claim.subscriber, seg, esc));
2776
2856
  if (claim.correctedPatient !== void 0) body.push(emitPerson(claim.correctedPatient, seg, esc));
@@ -2816,7 +2896,7 @@ function emitServiceLine(line, body, seg, esc, comp) {
2816
2896
  ])
2817
2897
  );
2818
2898
  emitServiceLineDtm(line, body, seg, esc);
2819
- emitCasGroup(line.adjustments ?? [], body, seg, esc);
2899
+ emitCasGroup(line.adjustments, "build835: serviceLine.adjustments", body, seg, esc);
2820
2900
  for (const ref of line.references ?? []) body.push(emitRef(ref, seg, esc));
2821
2901
  for (const amt of line.amounts ?? []) {
2822
2902
  body.push(seg(["AMT", esc(amt.qualifier), esc(amt.amount.toString())]));
@@ -2834,7 +2914,8 @@ function emitServiceLineDtm(line, body, seg, esc) {
2834
2914
  if (start !== void 0) body.push(seg(["DTM", "150", esc(start)]));
2835
2915
  if (end !== void 0) body.push(seg(["DTM", "151", esc(end)]));
2836
2916
  }
2837
- function emitCasGroup(adjustments, body, seg, esc) {
2917
+ function emitCasGroup(raw, at, body, seg, esc) {
2918
+ const adjustments = requireCallerArray(raw, at, refuseSpec);
2838
2919
  let i = 0;
2839
2920
  while (i < adjustments.length) {
2840
2921
  const first = adjustments[i];
@@ -2892,7 +2973,8 @@ function emitProvider(provider, seg, esc) {
2892
2973
  esc(provider.idCode ?? "")
2893
2974
  ]);
2894
2975
  }
2895
- function emitProviderAdjustments(adjustments, body, seg, esc, comp) {
2976
+ function emitProviderAdjustments(raw, at, body, seg, esc, comp) {
2977
+ const adjustments = requireCallerArray(raw, at, refuseSpec);
2896
2978
  let i = 0;
2897
2979
  while (i < adjustments.length) {
2898
2980
  const first = adjustments[i];
@@ -2925,7 +3007,7 @@ function padControl(value, width) {
2925
3007
  if (value.length < width) return "0".repeat(width - value.length) + value;
2926
3008
  throw new Remit835BuildError(
2927
3009
  REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
2928
- `build835: control number "${value}" exceeds the ${String(width)}-char spec limit.`
3010
+ `build835: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
2929
3011
  );
2930
3012
  }
2931
3013
  function expandYY(yymmdd) {
@@ -4086,6 +4168,15 @@ var Claim837BuildError = class extends Error {
4086
4168
  };
4087
4169
 
4088
4170
  // src/transactions/claim/build-837.ts
4171
+ function refuseHierarchy(message) {
4172
+ throw new Claim837BuildError(
4173
+ CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4174
+ message
4175
+ );
4176
+ }
4177
+ function refuseSpec2(message) {
4178
+ throw new Claim837BuildError(CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC, message);
4179
+ }
4089
4180
  var VERSION_BY_VARIANT = {
4090
4181
  P: "005010X222A2",
4091
4182
  I: "005010X223A3",
@@ -4196,26 +4287,45 @@ function buildClaim837(variant, spec) {
4196
4287
  return parseX12(raw);
4197
4288
  }
4198
4289
  function enforceStructuralSpec2(variant, spec) {
4199
- if (spec.billingProviders.length === 0) {
4290
+ const billingProviders = requireCallerArray(
4291
+ spec.billingProviders,
4292
+ "build837: spec.billingProviders",
4293
+ refuseHierarchy
4294
+ );
4295
+ if (billingProviders.length === 0) {
4200
4296
  throw new Claim837BuildError(
4201
4297
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4202
4298
  "build837: at least one billing provider (HL level 20) is required."
4203
4299
  );
4204
4300
  }
4205
- for (let b = 0; b < spec.billingProviders.length; b += 1) {
4206
- const billing = spec.billingProviders[b];
4301
+ for (let b = 0; b < billingProviders.length; b += 1) {
4302
+ const billing = billingProviders[b];
4207
4303
  if (billing === void 0) continue;
4208
- if (billing.subscribers.length === 0) {
4304
+ const subscribers = requireCallerArray(
4305
+ billing.subscribers,
4306
+ `build837: spec.billingProviders[${String(b)}].subscribers`,
4307
+ refuseHierarchy
4308
+ );
4309
+ if (subscribers.length === 0) {
4209
4310
  throw new Claim837BuildError(
4210
4311
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4211
4312
  `build837: billing provider at index ${String(b)} has no subscriber (HL level 22) child.`
4212
4313
  );
4213
4314
  }
4214
- for (let s = 0; s < billing.subscribers.length; s += 1) {
4215
- const subscriber = billing.subscribers[s];
4315
+ for (let s = 0; s < subscribers.length; s += 1) {
4316
+ const subscriber = subscribers[s];
4216
4317
  if (subscriber === void 0) continue;
4217
- const directClaims = subscriber.claims ?? [];
4218
- const patients = subscriber.patients ?? [];
4318
+ const locator = `spec.billingProviders[${String(b)}].subscribers[${String(s)}]`;
4319
+ const directClaims = requireCallerArray(
4320
+ subscriber.claims,
4321
+ `build837: ${locator}.claims`,
4322
+ refuseHierarchy
4323
+ );
4324
+ const patients = requireCallerArray(
4325
+ subscriber.patients,
4326
+ `build837: ${locator}.patients`,
4327
+ refuseHierarchy
4328
+ );
4219
4329
  if (directClaims.length === 0 && patients.length === 0) {
4220
4330
  throw new Claim837BuildError(
4221
4331
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
@@ -4235,14 +4345,19 @@ function enforceStructuralSpec2(variant, spec) {
4235
4345
  for (let p = 0; p < patients.length; p += 1) {
4236
4346
  const patient = patients[p];
4237
4347
  if (patient === void 0) continue;
4238
- if (patient.claims.length === 0) {
4348
+ const patientClaims = requireCallerArray(
4349
+ patient.claims,
4350
+ `build837: ${locator}.patients[${String(p)}].claims`,
4351
+ refuseHierarchy
4352
+ );
4353
+ if (patientClaims.length === 0) {
4239
4354
  throw new Claim837BuildError(
4240
4355
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4241
4356
  `build837: dependent patient at billing[${String(b)}].subscriber[${String(s)}].patient[${String(p)}] has no claim.`
4242
4357
  );
4243
4358
  }
4244
- for (let c = 0; c < patient.claims.length; c += 1) {
4245
- const claim = patient.claims[c];
4359
+ for (let c = 0; c < patientClaims.length; c += 1) {
4360
+ const claim = patientClaims[c];
4246
4361
  if (claim !== void 0) {
4247
4362
  enforceClaim(
4248
4363
  variant,
@@ -4262,19 +4377,24 @@ function enforceClaim(variant, claim, locator) {
4262
4377
  `build837: claim at ${locator} has an empty claimId (CLM-01 is required).`
4263
4378
  );
4264
4379
  }
4265
- if (claim.serviceLines.length === 0) {
4380
+ const serviceLines = requireCallerArray(
4381
+ claim.serviceLines,
4382
+ `build837: claim at ${locator}: serviceLines`,
4383
+ refuseSpec2
4384
+ );
4385
+ if (serviceLines.length === 0) {
4266
4386
  throw new Claim837BuildError(
4267
4387
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4268
4388
  `build837: claim at ${locator} has no service line (a CLM requires at least one LX/SVx loop).`
4269
4389
  );
4270
4390
  }
4271
- for (let l = 0; l < claim.serviceLines.length; l += 1) {
4272
- const line = claim.serviceLines[l];
4391
+ for (let l = 0; l < serviceLines.length; l += 1) {
4392
+ const line = serviceLines[l];
4273
4393
  if (line === void 0) continue;
4274
4394
  if (line.variant !== variant) {
4275
4395
  throw new Claim837BuildError(
4276
4396
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4277
- `build837${variant}: claim at ${locator} has a "${line.variant}" service line at index ${String(l)}; every line must be "${variant}".`
4397
+ `build837${variant}: claim at ${locator} has a ${renderCallerValue(line.variant)} service line at index ${String(l)}; every line must be "${variant}".`
4278
4398
  );
4279
4399
  }
4280
4400
  const code = line.variant === "I" ? line.revenueCode : line.procedureCode;
@@ -4499,12 +4619,13 @@ function emitAdjudication(adj, body, ctx) {
4499
4619
  adj.paidUnits === void 0 ? "" : ctx.esc(adj.paidUnits.toString())
4500
4620
  ])
4501
4621
  );
4502
- emitCasGroup2(adj.adjustments ?? [], body, ctx);
4622
+ emitCasGroup2(adj.adjustments, "build837: adjudication.adjustments", body, ctx);
4503
4623
  if (adj.dateAdjudicated !== void 0) {
4504
4624
  body.push(ctx.seg(["DTP", "573", "D8", ctx.esc(adj.dateAdjudicated)]));
4505
4625
  }
4506
4626
  }
4507
- function emitCasGroup2(adjustments, body, ctx) {
4627
+ function emitCasGroup2(raw, at, body, ctx) {
4628
+ const adjustments = requireCallerArray(raw, at, refuseSpec2);
4508
4629
  let i = 0;
4509
4630
  while (i < adjustments.length) {
4510
4631
  const first = adjustments[i];
@@ -4618,7 +4739,7 @@ function padControl2(value, width) {
4618
4739
  if (value.length < width) return "0".repeat(width - value.length) + value;
4619
4740
  throw new Claim837BuildError(
4620
4741
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4621
- `build837: control number "${value}" exceeds the ${String(width)}-char spec limit.`
4742
+ `build837: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
4622
4743
  );
4623
4744
  }
4624
4745
  function expandYY2(yymmdd) {
@@ -5222,6 +5343,12 @@ var Eligibility271BuildError = class extends Error {
5222
5343
  };
5223
5344
 
5224
5345
  // src/transactions/eligibility/build-271.ts
5346
+ function refuseHierarchy2(message) {
5347
+ throw new Eligibility271BuildError(
5348
+ ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5349
+ message
5350
+ );
5351
+ }
5225
5352
  var X279A1_VERSION_RELEASE = "005010X279A1";
5226
5353
  var X12_271_FUNCTIONAL_ID = "HB";
5227
5354
  var X12_AGENCY_CODE3 = "X";
@@ -5299,25 +5426,40 @@ function build271(spec) {
5299
5426
  return parseX12(raw);
5300
5427
  }
5301
5428
  function enforceStructuralSpec3(spec) {
5302
- if (spec.informationSources.length === 0) {
5429
+ const sources = requireCallerArray(
5430
+ spec.informationSources,
5431
+ "build271: spec.informationSources",
5432
+ refuseHierarchy2
5433
+ );
5434
+ if (sources.length === 0) {
5303
5435
  throw new Eligibility271BuildError(
5304
5436
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5305
5437
  "build271: at least one information source (HL level 20) is required."
5306
5438
  );
5307
5439
  }
5308
- for (let s = 0; s < spec.informationSources.length; s += 1) {
5309
- const source = spec.informationSources[s];
5440
+ for (let s = 0; s < sources.length; s += 1) {
5441
+ const source = sources[s];
5310
5442
  if (source === void 0) continue;
5311
- if (source.receivers.length === 0) {
5443
+ const receivers = requireCallerArray(
5444
+ source.receivers,
5445
+ `build271: spec.informationSources[${String(s)}].receivers`,
5446
+ refuseHierarchy2
5447
+ );
5448
+ if (receivers.length === 0) {
5312
5449
  throw new Eligibility271BuildError(
5313
5450
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5314
5451
  `build271: information source at index ${String(s)} has no receiver (HL level 21) child.`
5315
5452
  );
5316
5453
  }
5317
- for (let r = 0; r < source.receivers.length; r += 1) {
5318
- const receiver = source.receivers[r];
5454
+ for (let r = 0; r < receivers.length; r += 1) {
5455
+ const receiver = receivers[r];
5319
5456
  if (receiver === void 0) continue;
5320
- if (receiver.subscribers.length === 0) {
5457
+ const subscribers = requireCallerArray(
5458
+ receiver.subscribers,
5459
+ `build271: spec.informationSources[${String(s)}].receivers[${String(r)}].subscribers`,
5460
+ refuseHierarchy2
5461
+ );
5462
+ if (subscribers.length === 0) {
5321
5463
  throw new Eligibility271BuildError(
5322
5464
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5323
5465
  `build271: receiver at source[${String(s)}].receiver[${String(r)}] has no subscriber (HL level 22) child.`
@@ -5483,7 +5625,7 @@ function padControl3(value, width) {
5483
5625
  if (value.length < width) return "0".repeat(width - value.length) + value;
5484
5626
  throw new Eligibility271BuildError(
5485
5627
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_SPEC,
5486
- `build271: control number "${value}" exceeds the ${String(width)}-char spec limit.`
5628
+ `build271: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
5487
5629
  );
5488
5630
  }
5489
5631
  function expandYY3(yymmdd) {
@@ -5893,6 +6035,18 @@ var ClaimStatus277BuildError = class extends Error {
5893
6035
  };
5894
6036
 
5895
6037
  // src/transactions/status/build-277.ts
6038
+ function refuseHierarchy3(message) {
6039
+ throw new ClaimStatus277BuildError(
6040
+ CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6041
+ message
6042
+ );
6043
+ }
6044
+ function refuseSpec3(message) {
6045
+ throw new ClaimStatus277BuildError(
6046
+ CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6047
+ message
6048
+ );
6049
+ }
5896
6050
  var X12_277_FUNCTIONAL_ID = "HN";
5897
6051
  var X12_AGENCY_CODE4 = "X";
5898
6052
  var HL_LEVEL3 = {
@@ -5987,42 +6141,62 @@ function buildClaimStatus(version, spec) {
5987
6141
  return parseX12(raw);
5988
6142
  }
5989
6143
  function enforceStructuralSpec4(spec) {
5990
- if (spec.informationSources.length === 0) {
6144
+ const sources = requireCallerArray(
6145
+ spec.informationSources,
6146
+ "build277: spec.informationSources",
6147
+ refuseHierarchy3
6148
+ );
6149
+ if (sources.length === 0) {
5991
6150
  throw new ClaimStatus277BuildError(
5992
6151
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
5993
6152
  "build277: at least one information source (HL level 20) is required."
5994
6153
  );
5995
6154
  }
5996
- for (let s = 0; s < spec.informationSources.length; s += 1) {
5997
- const source = spec.informationSources[s];
6155
+ for (let s = 0; s < sources.length; s += 1) {
6156
+ const source = sources[s];
5998
6157
  if (source === void 0) continue;
5999
- if (source.receivers.length === 0) {
6158
+ const receivers = requireCallerArray(
6159
+ source.receivers,
6160
+ `build277: spec.informationSources[${String(s)}].receivers`,
6161
+ refuseHierarchy3
6162
+ );
6163
+ if (receivers.length === 0) {
6000
6164
  throw new ClaimStatus277BuildError(
6001
6165
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6002
6166
  `build277: information source at index ${String(s)} has no receiver (HL level 21) child.`
6003
6167
  );
6004
6168
  }
6005
- for (let r = 0; r < source.receivers.length; r += 1) {
6006
- const receiver = source.receivers[r];
6169
+ for (let r = 0; r < receivers.length; r += 1) {
6170
+ const receiver = receivers[r];
6007
6171
  if (receiver === void 0) continue;
6008
- if (receiver.providers.length === 0) {
6172
+ const providers = requireCallerArray(
6173
+ receiver.providers,
6174
+ `build277: spec.informationSources[${String(s)}].receivers[${String(r)}].providers`,
6175
+ refuseHierarchy3
6176
+ );
6177
+ if (providers.length === 0) {
6009
6178
  throw new ClaimStatus277BuildError(
6010
6179
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6011
6180
  `build277: receiver at source[${String(s)}].receiver[${String(r)}] has no provider (HL level 19) child.`
6012
6181
  );
6013
6182
  }
6014
- for (let p = 0; p < receiver.providers.length; p += 1) {
6015
- const provider = receiver.providers[p];
6183
+ for (let p = 0; p < providers.length; p += 1) {
6184
+ const provider = providers[p];
6016
6185
  if (provider === void 0) continue;
6017
6186
  const locator = `source[${String(s)}].receiver[${String(r)}].provider[${String(p)}]`;
6018
- if (provider.subscribers.length === 0) {
6187
+ const subscribers = requireCallerArray(
6188
+ provider.subscribers,
6189
+ `build277: ${locator}.subscribers`,
6190
+ refuseHierarchy3
6191
+ );
6192
+ if (subscribers.length === 0) {
6019
6193
  throw new ClaimStatus277BuildError(
6020
6194
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6021
6195
  `build277: provider at ${locator} has no subscriber (HL level 22) child.`
6022
6196
  );
6023
6197
  }
6024
- for (let u = 0; u < provider.subscribers.length; u += 1) {
6025
- const subscriber = provider.subscribers[u];
6198
+ for (let u = 0; u < subscribers.length; u += 1) {
6199
+ const subscriber = subscribers[u];
6026
6200
  if (subscriber === void 0) continue;
6027
6201
  enforceSubscriber(subscriber, `${locator}.subscriber[${String(u)}]`);
6028
6202
  }
@@ -6031,8 +6205,16 @@ function enforceStructuralSpec4(spec) {
6031
6205
  }
6032
6206
  }
6033
6207
  function enforceSubscriber(subscriber, locator) {
6034
- const claims = subscriber.claims ?? [];
6035
- const dependents = subscriber.dependents ?? [];
6208
+ const claims = requireCallerArray(
6209
+ subscriber.claims,
6210
+ `build277: subscriber at ${locator}: claims`,
6211
+ refuseHierarchy3
6212
+ );
6213
+ const dependents = requireCallerArray(
6214
+ subscriber.dependents,
6215
+ `build277: subscriber at ${locator}: dependents`,
6216
+ refuseHierarchy3
6217
+ );
6036
6218
  if (claims.length === 0 && dependents.length === 0) {
6037
6219
  throw new ClaimStatus277BuildError(
6038
6220
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
@@ -6047,21 +6229,34 @@ function enforceSubscriber(subscriber, locator) {
6047
6229
  const dependent = dependents[d];
6048
6230
  if (dependent === void 0) continue;
6049
6231
  const depLocator = `${locator}.dependent[${String(d)}]`;
6050
- if (dependent.claims.length === 0) {
6232
+ const depClaims = requireCallerArray(
6233
+ dependent.claims,
6234
+ `build277: dependent at ${depLocator}: claims`,
6235
+ refuseHierarchy3
6236
+ );
6237
+ if (depClaims.length === 0) {
6051
6238
  throw new ClaimStatus277BuildError(
6052
6239
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6053
6240
  `build277: dependent at ${depLocator} has no claim.`
6054
6241
  );
6055
6242
  }
6056
- for (let c = 0; c < dependent.claims.length; c += 1) {
6057
- const claim = dependent.claims[c];
6243
+ for (let c = 0; c < depClaims.length; c += 1) {
6244
+ const claim = depClaims[c];
6058
6245
  if (claim !== void 0) enforceClaim2(claim, `${depLocator}.claim[${String(c)}]`, c === 0);
6059
6246
  }
6060
6247
  }
6061
6248
  }
6062
6249
  function enforceClaim2(claim, locator, isFirst) {
6063
- const statuses = claim.statuses ?? [];
6064
- const serviceLines = claim.serviceLines ?? [];
6250
+ const statuses = requireCallerArray(
6251
+ claim.statuses,
6252
+ `build277: claim at ${locator}: statuses`,
6253
+ refuseSpec3
6254
+ );
6255
+ const serviceLines = requireCallerArray(
6256
+ claim.serviceLines,
6257
+ `build277: claim at ${locator}: serviceLines`,
6258
+ refuseSpec3
6259
+ );
6065
6260
  if (claim.trace === void 0 && statuses.length === 0 && serviceLines.length === 0) {
6066
6261
  throw new ClaimStatus277BuildError(
6067
6262
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
@@ -6080,7 +6275,11 @@ function enforceClaim2(claim, locator, isFirst) {
6080
6275
  for (let l = 0; l < serviceLines.length; l += 1) {
6081
6276
  const line = serviceLines[l];
6082
6277
  if (line === void 0) continue;
6083
- const lineStatuses = line.statuses ?? [];
6278
+ const lineStatuses = requireCallerArray(
6279
+ line.statuses,
6280
+ `build277: claim at ${locator}.line[${String(l)}]: statuses`,
6281
+ refuseSpec3
6282
+ );
6084
6283
  for (let i = 0; i < lineStatuses.length; i += 1) {
6085
6284
  enforceStatus(lineStatuses[i], `${locator}.line[${String(l)}].status[${String(i)}]`);
6086
6285
  }
@@ -6257,7 +6456,7 @@ function padControl4(value, width) {
6257
6456
  if (value.length < width) return "0".repeat(width - value.length) + value;
6258
6457
  throw new ClaimStatus277BuildError(
6259
6458
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6260
- `build277: control number "${value}" exceeds the ${String(width)}-char spec limit.`
6459
+ `build277: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
6261
6460
  );
6262
6461
  }
6263
6462
  function expandYY4(yymmdd) {
@@ -6630,6 +6829,9 @@ var Premium820BuildError = class extends Error {
6630
6829
  };
6631
6830
 
6632
6831
  // src/transactions/premium/build-820.ts
6832
+ function refuseSpec4(message) {
6833
+ throw new Premium820BuildError(PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC, message);
6834
+ }
6633
6835
  var X218_VERSION_RELEASE = "005010X218";
6634
6836
  var X12_820_FUNCTIONAL_ID = "RA";
6635
6837
  var X12_AGENCY_CODE5 = "X";
@@ -6773,20 +6975,26 @@ function build820(spec) {
6773
6975
  return parseX12(raw);
6774
6976
  }
6775
6977
  function enforceStructuralSpec5(spec) {
6776
- if (spec.traces.length === 0) {
6978
+ const traces = requireCallerArray(spec.traces, "build820: spec.traces", refuseSpec4);
6979
+ if (traces.length === 0) {
6777
6980
  throw new Premium820BuildError(
6778
6981
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6779
6982
  "build820: at least one TRN trace is required (TR3 005010X218 header)."
6780
6983
  );
6781
6984
  }
6782
- if (spec.remittances.length === 0) {
6985
+ const remittances = requireCallerArray(
6986
+ spec.remittances,
6987
+ "build820: spec.remittances",
6988
+ refuseSpec4
6989
+ );
6990
+ if (remittances.length === 0) {
6783
6991
  throw new Premium820BuildError(
6784
6992
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6785
6993
  "build820: at least one remittance (Loop 2000) is required."
6786
6994
  );
6787
6995
  }
6788
- for (let r = 0; r < spec.remittances.length; r += 1) {
6789
- const remittance = spec.remittances[r];
6996
+ for (let r = 0; r < remittances.length; r += 1) {
6997
+ const remittance = remittances[r];
6790
6998
  if (remittance === void 0) continue;
6791
6999
  if (remittance.entity === void 0 && remittance.individual === void 0) {
6792
7000
  throw new Premium820BuildError(
@@ -6794,14 +7002,19 @@ function enforceStructuralSpec5(spec) {
6794
7002
  `build820: remittance at index ${String(r)} has neither an entity (ENT) nor an individual (NM1) to open its loop.`
6795
7003
  );
6796
7004
  }
6797
- if (remittance.openItems.length === 0) {
7005
+ const openItems = requireCallerArray(
7006
+ remittance.openItems,
7007
+ `build820: spec.remittances[${String(r)}].openItems`,
7008
+ refuseSpec4
7009
+ );
7010
+ if (openItems.length === 0) {
6798
7011
  throw new Premium820BuildError(
6799
7012
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6800
7013
  `build820: remittance at index ${String(r)} has no RMR open item.`
6801
7014
  );
6802
7015
  }
6803
- for (let o = 0; o < remittance.openItems.length; o += 1) {
6804
- const item = remittance.openItems[o];
7016
+ for (let o = 0; o < openItems.length; o += 1) {
7017
+ const item = openItems[o];
6805
7018
  if (item === void 0) continue;
6806
7019
  if (item.qualifier === "" && item.referenceId === "") {
6807
7020
  throw new Premium820BuildError(
@@ -6914,7 +7127,7 @@ function padControl5(value, width) {
6914
7127
  if (value.length < width) return "0".repeat(width - value.length) + value;
6915
7128
  throw new Premium820BuildError(
6916
7129
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6917
- `build820: control number "${value}" exceeds the ${String(width)}-char spec limit.`
7130
+ `build820: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
6918
7131
  );
6919
7132
  }
6920
7133
  function expandYY5(yymmdd) {
@@ -7312,6 +7525,12 @@ var Enrollment834BuildError = class extends Error {
7312
7525
  };
7313
7526
 
7314
7527
  // src/transactions/enrollment/build-834.ts
7528
+ function refuseSpec5(message) {
7529
+ throw new Enrollment834BuildError(
7530
+ ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7531
+ message
7532
+ );
7533
+ }
7315
7534
  var X220A1_VERSION_RELEASE = "005010X220A1";
7316
7535
  var X12_834_FUNCTIONAL_ID = "BE";
7317
7536
  var X12_AGENCY_CODE6 = "X";
@@ -7411,14 +7630,15 @@ function build834(spec) {
7411
7630
  return parseX12(raw);
7412
7631
  }
7413
7632
  function enforceStructuralSpec6(spec) {
7414
- if (spec.members.length === 0) {
7633
+ const members = requireCallerArray(spec.members, "build834: spec.members", refuseSpec5);
7634
+ if (members.length === 0) {
7415
7635
  throw new Enrollment834BuildError(
7416
7636
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7417
7637
  "build834: at least one member loop (INS) is required."
7418
7638
  );
7419
7639
  }
7420
- for (let m = 0; m < spec.members.length; m += 1) {
7421
- const member = spec.members[m];
7640
+ for (let m = 0; m < members.length; m += 1) {
7641
+ const member = members[m];
7422
7642
  if (member === void 0) continue;
7423
7643
  if (member.maintenanceTypeCode === "") {
7424
7644
  throw new Enrollment834BuildError(
@@ -7429,17 +7649,22 @@ function enforceStructuralSpec6(spec) {
7429
7649
  if (lookupMaintenanceType(member.maintenanceTypeCode) === void 0) {
7430
7650
  throw new Enrollment834BuildError(
7431
7651
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE,
7432
- `build834: member at index ${String(m)} has an unknown INS-03 maintenance type code "${member.maintenanceTypeCode}" (outside X12 Code Source 875).`
7652
+ `build834: member at index ${String(m)} has an unknown INS-03 maintenance type code ${renderCallerValue(member.maintenanceTypeCode)} (outside X12 Code Source 875).`
7433
7653
  );
7434
7654
  }
7435
- for (let c = 0; c < (member.healthCoverages ?? []).length; c += 1) {
7436
- const coverage = member.healthCoverages?.[c];
7655
+ const coverages = requireCallerArray(
7656
+ member.healthCoverages,
7657
+ `build834: spec.members[${String(m)}].healthCoverages`,
7658
+ refuseSpec5
7659
+ );
7660
+ for (let c = 0; c < coverages.length; c += 1) {
7661
+ const coverage = coverages[c];
7437
7662
  if (coverage === void 0) continue;
7438
7663
  const hd01 = coverage.maintenanceTypeCode;
7439
7664
  if (hd01 !== void 0 && hd01 !== "" && lookupMaintenanceType(hd01) === void 0) {
7440
7665
  throw new Enrollment834BuildError(
7441
7666
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE,
7442
- `build834: coverage at member[${String(m)}].healthCoverages[${String(c)}] has an unknown HD-01 maintenance type code "${hd01}" (outside X12 Code Source 875).`
7667
+ `build834: coverage at member[${String(m)}].healthCoverages[${String(c)}] has an unknown HD-01 maintenance type code ${renderCallerValue(hd01)} (outside X12 Code Source 875).`
7443
7668
  );
7444
7669
  }
7445
7670
  }
@@ -7588,7 +7813,7 @@ function padControl6(value, width) {
7588
7813
  if (value.length < width) return "0".repeat(width - value.length) + value;
7589
7814
  throw new Enrollment834BuildError(
7590
7815
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7591
- `build834: control number "${value}" exceeds the ${String(width)}-char spec limit.`
7816
+ `build834: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
7592
7817
  );
7593
7818
  }
7594
7819
  function expandYY6(yymmdd) {
@@ -7951,6 +8176,12 @@ var ServicesReview278BuildError = class extends Error {
7951
8176
  };
7952
8177
 
7953
8178
  // src/transactions/auth/build-278.ts
8179
+ function refuseHierarchy4(message) {
8180
+ throw new ServicesReview278BuildError(
8181
+ AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
8182
+ message
8183
+ );
8184
+ }
7954
8185
  var X12_278_FUNCTIONAL_ID = "HI";
7955
8186
  var X12_AGENCY_CODE7 = "X";
7956
8187
  var HL_LEVEL4 = {
@@ -8062,7 +8293,11 @@ function buildServicesReview(version, direction, spec) {
8062
8293
  }
8063
8294
  function enforceStructuralSpec7(spec, direction) {
8064
8295
  const subscriber = spec.subscriber;
8065
- const subscriberReviews = subscriber.reviews ?? [];
8296
+ const subscriberReviews = requireCallerArray(
8297
+ subscriber.reviews,
8298
+ "build278: spec.subscriber.reviews",
8299
+ refuseHierarchy4
8300
+ );
8066
8301
  if (subscriberReviews.length === 0 && subscriber.dependent === void 0) {
8067
8302
  throw new ServicesReview278BuildError(
8068
8303
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
@@ -8075,14 +8310,19 @@ function enforceStructuralSpec7(spec, direction) {
8075
8310
  }
8076
8311
  const dependent = subscriber.dependent;
8077
8312
  if (dependent !== void 0) {
8078
- if (dependent.reviews.length === 0) {
8313
+ const dependentReviews = requireCallerArray(
8314
+ dependent.reviews,
8315
+ "build278: spec.subscriber.dependent.reviews",
8316
+ refuseHierarchy4
8317
+ );
8318
+ if (dependentReviews.length === 0) {
8079
8319
  throw new ServicesReview278BuildError(
8080
8320
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
8081
8321
  "build278: dependent has no review (HL level EV/SS) child."
8082
8322
  );
8083
8323
  }
8084
- for (let r = 0; r < dependent.reviews.length; r += 1) {
8085
- const review = dependent.reviews[r];
8324
+ for (let r = 0; r < dependentReviews.length; r += 1) {
8325
+ const review = dependentReviews[r];
8086
8326
  if (review !== void 0) enforceReview(review, `dependent.review[${String(r)}]`, direction);
8087
8327
  }
8088
8328
  }
@@ -8108,7 +8348,11 @@ function enforceReview(review, locator, direction) {
8108
8348
  );
8109
8349
  }
8110
8350
  }
8111
- const nested = review.reviews ?? [];
8351
+ const nested = requireCallerArray(
8352
+ review.reviews,
8353
+ `build278: review at ${locator}: reviews`,
8354
+ refuseHierarchy4
8355
+ );
8112
8356
  for (let r = 0; r < nested.length; r += 1) {
8113
8357
  const child = nested[r];
8114
8358
  if (child !== void 0) enforceReview(child, `${locator}.review[${String(r)}]`, direction);
@@ -8244,7 +8488,7 @@ function padControl7(value, width) {
8244
8488
  if (value.length < width) return "0".repeat(width - value.length) + value;
8245
8489
  throw new ServicesReview278BuildError(
8246
8490
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_SPEC,
8247
- `build278: control number "${value}" exceeds the ${String(width)}-char spec limit.`
8491
+ `build278: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
8248
8492
  );
8249
8493
  }
8250
8494
  function expandYY7(yymmdd) {
@@ -8846,7 +9090,7 @@ function enforceAcceptIsClean(group) {
8846
9090
  if (functionalIsAccept && functionalHasErrorCodes) {
8847
9091
  throw new AckBuildError(
8848
9092
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8849
- `build999: AK9-01 was 'A' (Accept) but AK9-05..AK9-09 carried ${String(
9093
+ `build999: AK9-01 was 'A' (Accept) but AK9-05..AK9-09 carried ${renderCallerValue(
8850
9094
  (group.syntaxErrorCodes ?? []).length
8851
9095
  )} syntax error code(s). Use 'E' (Accept, with errors noted) or a reject disposition instead.`
8852
9096
  );
@@ -8857,13 +9101,13 @@ function enforceAcceptIsClean(group) {
8857
9101
  if (responseIsAccept && responseHasErrors) {
8858
9102
  throw new AckBuildError(
8859
9103
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8860
- `build999: AK2 (ST-02 ${response.transactionSetControlNumber}) IK5-01 was 'A' (Accept) but the response carried error payload. Use 'E' (Accept, with errors noted) or a reject disposition instead.`
9104
+ `build999: AK2 (ST-02 ${renderCallerValue(response.transactionSetControlNumber)}) IK5-01 was 'A' (Accept) but the response carried error payload. Use 'E' (Accept, with errors noted) or a reject disposition instead.`
8861
9105
  );
8862
9106
  }
8863
9107
  if (functionalIsAccept && (!responseIsAccept || responseHasErrors)) {
8864
9108
  throw new AckBuildError(
8865
9109
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8866
- `build999: AK9-01 was 'A' (Accept) but transaction response (ST-02 ${response.transactionSetControlNumber}) reported a non-accept disposition or carried errors. Lift the functional disposition to 'P' (Partial), 'E' (Accept, errors noted), or a reject.`
9110
+ `build999: AK9-01 was 'A' (Accept) but transaction response (ST-02 ${renderCallerValue(response.transactionSetControlNumber)}) reported a non-accept disposition or carried errors. Lift the functional disposition to 'P' (Partial), 'E' (Accept, errors noted), or a reject.`
8867
9111
  );
8868
9112
  }
8869
9113
  }
@@ -8875,25 +9119,25 @@ function enforceCountInvariants(group) {
8875
9119
  if (declared < 0 || received < 0 || accepted < 0) {
8876
9120
  throw new AckBuildError(
8877
9121
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8878
- `build999: AK9 counts must be non-negative (declared=${String(declared)}, received=${String(received)}, accepted=${String(accepted)}).`
9122
+ `build999: AK9 counts must be non-negative (declared=${renderCallerValue(declared)}, received=${renderCallerValue(received)}, accepted=${renderCallerValue(accepted)}).`
8879
9123
  );
8880
9124
  }
8881
9125
  if (accepted > received) {
8882
9126
  throw new AckBuildError(
8883
9127
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8884
- `build999: AK9-04 accepted (${String(accepted)}) cannot exceed AK9-03 received (${String(received)}).`
9128
+ `build999: AK9-04 accepted (${renderCallerValue(accepted)}) cannot exceed AK9-03 received (${renderCallerValue(received)}).`
8885
9129
  );
8886
9130
  }
8887
9131
  if (received > declared) {
8888
9132
  throw new AckBuildError(
8889
9133
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8890
- `build999: AK9-03 received (${String(received)}) cannot exceed AK9-02 declared (${String(declared)}).`
9134
+ `build999: AK9-03 received (${renderCallerValue(received)}) cannot exceed AK9-02 declared (${renderCallerValue(declared)}).`
8891
9135
  );
8892
9136
  }
8893
9137
  if (group.transactionResponses.length !== received) {
8894
9138
  throw new AckBuildError(
8895
9139
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8896
- `build999: AK9-03 received (${String(received)}) must equal the number of supplied transaction responses (${String(group.transactionResponses.length)}).`
9140
+ `build999: AK9-03 received (${renderCallerValue(received)}) must equal the number of supplied transaction responses (${renderCallerValue(group.transactionResponses.length)}).`
8897
9141
  );
8898
9142
  }
8899
9143
  }
@@ -8962,7 +9206,7 @@ function buildIk5(response, esc, elementSeparator, segmentTerminator) {
8962
9206
  if (codes.length > 5) {
8963
9207
  throw new AckBuildError(
8964
9208
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8965
- `build999: IK5 accepts up to 5 syntax error codes (IK5-02..IK5-06); ${String(codes.length)} supplied.`
9209
+ `build999: IK5 accepts up to 5 syntax error codes (IK5-02..IK5-06); ${renderCallerValue(codes.length)} supplied.`
8966
9210
  );
8967
9211
  }
8968
9212
  for (const code of codes) parts.push(esc(code));
@@ -8980,7 +9224,7 @@ function buildAk9(group, esc, elementSeparator, segmentTerminator) {
8980
9224
  if (codes.length > 5) {
8981
9225
  throw new AckBuildError(
8982
9226
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8983
- `build999: AK9 accepts up to 5 syntax error codes (AK9-05..AK9-09); ${String(codes.length)} supplied.`
9227
+ `build999: AK9 accepts up to 5 syntax error codes (AK9-05..AK9-09); ${renderCallerValue(codes.length)} supplied.`
8984
9228
  );
8985
9229
  }
8986
9230
  for (const code of codes) parts.push(esc(code));
@@ -8999,7 +9243,7 @@ function padControl8(value, width) {
8999
9243
  if (value.length < width) return "0".repeat(width - value.length) + value;
9000
9244
  throw new AckBuildError(
9001
9245
  ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC,
9002
- `build999: control number "${value}" exceeds the ${String(width)}-char spec limit.`
9246
+ `build999: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
9003
9247
  );
9004
9248
  }
9005
9249
  function expandYY8(yymmdd) {
@@ -9029,7 +9273,7 @@ function enforceAcceptIsClean2(spec) {
9029
9273
  if (spec.ackCode === TA1_ACK_CODES.A && spec.noteCode !== "000") {
9030
9274
  throw new AckBuildError(
9031
9275
  ACK_BUILD_ERROR_CODES.X12_TA1_ACCEPT_WITH_NOTE,
9032
- `buildTA1: TA1-04 was "A" (Accept) but TA1-05 carried note "${spec.noteCode}". An accept must cite "000" (no error). Use ackCode "E" (accept, errors noted) when the inbound had defects you elected to ignore.`
9276
+ `buildTA1: TA1-04 was "A" (Accept) but TA1-05 carried note ${renderCallerValue(spec.noteCode)}. An accept must cite "000" (no error). Use ackCode "E" (accept, errors noted) when the inbound had defects you elected to ignore.`
9033
9277
  );
9034
9278
  }
9035
9279
  }
@@ -9320,7 +9564,11 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
9320
9564
  if (segment.length === 0 || (segment[0] ?? "") === "") {
9321
9565
  throw new X12BuildError(
9322
9566
  X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC,
9323
- `buildInterchange: a segment spec in transaction "${esc(tx.transactionSetIdCode)}" has no segment id.`
9567
+ // Rendered from the RAW id, not the `?`-escaped one. `esc` can double
9568
+ // the length, so escaping first made the reported "(N characters)" the
9569
+ // escaped length rather than the caller's: a 100-character all-`?` id
9570
+ // reported 200. The escape exists for the wire, and this is a message.
9571
+ `buildInterchange: a segment spec in transaction ${renderCallerValue(tx.transactionSetIdCode)} has no segment id.`
9324
9572
  );
9325
9573
  }
9326
9574
  bodySegments += joinSeg2(segment.map(esc), elementSeparator, segmentTerminator);
@@ -9346,7 +9594,7 @@ function padControl9(value, width) {
9346
9594
  if (value.length < width) return "0".repeat(width - value.length) + value;
9347
9595
  throw new X12BuildError(
9348
9596
  X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC,
9349
- `buildInterchange: control number "${value}" exceeds the ${String(width)}-char spec limit.`
9597
+ `buildInterchange: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
9350
9598
  );
9351
9599
  }
9352
9600
  function expandYY9(yymmdd) {
@@ -9398,17 +9646,17 @@ function levenshtein(a, b) {
9398
9646
  function validateProfileName(opts) {
9399
9647
  if (opts === null || opts === void 0) {
9400
9648
  throw new X12ProfileError(
9401
- `defineProfile: options is required and must be an object. Received: ${String(opts)}.`
9649
+ `defineProfile: options is required and must be an object. Received: ${renderCallerJson(opts)}.`
9402
9650
  );
9403
9651
  }
9404
9652
  if (typeof opts.name !== "string") {
9405
9653
  throw new X12ProfileError(
9406
- `defineProfile: 'name' is required and must be a non-empty string. Received: ${JSON.stringify(opts.name)}.`
9654
+ `defineProfile: 'name' is required and must be a non-empty string. Received: ${renderCallerJson(opts.name)}.`
9407
9655
  );
9408
9656
  }
9409
9657
  if (opts.name.trim().length === 0) {
9410
9658
  throw new X12ProfileError(
9411
- `defineProfile: 'name' is required and must be a non-empty string. Received: ${JSON.stringify(opts.name)}.`,
9659
+ `defineProfile: 'name' is required and must be a non-empty string. Received: ${renderCallerJson(opts.name)}.`,
9412
9660
  opts.name
9413
9661
  );
9414
9662
  }
@@ -9424,7 +9672,7 @@ function validateOptionKeys(opts) {
9424
9672
  }
9425
9673
  }
9426
9674
  throw new X12ProfileError(
9427
- `Profile '${opts.name}' has unknown option key '${key}'. ` + (hint !== void 0 ? `Did you mean '${hint}'? ` : "") + `Known keys: ${KNOWN_OPTION_KEYS.join(", ")}.`,
9675
+ `Profile ${renderCallerValue(opts.name)} has unknown option key ${renderCallerValue(key)}. ` + (hint !== void 0 ? `Did you mean '${hint}'? ` : "") + `Known keys: ${KNOWN_OPTION_KEYS.join(", ")}.`,
9428
9676
  opts.name
9429
9677
  );
9430
9678
  }
@@ -9433,44 +9681,46 @@ function validateQuirks(quirks, profileName) {
9433
9681
  const seenIds = /* @__PURE__ */ new Set();
9434
9682
  for (let i = 0; i < quirks.length; i++) {
9435
9683
  const q = quirks[i];
9436
- const at = `quirks[${String(i)}]`;
9437
9684
  if (q === void 0 || q === null || typeof q !== "object") {
9438
- throw new X12ProfileError(`Profile '${profileName}' ${at} must be an object.`, profileName);
9685
+ throw new X12ProfileError(
9686
+ `Profile ${renderCallerValue(profileName)} quirks[${String(i)}] must be an object.`,
9687
+ profileName
9688
+ );
9439
9689
  }
9440
9690
  if (typeof q.id !== "string" || !QUIRK_ID_RE.test(q.id)) {
9441
9691
  throw new X12ProfileError(
9442
- `Profile '${profileName}' ${at}.id must be a kebab-case string (e.g. "payer-loop-ref-2u"). Received: ${JSON.stringify(q.id)}.`,
9692
+ `Profile ${renderCallerValue(profileName)} quirks[${String(i)}].id must be a kebab-case string (e.g. "payer-loop-ref-2u"). Received: ${renderCallerJson(q.id)}.`,
9443
9693
  profileName
9444
9694
  );
9445
9695
  }
9446
9696
  if (seenIds.has(q.id)) {
9447
9697
  throw new X12ProfileError(
9448
- `Profile '${profileName}' declares duplicate quirk id '${q.id}'. Each quirk id must be unique within a profile.`,
9698
+ `Profile ${renderCallerValue(profileName)} declares duplicate quirk id ${renderCallerValue(q.id)}. Each quirk id must be unique within a profile.`,
9449
9699
  profileName
9450
9700
  );
9451
9701
  }
9452
9702
  seenIds.add(q.id);
9453
9703
  if (typeof q.effect !== "string" || !KNOWN_EFFECTS.includes(q.effect)) {
9454
9704
  throw new X12ProfileError(
9455
- `Profile '${profileName}' quirk '${q.id}' has invalid effect ${JSON.stringify(q.effect)} - must be one of ${KNOWN_EFFECTS.join(" / ")}.`,
9705
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} has invalid effect ${renderCallerJson(q.effect)} - must be one of ${KNOWN_EFFECTS.join(" / ")}.`,
9456
9706
  profileName
9457
9707
  );
9458
9708
  }
9459
9709
  if (typeof q.summary !== "string" || q.summary.trim().length === 0) {
9460
9710
  throw new X12ProfileError(
9461
- `Profile '${profileName}' quirk '${q.id}' must have a non-empty summary.`,
9711
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} must have a non-empty summary.`,
9462
9712
  profileName
9463
9713
  );
9464
9714
  }
9465
9715
  if (typeof q.fixture !== "string" || !FIXTURE_PATH_RE.test(q.fixture)) {
9466
9716
  throw new X12ProfileError(
9467
- `Profile '${profileName}' quirk '${q.id}' must cite a 'fixture' - a relative path under test/fixtures/ (e.g. "remit/835-availity-quirk.edi") demonstrating the deviation. No invented quirks. Received: ${JSON.stringify(q.fixture)}.`,
9717
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} must cite a 'fixture' - a relative path under test/fixtures/ (e.g. "remit/835-availity-quirk.edi") demonstrating the deviation. No invented quirks. Received: ${renderCallerJson(q.fixture)}.`,
9468
9718
  profileName
9469
9719
  );
9470
9720
  }
9471
9721
  if (typeof q.sourceCategory !== "string" || q.sourceCategory.trim().length === 0) {
9472
9722
  throw new X12ProfileError(
9473
- `Profile '${profileName}' quirk '${q.id}' must have a non-empty sourceCategory (where the deviation was observed).`,
9723
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} must have a non-empty sourceCategory (where the deviation was observed).`,
9474
9724
  profileName
9475
9725
  );
9476
9726
  }
@@ -9478,7 +9728,7 @@ function validateQuirks(quirks, profileName) {
9478
9728
  for (const code of q.expectedWarnings) {
9479
9729
  if (!WARNING_CODE_SET.has(code)) {
9480
9730
  throw new X12ProfileError(
9481
- `Profile '${profileName}' quirk '${q.id}' lists unknown expected warning ${JSON.stringify(code)} - must be a member of WARNING_CODES.`,
9731
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} lists unknown expected warning ${renderCallerJson(code)} - must be a member of WARNING_CODES.`,
9482
9732
  profileName
9483
9733
  );
9484
9734
  }
@@ -9640,8 +9890,8 @@ var profiles = Object.freeze({
9640
9890
  });
9641
9891
 
9642
9892
  // src/index.ts
9643
- var VERSION = "0.0.4";
9893
+ var VERSION = "0.0.6";
9644
9894
 
9645
- 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, BALANCE_INVARIANTS, 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, ClaimStatus277BuildError, DELIMITER_POSITIONS, 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, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, 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, 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, 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, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, 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 };
9895
+ 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, BALANCE_INVARIANTS, BUILD_REFUSAL_VALUE_MAX_LENGTH, BUILD_REFUSAL_VALUE_MAX_RENDERED, 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, ClaimStatus277BuildError, DELIMITER_POSITIONS, 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, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, 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, 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, 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, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, 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, renderCallerValue, resolveHiQualifier, segmentCountMismatch, serializeX12, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc };
9646
9896
  //# sourceMappingURL=index.mjs.map
9647
9897
  //# sourceMappingURL=index.mjs.map