@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.cjs CHANGED
@@ -1888,6 +1888,7 @@ function get835(delimiters, tx) {
1888
1888
  const warnings = [];
1889
1889
  const body = tx.se === void 0 ? tx.segments.slice(1) : tx.segments.slice(1, -1);
1890
1890
  let payment = EMPTY_HEADER;
1891
+ let bprSegmentIndex = 0;
1891
1892
  const traces = [];
1892
1893
  let payer;
1893
1894
  let payee;
@@ -1916,6 +1917,7 @@ function get835(delimiters, tx) {
1916
1917
  switch (seg.id) {
1917
1918
  case "BPR": {
1918
1919
  payment = decodeBpr(seg, delimiters);
1920
+ bprSegmentIndex = position.segmentIndex;
1919
1921
  break;
1920
1922
  }
1921
1923
  case "TRN": {
@@ -2083,7 +2085,7 @@ function get835(delimiters, tx) {
2083
2085
  payment.totalActualPayment,
2084
2086
  finalClaims,
2085
2087
  providerAdjustments,
2086
- { segmentIndex: 0, transactionIndex: 0 }
2088
+ { segmentIndex: bprSegmentIndex, transactionIndex: 0 }
2087
2089
  );
2088
2090
  if (remitTotalWarn !== void 0) warnings.push(remitTotalWarn);
2089
2091
  return Object.freeze({
@@ -2444,10 +2446,79 @@ var Remit835BuildError = class extends Error {
2444
2446
  }
2445
2447
  };
2446
2448
 
2449
+ // src/builder/caller-value.ts
2450
+ var BUILD_REFUSAL_VALUE_MAX_LENGTH = 63;
2451
+ var MAX_LENGTH_DIGITS = 10;
2452
+ var BUILD_REFUSAL_VALUE_MAX_RENDERED = BUILD_REFUSAL_VALUE_MAX_LENGTH + 2 + 1 + " ( characters)".length + MAX_LENGTH_DIGITS;
2453
+ function renderCallerValue(value) {
2454
+ const text = coerce(value);
2455
+ if (text.length <= BUILD_REFUSAL_VALUE_MAX_LENGTH) return `"${text}"`;
2456
+ return `"${text.slice(0, BUILD_REFUSAL_VALUE_MAX_LENGTH)}\u2026" (${String(text.length)} characters)`;
2457
+ }
2458
+ function coerce(value) {
2459
+ if (typeof value === "string") return value;
2460
+ try {
2461
+ return String(value);
2462
+ } catch {
2463
+ return "[unrenderable value]";
2464
+ }
2465
+ }
2466
+ function renderCallerJson(value) {
2467
+ let text;
2468
+ try {
2469
+ text = JSON.stringify(value) ?? "undefined";
2470
+ } catch {
2471
+ return "[unrenderable value]";
2472
+ }
2473
+ if (text.length <= BUILD_REFUSAL_VALUE_MAX_LENGTH) return text;
2474
+ return `${text.slice(0, BUILD_REFUSAL_VALUE_MAX_LENGTH)}\u2026 (${String(text.length)} characters)`;
2475
+ }
2476
+
2477
+ // src/builder/caller-array.ts
2478
+ var NONE = Object.freeze([]);
2479
+ function describeShape(value) {
2480
+ if (typeof value !== "object") {
2481
+ return `a ${typeof value} (${renderCallerValue(value)})`;
2482
+ }
2483
+ let length;
2484
+ try {
2485
+ length = value.length;
2486
+ } catch {
2487
+ return "an object whose 'length' getter threw";
2488
+ }
2489
+ if (length !== void 0) {
2490
+ return `an array-like object with length ${renderCallerValue(length)}`;
2491
+ }
2492
+ let tag;
2493
+ try {
2494
+ tag = Object.prototype.toString.call(value);
2495
+ } catch {
2496
+ tag = "[object Unknown]";
2497
+ }
2498
+ return `a non-array ${renderCallerValue(tag)}`;
2499
+ }
2500
+ function requireCallerArray(value, at, refuse) {
2501
+ if (value === void 0 || value === null) return NONE;
2502
+ if (!isRealArray(value)) {
2503
+ refuse(`${at} must be an array. Received ${describeShape(value)}.`);
2504
+ }
2505
+ return value;
2506
+ }
2507
+ function isRealArray(value) {
2508
+ return Array.isArray(value);
2509
+ }
2510
+
2447
2511
  // src/transactions/remit/build-835.ts
2512
+ function refuseSpec(message) {
2513
+ throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
2514
+ }
2448
2515
  var X221A1_VERSION_RELEASE = "005010X221A1";
2449
2516
  var X12_835_FUNCTIONAL_ID = "HP";
2450
2517
  var X12_AGENCY_CODE = "X";
2518
+ var UNANCHORED_BUILD_POSITION = Object.freeze({
2519
+ segmentIndex: 0,
2520
+ transactionIndex: 0
2521
+ });
2451
2522
  function build835(spec) {
2452
2523
  const { envelope } = spec;
2453
2524
  enforceStructuralSpec(spec);
@@ -2594,7 +2665,14 @@ function build835(spec) {
2594
2665
  emitClaim(claim, body, seg, esc, comp);
2595
2666
  }
2596
2667
  }
2597
- emitProviderAdjustments(spec.providerAdjustments ?? [], body, seg, esc, comp);
2668
+ emitProviderAdjustments(
2669
+ spec.providerAdjustments,
2670
+ "build835: spec.providerAdjustments",
2671
+ body,
2672
+ seg,
2673
+ esc,
2674
+ comp
2675
+ );
2598
2676
  const seCount = body.length + 2;
2599
2677
  const se = seg(["SE", String(seCount), esc(stControlNumber)]);
2600
2678
  const ge = seg(["GE", "1", esc(envelope.groupControlNumber)]);
@@ -2603,14 +2681,16 @@ function build835(spec) {
2603
2681
  return parseX12(raw);
2604
2682
  }
2605
2683
  function enforceStructuralSpec(spec) {
2606
- if (spec.traces.length === 0) {
2684
+ const traces = requireCallerArray(spec.traces, "build835: spec.traces", refuseSpec);
2685
+ if (traces.length === 0) {
2607
2686
  throw new Remit835BuildError(
2608
2687
  REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
2609
2688
  "build835: at least one TRN trace is required (TR3 005010X221A1 Loop header)."
2610
2689
  );
2611
2690
  }
2612
- for (let i = 0; i < spec.claims.length; i += 1) {
2613
- const claim = spec.claims[i];
2691
+ const claims = requireCallerArray(spec.claims, "build835: spec.claims", refuseSpec);
2692
+ for (let i = 0; i < claims.length; i += 1) {
2693
+ const claim = claims[i];
2614
2694
  if (claim === void 0) continue;
2615
2695
  if (claim.patientControlNumber === "") {
2616
2696
  throw new Remit835BuildError(
@@ -2621,7 +2701,7 @@ function enforceStructuralSpec(spec) {
2621
2701
  }
2622
2702
  }
2623
2703
  function enforceBalance(spec) {
2624
- const position = { segmentIndex: 0, transactionIndex: 0 };
2704
+ const position = UNANCHORED_BUILD_POSITION;
2625
2705
  const claims = spec.claims.map(materializeClaim);
2626
2706
  for (const claim of claims) {
2627
2707
  const claimWarn = checkClaimBalance(claim, position);
@@ -2772,7 +2852,7 @@ function emitClaim(claim, body, seg, esc, comp) {
2772
2852
  comp([claim.facilityTypeCode ?? "", "", claim.claimFrequencyCode ?? ""])
2773
2853
  ])
2774
2854
  );
2775
- emitCasGroup(claim.adjustments ?? [], body, seg, esc);
2855
+ emitCasGroup(claim.adjustments, "build835: claim.adjustments", body, seg, esc);
2776
2856
  if (claim.patient !== void 0) body.push(emitPerson(claim.patient, seg, esc));
2777
2857
  if (claim.subscriber !== void 0) body.push(emitPerson(claim.subscriber, seg, esc));
2778
2858
  if (claim.correctedPatient !== void 0) body.push(emitPerson(claim.correctedPatient, seg, esc));
@@ -2818,7 +2898,7 @@ function emitServiceLine(line, body, seg, esc, comp) {
2818
2898
  ])
2819
2899
  );
2820
2900
  emitServiceLineDtm(line, body, seg, esc);
2821
- emitCasGroup(line.adjustments ?? [], body, seg, esc);
2901
+ emitCasGroup(line.adjustments, "build835: serviceLine.adjustments", body, seg, esc);
2822
2902
  for (const ref of line.references ?? []) body.push(emitRef(ref, seg, esc));
2823
2903
  for (const amt of line.amounts ?? []) {
2824
2904
  body.push(seg(["AMT", esc(amt.qualifier), esc(amt.amount.toString())]));
@@ -2836,7 +2916,8 @@ function emitServiceLineDtm(line, body, seg, esc) {
2836
2916
  if (start !== void 0) body.push(seg(["DTM", "150", esc(start)]));
2837
2917
  if (end !== void 0) body.push(seg(["DTM", "151", esc(end)]));
2838
2918
  }
2839
- function emitCasGroup(adjustments, body, seg, esc) {
2919
+ function emitCasGroup(raw, at, body, seg, esc) {
2920
+ const adjustments = requireCallerArray(raw, at, refuseSpec);
2840
2921
  let i = 0;
2841
2922
  while (i < adjustments.length) {
2842
2923
  const first = adjustments[i];
@@ -2894,7 +2975,8 @@ function emitProvider(provider, seg, esc) {
2894
2975
  esc(provider.idCode ?? "")
2895
2976
  ]);
2896
2977
  }
2897
- function emitProviderAdjustments(adjustments, body, seg, esc, comp) {
2978
+ function emitProviderAdjustments(raw, at, body, seg, esc, comp) {
2979
+ const adjustments = requireCallerArray(raw, at, refuseSpec);
2898
2980
  let i = 0;
2899
2981
  while (i < adjustments.length) {
2900
2982
  const first = adjustments[i];
@@ -2927,7 +3009,7 @@ function padControl(value, width) {
2927
3009
  if (value.length < width) return "0".repeat(width - value.length) + value;
2928
3010
  throw new Remit835BuildError(
2929
3011
  REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC,
2930
- `build835: control number "${value}" exceeds the ${String(width)}-char spec limit.`
3012
+ `build835: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
2931
3013
  );
2932
3014
  }
2933
3015
  function expandYY(yymmdd) {
@@ -4088,6 +4170,15 @@ var Claim837BuildError = class extends Error {
4088
4170
  };
4089
4171
 
4090
4172
  // src/transactions/claim/build-837.ts
4173
+ function refuseHierarchy(message) {
4174
+ throw new Claim837BuildError(
4175
+ CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4176
+ message
4177
+ );
4178
+ }
4179
+ function refuseSpec2(message) {
4180
+ throw new Claim837BuildError(CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC, message);
4181
+ }
4091
4182
  var VERSION_BY_VARIANT = {
4092
4183
  P: "005010X222A2",
4093
4184
  I: "005010X223A3",
@@ -4198,26 +4289,45 @@ function buildClaim837(variant, spec) {
4198
4289
  return parseX12(raw);
4199
4290
  }
4200
4291
  function enforceStructuralSpec2(variant, spec) {
4201
- if (spec.billingProviders.length === 0) {
4292
+ const billingProviders = requireCallerArray(
4293
+ spec.billingProviders,
4294
+ "build837: spec.billingProviders",
4295
+ refuseHierarchy
4296
+ );
4297
+ if (billingProviders.length === 0) {
4202
4298
  throw new Claim837BuildError(
4203
4299
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4204
4300
  "build837: at least one billing provider (HL level 20) is required."
4205
4301
  );
4206
4302
  }
4207
- for (let b = 0; b < spec.billingProviders.length; b += 1) {
4208
- const billing = spec.billingProviders[b];
4303
+ for (let b = 0; b < billingProviders.length; b += 1) {
4304
+ const billing = billingProviders[b];
4209
4305
  if (billing === void 0) continue;
4210
- if (billing.subscribers.length === 0) {
4306
+ const subscribers = requireCallerArray(
4307
+ billing.subscribers,
4308
+ `build837: spec.billingProviders[${String(b)}].subscribers`,
4309
+ refuseHierarchy
4310
+ );
4311
+ if (subscribers.length === 0) {
4211
4312
  throw new Claim837BuildError(
4212
4313
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4213
4314
  `build837: billing provider at index ${String(b)} has no subscriber (HL level 22) child.`
4214
4315
  );
4215
4316
  }
4216
- for (let s = 0; s < billing.subscribers.length; s += 1) {
4217
- const subscriber = billing.subscribers[s];
4317
+ for (let s = 0; s < subscribers.length; s += 1) {
4318
+ const subscriber = subscribers[s];
4218
4319
  if (subscriber === void 0) continue;
4219
- const directClaims = subscriber.claims ?? [];
4220
- const patients = subscriber.patients ?? [];
4320
+ const locator = `spec.billingProviders[${String(b)}].subscribers[${String(s)}]`;
4321
+ const directClaims = requireCallerArray(
4322
+ subscriber.claims,
4323
+ `build837: ${locator}.claims`,
4324
+ refuseHierarchy
4325
+ );
4326
+ const patients = requireCallerArray(
4327
+ subscriber.patients,
4328
+ `build837: ${locator}.patients`,
4329
+ refuseHierarchy
4330
+ );
4221
4331
  if (directClaims.length === 0 && patients.length === 0) {
4222
4332
  throw new Claim837BuildError(
4223
4333
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
@@ -4237,14 +4347,19 @@ function enforceStructuralSpec2(variant, spec) {
4237
4347
  for (let p = 0; p < patients.length; p += 1) {
4238
4348
  const patient = patients[p];
4239
4349
  if (patient === void 0) continue;
4240
- if (patient.claims.length === 0) {
4350
+ const patientClaims = requireCallerArray(
4351
+ patient.claims,
4352
+ `build837: ${locator}.patients[${String(p)}].claims`,
4353
+ refuseHierarchy
4354
+ );
4355
+ if (patientClaims.length === 0) {
4241
4356
  throw new Claim837BuildError(
4242
4357
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_HIERARCHY,
4243
4358
  `build837: dependent patient at billing[${String(b)}].subscriber[${String(s)}].patient[${String(p)}] has no claim.`
4244
4359
  );
4245
4360
  }
4246
- for (let c = 0; c < patient.claims.length; c += 1) {
4247
- const claim = patient.claims[c];
4361
+ for (let c = 0; c < patientClaims.length; c += 1) {
4362
+ const claim = patientClaims[c];
4248
4363
  if (claim !== void 0) {
4249
4364
  enforceClaim(
4250
4365
  variant,
@@ -4264,19 +4379,24 @@ function enforceClaim(variant, claim, locator) {
4264
4379
  `build837: claim at ${locator} has an empty claimId (CLM-01 is required).`
4265
4380
  );
4266
4381
  }
4267
- if (claim.serviceLines.length === 0) {
4382
+ const serviceLines = requireCallerArray(
4383
+ claim.serviceLines,
4384
+ `build837: claim at ${locator}: serviceLines`,
4385
+ refuseSpec2
4386
+ );
4387
+ if (serviceLines.length === 0) {
4268
4388
  throw new Claim837BuildError(
4269
4389
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4270
4390
  `build837: claim at ${locator} has no service line (a CLM requires at least one LX/SVx loop).`
4271
4391
  );
4272
4392
  }
4273
- for (let l = 0; l < claim.serviceLines.length; l += 1) {
4274
- const line = claim.serviceLines[l];
4393
+ for (let l = 0; l < serviceLines.length; l += 1) {
4394
+ const line = serviceLines[l];
4275
4395
  if (line === void 0) continue;
4276
4396
  if (line.variant !== variant) {
4277
4397
  throw new Claim837BuildError(
4278
4398
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4279
- `build837${variant}: claim at ${locator} has a "${line.variant}" service line at index ${String(l)}; every line must be "${variant}".`
4399
+ `build837${variant}: claim at ${locator} has a ${renderCallerValue(line.variant)} service line at index ${String(l)}; every line must be "${variant}".`
4280
4400
  );
4281
4401
  }
4282
4402
  const code = line.variant === "I" ? line.revenueCode : line.procedureCode;
@@ -4501,12 +4621,13 @@ function emitAdjudication(adj, body, ctx) {
4501
4621
  adj.paidUnits === void 0 ? "" : ctx.esc(adj.paidUnits.toString())
4502
4622
  ])
4503
4623
  );
4504
- emitCasGroup2(adj.adjustments ?? [], body, ctx);
4624
+ emitCasGroup2(adj.adjustments, "build837: adjudication.adjustments", body, ctx);
4505
4625
  if (adj.dateAdjudicated !== void 0) {
4506
4626
  body.push(ctx.seg(["DTP", "573", "D8", ctx.esc(adj.dateAdjudicated)]));
4507
4627
  }
4508
4628
  }
4509
- function emitCasGroup2(adjustments, body, ctx) {
4629
+ function emitCasGroup2(raw, at, body, ctx) {
4630
+ const adjustments = requireCallerArray(raw, at, refuseSpec2);
4510
4631
  let i = 0;
4511
4632
  while (i < adjustments.length) {
4512
4633
  const first = adjustments[i];
@@ -4620,7 +4741,7 @@ function padControl2(value, width) {
4620
4741
  if (value.length < width) return "0".repeat(width - value.length) + value;
4621
4742
  throw new Claim837BuildError(
4622
4743
  CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC,
4623
- `build837: control number "${value}" exceeds the ${String(width)}-char spec limit.`
4744
+ `build837: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
4624
4745
  );
4625
4746
  }
4626
4747
  function expandYY2(yymmdd) {
@@ -5224,6 +5345,12 @@ var Eligibility271BuildError = class extends Error {
5224
5345
  };
5225
5346
 
5226
5347
  // src/transactions/eligibility/build-271.ts
5348
+ function refuseHierarchy2(message) {
5349
+ throw new Eligibility271BuildError(
5350
+ ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5351
+ message
5352
+ );
5353
+ }
5227
5354
  var X279A1_VERSION_RELEASE = "005010X279A1";
5228
5355
  var X12_271_FUNCTIONAL_ID = "HB";
5229
5356
  var X12_AGENCY_CODE3 = "X";
@@ -5301,25 +5428,40 @@ function build271(spec) {
5301
5428
  return parseX12(raw);
5302
5429
  }
5303
5430
  function enforceStructuralSpec3(spec) {
5304
- if (spec.informationSources.length === 0) {
5431
+ const sources = requireCallerArray(
5432
+ spec.informationSources,
5433
+ "build271: spec.informationSources",
5434
+ refuseHierarchy2
5435
+ );
5436
+ if (sources.length === 0) {
5305
5437
  throw new Eligibility271BuildError(
5306
5438
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5307
5439
  "build271: at least one information source (HL level 20) is required."
5308
5440
  );
5309
5441
  }
5310
- for (let s = 0; s < spec.informationSources.length; s += 1) {
5311
- const source = spec.informationSources[s];
5442
+ for (let s = 0; s < sources.length; s += 1) {
5443
+ const source = sources[s];
5312
5444
  if (source === void 0) continue;
5313
- if (source.receivers.length === 0) {
5445
+ const receivers = requireCallerArray(
5446
+ source.receivers,
5447
+ `build271: spec.informationSources[${String(s)}].receivers`,
5448
+ refuseHierarchy2
5449
+ );
5450
+ if (receivers.length === 0) {
5314
5451
  throw new Eligibility271BuildError(
5315
5452
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5316
5453
  `build271: information source at index ${String(s)} has no receiver (HL level 21) child.`
5317
5454
  );
5318
5455
  }
5319
- for (let r = 0; r < source.receivers.length; r += 1) {
5320
- const receiver = source.receivers[r];
5456
+ for (let r = 0; r < receivers.length; r += 1) {
5457
+ const receiver = receivers[r];
5321
5458
  if (receiver === void 0) continue;
5322
- if (receiver.subscribers.length === 0) {
5459
+ const subscribers = requireCallerArray(
5460
+ receiver.subscribers,
5461
+ `build271: spec.informationSources[${String(s)}].receivers[${String(r)}].subscribers`,
5462
+ refuseHierarchy2
5463
+ );
5464
+ if (subscribers.length === 0) {
5323
5465
  throw new Eligibility271BuildError(
5324
5466
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_HIERARCHY,
5325
5467
  `build271: receiver at source[${String(s)}].receiver[${String(r)}] has no subscriber (HL level 22) child.`
@@ -5485,7 +5627,7 @@ function padControl3(value, width) {
5485
5627
  if (value.length < width) return "0".repeat(width - value.length) + value;
5486
5628
  throw new Eligibility271BuildError(
5487
5629
  ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_SPEC,
5488
- `build271: control number "${value}" exceeds the ${String(width)}-char spec limit.`
5630
+ `build271: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
5489
5631
  );
5490
5632
  }
5491
5633
  function expandYY3(yymmdd) {
@@ -5895,6 +6037,18 @@ var ClaimStatus277BuildError = class extends Error {
5895
6037
  };
5896
6038
 
5897
6039
  // src/transactions/status/build-277.ts
6040
+ function refuseHierarchy3(message) {
6041
+ throw new ClaimStatus277BuildError(
6042
+ CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6043
+ message
6044
+ );
6045
+ }
6046
+ function refuseSpec3(message) {
6047
+ throw new ClaimStatus277BuildError(
6048
+ CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6049
+ message
6050
+ );
6051
+ }
5898
6052
  var X12_277_FUNCTIONAL_ID = "HN";
5899
6053
  var X12_AGENCY_CODE4 = "X";
5900
6054
  var HL_LEVEL3 = {
@@ -5989,42 +6143,62 @@ function buildClaimStatus(version, spec) {
5989
6143
  return parseX12(raw);
5990
6144
  }
5991
6145
  function enforceStructuralSpec4(spec) {
5992
- if (spec.informationSources.length === 0) {
6146
+ const sources = requireCallerArray(
6147
+ spec.informationSources,
6148
+ "build277: spec.informationSources",
6149
+ refuseHierarchy3
6150
+ );
6151
+ if (sources.length === 0) {
5993
6152
  throw new ClaimStatus277BuildError(
5994
6153
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
5995
6154
  "build277: at least one information source (HL level 20) is required."
5996
6155
  );
5997
6156
  }
5998
- for (let s = 0; s < spec.informationSources.length; s += 1) {
5999
- const source = spec.informationSources[s];
6157
+ for (let s = 0; s < sources.length; s += 1) {
6158
+ const source = sources[s];
6000
6159
  if (source === void 0) continue;
6001
- if (source.receivers.length === 0) {
6160
+ const receivers = requireCallerArray(
6161
+ source.receivers,
6162
+ `build277: spec.informationSources[${String(s)}].receivers`,
6163
+ refuseHierarchy3
6164
+ );
6165
+ if (receivers.length === 0) {
6002
6166
  throw new ClaimStatus277BuildError(
6003
6167
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6004
6168
  `build277: information source at index ${String(s)} has no receiver (HL level 21) child.`
6005
6169
  );
6006
6170
  }
6007
- for (let r = 0; r < source.receivers.length; r += 1) {
6008
- const receiver = source.receivers[r];
6171
+ for (let r = 0; r < receivers.length; r += 1) {
6172
+ const receiver = receivers[r];
6009
6173
  if (receiver === void 0) continue;
6010
- if (receiver.providers.length === 0) {
6174
+ const providers = requireCallerArray(
6175
+ receiver.providers,
6176
+ `build277: spec.informationSources[${String(s)}].receivers[${String(r)}].providers`,
6177
+ refuseHierarchy3
6178
+ );
6179
+ if (providers.length === 0) {
6011
6180
  throw new ClaimStatus277BuildError(
6012
6181
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6013
6182
  `build277: receiver at source[${String(s)}].receiver[${String(r)}] has no provider (HL level 19) child.`
6014
6183
  );
6015
6184
  }
6016
- for (let p = 0; p < receiver.providers.length; p += 1) {
6017
- const provider = receiver.providers[p];
6185
+ for (let p = 0; p < providers.length; p += 1) {
6186
+ const provider = providers[p];
6018
6187
  if (provider === void 0) continue;
6019
6188
  const locator = `source[${String(s)}].receiver[${String(r)}].provider[${String(p)}]`;
6020
- if (provider.subscribers.length === 0) {
6189
+ const subscribers = requireCallerArray(
6190
+ provider.subscribers,
6191
+ `build277: ${locator}.subscribers`,
6192
+ refuseHierarchy3
6193
+ );
6194
+ if (subscribers.length === 0) {
6021
6195
  throw new ClaimStatus277BuildError(
6022
6196
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6023
6197
  `build277: provider at ${locator} has no subscriber (HL level 22) child.`
6024
6198
  );
6025
6199
  }
6026
- for (let u = 0; u < provider.subscribers.length; u += 1) {
6027
- const subscriber = provider.subscribers[u];
6200
+ for (let u = 0; u < subscribers.length; u += 1) {
6201
+ const subscriber = subscribers[u];
6028
6202
  if (subscriber === void 0) continue;
6029
6203
  enforceSubscriber(subscriber, `${locator}.subscriber[${String(u)}]`);
6030
6204
  }
@@ -6033,8 +6207,16 @@ function enforceStructuralSpec4(spec) {
6033
6207
  }
6034
6208
  }
6035
6209
  function enforceSubscriber(subscriber, locator) {
6036
- const claims = subscriber.claims ?? [];
6037
- const dependents = subscriber.dependents ?? [];
6210
+ const claims = requireCallerArray(
6211
+ subscriber.claims,
6212
+ `build277: subscriber at ${locator}: claims`,
6213
+ refuseHierarchy3
6214
+ );
6215
+ const dependents = requireCallerArray(
6216
+ subscriber.dependents,
6217
+ `build277: subscriber at ${locator}: dependents`,
6218
+ refuseHierarchy3
6219
+ );
6038
6220
  if (claims.length === 0 && dependents.length === 0) {
6039
6221
  throw new ClaimStatus277BuildError(
6040
6222
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
@@ -6049,21 +6231,34 @@ function enforceSubscriber(subscriber, locator) {
6049
6231
  const dependent = dependents[d];
6050
6232
  if (dependent === void 0) continue;
6051
6233
  const depLocator = `${locator}.dependent[${String(d)}]`;
6052
- if (dependent.claims.length === 0) {
6234
+ const depClaims = requireCallerArray(
6235
+ dependent.claims,
6236
+ `build277: dependent at ${depLocator}: claims`,
6237
+ refuseHierarchy3
6238
+ );
6239
+ if (depClaims.length === 0) {
6053
6240
  throw new ClaimStatus277BuildError(
6054
6241
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_HIERARCHY,
6055
6242
  `build277: dependent at ${depLocator} has no claim.`
6056
6243
  );
6057
6244
  }
6058
- for (let c = 0; c < dependent.claims.length; c += 1) {
6059
- const claim = dependent.claims[c];
6245
+ for (let c = 0; c < depClaims.length; c += 1) {
6246
+ const claim = depClaims[c];
6060
6247
  if (claim !== void 0) enforceClaim2(claim, `${depLocator}.claim[${String(c)}]`, c === 0);
6061
6248
  }
6062
6249
  }
6063
6250
  }
6064
6251
  function enforceClaim2(claim, locator, isFirst) {
6065
- const statuses = claim.statuses ?? [];
6066
- const serviceLines = claim.serviceLines ?? [];
6252
+ const statuses = requireCallerArray(
6253
+ claim.statuses,
6254
+ `build277: claim at ${locator}: statuses`,
6255
+ refuseSpec3
6256
+ );
6257
+ const serviceLines = requireCallerArray(
6258
+ claim.serviceLines,
6259
+ `build277: claim at ${locator}: serviceLines`,
6260
+ refuseSpec3
6261
+ );
6067
6262
  if (claim.trace === void 0 && statuses.length === 0 && serviceLines.length === 0) {
6068
6263
  throw new ClaimStatus277BuildError(
6069
6264
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
@@ -6082,7 +6277,11 @@ function enforceClaim2(claim, locator, isFirst) {
6082
6277
  for (let l = 0; l < serviceLines.length; l += 1) {
6083
6278
  const line = serviceLines[l];
6084
6279
  if (line === void 0) continue;
6085
- const lineStatuses = line.statuses ?? [];
6280
+ const lineStatuses = requireCallerArray(
6281
+ line.statuses,
6282
+ `build277: claim at ${locator}.line[${String(l)}]: statuses`,
6283
+ refuseSpec3
6284
+ );
6086
6285
  for (let i = 0; i < lineStatuses.length; i += 1) {
6087
6286
  enforceStatus(lineStatuses[i], `${locator}.line[${String(l)}].status[${String(i)}]`);
6088
6287
  }
@@ -6259,7 +6458,7 @@ function padControl4(value, width) {
6259
6458
  if (value.length < width) return "0".repeat(width - value.length) + value;
6260
6459
  throw new ClaimStatus277BuildError(
6261
6460
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6262
- `build277: control number "${value}" exceeds the ${String(width)}-char spec limit.`
6461
+ `build277: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
6263
6462
  );
6264
6463
  }
6265
6464
  function expandYY4(yymmdd) {
@@ -6632,6 +6831,9 @@ var Premium820BuildError = class extends Error {
6632
6831
  };
6633
6832
 
6634
6833
  // src/transactions/premium/build-820.ts
6834
+ function refuseSpec4(message) {
6835
+ throw new Premium820BuildError(PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC, message);
6836
+ }
6635
6837
  var X218_VERSION_RELEASE = "005010X218";
6636
6838
  var X12_820_FUNCTIONAL_ID = "RA";
6637
6839
  var X12_AGENCY_CODE5 = "X";
@@ -6775,20 +6977,26 @@ function build820(spec) {
6775
6977
  return parseX12(raw);
6776
6978
  }
6777
6979
  function enforceStructuralSpec5(spec) {
6778
- if (spec.traces.length === 0) {
6980
+ const traces = requireCallerArray(spec.traces, "build820: spec.traces", refuseSpec4);
6981
+ if (traces.length === 0) {
6779
6982
  throw new Premium820BuildError(
6780
6983
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6781
6984
  "build820: at least one TRN trace is required (TR3 005010X218 header)."
6782
6985
  );
6783
6986
  }
6784
- if (spec.remittances.length === 0) {
6987
+ const remittances = requireCallerArray(
6988
+ spec.remittances,
6989
+ "build820: spec.remittances",
6990
+ refuseSpec4
6991
+ );
6992
+ if (remittances.length === 0) {
6785
6993
  throw new Premium820BuildError(
6786
6994
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6787
6995
  "build820: at least one remittance (Loop 2000) is required."
6788
6996
  );
6789
6997
  }
6790
- for (let r = 0; r < spec.remittances.length; r += 1) {
6791
- const remittance = spec.remittances[r];
6998
+ for (let r = 0; r < remittances.length; r += 1) {
6999
+ const remittance = remittances[r];
6792
7000
  if (remittance === void 0) continue;
6793
7001
  if (remittance.entity === void 0 && remittance.individual === void 0) {
6794
7002
  throw new Premium820BuildError(
@@ -6796,14 +7004,19 @@ function enforceStructuralSpec5(spec) {
6796
7004
  `build820: remittance at index ${String(r)} has neither an entity (ENT) nor an individual (NM1) to open its loop.`
6797
7005
  );
6798
7006
  }
6799
- if (remittance.openItems.length === 0) {
7007
+ const openItems = requireCallerArray(
7008
+ remittance.openItems,
7009
+ `build820: spec.remittances[${String(r)}].openItems`,
7010
+ refuseSpec4
7011
+ );
7012
+ if (openItems.length === 0) {
6800
7013
  throw new Premium820BuildError(
6801
7014
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6802
7015
  `build820: remittance at index ${String(r)} has no RMR open item.`
6803
7016
  );
6804
7017
  }
6805
- for (let o = 0; o < remittance.openItems.length; o += 1) {
6806
- const item = remittance.openItems[o];
7018
+ for (let o = 0; o < openItems.length; o += 1) {
7019
+ const item = openItems[o];
6807
7020
  if (item === void 0) continue;
6808
7021
  if (item.qualifier === "" && item.referenceId === "") {
6809
7022
  throw new Premium820BuildError(
@@ -6916,7 +7129,7 @@ function padControl5(value, width) {
6916
7129
  if (value.length < width) return "0".repeat(width - value.length) + value;
6917
7130
  throw new Premium820BuildError(
6918
7131
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
6919
- `build820: control number "${value}" exceeds the ${String(width)}-char spec limit.`
7132
+ `build820: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
6920
7133
  );
6921
7134
  }
6922
7135
  function expandYY5(yymmdd) {
@@ -7314,6 +7527,12 @@ var Enrollment834BuildError = class extends Error {
7314
7527
  };
7315
7528
 
7316
7529
  // src/transactions/enrollment/build-834.ts
7530
+ function refuseSpec5(message) {
7531
+ throw new Enrollment834BuildError(
7532
+ ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7533
+ message
7534
+ );
7535
+ }
7317
7536
  var X220A1_VERSION_RELEASE = "005010X220A1";
7318
7537
  var X12_834_FUNCTIONAL_ID = "BE";
7319
7538
  var X12_AGENCY_CODE6 = "X";
@@ -7413,14 +7632,15 @@ function build834(spec) {
7413
7632
  return parseX12(raw);
7414
7633
  }
7415
7634
  function enforceStructuralSpec6(spec) {
7416
- if (spec.members.length === 0) {
7635
+ const members = requireCallerArray(spec.members, "build834: spec.members", refuseSpec5);
7636
+ if (members.length === 0) {
7417
7637
  throw new Enrollment834BuildError(
7418
7638
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7419
7639
  "build834: at least one member loop (INS) is required."
7420
7640
  );
7421
7641
  }
7422
- for (let m = 0; m < spec.members.length; m += 1) {
7423
- const member = spec.members[m];
7642
+ for (let m = 0; m < members.length; m += 1) {
7643
+ const member = members[m];
7424
7644
  if (member === void 0) continue;
7425
7645
  if (member.maintenanceTypeCode === "") {
7426
7646
  throw new Enrollment834BuildError(
@@ -7431,17 +7651,22 @@ function enforceStructuralSpec6(spec) {
7431
7651
  if (lookupMaintenanceType(member.maintenanceTypeCode) === void 0) {
7432
7652
  throw new Enrollment834BuildError(
7433
7653
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE,
7434
- `build834: member at index ${String(m)} has an unknown INS-03 maintenance type code "${member.maintenanceTypeCode}" (outside X12 Code Source 875).`
7654
+ `build834: member at index ${String(m)} has an unknown INS-03 maintenance type code ${renderCallerValue(member.maintenanceTypeCode)} (outside X12 Code Source 875).`
7435
7655
  );
7436
7656
  }
7437
- for (let c = 0; c < (member.healthCoverages ?? []).length; c += 1) {
7438
- const coverage = member.healthCoverages?.[c];
7657
+ const coverages = requireCallerArray(
7658
+ member.healthCoverages,
7659
+ `build834: spec.members[${String(m)}].healthCoverages`,
7660
+ refuseSpec5
7661
+ );
7662
+ for (let c = 0; c < coverages.length; c += 1) {
7663
+ const coverage = coverages[c];
7439
7664
  if (coverage === void 0) continue;
7440
7665
  const hd01 = coverage.maintenanceTypeCode;
7441
7666
  if (hd01 !== void 0 && hd01 !== "" && lookupMaintenanceType(hd01) === void 0) {
7442
7667
  throw new Enrollment834BuildError(
7443
7668
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_UNKNOWN_MAINTENANCE_TYPE,
7444
- `build834: coverage at member[${String(m)}].healthCoverages[${String(c)}] has an unknown HD-01 maintenance type code "${hd01}" (outside X12 Code Source 875).`
7669
+ `build834: coverage at member[${String(m)}].healthCoverages[${String(c)}] has an unknown HD-01 maintenance type code ${renderCallerValue(hd01)} (outside X12 Code Source 875).`
7445
7670
  );
7446
7671
  }
7447
7672
  }
@@ -7590,7 +7815,7 @@ function padControl6(value, width) {
7590
7815
  if (value.length < width) return "0".repeat(width - value.length) + value;
7591
7816
  throw new Enrollment834BuildError(
7592
7817
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7593
- `build834: control number "${value}" exceeds the ${String(width)}-char spec limit.`
7818
+ `build834: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
7594
7819
  );
7595
7820
  }
7596
7821
  function expandYY6(yymmdd) {
@@ -7953,6 +8178,12 @@ var ServicesReview278BuildError = class extends Error {
7953
8178
  };
7954
8179
 
7955
8180
  // src/transactions/auth/build-278.ts
8181
+ function refuseHierarchy4(message) {
8182
+ throw new ServicesReview278BuildError(
8183
+ AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
8184
+ message
8185
+ );
8186
+ }
7956
8187
  var X12_278_FUNCTIONAL_ID = "HI";
7957
8188
  var X12_AGENCY_CODE7 = "X";
7958
8189
  var HL_LEVEL4 = {
@@ -8064,7 +8295,11 @@ function buildServicesReview(version, direction, spec) {
8064
8295
  }
8065
8296
  function enforceStructuralSpec7(spec, direction) {
8066
8297
  const subscriber = spec.subscriber;
8067
- const subscriberReviews = subscriber.reviews ?? [];
8298
+ const subscriberReviews = requireCallerArray(
8299
+ subscriber.reviews,
8300
+ "build278: spec.subscriber.reviews",
8301
+ refuseHierarchy4
8302
+ );
8068
8303
  if (subscriberReviews.length === 0 && subscriber.dependent === void 0) {
8069
8304
  throw new ServicesReview278BuildError(
8070
8305
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
@@ -8077,14 +8312,19 @@ function enforceStructuralSpec7(spec, direction) {
8077
8312
  }
8078
8313
  const dependent = subscriber.dependent;
8079
8314
  if (dependent !== void 0) {
8080
- if (dependent.reviews.length === 0) {
8315
+ const dependentReviews = requireCallerArray(
8316
+ dependent.reviews,
8317
+ "build278: spec.subscriber.dependent.reviews",
8318
+ refuseHierarchy4
8319
+ );
8320
+ if (dependentReviews.length === 0) {
8081
8321
  throw new ServicesReview278BuildError(
8082
8322
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_HIERARCHY,
8083
8323
  "build278: dependent has no review (HL level EV/SS) child."
8084
8324
  );
8085
8325
  }
8086
- for (let r = 0; r < dependent.reviews.length; r += 1) {
8087
- const review = dependent.reviews[r];
8326
+ for (let r = 0; r < dependentReviews.length; r += 1) {
8327
+ const review = dependentReviews[r];
8088
8328
  if (review !== void 0) enforceReview(review, `dependent.review[${String(r)}]`, direction);
8089
8329
  }
8090
8330
  }
@@ -8110,7 +8350,11 @@ function enforceReview(review, locator, direction) {
8110
8350
  );
8111
8351
  }
8112
8352
  }
8113
- const nested = review.reviews ?? [];
8353
+ const nested = requireCallerArray(
8354
+ review.reviews,
8355
+ `build278: review at ${locator}: reviews`,
8356
+ refuseHierarchy4
8357
+ );
8114
8358
  for (let r = 0; r < nested.length; r += 1) {
8115
8359
  const child = nested[r];
8116
8360
  if (child !== void 0) enforceReview(child, `${locator}.review[${String(r)}]`, direction);
@@ -8246,7 +8490,7 @@ function padControl7(value, width) {
8246
8490
  if (value.length < width) return "0".repeat(width - value.length) + value;
8247
8491
  throw new ServicesReview278BuildError(
8248
8492
  AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_SPEC,
8249
- `build278: control number "${value}" exceeds the ${String(width)}-char spec limit.`
8493
+ `build278: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
8250
8494
  );
8251
8495
  }
8252
8496
  function expandYY7(yymmdd) {
@@ -8848,7 +9092,7 @@ function enforceAcceptIsClean(group) {
8848
9092
  if (functionalIsAccept && functionalHasErrorCodes) {
8849
9093
  throw new AckBuildError(
8850
9094
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8851
- `build999: AK9-01 was 'A' (Accept) but AK9-05..AK9-09 carried ${String(
9095
+ `build999: AK9-01 was 'A' (Accept) but AK9-05..AK9-09 carried ${renderCallerValue(
8852
9096
  (group.syntaxErrorCodes ?? []).length
8853
9097
  )} syntax error code(s). Use 'E' (Accept, with errors noted) or a reject disposition instead.`
8854
9098
  );
@@ -8859,13 +9103,13 @@ function enforceAcceptIsClean(group) {
8859
9103
  if (responseIsAccept && responseHasErrors) {
8860
9104
  throw new AckBuildError(
8861
9105
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8862
- `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.`
9106
+ `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.`
8863
9107
  );
8864
9108
  }
8865
9109
  if (functionalIsAccept && (!responseIsAccept || responseHasErrors)) {
8866
9110
  throw new AckBuildError(
8867
9111
  ACK_BUILD_ERROR_CODES.X12_ACK_ACCEPT_WITH_ERRORS,
8868
- `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.`
9112
+ `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.`
8869
9113
  );
8870
9114
  }
8871
9115
  }
@@ -8877,25 +9121,25 @@ function enforceCountInvariants(group) {
8877
9121
  if (declared < 0 || received < 0 || accepted < 0) {
8878
9122
  throw new AckBuildError(
8879
9123
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8880
- `build999: AK9 counts must be non-negative (declared=${String(declared)}, received=${String(received)}, accepted=${String(accepted)}).`
9124
+ `build999: AK9 counts must be non-negative (declared=${renderCallerValue(declared)}, received=${renderCallerValue(received)}, accepted=${renderCallerValue(accepted)}).`
8881
9125
  );
8882
9126
  }
8883
9127
  if (accepted > received) {
8884
9128
  throw new AckBuildError(
8885
9129
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8886
- `build999: AK9-04 accepted (${String(accepted)}) cannot exceed AK9-03 received (${String(received)}).`
9130
+ `build999: AK9-04 accepted (${renderCallerValue(accepted)}) cannot exceed AK9-03 received (${renderCallerValue(received)}).`
8887
9131
  );
8888
9132
  }
8889
9133
  if (received > declared) {
8890
9134
  throw new AckBuildError(
8891
9135
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8892
- `build999: AK9-03 received (${String(received)}) cannot exceed AK9-02 declared (${String(declared)}).`
9136
+ `build999: AK9-03 received (${renderCallerValue(received)}) cannot exceed AK9-02 declared (${renderCallerValue(declared)}).`
8893
9137
  );
8894
9138
  }
8895
9139
  if (group.transactionResponses.length !== received) {
8896
9140
  throw new AckBuildError(
8897
9141
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8898
- `build999: AK9-03 received (${String(received)}) must equal the number of supplied transaction responses (${String(group.transactionResponses.length)}).`
9142
+ `build999: AK9-03 received (${renderCallerValue(received)}) must equal the number of supplied transaction responses (${renderCallerValue(group.transactionResponses.length)}).`
8899
9143
  );
8900
9144
  }
8901
9145
  }
@@ -8964,7 +9208,7 @@ function buildIk5(response, esc, elementSeparator, segmentTerminator) {
8964
9208
  if (codes.length > 5) {
8965
9209
  throw new AckBuildError(
8966
9210
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8967
- `build999: IK5 accepts up to 5 syntax error codes (IK5-02..IK5-06); ${String(codes.length)} supplied.`
9211
+ `build999: IK5 accepts up to 5 syntax error codes (IK5-02..IK5-06); ${renderCallerValue(codes.length)} supplied.`
8968
9212
  );
8969
9213
  }
8970
9214
  for (const code of codes) parts.push(esc(code));
@@ -8982,7 +9226,7 @@ function buildAk9(group, esc, elementSeparator, segmentTerminator) {
8982
9226
  if (codes.length > 5) {
8983
9227
  throw new AckBuildError(
8984
9228
  ACK_BUILD_ERROR_CODES.X12_ACK_COUNT_MISMATCH,
8985
- `build999: AK9 accepts up to 5 syntax error codes (AK9-05..AK9-09); ${String(codes.length)} supplied.`
9229
+ `build999: AK9 accepts up to 5 syntax error codes (AK9-05..AK9-09); ${renderCallerValue(codes.length)} supplied.`
8986
9230
  );
8987
9231
  }
8988
9232
  for (const code of codes) parts.push(esc(code));
@@ -9001,7 +9245,7 @@ function padControl8(value, width) {
9001
9245
  if (value.length < width) return "0".repeat(width - value.length) + value;
9002
9246
  throw new AckBuildError(
9003
9247
  ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC,
9004
- `build999: control number "${value}" exceeds the ${String(width)}-char spec limit.`
9248
+ `build999: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
9005
9249
  );
9006
9250
  }
9007
9251
  function expandYY8(yymmdd) {
@@ -9031,7 +9275,7 @@ function enforceAcceptIsClean2(spec) {
9031
9275
  if (spec.ackCode === TA1_ACK_CODES.A && spec.noteCode !== "000") {
9032
9276
  throw new AckBuildError(
9033
9277
  ACK_BUILD_ERROR_CODES.X12_TA1_ACCEPT_WITH_NOTE,
9034
- `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.`
9278
+ `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.`
9035
9279
  );
9036
9280
  }
9037
9281
  }
@@ -9322,7 +9566,11 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
9322
9566
  if (segment.length === 0 || (segment[0] ?? "") === "") {
9323
9567
  throw new X12BuildError(
9324
9568
  X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC,
9325
- `buildInterchange: a segment spec in transaction "${esc(tx.transactionSetIdCode)}" has no segment id.`
9569
+ // Rendered from the RAW id, not the `?`-escaped one. `esc` can double
9570
+ // the length, so escaping first made the reported "(N characters)" the
9571
+ // escaped length rather than the caller's: a 100-character all-`?` id
9572
+ // reported 200. The escape exists for the wire, and this is a message.
9573
+ `buildInterchange: a segment spec in transaction ${renderCallerValue(tx.transactionSetIdCode)} has no segment id.`
9326
9574
  );
9327
9575
  }
9328
9576
  bodySegments += joinSeg2(segment.map(esc), elementSeparator, segmentTerminator);
@@ -9348,7 +9596,7 @@ function padControl9(value, width) {
9348
9596
  if (value.length < width) return "0".repeat(width - value.length) + value;
9349
9597
  throw new X12BuildError(
9350
9598
  X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC,
9351
- `buildInterchange: control number "${value}" exceeds the ${String(width)}-char spec limit.`
9599
+ `buildInterchange: control number ${renderCallerValue(value)} exceeds the ${String(width)}-char spec limit.`
9352
9600
  );
9353
9601
  }
9354
9602
  function expandYY9(yymmdd) {
@@ -9400,17 +9648,17 @@ function levenshtein(a, b) {
9400
9648
  function validateProfileName(opts) {
9401
9649
  if (opts === null || opts === void 0) {
9402
9650
  throw new X12ProfileError(
9403
- `defineProfile: options is required and must be an object. Received: ${String(opts)}.`
9651
+ `defineProfile: options is required and must be an object. Received: ${renderCallerJson(opts)}.`
9404
9652
  );
9405
9653
  }
9406
9654
  if (typeof opts.name !== "string") {
9407
9655
  throw new X12ProfileError(
9408
- `defineProfile: 'name' is required and must be a non-empty string. Received: ${JSON.stringify(opts.name)}.`
9656
+ `defineProfile: 'name' is required and must be a non-empty string. Received: ${renderCallerJson(opts.name)}.`
9409
9657
  );
9410
9658
  }
9411
9659
  if (opts.name.trim().length === 0) {
9412
9660
  throw new X12ProfileError(
9413
- `defineProfile: 'name' is required and must be a non-empty string. Received: ${JSON.stringify(opts.name)}.`,
9661
+ `defineProfile: 'name' is required and must be a non-empty string. Received: ${renderCallerJson(opts.name)}.`,
9414
9662
  opts.name
9415
9663
  );
9416
9664
  }
@@ -9426,7 +9674,7 @@ function validateOptionKeys(opts) {
9426
9674
  }
9427
9675
  }
9428
9676
  throw new X12ProfileError(
9429
- `Profile '${opts.name}' has unknown option key '${key}'. ` + (hint !== void 0 ? `Did you mean '${hint}'? ` : "") + `Known keys: ${KNOWN_OPTION_KEYS.join(", ")}.`,
9677
+ `Profile ${renderCallerValue(opts.name)} has unknown option key ${renderCallerValue(key)}. ` + (hint !== void 0 ? `Did you mean '${hint}'? ` : "") + `Known keys: ${KNOWN_OPTION_KEYS.join(", ")}.`,
9430
9678
  opts.name
9431
9679
  );
9432
9680
  }
@@ -9435,44 +9683,46 @@ function validateQuirks(quirks, profileName) {
9435
9683
  const seenIds = /* @__PURE__ */ new Set();
9436
9684
  for (let i = 0; i < quirks.length; i++) {
9437
9685
  const q = quirks[i];
9438
- const at = `quirks[${String(i)}]`;
9439
9686
  if (q === void 0 || q === null || typeof q !== "object") {
9440
- throw new X12ProfileError(`Profile '${profileName}' ${at} must be an object.`, profileName);
9687
+ throw new X12ProfileError(
9688
+ `Profile ${renderCallerValue(profileName)} quirks[${String(i)}] must be an object.`,
9689
+ profileName
9690
+ );
9441
9691
  }
9442
9692
  if (typeof q.id !== "string" || !QUIRK_ID_RE.test(q.id)) {
9443
9693
  throw new X12ProfileError(
9444
- `Profile '${profileName}' ${at}.id must be a kebab-case string (e.g. "payer-loop-ref-2u"). Received: ${JSON.stringify(q.id)}.`,
9694
+ `Profile ${renderCallerValue(profileName)} quirks[${String(i)}].id must be a kebab-case string (e.g. "payer-loop-ref-2u"). Received: ${renderCallerJson(q.id)}.`,
9445
9695
  profileName
9446
9696
  );
9447
9697
  }
9448
9698
  if (seenIds.has(q.id)) {
9449
9699
  throw new X12ProfileError(
9450
- `Profile '${profileName}' declares duplicate quirk id '${q.id}'. Each quirk id must be unique within a profile.`,
9700
+ `Profile ${renderCallerValue(profileName)} declares duplicate quirk id ${renderCallerValue(q.id)}. Each quirk id must be unique within a profile.`,
9451
9701
  profileName
9452
9702
  );
9453
9703
  }
9454
9704
  seenIds.add(q.id);
9455
9705
  if (typeof q.effect !== "string" || !KNOWN_EFFECTS.includes(q.effect)) {
9456
9706
  throw new X12ProfileError(
9457
- `Profile '${profileName}' quirk '${q.id}' has invalid effect ${JSON.stringify(q.effect)} - must be one of ${KNOWN_EFFECTS.join(" / ")}.`,
9707
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} has invalid effect ${renderCallerJson(q.effect)} - must be one of ${KNOWN_EFFECTS.join(" / ")}.`,
9458
9708
  profileName
9459
9709
  );
9460
9710
  }
9461
9711
  if (typeof q.summary !== "string" || q.summary.trim().length === 0) {
9462
9712
  throw new X12ProfileError(
9463
- `Profile '${profileName}' quirk '${q.id}' must have a non-empty summary.`,
9713
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} must have a non-empty summary.`,
9464
9714
  profileName
9465
9715
  );
9466
9716
  }
9467
9717
  if (typeof q.fixture !== "string" || !FIXTURE_PATH_RE.test(q.fixture)) {
9468
9718
  throw new X12ProfileError(
9469
- `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)}.`,
9719
+ `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)}.`,
9470
9720
  profileName
9471
9721
  );
9472
9722
  }
9473
9723
  if (typeof q.sourceCategory !== "string" || q.sourceCategory.trim().length === 0) {
9474
9724
  throw new X12ProfileError(
9475
- `Profile '${profileName}' quirk '${q.id}' must have a non-empty sourceCategory (where the deviation was observed).`,
9725
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} must have a non-empty sourceCategory (where the deviation was observed).`,
9476
9726
  profileName
9477
9727
  );
9478
9728
  }
@@ -9480,7 +9730,7 @@ function validateQuirks(quirks, profileName) {
9480
9730
  for (const code of q.expectedWarnings) {
9481
9731
  if (!WARNING_CODE_SET.has(code)) {
9482
9732
  throw new X12ProfileError(
9483
- `Profile '${profileName}' quirk '${q.id}' lists unknown expected warning ${JSON.stringify(code)} - must be a member of WARNING_CODES.`,
9733
+ `Profile ${renderCallerValue(profileName)} quirk ${renderCallerValue(q.id)} lists unknown expected warning ${renderCallerJson(code)} - must be a member of WARNING_CODES.`,
9484
9734
  profileName
9485
9735
  );
9486
9736
  }
@@ -9642,7 +9892,7 @@ var profiles = Object.freeze({
9642
9892
  });
9643
9893
 
9644
9894
  // src/index.ts
9645
- var VERSION = "0.0.4";
9895
+ var VERSION = "0.0.6";
9646
9896
 
9647
9897
  exports.ACK_BUILD_ERROR_CODES = ACK_BUILD_ERROR_CODES;
9648
9898
  exports.ALL_WARNING_MESSAGES = ALL_WARNING_MESSAGES;
@@ -9655,6 +9905,8 @@ exports.AUTH_278_LOOP_2000E = AUTH_278_LOOP_2000E;
9655
9905
  exports.AUTH_278_LOOP_2000F = AUTH_278_LOOP_2000F;
9656
9906
  exports.AckBuildError = AckBuildError;
9657
9907
  exports.BALANCE_INVARIANTS = BALANCE_INVARIANTS;
9908
+ exports.BUILD_REFUSAL_VALUE_MAX_LENGTH = BUILD_REFUSAL_VALUE_MAX_LENGTH;
9909
+ exports.BUILD_REFUSAL_VALUE_MAX_RENDERED = BUILD_REFUSAL_VALUE_MAX_RENDERED;
9658
9910
  exports.CARC = CARC;
9659
9911
  exports.CLAIM_837D_LOOP_2000A = CLAIM_837D_LOOP_2000A;
9660
9912
  exports.CLAIM_837D_LOOP_2300 = CLAIM_837D_LOOP_2300;
@@ -9816,6 +10068,7 @@ exports.partitionWarnings = partitionWarnings;
9816
10068
  exports.pre005010 = pre005010;
9817
10069
  exports.profiles = profiles;
9818
10070
  exports.remitBalanceMismatch = remitBalanceMismatch;
10071
+ exports.renderCallerValue = renderCallerValue;
9819
10072
  exports.resolveHiQualifier = resolveHiQualifier;
9820
10073
  exports.segmentCountMismatch = segmentCountMismatch;
9821
10074
  exports.serializeX12 = serializeX12;