Skip to main content
Glama
dennisonbertram

Brex MCP Server

money.ts4.18 kB
export type FormatMode = 'cents' | 'dollars' | 'both'; export interface MoneyInput { amount: number; currency?: string; } export interface MoneyOptions { locale?: string; includeFormatted?: boolean; formatMode?: FormatMode; } export function formatCurrency(amountDollars: number, currency = 'USD', locale = 'en-US'): string { try { return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amountDollars); } catch { // Fallback simple formatter return `${currency} ${amountDollars.toFixed(2)}`; } } export function formatMoney(input: MoneyInput, opts?: MoneyOptions) { const currency = input.currency || 'USD'; const cents = typeof input.amount === 'number' ? input.amount : 0; const dollars = cents / 100; const includeFormatted = opts?.includeFormatted ?? true; const locale = opts?.locale || 'en-US'; const formatted = includeFormatted ? formatCurrency(dollars, currency, locale) : undefined; return { amount_cents: cents, amount_dollars: dollars, ...(includeFormatted ? { amount_formatted: formatted } : {}), currency } as const; } // Shallow predicate for Brex-like Money objects function isMoneyLike(obj: any): obj is MoneyInput { return obj && typeof obj === 'object' && typeof obj.amount === 'number'; } export interface AnnotateOptions extends MoneyOptions {} export function annotateAmounts(value: any, opts?: AnnotateOptions): any { const mode: FormatMode = opts?.formatMode ?? 'both'; function annotateMoney(m: any) { if (!isMoneyLike(m)) return m; const fm = formatMoney(m, opts); const mm = m as any; if (mode === 'cents') { mm.amount_cents = fm.amount_cents; if (opts?.includeFormatted ?? true) mm.amount_formatted = fm.amount_formatted; mm.currency = fm.currency; } else if (mode === 'dollars') { mm.amount_dollars = fm.amount_dollars; if (opts?.includeFormatted ?? true) mm.amount_formatted = fm.amount_formatted; mm.currency = fm.currency; } else { // both mm.amount_cents = fm.amount_cents; mm.amount_dollars = fm.amount_dollars; if (opts?.includeFormatted ?? true) mm.amount_formatted = fm.amount_formatted; mm.currency = fm.currency; } return m; } function walk(node: any): any { if (Array.isArray(node)) { return node.map(walk); } if (node && typeof node === 'object') { // If this object itself is money-like, annotate it if (isMoneyLike(node)) return annotateMoney(node); // Else traverse fields for (const k of Object.keys(node)) { const v = (node as any)[k]; (node as any)[k] = walk(v); } return node; } return node; } return walk(value); } export interface Summary { total_cents: number; total_dollars: number; total_formatted?: string; average_dollars: number; count: number; largest_dollars?: number; smallest_dollars?: number; } export function summarizeAmounts<T>(items: T[], getMoney: (item: T) => MoneyInput | undefined, opts?: { currency?: string; locale?: string; includeFormatted?: boolean }): Summary { let totalCents = 0; let count = 0; let largestD = -Infinity; let smallestD = Infinity; for (const it of items) { const m = getMoney(it); if (!m) continue; totalCents += m.amount || 0; count++; const d = (m.amount || 0) / 100; if (d > largestD) largestD = d; if (d < smallestD) smallestD = d; } const totalD = totalCents / 100; const avgD = count ? totalD / count : 0; const currency = opts?.currency || 'USD'; const includeFormatted = opts?.includeFormatted ?? true; return { total_cents: totalCents, total_dollars: totalD, ...(includeFormatted ? { total_formatted: formatCurrency(totalD, currency, opts?.locale || 'en-US') } : {}), average_dollars: avgD, count, largest_dollars: isFinite(largestD) ? largestD : undefined, smallest_dollars: isFinite(smallestD) ? smallestD : undefined, }; } export function defaultFieldNotes() { return { amount: 'All monetary amounts are in cents. Use amount_dollars and amount_formatted for display and arithmetic.' }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dennisonbertram/mcp-brex'

If you have feedback or need assistance with the MCP directory API, please join our Discord server