@claritylabs/cl-sdk 3.0.23 → 3.0.24

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.js CHANGED
@@ -3300,6 +3300,9 @@ function cleanValue(value) {
3300
3300
  if (!value) return void 0;
3301
3301
  return normalizeWhitespace3(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
3302
3302
  }
3303
+ function cleanCoverageLabel(value) {
3304
+ return cleanValue(value)?.replace(/^column\s+\d+\s*:\s*/i, "");
3305
+ }
3303
3306
  function moneyValue(value) {
3304
3307
  const clean = cleanValue(value);
3305
3308
  if (!clean) return void 0;
@@ -3357,12 +3360,12 @@ function inferDocumentType(nodes) {
3357
3360
  }
3358
3361
  function coverageNameFromRow(text) {
3359
3362
  const labelled = text.match(/\b(?:coverage|coverage part|line)\s*:?\s*([^|;$]{3,80})/i)?.[1];
3360
- if (labelled) return cleanValue(labelled);
3361
- const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanValue).filter(Boolean);
3363
+ if (labelled) return cleanCoverageLabel(labelled);
3364
+ const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanCoverageLabel).filter(Boolean);
3362
3365
  const first = parts.find(
3363
3366
  (part) => !/^(limit|limits?|deductible|premium|amount|basis|rate|retroactive|aggregate|each occurrence)$/i.test(part) && !/^\$?[\d,]+/.test(part)
3364
3367
  );
3365
- return cleanValue(first);
3368
+ return cleanCoverageLabel(first);
3366
3369
  }
3367
3370
  function limitFromText(text) {
3368
3371
  return moneyValue(
@@ -3479,21 +3482,40 @@ function endorsementAncestor(node, byId) {
3479
3482
  function endorsementNumberFrom(value) {
3480
3483
  return cleanValue(value?.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)/i)?.[1]);
3481
3484
  }
3485
+ function endorsementNameFrom(node) {
3486
+ const candidates = [node.title, node.textExcerpt, node.description, nodeText(node)].filter(Boolean);
3487
+ for (const candidate of candidates) {
3488
+ const match = candidate.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)\s*[—-]\s*(.{3,140}?)(?=\s+This\s+endorsement\b|\.|$)/i);
3489
+ if (match) return cleanValue(`Endorsement No. ${match[1]} - ${match[2]}`) ?? node.title;
3490
+ }
3491
+ return node.title;
3492
+ }
3482
3493
  function sourceIds(nodes) {
3483
3494
  return {
3484
3495
  sourceNodeIds: [...new Set(nodes.map((node) => node.id))],
3485
3496
  sourceSpanIds: [...new Set(nodes.flatMap((node) => node.sourceSpanIds))]
3486
3497
  };
3487
3498
  }
3499
+ function relabelGenericTerm(term, label) {
3500
+ const cleanLabel = cleanValue(label);
3501
+ if (!cleanLabel || !/^column\s+\d+$/i.test(term.label)) return term;
3502
+ return {
3503
+ ...term,
3504
+ kind: termKind(cleanLabel, term.value),
3505
+ label: cleanLabel
3506
+ };
3507
+ }
3488
3508
  function termFromCell(params) {
3489
3509
  const value = cleanValue(params.value);
3490
3510
  if (!value) return void 0;
3491
3511
  const nodes = [params.row, params.cell].filter((node) => Boolean(node));
3512
+ const kind = termKind(params.label, value);
3513
+ const amount = moneyAmount(value);
3492
3514
  return {
3493
- kind: termKind(params.label, value),
3515
+ kind,
3494
3516
  label: params.label,
3495
3517
  value,
3496
- ...moneyAmount(value) !== void 0 ? { amount: moneyAmount(value) } : {},
3518
+ ...amount !== void 0 && kind !== "retroactive_date" ? { amount } : {},
3497
3519
  ...params.appliesTo ? { appliesTo: params.appliesTo } : {},
3498
3520
  ...sourceIds(nodes)
3499
3521
  };
@@ -3530,7 +3552,7 @@ function nameFromRow(row, children) {
3530
3552
  const cells = cellRows(row, children);
3531
3553
  const named = cells.find((cell) => isNameCell(cell.label, cell.value));
3532
3554
  if (named) return cleanValue(named.value);
3533
- return coverageNameFromRow(nodeText(row));
3555
+ return coverageNameFromRow(row.textExcerpt ?? row.description ?? nodeText(row));
3534
3556
  }
3535
3557
  function legacyLimit(terms) {
3536
3558
  return terms.find(
@@ -3583,31 +3605,39 @@ function coverageFromEndorsement(endorsement, children) {
3583
3605
  const terms = uniqueTerms(rows.flatMap(
3584
3606
  (row) => termsFromRow(row, children).map((term) => {
3585
3607
  const appliesTo = nameFromRow(row, children);
3586
- return appliesTo && !/^(each claim limit|aggregate limit|retroactive date)$/i.test(appliesTo) ? { ...term, appliesTo } : term;
3608
+ const labelled = relabelGenericTerm(term, appliesTo);
3609
+ return appliesTo && labelled.label !== appliesTo ? { ...labelled, appliesTo } : labelled;
3587
3610
  })
3588
3611
  ));
3589
3612
  if (terms.length === 0) return void 0;
3590
3613
  const ids = sourceIds([endorsement, ...rows, ...rows.flatMap((row) => directChildren(row, children))]);
3614
+ const name = endorsementNameFrom(endorsement);
3591
3615
  return {
3592
- name: endorsement.title,
3616
+ name,
3593
3617
  limit: legacyLimit(terms),
3594
3618
  deductible: legacyDeductible(terms),
3595
3619
  premium: legacyPremium(terms),
3596
3620
  retroactiveDate: retroDate(terms),
3597
3621
  formNumber: typeof endorsement.metadata?.formNumber === "string" ? endorsement.metadata.formNumber : void 0,
3598
- sectionRef: endorsement.title,
3622
+ sectionRef: name,
3599
3623
  coverageOrigin: "endorsement",
3600
- endorsementNumber: endorsementNumberFrom(endorsement.title),
3624
+ endorsementNumber: endorsementNumberFrom(name),
3601
3625
  limits: terms,
3602
3626
  ...ids
3603
3627
  };
3604
3628
  }
3629
+ function hasDescendantEndorsementWithTableRows(endorsement, children) {
3630
+ return descendants(endorsement, children).some(
3631
+ (node) => node.kind === "endorsement" && descendants(node, children).some((descendant) => descendant.kind === "table_row")
3632
+ );
3633
+ }
3605
3634
  function buildCoverages(nodes) {
3606
3635
  const children = childMap(nodes);
3607
3636
  const byId = new Map(nodes.map((node) => [node.id, node]));
3608
3637
  const coverages = [];
3609
3638
  const seen = /* @__PURE__ */ new Set();
3610
3639
  for (const endorsement of nodes.filter((node) => node.kind === "endorsement")) {
3640
+ if (hasDescendantEndorsementWithTableRows(endorsement, children)) continue;
3611
3641
  const coverage = coverageFromEndorsement(endorsement, children);
3612
3642
  if (!coverage) continue;
3613
3643
  const key = [coverage.name.toLowerCase(), coverage.sourceNodeIds.join(",")].join("|");
@@ -3792,7 +3822,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
3792
3822
  sourceSpanIds
3793
3823
  };
3794
3824
  };
3795
- const coverages = Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
3825
+ const coverages = base.coverages.length > 0 ? base.coverages : Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
3796
3826
  const record = coverage;
3797
3827
  const limits = Array.isArray(record.limits) ? record.limits.filter(
3798
3828
  (term) => Boolean(term) && typeof term === "object" && !Array.isArray(term)