@claritylabs/cl-sdk 3.0.23 → 3.0.25
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 +77 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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;
|
|
@@ -3356,13 +3359,17 @@ function inferDocumentType(nodes) {
|
|
|
3356
3359
|
return "policy";
|
|
3357
3360
|
}
|
|
3358
3361
|
function coverageNameFromRow(text) {
|
|
3359
|
-
const labelled = text.match(/\b(
|
|
3360
|
-
if (labelled)
|
|
3361
|
-
|
|
3362
|
+
const labelled = text.match(/\b(coverage part|coverage|line)\s*:?\s*([^|;$]{3,80})/i);
|
|
3363
|
+
if (labelled) {
|
|
3364
|
+
const value = cleanCoverageLabel(labelled[2]);
|
|
3365
|
+
if (!value) return void 0;
|
|
3366
|
+
return /^coverage part$/i.test(labelled[1]) ? `Coverage Part ${value}` : value;
|
|
3367
|
+
}
|
|
3368
|
+
const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanCoverageLabel).filter(Boolean);
|
|
3362
3369
|
const first = parts.find(
|
|
3363
3370
|
(part) => !/^(limit|limits?|deductible|premium|amount|basis|rate|retroactive|aggregate|each occurrence)$/i.test(part) && !/^\$?[\d,]+/.test(part)
|
|
3364
3371
|
);
|
|
3365
|
-
return
|
|
3372
|
+
return cleanCoverageLabel(first);
|
|
3366
3373
|
}
|
|
3367
3374
|
function limitFromText(text) {
|
|
3368
3375
|
return moneyValue(
|
|
@@ -3479,21 +3486,40 @@ function endorsementAncestor(node, byId) {
|
|
|
3479
3486
|
function endorsementNumberFrom(value) {
|
|
3480
3487
|
return cleanValue(value?.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)/i)?.[1]);
|
|
3481
3488
|
}
|
|
3489
|
+
function endorsementNameFrom(node) {
|
|
3490
|
+
const candidates = [node.title, node.textExcerpt, node.description, nodeText(node)].filter(Boolean);
|
|
3491
|
+
for (const candidate of candidates) {
|
|
3492
|
+
const match = candidate.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)\s*[—-]\s*(.{3,140}?)(?=\s+This\s+endorsement\b|\.|$)/i);
|
|
3493
|
+
if (match) return cleanValue(`Endorsement No. ${match[1]} - ${match[2]}`) ?? node.title;
|
|
3494
|
+
}
|
|
3495
|
+
return node.title;
|
|
3496
|
+
}
|
|
3482
3497
|
function sourceIds(nodes) {
|
|
3483
3498
|
return {
|
|
3484
3499
|
sourceNodeIds: [...new Set(nodes.map((node) => node.id))],
|
|
3485
3500
|
sourceSpanIds: [...new Set(nodes.flatMap((node) => node.sourceSpanIds))]
|
|
3486
3501
|
};
|
|
3487
3502
|
}
|
|
3503
|
+
function relabelGenericTerm(term, label) {
|
|
3504
|
+
const cleanLabel = cleanValue(label);
|
|
3505
|
+
if (!cleanLabel || !/^column\s+\d+$/i.test(term.label)) return term;
|
|
3506
|
+
return {
|
|
3507
|
+
...term,
|
|
3508
|
+
kind: termKind(cleanLabel, term.value),
|
|
3509
|
+
label: cleanLabel
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3488
3512
|
function termFromCell(params) {
|
|
3489
3513
|
const value = cleanValue(params.value);
|
|
3490
3514
|
if (!value) return void 0;
|
|
3491
3515
|
const nodes = [params.row, params.cell].filter((node) => Boolean(node));
|
|
3516
|
+
const kind = termKind(params.label, value);
|
|
3517
|
+
const amount = moneyAmount(value);
|
|
3492
3518
|
return {
|
|
3493
|
-
kind
|
|
3519
|
+
kind,
|
|
3494
3520
|
label: params.label,
|
|
3495
3521
|
value,
|
|
3496
|
-
...
|
|
3522
|
+
...amount !== void 0 && kind !== "retroactive_date" ? { amount } : {},
|
|
3497
3523
|
...params.appliesTo ? { appliesTo: params.appliesTo } : {},
|
|
3498
3524
|
...sourceIds(nodes)
|
|
3499
3525
|
};
|
|
@@ -3530,7 +3556,7 @@ function nameFromRow(row, children) {
|
|
|
3530
3556
|
const cells = cellRows(row, children);
|
|
3531
3557
|
const named = cells.find((cell) => isNameCell(cell.label, cell.value));
|
|
3532
3558
|
if (named) return cleanValue(named.value);
|
|
3533
|
-
return coverageNameFromRow(nodeText(row));
|
|
3559
|
+
return coverageNameFromRow(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
3534
3560
|
}
|
|
3535
3561
|
function legacyLimit(terms) {
|
|
3536
3562
|
return terms.find(
|
|
@@ -3546,6 +3572,22 @@ function legacyPremium(terms) {
|
|
|
3546
3572
|
function retroDate(terms) {
|
|
3547
3573
|
return terms.find((term) => term.kind === "retroactive_date")?.value;
|
|
3548
3574
|
}
|
|
3575
|
+
function hasCoverageLimitTerm(terms) {
|
|
3576
|
+
return terms.some(
|
|
3577
|
+
(term) => ["each_claim_limit", "each_occurrence_limit", "each_loss_limit", "aggregate_limit", "sublimit"].includes(term.kind) || term.kind === "other" && /\blimit\b/i.test(term.label) && moneyAmount(term.value) !== void 0
|
|
3578
|
+
);
|
|
3579
|
+
}
|
|
3580
|
+
function isOperationalCoverageRow(coverage) {
|
|
3581
|
+
const name = normalizeLabel(coverage.name);
|
|
3582
|
+
if (!hasCoverageLimitTerm(coverage.limits)) return false;
|
|
3583
|
+
if (/^(item\s+\d+|option:|annual policy premium|total premium|premium and payment)\b/i.test(coverage.name)) return false;
|
|
3584
|
+
if (/^(nwc|iso|cg|il|acord)[-\s]?[a-z0-9]/i.test(coverage.name)) return false;
|
|
3585
|
+
if (/\b(forms?|endorsements?|premium|payment|terrorism risk insurance act|tria|erp option|bilateral discovery)\b/i.test(name)) return false;
|
|
3586
|
+
if (coverage.name.split(/\s+/).length > 16 && !/\b(coverage|liability|sub[-\s]?limit|aggregate|each\s+(claim|loss|occurrence)|limit)\b/i.test(coverage.name)) {
|
|
3587
|
+
return false;
|
|
3588
|
+
}
|
|
3589
|
+
return /\b(coverage|coverage part|liability|sub[-\s]?limit|aggregate|each\s+(claim|loss|occurrence)|bricking|cyber|privacy|media|regulatory|defense|ai\/ml|errors?\s*&?\s*omissions|technology)\b/i.test(coverage.name);
|
|
3590
|
+
}
|
|
3549
3591
|
function uniqueTerms(terms) {
|
|
3550
3592
|
const seen = /* @__PURE__ */ new Set();
|
|
3551
3593
|
const result = [];
|
|
@@ -3583,31 +3625,39 @@ function coverageFromEndorsement(endorsement, children) {
|
|
|
3583
3625
|
const terms = uniqueTerms(rows.flatMap(
|
|
3584
3626
|
(row) => termsFromRow(row, children).map((term) => {
|
|
3585
3627
|
const appliesTo = nameFromRow(row, children);
|
|
3586
|
-
|
|
3628
|
+
const labelled = relabelGenericTerm(term, appliesTo);
|
|
3629
|
+
return appliesTo && labelled.label !== appliesTo ? { ...labelled, appliesTo } : labelled;
|
|
3587
3630
|
})
|
|
3588
3631
|
));
|
|
3589
3632
|
if (terms.length === 0) return void 0;
|
|
3590
3633
|
const ids = sourceIds([endorsement, ...rows, ...rows.flatMap((row) => directChildren(row, children))]);
|
|
3634
|
+
const name = endorsementNameFrom(endorsement);
|
|
3591
3635
|
return {
|
|
3592
|
-
name
|
|
3636
|
+
name,
|
|
3593
3637
|
limit: legacyLimit(terms),
|
|
3594
3638
|
deductible: legacyDeductible(terms),
|
|
3595
3639
|
premium: legacyPremium(terms),
|
|
3596
3640
|
retroactiveDate: retroDate(terms),
|
|
3597
3641
|
formNumber: typeof endorsement.metadata?.formNumber === "string" ? endorsement.metadata.formNumber : void 0,
|
|
3598
|
-
sectionRef:
|
|
3642
|
+
sectionRef: name,
|
|
3599
3643
|
coverageOrigin: "endorsement",
|
|
3600
|
-
endorsementNumber: endorsementNumberFrom(
|
|
3644
|
+
endorsementNumber: endorsementNumberFrom(name),
|
|
3601
3645
|
limits: terms,
|
|
3602
3646
|
...ids
|
|
3603
3647
|
};
|
|
3604
3648
|
}
|
|
3649
|
+
function hasDescendantEndorsementWithTableRows(endorsement, children) {
|
|
3650
|
+
return descendants(endorsement, children).some(
|
|
3651
|
+
(node) => node.kind === "endorsement" && descendants(node, children).some((descendant) => descendant.kind === "table_row")
|
|
3652
|
+
);
|
|
3653
|
+
}
|
|
3605
3654
|
function buildCoverages(nodes) {
|
|
3606
3655
|
const children = childMap(nodes);
|
|
3607
3656
|
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
3608
3657
|
const coverages = [];
|
|
3609
3658
|
const seen = /* @__PURE__ */ new Set();
|
|
3610
3659
|
for (const endorsement of nodes.filter((node) => node.kind === "endorsement")) {
|
|
3660
|
+
if (hasDescendantEndorsementWithTableRows(endorsement, children)) continue;
|
|
3611
3661
|
const coverage = coverageFromEndorsement(endorsement, children);
|
|
3612
3662
|
if (!coverage) continue;
|
|
3613
3663
|
const key = [coverage.name.toLowerCase(), coverage.sourceNodeIds.join(",")].join("|");
|
|
@@ -3623,6 +3673,7 @@ function buildCoverages(nodes) {
|
|
|
3623
3673
|
if (endorsementAncestor(row, byId)) continue;
|
|
3624
3674
|
const structured = row.kind === "table_row" ? coverageFromTableRow(row, children, byId) : void 0;
|
|
3625
3675
|
if (structured) {
|
|
3676
|
+
if (!isOperationalCoverageRow(structured)) continue;
|
|
3626
3677
|
const key2 = [
|
|
3627
3678
|
structured.name.toLowerCase(),
|
|
3628
3679
|
structured.limits.map((term) => `${term.kind}:${term.value}`).join(","),
|
|
@@ -3640,6 +3691,20 @@ function buildCoverages(nodes) {
|
|
|
3640
3691
|
const deductible = deductibleFromText(text);
|
|
3641
3692
|
const premium = premiumFromText(text);
|
|
3642
3693
|
if (!name || !limit && !deductible && !premium) continue;
|
|
3694
|
+
if (!isOperationalCoverageRow({
|
|
3695
|
+
name,
|
|
3696
|
+
limit,
|
|
3697
|
+
deductible,
|
|
3698
|
+
premium,
|
|
3699
|
+
coverageOrigin: "core",
|
|
3700
|
+
limits: [
|
|
3701
|
+
...limit ? [{ kind: "other", label: "Limit", value: limit, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : [],
|
|
3702
|
+
...deductible ? [{ kind: "deductible", label: "Deductible", value: deductible, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : [],
|
|
3703
|
+
...premium ? [{ kind: "premium", label: "Premium", value: premium, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : []
|
|
3704
|
+
],
|
|
3705
|
+
sourceNodeIds: [row.id],
|
|
3706
|
+
sourceSpanIds: row.sourceSpanIds
|
|
3707
|
+
})) continue;
|
|
3643
3708
|
const key = [name.toLowerCase(), limit, deductible, premium].join("|");
|
|
3644
3709
|
if (seen.has(key)) continue;
|
|
3645
3710
|
seen.add(key);
|
|
@@ -3792,7 +3857,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
|
|
|
3792
3857
|
sourceSpanIds
|
|
3793
3858
|
};
|
|
3794
3859
|
};
|
|
3795
|
-
const coverages = Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
|
|
3860
|
+
const coverages = base.coverages.length > 0 ? base.coverages : Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
|
|
3796
3861
|
const record = coverage;
|
|
3797
3862
|
const limits = Array.isArray(record.limits) ? record.limits.filter(
|
|
3798
3863
|
(term) => Boolean(term) && typeof term === "object" && !Array.isArray(term)
|