/** * Vela Payroll Engine — Jurisdiction Factory & Barrel Exports * * Factory function: getTaxJurisdiction(countryCode, options?) * Returns the appropriate TaxJurisdiction plugin for the given country. */ import { TaxJurisdiction, PayFrequency, PayrollInput, PayslipCalculation } from "./types"; import { PayrollEngine } from "./engine"; // Jurisdiction implementations import { AustraliaTax } from "./jurisdictions/australia"; import { USTax, USTaxOptions } from "./jurisdictions/usa"; import { UKTax } from "./jurisdictions/uk"; import { CanadaTax } from "./jurisdictions/canada"; import { NewZealandTax } from "./jurisdictions/new-zealand"; import { SingaporeTax, SingaporeTaxOptions } from "./jurisdictions/singapore"; import { FlatRateTax, FlatRateTaxOptions } from "./jurisdictions/flat-rate"; // ── Registry of supported jurisdictions ────────────────────── const jurisdictionRegistry: Record TaxJurisdiction> = { // Australia — ATO PAYG AU: () => new AustraliaTax(), AUS: () => new AustraliaTax(), // United States — IRS federal + state override US: (opts?: USTaxOptions) => new USTax(opts), USA: (opts?: USTaxOptions) => new USTax(opts), // United Kingdom — HMRC PAYE GB: () => new UKTax(), GBR: () => new UKTax(), UK: () => new UKTax(), // Canada — CRA federal CA: () => new CanadaTax(), CAN: () => new CanadaTax(), // New Zealand — IRD PAYE NZ: () => new NewZealandTax(), NZL: () => new NewZealandTax(), // Singapore — IRAS (no withholding) + CPF SG: (opts?: SingaporeTaxOptions) => new SingaporeTax(opts), SGP: (opts?: SingaporeTaxOptions) => new SingaporeTax(opts), // EU countries — Flat Rate Tax (customise via options) DE: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.25, employerPensionRate: 0.0965, employerTaxRate: 0.0, displayName: "Germany", currency: "EUR", countryCode: "DE", taxFreeAllowance: 11_604, ...opts, }), DEU: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["DE"](opts), FR: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.20, employerPensionRate: 0.0855, employerTaxRate: 0.0, displayName: "France", currency: "EUR", countryCode: "FR", taxFreeAllowance: 11_294, ...opts, }), FRA: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["FR"](opts), ES: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.24, employerPensionRate: 0.236, employerTaxRate: 0.0, displayName: "Spain", currency: "EUR", countryCode: "ES", taxFreeAllowance: 5_550, ...opts, }), ESP: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["ES"](opts), IT: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.23, employerPensionRate: 0.2381, employerTaxRate: 0.0, displayName: "Italy", currency: "EUR", countryCode: "IT", taxFreeAllowance: 8_500, ...opts, }), ITA: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["IT"](opts), IE: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.20, employerPensionRate: 0.0, employerTaxRate: 0.1105, displayName: "Ireland", currency: "EUR", countryCode: "IE", taxFreeAllowance: 20_000, ...opts, }), IRL: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["IE"](opts), NL: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.3697, employerPensionRate: 0.0, employerTaxRate: 0.179, displayName: "Netherlands", currency: "EUR", countryCode: "NL", taxFreeAllowance: 3_693, ...opts, }), NLD: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["NL"](opts), BE: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.25, employerPensionRate: 0.0886, employerTaxRate: 0.0, displayName: "Belgium", currency: "EUR", countryCode: "BE", taxFreeAllowance: 10_160, ...opts, }), BEL: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["BE"](opts), AT: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.25, employerPensionRate: 0.1025, employerTaxRate: 0.0, displayName: "Austria", currency: "EUR", countryCode: "AT", taxFreeAllowance: 12_810, ...opts, }), AUT: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["AT"](opts), PT: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.23, employerPensionRate: 0.1875, employerTaxRate: 0.0, displayName: "Portugal", currency: "EUR", countryCode: "PT", taxFreeAllowance: 4_704, ...opts, }), PRT: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["PT"](opts), FI: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.24, employerPensionRate: 0.121, employerTaxRate: 0.0, displayName: "Finland", currency: "EUR", countryCode: "FI", taxFreeAllowance: 9_310, ...opts, }), FIN: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["FI"](opts), SE: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.32, employerPensionRate: 0.1021, employerTaxRate: 0.0, displayName: "Sweden", currency: "SEK", countryCode: "SE", taxFreeAllowance: 0, ...opts, }), SWE: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["SE"](opts), DK: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.37, employerPensionRate: 0.0, employerTaxRate: 0.0, displayName: "Denmark", currency: "DKK", countryCode: "DK", taxFreeAllowance: 46_700, ...opts, }), DNK: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["DK"](opts), NO: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.22, employerPensionRate: 0.0, employerTaxRate: 0.141, displayName: "Norway", currency: "NOK", countryCode: "NO", taxFreeAllowance: 94_850, ...opts, }), NOR: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["NO"](opts), PL: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: 0.12, employerPensionRate: 0.0976, employerTaxRate: 0.0953, displayName: "Poland", currency: "PLN", countryCode: "PL", taxFreeAllowance: 30_000, ...opts, }), POL: (opts?: FlatRateTaxOptions) => jurisdictionRegistry["PL"](opts), // Generic fallback for any unsupported country DEFAULT: (opts?: FlatRateTaxOptions) => new FlatRateTax({ flatIncomeTaxRate: opts?.flatIncomeTaxRate ?? 0.20, employerPensionRate: opts?.employerPensionRate ?? 0, employerTaxRate: opts?.employerTaxRate ?? 0, displayName: opts?.displayName ?? "Custom Jurisdiction", currency: opts?.currency ?? "USD", countryCode: opts?.countryCode ?? "XX", taxFreeAllowance: opts?.taxFreeAllowance ?? 0, ...opts, }), }; // ── Factory Function ───────────────────────────────────────── /** * Get the appropriate TaxJurisdiction plugin for a country code. * * @param countryCode — ISO 3166-1 alpha-2 or alpha-3 country code * @param options — Jurisdiction-specific options (e.g. stateTaxRate for US) * @returns TaxJurisdiction instance * * @example * const au = getTaxJurisdiction("AU"); * const us = getTaxJurisdiction("US", { stateTaxRate: 0.06, stateName: "NY" }); * const de = getTaxJurisdiction("DE", { flatIncomeTaxRate: 0.30 }); * const custom = getTaxJurisdiction("XX", { flatIncomeTaxRate: 0.15, displayName: "Custom" }); */ export function getTaxJurisdiction( countryCode: string, options?: Record ): TaxJurisdiction { const key = countryCode.trim().toUpperCase(); const factory = jurisdictionRegistry[key] ?? jurisdictionRegistry["DEFAULT"]; return factory(options); } /** * List all supported jurisdiction codes. */ export function getSupportedJurisdictions(): string[] { return Object.keys(jurisdictionRegistry).filter((k) => k !== "DEFAULT"); } /** * Check if a jurisdiction code is supported natively (not via FlatRateTax). */ export function isNativelySupported(countryCode: string): boolean { const key = countryCode.trim().toUpperCase(); return ["AU", "AUS", "US", "USA", "GB", "GBR", "UK", "CA", "CAN", "NZ", "NZL", "SG", "SGP"].includes(key); } // ── Core Engine ────────────────────────────────────────────── /** * Calculate a complete payslip for the given input. * * @example * const result = calculatePayslip({ * grossAnnual: 95000, * payFrequency: "monthly", * jurisdiction: getTaxJurisdiction("AU"), * }); * console.log(result.netPay); // monthly net pay */ export function calculatePayslip(input: PayrollInput): PayslipCalculation { const engine = new PayrollEngine(); return engine.calculate(input); } // ── Barrel Exports ─────────────────────────────────────────── export { PayrollEngine } from "./engine"; // Re-export all types export type { TaxBracket, DeductionLineItem, EmployerContribution, PayslipCalculation, TaxJurisdiction, PayFrequency, PayrollInput, } from "./types"; export { hourlyToAnnual, toPeriod, progressiveTaxCalc, round2, } from "./types"; // Re-export all jurisdiction classes export { AustraliaTax } from "./jurisdictions/australia"; export { USTax } from "./jurisdictions/usa"; export type { USTaxOptions } from "./jurisdictions/usa"; export { UKTax } from "./jurisdictions/uk"; export { CanadaTax } from "./jurisdictions/canada"; export { NewZealandTax } from "./jurisdictions/new-zealand"; export { SingaporeTax } from "./jurisdictions/singapore"; export type { SingaporeTaxOptions } from "./jurisdictions/singapore"; export { FlatRateTax } from "./jurisdictions/flat-rate"; export type { FlatRateTaxOptions } from "./jurisdictions/flat-rate";