{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/registry.ts"],"sourcesContent":["export {\n  TaxCodeNotFoundError,\n  TaxRateNotFoundError,\n} from \"./core/errors.js\";\nexport { createTaxRegistry } from \"./core/registry.js\";\nexport type {\n  ResolvedTaxRate,\n  TaxCode,\n  TaxRateScheduleEntry,\n} from \"./core/types.js\";\n","export class TaxCodeNotFoundError extends Error {\n  constructor(public readonly code: string) {\n    super(`Tax code not registered: ${code}`);\n    this.name = \"TaxCodeNotFoundError\";\n  }\n}\n\nexport class TaxRateNotFoundError extends Error {\n  constructor(\n    public readonly code: string,\n    public readonly asOf: string,\n  ) {\n    super(`No tax rate for code ${code} effective on or before ${asOf}`);\n    this.name = \"TaxRateNotFoundError\";\n  }\n}\n","import { Money, Tax } from \"@eristack/money\";\nimport {\n  TaxCodeNotFoundError,\n  TaxRateNotFoundError,\n} from \"./errors.js\";\nimport type {\n  ResolvedTaxRate,\n  TaxCode,\n  TaxRateScheduleEntry,\n} from \"./types.js\";\n\nfunction normalizeWallDate(date: string): string {\n  const trimmed = date.trim();\n  if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(trimmed)) {\n    throw new Error(`Tax asOf must be wall date YYYY-MM-DD, got \"${date}\"`);\n  }\n  return trimmed;\n}\n\nexport function createTaxRegistry(initial?: {\n  codes?: TaxCode[];\n  rates?: TaxRateScheduleEntry[];\n}) {\n  const codes = new Map<string, TaxCode>();\n  const schedules: TaxRateScheduleEntry[] = [];\n\n  function registerTaxCode(entry: TaxCode): void {\n    const code = entry.code.trim();\n    if (!code) throw new Error(\"Tax code cannot be empty\");\n    codes.set(code, { ...entry, code });\n  }\n\n  function registerRateSchedule(entry: TaxRateScheduleEntry): void {\n    const code = entry.code.trim();\n    if (!codes.has(code)) {\n      throw new TaxCodeNotFoundError(code);\n    }\n    schedules.push({\n      ...entry,\n      code,\n      effectiveFrom: normalizeWallDate(entry.effectiveFrom),\n      ratePercent: entry.ratePercent.trim(),\n    });\n    schedules.sort((a, b) => {\n      const byCode = a.code.localeCompare(b.code);\n      if (byCode !== 0) return byCode;\n      return a.effectiveFrom.localeCompare(b.effectiveFrom);\n    });\n  }\n\n  for (const c of initial?.codes ?? []) registerTaxCode(c);\n  for (const r of initial?.rates ?? []) registerRateSchedule(r);\n\n  function resolveTaxRate(args: {\n    code: string;\n    asOf: string;\n  }): ResolvedTaxRate {\n    const code = args.code.trim();\n    if (!codes.has(code)) {\n      throw new TaxCodeNotFoundError(code);\n    }\n    const asOf = normalizeWallDate(args.asOf);\n    let match: TaxRateScheduleEntry | undefined;\n    for (const row of schedules) {\n      if (row.code !== code) continue;\n      if (row.effectiveFrom <= asOf) {\n        match = row;\n      } else if (match) {\n        break;\n      }\n    }\n    if (!match) {\n      throw new TaxRateNotFoundError(code, asOf);\n    }\n    return {\n      code: match.code,\n      effectiveFrom: match.effectiveFrom,\n      ratePercent: match.ratePercent,\n    };\n  }\n\n  function applyTaxToAmount(base: Money, ratePercent: string): Money {\n    return base.with(Tax.onExclusive(ratePercent));\n  }\n\n  function listTaxCodes(): TaxCode[] {\n    return [...codes.values()];\n  }\n\n  return {\n    registerTaxCode,\n    registerRateSchedule,\n    resolveTaxRate,\n    applyTaxToAmount,\n    listTaxCodes,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAA4B,MAAc;AACxC,UAAM,4BAA4B,IAAI,EAAE;AADd;AAE1B,SAAK,OAAO;AAAA,EACd;AAAA,EAH4B;AAI9B;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YACkB,MACA,MAChB;AACA,UAAM,wBAAwB,IAAI,2BAA2B,IAAI,EAAE;AAHnD;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;;;ACfA,mBAA2B;AAW3B,SAAS,kBAAkB,MAAsB;AAC/C,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,CAAC,sBAAsB,KAAK,OAAO,GAAG;AACxC,UAAM,IAAI,MAAM,+CAA+C,IAAI,GAAG;AAAA,EACxE;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,SAG/B;AACD,QAAM,QAAQ,oBAAI,IAAqB;AACvC,QAAM,YAAoC,CAAC;AAE3C,WAAS,gBAAgB,OAAsB;AAC7C,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,0BAA0B;AACrD,UAAM,IAAI,MAAM,EAAE,GAAG,OAAO,KAAK,CAAC;AAAA,EACpC;AAEA,WAAS,qBAAqB,OAAmC;AAC/D,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,QAAI,CAAC,MAAM,IAAI,IAAI,GAAG;AACpB,YAAM,IAAI,qBAAqB,IAAI;AAAA,IACrC;AACA,cAAU,KAAK;AAAA,MACb,GAAG;AAAA,MACH;AAAA,MACA,eAAe,kBAAkB,MAAM,aAAa;AAAA,MACpD,aAAa,MAAM,YAAY,KAAK;AAAA,IACtC,CAAC;AACD,cAAU,KAAK,CAAC,GAAG,MAAM;AACvB,YAAM,SAAS,EAAE,KAAK,cAAc,EAAE,IAAI;AAC1C,UAAI,WAAW,EAAG,QAAO;AACzB,aAAO,EAAE,cAAc,cAAc,EAAE,aAAa;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,aAAW,KAAK,SAAS,SAAS,CAAC,EAAG,iBAAgB,CAAC;AACvD,aAAW,KAAK,SAAS,SAAS,CAAC,EAAG,sBAAqB,CAAC;AAE5D,WAAS,eAAe,MAGJ;AAClB,UAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,QAAI,CAAC,MAAM,IAAI,IAAI,GAAG;AACpB,YAAM,IAAI,qBAAqB,IAAI;AAAA,IACrC;AACA,UAAM,OAAO,kBAAkB,KAAK,IAAI;AACxC,QAAI;AACJ,eAAW,OAAO,WAAW;AAC3B,UAAI,IAAI,SAAS,KAAM;AACvB,UAAI,IAAI,iBAAiB,MAAM;AAC7B,gBAAQ;AAAA,MACV,WAAW,OAAO;AAChB;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,qBAAqB,MAAM,IAAI;AAAA,IAC3C;AACA,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,eAAe,MAAM;AAAA,MACrB,aAAa,MAAM;AAAA,IACrB;AAAA,EACF;AAEA,WAAS,iBAAiB,MAAa,aAA4B;AACjE,WAAO,KAAK,KAAK,iBAAI,YAAY,WAAW,CAAC;AAAA,EAC/C;AAEA,WAAS,eAA0B;AACjC,WAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}