Fix TypeScript build errors
- Remove duplicate EscalationLevel export from regulatory.ts - Add missing logger.ts and reports.ts files to audit package - Fix treasury package type issues - Clean dist folders and rebuild
This commit is contained in:
33
packages/utils/src/currency.d.ts
vendored
Normal file
33
packages/utils/src/currency.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Currency conversion and USD equivalent calculation utilities
|
||||
*/
|
||||
export interface ExchangeRate {
|
||||
fromCurrency: string;
|
||||
toCurrency: string;
|
||||
rate: number;
|
||||
effectiveDate: Date;
|
||||
source?: string;
|
||||
}
|
||||
export interface CurrencyConverter {
|
||||
convert(amount: number, fromCurrency: string, toCurrency: string, date?: Date): number;
|
||||
getUSDEquivalent(amount: number, currency: string, date?: Date): number;
|
||||
getRate(fromCurrency: string, toCurrency: string, date?: Date): number | null;
|
||||
}
|
||||
/**
|
||||
* Simple in-memory currency converter with configurable rates
|
||||
* In production, this would integrate with a real-time FX rate service
|
||||
*/
|
||||
export declare class SimpleCurrencyConverter implements CurrencyConverter {
|
||||
private rates;
|
||||
private defaultUSDRates;
|
||||
constructor(initialRates?: ExchangeRate[]);
|
||||
private initializeDefaultRates;
|
||||
addRate(rate: ExchangeRate): void;
|
||||
private getRateKey;
|
||||
getRate(fromCurrency: string, toCurrency: string, date?: Date): number | null;
|
||||
convert(amount: number, fromCurrency: string, toCurrency: string, date?: Date): number;
|
||||
getUSDEquivalent(amount: number, currency: string, date?: Date): number;
|
||||
}
|
||||
export declare function getDefaultConverter(): CurrencyConverter;
|
||||
export declare function setDefaultConverter(converter: CurrencyConverter): void;
|
||||
//# sourceMappingURL=currency.d.ts.map
|
||||
1
packages/utils/src/currency.d.ts.map
Normal file
1
packages/utils/src/currency.d.ts.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["currency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACvF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACxE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;CAC/E;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,eAAe,CAKrB;gBAEU,YAAY,CAAC,EAAE,YAAY,EAAE;IAOzC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAYjC,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI;IAsB7E,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM;IAiBtF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM;CAMxE;AAID,wBAAgB,mBAAmB,IAAI,iBAAiB,CAKvD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAEtE"}
|
||||
98
packages/utils/src/currency.js
Normal file
98
packages/utils/src/currency.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Currency conversion and USD equivalent calculation utilities
|
||||
*/
|
||||
import Decimal from 'decimal.js';
|
||||
/**
|
||||
* Simple in-memory currency converter with configurable rates
|
||||
* In production, this would integrate with a real-time FX rate service
|
||||
*/
|
||||
export class SimpleCurrencyConverter {
|
||||
rates = new Map();
|
||||
defaultUSDRates = {
|
||||
USD: 1.0,
|
||||
BRL: 0.2,
|
||||
EUR: 1.1,
|
||||
GBP: 1.27,
|
||||
};
|
||||
constructor(initialRates) {
|
||||
if (initialRates) {
|
||||
initialRates.forEach((rate) => this.addRate(rate));
|
||||
}
|
||||
this.initializeDefaultRates();
|
||||
}
|
||||
initializeDefaultRates() {
|
||||
const now = new Date();
|
||||
Object.entries(this.defaultUSDRates).forEach(([currency, rate]) => {
|
||||
if (currency !== 'USD') {
|
||||
this.addRate({
|
||||
fromCurrency: currency,
|
||||
toCurrency: 'USD',
|
||||
rate,
|
||||
effectiveDate: now,
|
||||
source: 'default',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
addRate(rate) {
|
||||
const key = this.getRateKey(rate.fromCurrency, rate.toCurrency);
|
||||
this.rates.set(key, rate);
|
||||
const inverseKey = this.getRateKey(rate.toCurrency, rate.fromCurrency);
|
||||
this.rates.set(inverseKey, {
|
||||
...rate,
|
||||
fromCurrency: rate.toCurrency,
|
||||
toCurrency: rate.fromCurrency,
|
||||
rate: 1 / rate.rate,
|
||||
});
|
||||
}
|
||||
getRateKey(fromCurrency, toCurrency) {
|
||||
return `${fromCurrency}:${toCurrency}`;
|
||||
}
|
||||
getRate(fromCurrency, toCurrency, date) {
|
||||
if (fromCurrency === toCurrency) {
|
||||
return 1.0;
|
||||
}
|
||||
const key = this.getRateKey(fromCurrency, toCurrency);
|
||||
const rate = this.rates.get(key);
|
||||
if (!rate) {
|
||||
if (fromCurrency !== 'USD' && toCurrency !== 'USD') {
|
||||
const fromToUSD = this.getRate(fromCurrency, 'USD', date);
|
||||
const usdToTo = this.getRate('USD', toCurrency, date);
|
||||
if (fromToUSD && usdToTo) {
|
||||
return fromToUSD * usdToTo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return rate.rate;
|
||||
}
|
||||
convert(amount, fromCurrency, toCurrency, date) {
|
||||
if (fromCurrency === toCurrency) {
|
||||
return amount;
|
||||
}
|
||||
const rate = this.getRate(fromCurrency, toCurrency, date);
|
||||
if (rate === null) {
|
||||
throw new Error(`No exchange rate available for ${fromCurrency} to ${toCurrency}`);
|
||||
}
|
||||
const amountDecimal = new Decimal(amount);
|
||||
const rateDecimal = new Decimal(rate);
|
||||
return amountDecimal.mul(rateDecimal).toNumber();
|
||||
}
|
||||
getUSDEquivalent(amount, currency, date) {
|
||||
if (currency === 'USD') {
|
||||
return amount;
|
||||
}
|
||||
return this.convert(amount, currency, 'USD', date);
|
||||
}
|
||||
}
|
||||
let defaultConverter = null;
|
||||
export function getDefaultConverter() {
|
||||
if (!defaultConverter) {
|
||||
defaultConverter = new SimpleCurrencyConverter();
|
||||
}
|
||||
return defaultConverter;
|
||||
}
|
||||
export function setDefaultConverter(converter) {
|
||||
defaultConverter = converter;
|
||||
}
|
||||
//# sourceMappingURL=currency.js.map
|
||||
1
packages/utils/src/currency.js.map
Normal file
1
packages/utils/src/currency.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"currency.js","sourceRoot":"","sources":["currency.ts"],"names":[],"mappings":"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"}
|
||||
18
packages/utils/src/dates.d.ts
vendored
Normal file
18
packages/utils/src/dates.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Date utilities for effective date logic and rolling windows
|
||||
*/
|
||||
export declare function isEffectiveDate(date: Date, effectiveDate: Date, expiryDate?: Date): boolean;
|
||||
export interface RollingWindow {
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
days: number;
|
||||
}
|
||||
export declare function calculateRollingWindow(referenceDate: Date, windowDays: number): RollingWindow;
|
||||
export declare function isWithinRollingWindow(date: Date, window: RollingWindow): boolean;
|
||||
export declare function filterDatesInWindow(dates: Date[], window: RollingWindow): Date[];
|
||||
export declare function calculateRetentionExpiry(creationDate: Date, retentionDays: number): Date;
|
||||
export declare function shouldArchive(creationDate: Date, archivalAfterDays: number, currentDate?: Date): boolean;
|
||||
export declare function shouldDelete(creationDate: Date, retentionDays: number, currentDate?: Date): boolean;
|
||||
export declare function formatISO20022Date(date: Date): string;
|
||||
export declare function formatISO20022DateTime(date: Date): string;
|
||||
//# sourceMappingURL=dates.d.ts.map
|
||||
1
packages/utils/src/dates.d.ts.map
Normal file
1
packages/utils/src/dates.d.ts.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["dates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,OAAO,CAQ3F;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,IAAI,EACnB,UAAU,EAAE,MAAM,GACjB,aAAa,CAOf;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,GACpB,OAAO,CAKT;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,aAAa,GACpB,IAAI,EAAE,CAER;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,IAAI,EAClB,aAAa,EAAE,MAAM,GACpB,IAAI,CAEN;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,IAAI,EAClB,iBAAiB,EAAE,MAAM,EACzB,WAAW,GAAE,IAAiB,GAC7B,OAAO,CAGT;AAED,wBAAgB,YAAY,CAC1B,YAAY,EAAE,IAAI,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,IAAiB,GAC7B,OAAO,CAGT;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAErD;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEzD"}
|
||||
48
packages/utils/src/dates.js
Normal file
48
packages/utils/src/dates.js
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Date utilities for effective date logic and rolling windows
|
||||
*/
|
||||
import { addDays, isAfter, isBefore, isWithinInterval, subDays } from 'date-fns';
|
||||
export function isEffectiveDate(date, effectiveDate, expiryDate) {
|
||||
if (isBefore(date, effectiveDate)) {
|
||||
return false;
|
||||
}
|
||||
if (expiryDate && isAfter(date, expiryDate)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export function calculateRollingWindow(referenceDate, windowDays) {
|
||||
const startDate = subDays(referenceDate, windowDays);
|
||||
return {
|
||||
startDate,
|
||||
endDate: referenceDate,
|
||||
days: windowDays,
|
||||
};
|
||||
}
|
||||
export function isWithinRollingWindow(date, window) {
|
||||
return isWithinInterval(date, {
|
||||
start: window.startDate,
|
||||
end: window.endDate,
|
||||
});
|
||||
}
|
||||
export function filterDatesInWindow(dates, window) {
|
||||
return dates.filter((date) => isWithinRollingWindow(date, window));
|
||||
}
|
||||
export function calculateRetentionExpiry(creationDate, retentionDays) {
|
||||
return addDays(creationDate, retentionDays);
|
||||
}
|
||||
export function shouldArchive(creationDate, archivalAfterDays, currentDate = new Date()) {
|
||||
const archivalDate = addDays(creationDate, archivalAfterDays);
|
||||
return isAfter(currentDate, archivalDate);
|
||||
}
|
||||
export function shouldDelete(creationDate, retentionDays, currentDate = new Date()) {
|
||||
const expiryDate = calculateRetentionExpiry(creationDate, retentionDays);
|
||||
return isAfter(currentDate, expiryDate);
|
||||
}
|
||||
export function formatISO20022Date(date) {
|
||||
return date.toISOString().split('T')[0];
|
||||
}
|
||||
export function formatISO20022DateTime(date) {
|
||||
return date.toISOString().split('.')[0];
|
||||
}
|
||||
//# sourceMappingURL=dates.js.map
|
||||
1
packages/utils/src/dates.js.map
Normal file
1
packages/utils/src/dates.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dates.js","sourceRoot":"","sources":["dates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEjF,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,aAAmB,EAAE,UAAiB;IAChF,IAAI,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQD,MAAM,UAAU,sBAAsB,CACpC,aAAmB,EACnB,UAAkB;IAElB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACrD,OAAO;QACL,SAAS;QACT,OAAO,EAAE,aAAa;QACtB,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,IAAU,EACV,MAAqB;IAErB,OAAO,gBAAgB,CAAC,IAAI,EAAE;QAC5B,KAAK,EAAE,MAAM,CAAC,SAAS;QACvB,GAAG,EAAE,MAAM,CAAC,OAAO;KACpB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAqB;IAErB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,YAAkB,EAClB,aAAqB;IAErB,OAAO,OAAO,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,YAAkB,EAClB,iBAAyB,EACzB,cAAoB,IAAI,IAAI,EAAE;IAE9B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,YAAkB,EAClB,aAAqB,EACrB,cAAoB,IAAI,IAAI,EAAE;IAE9B,MAAM,UAAU,GAAG,wBAAwB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IACzE,OAAO,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAU;IAC3C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAU;IAC/C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC"}
|
||||
31
packages/utils/src/eo-uplift.d.ts
vendored
Normal file
31
packages/utils/src/eo-uplift.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Errors & Omissions (E&O) Uplift calculator
|
||||
*
|
||||
* E&O uplift is a +10% exposure buffer applied to transaction amounts
|
||||
* to account for errors and omissions outside of direct operations.
|
||||
*
|
||||
* Treatment: Off-balance-sheet, non-booked risk buffer
|
||||
*/
|
||||
import type { EOUplift, TransactionEOUplift, BatchEOUplift } from '@brazil-swift-ops/types';
|
||||
export declare const DEFAULT_EO_UPLIFT_RATE = 0.1;
|
||||
/**
|
||||
* Calculate E&O uplift for a single transaction
|
||||
*/
|
||||
export declare function calculateTransactionEOUplift(baseAmount: number, currency: string, upliftRate?: number, usdEquivalent?: number): TransactionEOUplift;
|
||||
/**
|
||||
* Calculate E&O uplift for a batch of transactions
|
||||
*/
|
||||
export declare function calculateBatchEOUplift(baseAmount: number, currency: string, transactionCount: number, upliftRate?: number, usdEquivalent?: number): BatchEOUplift;
|
||||
/**
|
||||
* Calculate E&O uplift for a simple amount (no transaction context)
|
||||
*/
|
||||
export declare function calculateEOUplift(baseAmount: number, upliftRate?: number): EOUplift;
|
||||
/**
|
||||
* Apply E&O uplift to an array of transaction amounts
|
||||
*/
|
||||
export declare function applyEOUpliftToAmounts(amounts: number[], upliftRate?: number): {
|
||||
baseAmount: number;
|
||||
upliftAmount: number;
|
||||
adjustedExposure: number;
|
||||
}[];
|
||||
//# sourceMappingURL=eo-uplift.d.ts.map
|
||||
1
packages/utils/src/eo-uplift.d.ts.map
Normal file
1
packages/utils/src/eo-uplift.d.ts.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"eo-uplift.d.ts","sourceRoot":"","sources":["eo-uplift.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE5F,eAAO,MAAM,sBAAsB,MAAO,CAAC;AAE3C;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAA+B,EAC3C,aAAa,CAAC,EAAE,MAAM,GACrB,mBAAmB,CA4BrB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,UAAU,GAAE,MAA+B,EAC3C,aAAa,CAAC,EAAE,MAAM,GACrB,aAAa,CA4Bf;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,UAAU,GAAE,MAA+B,GAC1C,QAAQ,CAaV;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,GAAE,MAA+B,GAC1C;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,EAAE,CAS1E"}
|
||||
98
packages/utils/src/eo-uplift.js
Normal file
98
packages/utils/src/eo-uplift.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Errors & Omissions (E&O) Uplift calculator
|
||||
*
|
||||
* E&O uplift is a +10% exposure buffer applied to transaction amounts
|
||||
* to account for errors and omissions outside of direct operations.
|
||||
*
|
||||
* Treatment: Off-balance-sheet, non-booked risk buffer
|
||||
*/
|
||||
import Decimal from 'decimal.js';
|
||||
export const DEFAULT_EO_UPLIFT_RATE = 0.10; // 10%
|
||||
/**
|
||||
* Calculate E&O uplift for a single transaction
|
||||
*/
|
||||
export function calculateTransactionEOUplift(baseAmount, currency, upliftRate = DEFAULT_EO_UPLIFT_RATE, usdEquivalent) {
|
||||
// Use Decimal.js for precise calculations
|
||||
const baseDecimal = new Decimal(baseAmount);
|
||||
const rateDecimal = new Decimal(upliftRate);
|
||||
const upliftDecimal = baseDecimal.mul(rateDecimal);
|
||||
const adjustedDecimal = baseDecimal.add(upliftDecimal);
|
||||
const upliftAmount = upliftDecimal.toNumber();
|
||||
const adjustedExposure = adjustedDecimal.toNumber();
|
||||
// Calculate USD equivalent for uplift if provided
|
||||
let upliftUsdEquivalent;
|
||||
if (usdEquivalent !== undefined) {
|
||||
const usdBaseDecimal = new Decimal(usdEquivalent);
|
||||
const usdUpliftDecimal = usdBaseDecimal.mul(rateDecimal);
|
||||
upliftUsdEquivalent = usdBaseDecimal.add(usdUpliftDecimal).toNumber();
|
||||
}
|
||||
return {
|
||||
transactionId: '', // Will be set by caller
|
||||
baseAmount,
|
||||
currency,
|
||||
upliftRate,
|
||||
upliftAmount,
|
||||
adjustedExposure,
|
||||
usdEquivalent: upliftUsdEquivalent,
|
||||
treatment: 'off_balance_sheet',
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Calculate E&O uplift for a batch of transactions
|
||||
*/
|
||||
export function calculateBatchEOUplift(baseAmount, currency, transactionCount, upliftRate = DEFAULT_EO_UPLIFT_RATE, usdEquivalent) {
|
||||
const baseDecimal = new Decimal(baseAmount);
|
||||
const rateDecimal = new Decimal(upliftRate);
|
||||
const upliftDecimal = baseDecimal.mul(rateDecimal);
|
||||
const adjustedDecimal = baseDecimal.add(upliftDecimal);
|
||||
const upliftAmount = upliftDecimal.toNumber();
|
||||
const adjustedExposure = adjustedDecimal.toNumber();
|
||||
// Calculate USD equivalent for uplift if provided
|
||||
let upliftUsdEquivalent;
|
||||
if (usdEquivalent !== undefined) {
|
||||
const usdBaseDecimal = new Decimal(usdEquivalent);
|
||||
const usdUpliftDecimal = usdBaseDecimal.mul(rateDecimal);
|
||||
upliftUsdEquivalent = usdBaseDecimal.add(usdUpliftDecimal).toNumber();
|
||||
}
|
||||
return {
|
||||
batchId: '', // Will be set by caller
|
||||
baseAmount,
|
||||
currency,
|
||||
transactionCount,
|
||||
upliftRate,
|
||||
upliftAmount,
|
||||
adjustedExposure,
|
||||
usdEquivalent: upliftUsdEquivalent,
|
||||
treatment: 'off_balance_sheet',
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Calculate E&O uplift for a simple amount (no transaction context)
|
||||
*/
|
||||
export function calculateEOUplift(baseAmount, upliftRate = DEFAULT_EO_UPLIFT_RATE) {
|
||||
const baseDecimal = new Decimal(baseAmount);
|
||||
const rateDecimal = new Decimal(upliftRate);
|
||||
const upliftDecimal = baseDecimal.mul(rateDecimal);
|
||||
const adjustedDecimal = baseDecimal.add(upliftDecimal);
|
||||
return {
|
||||
baseAmount,
|
||||
upliftRate,
|
||||
upliftAmount: upliftDecimal.toNumber(),
|
||||
adjustedExposure: adjustedDecimal.toNumber(),
|
||||
treatment: 'off_balance_sheet',
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Apply E&O uplift to an array of transaction amounts
|
||||
*/
|
||||
export function applyEOUpliftToAmounts(amounts, upliftRate = DEFAULT_EO_UPLIFT_RATE) {
|
||||
return amounts.map((amount) => {
|
||||
const uplift = calculateEOUplift(amount, upliftRate);
|
||||
return {
|
||||
baseAmount: uplift.baseAmount,
|
||||
upliftAmount: uplift.upliftAmount,
|
||||
adjustedExposure: uplift.adjustedExposure,
|
||||
};
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=eo-uplift.js.map
|
||||
1
packages/utils/src/eo-uplift.js.map
Normal file
1
packages/utils/src/eo-uplift.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"eo-uplift.js","sourceRoot":"","sources":["eo-uplift.ts"],"names":[],"mappings":"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"}
|
||||
10
packages/utils/src/index.d.ts
vendored
Normal file
10
packages/utils/src/index.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brazil-swift-ops/utils
|
||||
*
|
||||
* Shared utilities for the Brazil SWIFT Operations Platform
|
||||
*/
|
||||
export * from './currency';
|
||||
export * from './dates';
|
||||
export * from './validation';
|
||||
export * from './eo-uplift';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
packages/utils/src/index.d.ts.map
Normal file
1
packages/utils/src/index.d.ts.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
||||
10
packages/utils/src/index.js
Normal file
10
packages/utils/src/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @brazil-swift-ops/utils
|
||||
*
|
||||
* Shared utilities for the Brazil SWIFT Operations Platform
|
||||
*/
|
||||
export * from './currency';
|
||||
export * from './dates';
|
||||
export * from './validation';
|
||||
export * from './eo-uplift';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
packages/utils/src/index.js.map
Normal file
1
packages/utils/src/index.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
||||
35
packages/utils/src/validation.d.ts
vendored
Normal file
35
packages/utils/src/validation.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Brazilian ID validation utilities (CPF/CNPJ)
|
||||
*/
|
||||
/**
|
||||
* Validate CPF (Cadastro de Pessoa Física) format and checksum
|
||||
* CPF format: XXX.XXX.XXX-XX (11 digits)
|
||||
*/
|
||||
export declare function validateCPF(cpf: string): {
|
||||
valid: boolean;
|
||||
formatted?: string;
|
||||
error?: string;
|
||||
};
|
||||
/**
|
||||
* Validate CNPJ (Cadastro Nacional da Pessoa Jurídica) format and checksum
|
||||
* CNPJ format: XX.XXX.XXX/XXXX-XX (14 digits)
|
||||
*/
|
||||
export declare function validateCNPJ(cnpj: string): {
|
||||
valid: boolean;
|
||||
formatted?: string;
|
||||
error?: string;
|
||||
};
|
||||
/**
|
||||
* Validate Brazilian tax ID (CPF or CNPJ)
|
||||
*/
|
||||
export declare function validateBrazilianTaxId(taxId: string): {
|
||||
valid: boolean;
|
||||
type?: 'CPF' | 'CNPJ';
|
||||
formatted?: string;
|
||||
error?: string;
|
||||
};
|
||||
/**
|
||||
* Format tax ID for display (CPF or CNPJ)
|
||||
*/
|
||||
export declare function formatTaxId(taxId: string): string;
|
||||
//# sourceMappingURL=validation.d.ts.map
|
||||
1
packages/utils/src/validation.d.ts.map
Normal file
1
packages/utils/src/validation.d.ts.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA2C/F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiDjG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAqBA;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD"}
|
||||
133
packages/utils/src/validation.js
Normal file
133
packages/utils/src/validation.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Brazilian ID validation utilities (CPF/CNPJ)
|
||||
*/
|
||||
/**
|
||||
* Validate CPF (Cadastro de Pessoa Física) format and checksum
|
||||
* CPF format: XXX.XXX.XXX-XX (11 digits)
|
||||
*/
|
||||
export function validateCPF(cpf) {
|
||||
// Remove non-numeric characters
|
||||
const cleaned = cpf.replace(/\D/g, '');
|
||||
// Check length
|
||||
if (cleaned.length !== 11) {
|
||||
return { valid: false, error: 'CPF must have 11 digits' };
|
||||
}
|
||||
// Check for invalid patterns (all same digits)
|
||||
if (/^(\d)\1{10}$/.test(cleaned)) {
|
||||
return { valid: false, error: 'CPF cannot have all same digits' };
|
||||
}
|
||||
// Validate checksum digits
|
||||
let sum = 0;
|
||||
let remainder;
|
||||
// Validate first check digit
|
||||
for (let i = 1; i <= 9; i++) {
|
||||
sum += parseInt(cleaned.substring(i - 1, i)) * (11 - i);
|
||||
}
|
||||
remainder = (sum * 10) % 11;
|
||||
if (remainder === 10 || remainder === 11)
|
||||
remainder = 0;
|
||||
if (remainder !== parseInt(cleaned.substring(9, 10))) {
|
||||
return { valid: false, error: 'Invalid CPF checksum (first digit)' };
|
||||
}
|
||||
// Validate second check digit
|
||||
sum = 0;
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
sum += parseInt(cleaned.substring(i - 1, i)) * (12 - i);
|
||||
}
|
||||
remainder = (sum * 10) % 11;
|
||||
if (remainder === 10 || remainder === 11)
|
||||
remainder = 0;
|
||||
if (remainder !== parseInt(cleaned.substring(10, 11))) {
|
||||
return { valid: false, error: 'Invalid CPF checksum (second digit)' };
|
||||
}
|
||||
// Format CPF
|
||||
const formatted = `${cleaned.substring(0, 3)}.${cleaned.substring(3, 6)}.${cleaned.substring(6, 9)}-${cleaned.substring(9, 11)}`;
|
||||
return { valid: true, formatted };
|
||||
}
|
||||
/**
|
||||
* Validate CNPJ (Cadastro Nacional da Pessoa Jurídica) format and checksum
|
||||
* CNPJ format: XX.XXX.XXX/XXXX-XX (14 digits)
|
||||
*/
|
||||
export function validateCNPJ(cnpj) {
|
||||
// Remove non-numeric characters
|
||||
const cleaned = cnpj.replace(/\D/g, '');
|
||||
// Check length
|
||||
if (cleaned.length !== 14) {
|
||||
return { valid: false, error: 'CNPJ must have 14 digits' };
|
||||
}
|
||||
// Check for invalid patterns (all same digits)
|
||||
if (/^(\d)\1{13}$/.test(cleaned)) {
|
||||
return { valid: false, error: 'CNPJ cannot have all same digits' };
|
||||
}
|
||||
// Validate checksum digits
|
||||
let length = cleaned.length - 2;
|
||||
let numbers = cleaned.substring(0, length);
|
||||
const digits = cleaned.substring(length);
|
||||
let sum = 0;
|
||||
let pos = length - 7;
|
||||
// Validate first check digit
|
||||
for (let i = length; i >= 1; i--) {
|
||||
sum += parseInt(numbers.charAt(length - i)) * pos--;
|
||||
if (pos < 2)
|
||||
pos = 9;
|
||||
}
|
||||
let result = sum % 11 < 2 ? 0 : 11 - (sum % 11);
|
||||
if (result !== parseInt(digits.charAt(0))) {
|
||||
return { valid: false, error: 'Invalid CNPJ checksum (first digit)' };
|
||||
}
|
||||
// Validate second check digit
|
||||
length = length + 1;
|
||||
numbers = cleaned.substring(0, length);
|
||||
sum = 0;
|
||||
pos = length - 7;
|
||||
for (let i = length; i >= 1; i--) {
|
||||
sum += parseInt(numbers.charAt(length - i)) * pos--;
|
||||
if (pos < 2)
|
||||
pos = 9;
|
||||
}
|
||||
result = sum % 11 < 2 ? 0 : 11 - (sum % 11);
|
||||
if (result !== parseInt(digits.charAt(1))) {
|
||||
return { valid: false, error: 'Invalid CNPJ checksum (second digit)' };
|
||||
}
|
||||
// Format CNPJ
|
||||
const formatted = `${cleaned.substring(0, 2)}.${cleaned.substring(2, 5)}.${cleaned.substring(5, 8)}/${cleaned.substring(8, 12)}-${cleaned.substring(12, 14)}`;
|
||||
return { valid: true, formatted };
|
||||
}
|
||||
/**
|
||||
* Validate Brazilian tax ID (CPF or CNPJ)
|
||||
*/
|
||||
export function validateBrazilianTaxId(taxId) {
|
||||
const cleaned = taxId.replace(/\D/g, '');
|
||||
if (cleaned.length === 11) {
|
||||
const cpfResult = validateCPF(taxId);
|
||||
return {
|
||||
...cpfResult,
|
||||
type: cpfResult.valid ? 'CPF' : undefined,
|
||||
};
|
||||
}
|
||||
else if (cleaned.length === 14) {
|
||||
const cnpjResult = validateCNPJ(taxId);
|
||||
return {
|
||||
...cnpjResult,
|
||||
type: cnpjResult.valid ? 'CNPJ' : undefined,
|
||||
};
|
||||
}
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Tax ID must be 11 digits (CPF) or 14 digits (CNPJ)',
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Format tax ID for display (CPF or CNPJ)
|
||||
*/
|
||||
export function formatTaxId(taxId) {
|
||||
const cleaned = taxId.replace(/\D/g, '');
|
||||
if (cleaned.length === 11) {
|
||||
return `${cleaned.substring(0, 3)}.${cleaned.substring(3, 6)}.${cleaned.substring(6, 9)}-${cleaned.substring(9, 11)}`;
|
||||
}
|
||||
else if (cleaned.length === 14) {
|
||||
return `${cleaned.substring(0, 2)}.${cleaned.substring(2, 5)}.${cleaned.substring(5, 8)}/${cleaned.substring(8, 12)}-${cleaned.substring(12, 14)}`;
|
||||
}
|
||||
return taxId;
|
||||
}
|
||||
//# sourceMappingURL=validation.js.map
|
||||
1
packages/utils/src/validation.js.map
Normal file
1
packages/utils/src/validation.js.map
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user