Fix Intl interop crash on Kotlin/JS web target

js("new Foo(x).bar()") can misparse so `new` binds to the whole chain
instead of just the constructor call, throwing "X.resolvedOptions is not a
constructor" at runtime on the JS target (Kotlin/Wasm was unaffected, since
its js() compiles through a different path). Binding the constructor result
to a local variable first removes the ambiguity.

This was also silently breaking systemCurrencies() and the currency display
name lookup, and had been cascading into an unrelated CoinGecko test
failure in the same karma bundle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QpjMKWGoiT5aJBzhxvXkwp
This commit is contained in:
2026-09-08 09:34:40 +03:00
co-authored by Claude Sonnet 5
parent 14298d450e
commit 200319de86
@@ -4,8 +4,11 @@ package xyz.tyiu.satsprice
private fun jsSupportedCurrencyCodes(): JsArray<JsString> = js("Intl.supportedValuesOf('currency')") private fun jsSupportedCurrencyCodes(): JsArray<JsString> = js("Intl.supportedValuesOf('currency')")
private fun jsCurrencyDisplayName(code: String): String = // A chained `new Foo(x).bar()` inside js() can misparse (`new` binding to the whole chain rather
js("new Intl.DisplayNames(['en'], { type: 'currency' }).of(code)") // than just the constructor call), so the constructor result is bound to a variable first.
private fun jsCurrencyDisplayName(code: String): String = js(
"(function() { var names = new Intl.DisplayNames(['en'], { type: 'currency' }); return names.of(code); })()",
)
actual fun systemCurrencies(): List<CurrencyInfo> = actual fun systemCurrencies(): List<CurrencyInfo> =
jsSupportedCurrencyCodes() jsSupportedCurrencyCodes()
@@ -24,8 +27,9 @@ actual fun systemCurrencies(): List<CurrencyInfo> =
*/ */
actual fun localeCurrencyCode(): String? = null actual fun localeCurrencyCode(): String? = null
private fun jsCurrencyFractionDigits(code: String): Int = private fun jsCurrencyFractionDigits(code: String): Int = js(
js("new Intl.NumberFormat('en', { style: 'currency', currency: code }).resolvedOptions().maximumFractionDigits") """(function() { var fmt = new Intl.NumberFormat('en', { style: 'currency', currency: code }); return fmt.resolvedOptions().maximumFractionDigits; })()""",
)
actual fun currencyDecimalDigits(code: String): Int = try { actual fun currencyDecimalDigits(code: String): Int = try {
jsCurrencyFractionDigits(code) jsCurrencyFractionDigits(code)