Functional Weave
Code in Rust

legal.limitation-date@1.0.1

impl/typescript.ts

2,163 bytes · the TypeScript implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import { parseIsoDate } from "./dates_add_days.ts";  ← from dates.add-days ^1.0.0 · built alongside by fune
import { addMonths } from "./dates_add_months.ts";  ← from dates.add-months ^1.0.0 · built alongside by fune
import { LIMITATION_PERIODS, LIMITATION_PERIODS_HISTORY } from "./legal_limitation_date_data.ts";  ← this capability’s own data, compiled from data/limitation-periods.json into the same file by fune build
import { type LimitationPeriod } from "./legal_limitation_date_types.ts";

/**
 * The last day to bring a claim: the anniversary of the accrual date (or the
 * later date of knowledge) the period's number of years on, the accrual day
 * itself excluded, and the month's last day where no anniversary exists.
 */
export function limitationDate(claimType: string, accrualDate: string, knowledgeDate: string | null): LimitationPeriod {
  parseIsoDate(accrualDate);
  const rows = LIMITATION_PERIODS.filter((r) => r.claimType === claimType);
  if (rows.length === 0) {
    const known = Array.from(new Set(LIMITATION_PERIODS.map((r) => r.claimType))).join(", ");
    throw new RangeError(`unknown claim type "${claimType}": expected one of ${known}`);
  }
  const rule = rows.find((r) => accrualDate >= r.validFrom && (r.validTo === null || accrualDate <= r.validTo));
  if (rule === undefined) {
    const earliest = rows.map((r) => r.validFrom).reduce((a, b) => (b < a ? b : a));
    if (LIMITATION_PERIODS_HISTORY !== "full" && accrualDate < earliest) {
      throw new RangeError(
        `no limitation rule for ${claimType} accruing on ${accrualDate}: this build was installed with history=${LIMITATION_PERIODS_HISTORY}, so it only carries rules from ${earliest}. Reinstall with history=full for older claims.`,
      );
    }
    throw new RangeError(`no limitation rule for ${claimType} accruing on ${accrualDate}`);
  }
  let runsFrom = accrualDate;
  if (knowledgeDate !== null) {
    if (!rule.fromKnowledge) {
      throw new RangeError(`a ${claimType} claim runs from accrual under ${rule.section}; knowledgeDate must be null`);
    }
    parseIsoDate(knowledgeDate);
    if (knowledgeDate > accrualDate) runsFrom = knowledgeDate;
  }
  // The corresponding date rule: the anniversary, clamped to the month end.
  const expiry = addMonths(runsFrom, rule.years * 12);
  return { claimType, years: rule.years, section: rule.section, runsFrom, expiry };
}