@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.mjs
CHANGED
|
@@ -2944,6 +2944,9 @@ function cleanValue(value) {
|
|
|
2944
2944
|
if (!value) return void 0;
|
|
2945
2945
|
return normalizeWhitespace3(value.replace(/^[\s:;#-]+|[\s;,.]+$/g, ""));
|
|
2946
2946
|
}
|
|
2947
|
+
function cleanCoverageLabel(value) {
|
|
2948
|
+
return cleanValue(value)?.replace(/^column\s+\d+\s*:\s*/i, "");
|
|
2949
|
+
}
|
|
2947
2950
|
function moneyValue(value) {
|
|
2948
2951
|
const clean = cleanValue(value);
|
|
2949
2952
|
if (!clean) return void 0;
|
|
@@ -3000,13 +3003,17 @@ function inferDocumentType(nodes) {
|
|
|
3000
3003
|
return "policy";
|
|
3001
3004
|
}
|
|
3002
3005
|
function coverageNameFromRow(text) {
|
|
3003
|
-
const labelled = text.match(/\b(
|
|
3004
|
-
if (labelled)
|
|
3005
|
-
|
|
3006
|
+
const labelled = text.match(/\b(coverage part|coverage|line)\s*:?\s*([^|;$]{3,80})/i);
|
|
3007
|
+
if (labelled) {
|
|
3008
|
+
const value = cleanCoverageLabel(labelled[2]);
|
|
3009
|
+
if (!value) return void 0;
|
|
3010
|
+
return /^coverage part$/i.test(labelled[1]) ? `Coverage Part ${value}` : value;
|
|
3011
|
+
}
|
|
3012
|
+
const parts = text.split(/\s+\|\s+| {2,}|\t/).map(cleanCoverageLabel).filter(Boolean);
|
|
3006
3013
|
const first = parts.find(
|
|
3007
3014
|
(part) => !/^(limit|limits?|deductible|premium|amount|basis|rate|retroactive|aggregate|each occurrence)$/i.test(part) && !/^\$?[\d,]+/.test(part)
|
|
3008
3015
|
);
|
|
3009
|
-
return
|
|
3016
|
+
return cleanCoverageLabel(first);
|
|
3010
3017
|
}
|
|
3011
3018
|
function limitFromText(text) {
|
|
3012
3019
|
return moneyValue(
|
|
@@ -3123,21 +3130,40 @@ function endorsementAncestor(node, byId) {
|
|
|
3123
3130
|
function endorsementNumberFrom(value) {
|
|
3124
3131
|
return cleanValue(value?.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)/i)?.[1]);
|
|
3125
3132
|
}
|
|
3133
|
+
function endorsementNameFrom(node) {
|
|
3134
|
+
const candidates = [node.title, node.textExcerpt, node.description, nodeText(node)].filter(Boolean);
|
|
3135
|
+
for (const candidate of candidates) {
|
|
3136
|
+
const match = candidate.match(/\bendorsement\s+no\.?\s*([0-9A-Z-]+)\s*[—-]\s*(.{3,140}?)(?=\s+This\s+endorsement\b|\.|$)/i);
|
|
3137
|
+
if (match) return cleanValue(`Endorsement No. ${match[1]} - ${match[2]}`) ?? node.title;
|
|
3138
|
+
}
|
|
3139
|
+
return node.title;
|
|
3140
|
+
}
|
|
3126
3141
|
function sourceIds(nodes) {
|
|
3127
3142
|
return {
|
|
3128
3143
|
sourceNodeIds: [...new Set(nodes.map((node) => node.id))],
|
|
3129
3144
|
sourceSpanIds: [...new Set(nodes.flatMap((node) => node.sourceSpanIds))]
|
|
3130
3145
|
};
|
|
3131
3146
|
}
|
|
3147
|
+
function relabelGenericTerm(term, label) {
|
|
3148
|
+
const cleanLabel = cleanValue(label);
|
|
3149
|
+
if (!cleanLabel || !/^column\s+\d+$/i.test(term.label)) return term;
|
|
3150
|
+
return {
|
|
3151
|
+
...term,
|
|
3152
|
+
kind: termKind(cleanLabel, term.value),
|
|
3153
|
+
label: cleanLabel
|
|
3154
|
+
};
|
|
3155
|
+
}
|
|
3132
3156
|
function termFromCell(params) {
|
|
3133
3157
|
const value = cleanValue(params.value);
|
|
3134
3158
|
if (!value) return void 0;
|
|
3135
3159
|
const nodes = [params.row, params.cell].filter((node) => Boolean(node));
|
|
3160
|
+
const kind = termKind(params.label, value);
|
|
3161
|
+
const amount = moneyAmount(value);
|
|
3136
3162
|
return {
|
|
3137
|
-
kind
|
|
3163
|
+
kind,
|
|
3138
3164
|
label: params.label,
|
|
3139
3165
|
value,
|
|
3140
|
-
...
|
|
3166
|
+
...amount !== void 0 && kind !== "retroactive_date" ? { amount } : {},
|
|
3141
3167
|
...params.appliesTo ? { appliesTo: params.appliesTo } : {},
|
|
3142
3168
|
...sourceIds(nodes)
|
|
3143
3169
|
};
|
|
@@ -3174,7 +3200,7 @@ function nameFromRow(row, children) {
|
|
|
3174
3200
|
const cells = cellRows(row, children);
|
|
3175
3201
|
const named = cells.find((cell) => isNameCell(cell.label, cell.value));
|
|
3176
3202
|
if (named) return cleanValue(named.value);
|
|
3177
|
-
return coverageNameFromRow(nodeText(row));
|
|
3203
|
+
return coverageNameFromRow(row.textExcerpt ?? row.description ?? nodeText(row));
|
|
3178
3204
|
}
|
|
3179
3205
|
function legacyLimit(terms) {
|
|
3180
3206
|
return terms.find(
|
|
@@ -3190,6 +3216,22 @@ function legacyPremium(terms) {
|
|
|
3190
3216
|
function retroDate(terms) {
|
|
3191
3217
|
return terms.find((term) => term.kind === "retroactive_date")?.value;
|
|
3192
3218
|
}
|
|
3219
|
+
function hasCoverageLimitTerm(terms) {
|
|
3220
|
+
return terms.some(
|
|
3221
|
+
(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
|
|
3222
|
+
);
|
|
3223
|
+
}
|
|
3224
|
+
function isOperationalCoverageRow(coverage) {
|
|
3225
|
+
const name = normalizeLabel(coverage.name);
|
|
3226
|
+
if (!hasCoverageLimitTerm(coverage.limits)) return false;
|
|
3227
|
+
if (/^(item\s+\d+|option:|annual policy premium|total premium|premium and payment)\b/i.test(coverage.name)) return false;
|
|
3228
|
+
if (/^(nwc|iso|cg|il|acord)[-\s]?[a-z0-9]/i.test(coverage.name)) return false;
|
|
3229
|
+
if (/\b(forms?|endorsements?|premium|payment|terrorism risk insurance act|tria|erp option|bilateral discovery)\b/i.test(name)) return false;
|
|
3230
|
+
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)) {
|
|
3231
|
+
return false;
|
|
3232
|
+
}
|
|
3233
|
+
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);
|
|
3234
|
+
}
|
|
3193
3235
|
function uniqueTerms(terms) {
|
|
3194
3236
|
const seen = /* @__PURE__ */ new Set();
|
|
3195
3237
|
const result = [];
|
|
@@ -3227,31 +3269,39 @@ function coverageFromEndorsement(endorsement, children) {
|
|
|
3227
3269
|
const terms = uniqueTerms(rows.flatMap(
|
|
3228
3270
|
(row) => termsFromRow(row, children).map((term) => {
|
|
3229
3271
|
const appliesTo = nameFromRow(row, children);
|
|
3230
|
-
|
|
3272
|
+
const labelled = relabelGenericTerm(term, appliesTo);
|
|
3273
|
+
return appliesTo && labelled.label !== appliesTo ? { ...labelled, appliesTo } : labelled;
|
|
3231
3274
|
})
|
|
3232
3275
|
));
|
|
3233
3276
|
if (terms.length === 0) return void 0;
|
|
3234
3277
|
const ids = sourceIds([endorsement, ...rows, ...rows.flatMap((row) => directChildren(row, children))]);
|
|
3278
|
+
const name = endorsementNameFrom(endorsement);
|
|
3235
3279
|
return {
|
|
3236
|
-
name
|
|
3280
|
+
name,
|
|
3237
3281
|
limit: legacyLimit(terms),
|
|
3238
3282
|
deductible: legacyDeductible(terms),
|
|
3239
3283
|
premium: legacyPremium(terms),
|
|
3240
3284
|
retroactiveDate: retroDate(terms),
|
|
3241
3285
|
formNumber: typeof endorsement.metadata?.formNumber === "string" ? endorsement.metadata.formNumber : void 0,
|
|
3242
|
-
sectionRef:
|
|
3286
|
+
sectionRef: name,
|
|
3243
3287
|
coverageOrigin: "endorsement",
|
|
3244
|
-
endorsementNumber: endorsementNumberFrom(
|
|
3288
|
+
endorsementNumber: endorsementNumberFrom(name),
|
|
3245
3289
|
limits: terms,
|
|
3246
3290
|
...ids
|
|
3247
3291
|
};
|
|
3248
3292
|
}
|
|
3293
|
+
function hasDescendantEndorsementWithTableRows(endorsement, children) {
|
|
3294
|
+
return descendants(endorsement, children).some(
|
|
3295
|
+
(node) => node.kind === "endorsement" && descendants(node, children).some((descendant) => descendant.kind === "table_row")
|
|
3296
|
+
);
|
|
3297
|
+
}
|
|
3249
3298
|
function buildCoverages(nodes) {
|
|
3250
3299
|
const children = childMap(nodes);
|
|
3251
3300
|
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
3252
3301
|
const coverages = [];
|
|
3253
3302
|
const seen = /* @__PURE__ */ new Set();
|
|
3254
3303
|
for (const endorsement of nodes.filter((node) => node.kind === "endorsement")) {
|
|
3304
|
+
if (hasDescendantEndorsementWithTableRows(endorsement, children)) continue;
|
|
3255
3305
|
const coverage = coverageFromEndorsement(endorsement, children);
|
|
3256
3306
|
if (!coverage) continue;
|
|
3257
3307
|
const key = [coverage.name.toLowerCase(), coverage.sourceNodeIds.join(",")].join("|");
|
|
@@ -3267,6 +3317,7 @@ function buildCoverages(nodes) {
|
|
|
3267
3317
|
if (endorsementAncestor(row, byId)) continue;
|
|
3268
3318
|
const structured = row.kind === "table_row" ? coverageFromTableRow(row, children, byId) : void 0;
|
|
3269
3319
|
if (structured) {
|
|
3320
|
+
if (!isOperationalCoverageRow(structured)) continue;
|
|
3270
3321
|
const key2 = [
|
|
3271
3322
|
structured.name.toLowerCase(),
|
|
3272
3323
|
structured.limits.map((term) => `${term.kind}:${term.value}`).join(","),
|
|
@@ -3284,6 +3335,20 @@ function buildCoverages(nodes) {
|
|
|
3284
3335
|
const deductible = deductibleFromText(text);
|
|
3285
3336
|
const premium = premiumFromText(text);
|
|
3286
3337
|
if (!name || !limit && !deductible && !premium) continue;
|
|
3338
|
+
if (!isOperationalCoverageRow({
|
|
3339
|
+
name,
|
|
3340
|
+
limit,
|
|
3341
|
+
deductible,
|
|
3342
|
+
premium,
|
|
3343
|
+
coverageOrigin: "core",
|
|
3344
|
+
limits: [
|
|
3345
|
+
...limit ? [{ kind: "other", label: "Limit", value: limit, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : [],
|
|
3346
|
+
...deductible ? [{ kind: "deductible", label: "Deductible", value: deductible, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : [],
|
|
3347
|
+
...premium ? [{ kind: "premium", label: "Premium", value: premium, sourceNodeIds: [row.id], sourceSpanIds: row.sourceSpanIds }] : []
|
|
3348
|
+
],
|
|
3349
|
+
sourceNodeIds: [row.id],
|
|
3350
|
+
sourceSpanIds: row.sourceSpanIds
|
|
3351
|
+
})) continue;
|
|
3287
3352
|
const key = [name.toLowerCase(), limit, deductible, premium].join("|");
|
|
3288
3353
|
if (seen.has(key)) continue;
|
|
3289
3354
|
seen.add(key);
|
|
@@ -3436,7 +3501,7 @@ function mergeOperationalProfile(base, candidate, validNodeIds, validSpanIds) {
|
|
|
3436
3501
|
sourceSpanIds
|
|
3437
3502
|
};
|
|
3438
3503
|
};
|
|
3439
|
-
const coverages = Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
|
|
3504
|
+
const coverages = base.coverages.length > 0 ? base.coverages : Array.isArray(candidate.coverages) ? candidate.coverages.map((coverage) => {
|
|
3440
3505
|
const record = coverage;
|
|
3441
3506
|
const limits = Array.isArray(record.limits) ? record.limits.filter(
|
|
3442
3507
|
(term) => Boolean(term) && typeof term === "object" && !Array.isArray(term)
|