From 9ba812c82d00dacc688d02904d86315ad404db9d Mon Sep 17 00:00:00 2001 From: Terry Yiu Date: Thu, 10 Sep 2026 14:38:07 +0300 Subject: [PATCH] Switch web's currency filter from exclude-list to allowlist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous WITHDRAWN_CURRENCY_CODES exclusion list only covered the 5 retired codes I'd found by diffing against the JVM — but which codes Intl.supportedValuesOf('currency') returns is ICU-version- dependent, and apparently some browsers' ICU data includes currencies retired decades ago (AFA, ALK, AOK, AON, AOR, and evidently more) alongside current ones. An exclusion list can't keep up with an unbounded, browser-dependent set of historical codes. Replaced with ACTIVE_CURRENCY_CODES, an allowlist taken directly from the JVM's own live-derived "currently used" set (verified against a real JVM run, 155 codes) plus PRECIOUS_METAL_CURRENCY_CODES. This naturally excludes every retired code regardless of what a given browser's Intl data happens to expose, rather than needing to know about each one in advance. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01FXcrACM5sok3M1KQJ8kByy --- .../tyiu/satsprice/SystemCurrencies.web.kt | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/shared/src/webMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.web.kt b/shared/src/webMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.web.kt index 550c276..ee9269f 100644 --- a/shared/src/webMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.web.kt +++ b/shared/src/webMain/kotlin/xyz/tyiu/satsprice/SystemCurrencies.web.kt @@ -13,26 +13,35 @@ private fun jsCurrencyDisplayName(code: String): String = js( ) /** - * `Intl.supportedValuesOf('currency')` includes a handful of codes for currencies that have - * actually been withdrawn/superseded since — unlike JVM/Android/Apple, there's no web API to - * derive "currently assigned to some country" the way `java.util.Currency`/`NSLocale` do (see - * [localeCurrencyCode] below), so this is a manually maintained exclusion list instead, checked - * (2026-09-10) against the JVM's own live-derived set. Needs a new entry whenever another - * currency is retired. + * Which currency codes `Intl.supportedValuesOf('currency')` returns is ICU-version-dependent, and + * some browsers' ICU data includes codes for currencies retired decades ago (AFA, ALK, AOK, AON, + * AOR, ...) alongside genuinely current ones — a moving target, and not one an exclusion list can + * keep up with. So rather than trying to exclude every historical code some browser might expose, + * this allowlists the ones actually still in use instead: unlike JVM/Android/Apple, there's no web + * API to derive "currently assigned to some country" the way `java.util.Currency`/`NSLocale` do + * (see [localeCurrencyCode] below), so this is a manually maintained list, taken directly from the + * JVM's own live-derived set (checked 2026-09-10). Needs a new entry whenever a currency changes. */ -private val WITHDRAWN_CURRENCY_CODES = setOf( - "ANG", // Netherlands Antillean Guilder — replaced by XCG (Caribbean Guilder), April 2025 - "CUC", // Cuban Convertible Peso — unified into CUP, January 2021 - "HRK", // Croatian Kuna — replaced by EUR, January 2023 - "SLL", // Sierra Leonean Leone (old) — redenominated to SLE, 2022 - "ZWL", // Zimbabwean Dollar (old) — replaced by ZWG (Zimbabwe Gold), April 2024 -) +private val ACTIVE_CURRENCY_CODES = setOf( + "AED", "AFN", "ALL", "AMD", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", + "BHD", "BIF", "BMD", "BND", "BOB", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD", "CAD", "CDF", + "CHF", "CLP", "CNY", "COP", "CRC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EGP", + "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", + "HKD", "HNL", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", + "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", + "LSL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRU", "MUR", "MVR", "MWK", + "MXN", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", + "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", + "SEK", "SGD", "SHP", "SLE", "SOS", "SRD", "SSP", "STN", "SVC", "SYP", "SZL", "THB", "TJS", + "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VES", + "VND", "VUV", "WST", "XAF", "XCD", "XCG", "XOF", "XPF", "YER", "ZAR", "ZMW", "ZWG", +) + PRECIOUS_METAL_CURRENCY_CODES actual fun systemCurrencies(): List = jsSupportedCurrencyCodes() .toList() .map { it.toString() } - .filterNot { it in WITHDRAWN_CURRENCY_CODES } + .filter { it in ACTIVE_CURRENCY_CODES } .map { code -> CurrencyInfo(code, jsCurrencyDisplayName(code)) } .sortedBy { it.code }