import { parseAmount } from "../../../common/providers/whmcs-utils/index.js"; import { whmcsCatalogProductListResponseSchema, type WhmcsCatalogProductListResponse, } from "./raw.types.js"; export interface WhmcsCatalogPricing { currency: string; prefix?: string; suffix?: string; monthly?: number; quarterly?: number; semiannually?: number; annually?: number; biennially?: number; triennially?: number; setupFees: { monthly?: number; quarterly?: number; semiannually?: number; annually?: number; biennially?: number; triennially?: number; }; } export interface WhmcsCatalogProductNormalized { id: string; groupId: number; name: string; description: string; module: string; payType: string; pricing: Record; } const cycles = [ "monthly", "quarterly", "semiannually", "annually", "biennially", "triennially", ] as const; const setupFeeKeys = [ "msetupfee", "qsetupfee", "ssetupfee", "asetupfee", "bsetupfee", "tsetupfee", ] as const; const normalizePrice = (value: string | undefined): number | undefined => value === undefined ? undefined : parseAmount(value); export function parseWhmcsCatalogProductListResponse( raw: unknown ): WhmcsCatalogProductListResponse { return whmcsCatalogProductListResponseSchema.parse(raw); } export function transformWhmcsCatalogProductsResponse( raw: unknown ): WhmcsCatalogProductNormalized[] { const parsed = parseWhmcsCatalogProductListResponse(raw); const products = parsed.products.product; return products.map(product => { const pricingEntries = Object.entries(product.pricing ?? {}); const pricing = pricingEntries.reduce>( (acc, [currency, cyclePricing]) => { const normalizedCycles: Partial = { currency, prefix: cyclePricing.prefix, suffix: cyclePricing.suffix, }; cycles.forEach(cycle => { const value = cyclePricing[cycle]; if (value !== undefined) { normalizedCycles[cycle] = normalizePrice(value); } }); const setupFees: WhmcsCatalogPricing["setupFees"] = {}; setupFeeKeys.forEach((feeKey, index) => { const value = cyclePricing[feeKey]; if (value !== undefined) { setupFees[cycles[index]] = normalizePrice(value); } }); acc[currency] = { currency, prefix: cyclePricing.prefix, suffix: cyclePricing.suffix, monthly: normalizedCycles.monthly, quarterly: normalizedCycles.quarterly, semiannually: normalizedCycles.semiannually, annually: normalizedCycles.annually, biennially: normalizedCycles.biennially, triennially: normalizedCycles.triennially, setupFees, }; return acc; }, {} ); return { id: String(product.pid), groupId: product.gid, name: product.name, description: product.description, module: product.module, payType: product.paytype, pricing, } satisfies WhmcsCatalogProductNormalized; }); }