@whop/elements-react-native 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/README.md +179 -0
  2. package/android/build.gradle +64 -0
  3. package/android/consumer-rules.pro +3 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/java/com/whop/elements/WhopAddressSuggestionsModule.kt +102 -0
  6. package/android/src/main/java/com/whop/elements/WhopAuthSessionModule.kt +126 -0
  7. package/android/src/main/java/com/whop/elements/WhopElementsPackage.kt +39 -0
  8. package/android/src/main/java/com/whop/elements/WhopPayButtonManager.kt +74 -0
  9. package/android/src/main/java/com/whop/elements/WhopPayButtonPressEvent.kt +17 -0
  10. package/android/src/main/java/com/whop/elements/WhopPayButtonView.kt +178 -0
  11. package/android/src/main/java/com/whop/elements/WhopPlatformPayModule.kt +212 -0
  12. package/assets/whop-wordmark-dark.png +0 -0
  13. package/assets/whop-wordmark-dark@2x.png +0 -0
  14. package/assets/whop-wordmark-dark@3x.png +0 -0
  15. package/assets/whop-wordmark-light.png +0 -0
  16. package/assets/whop-wordmark-light@2x.png +0 -0
  17. package/assets/whop-wordmark-light@3x.png +0 -0
  18. package/ios/Package.swift +59 -0
  19. package/ios/Sources/ElementsReactNative/WhopAddressSuggestionsImpl.swift +189 -0
  20. package/ios/Sources/ElementsReactNative/WhopAuthSessionImpl.swift +106 -0
  21. package/ios/Sources/ElementsReactNative/WhopPayButtonImpl.swift +89 -0
  22. package/ios/Sources/ElementsReactNative/WhopPlatformPayImpl.swift +181 -0
  23. package/ios/generated/WhopAddressSuggestionsModule.h +11 -0
  24. package/ios/generated/WhopAddressSuggestionsModule.mm +46 -0
  25. package/ios/generated/WhopAuthSessionModule.h +11 -0
  26. package/ios/generated/WhopAuthSessionModule.mm +45 -0
  27. package/ios/generated/WhopElementsShims.h +35 -0
  28. package/ios/generated/WhopPayButtonComponentView.h +12 -0
  29. package/ios/generated/WhopPayButtonComponentView.mm +82 -0
  30. package/ios/generated/WhopPlatformPayModule.h +11 -0
  31. package/ios/generated/WhopPlatformPayModule.mm +51 -0
  32. package/lib/module/api/client.js +139 -0
  33. package/lib/module/api/client.js.map +1 -0
  34. package/lib/module/api/client.test.js +137 -0
  35. package/lib/module/api/client.test.js.map +1 -0
  36. package/lib/module/api/types.js +2 -0
  37. package/lib/module/api/types.js.map +1 -0
  38. package/lib/module/controller/actions.js +148 -0
  39. package/lib/module/controller/actions.js.map +1 -0
  40. package/lib/module/controller/actions.test.js +102 -0
  41. package/lib/module/controller/actions.test.js.map +1 -0
  42. package/lib/module/controller/store.js +158 -0
  43. package/lib/module/controller/store.js.map +1 -0
  44. package/lib/module/core/address/country-data.js +1370 -0
  45. package/lib/module/core/address/country-data.js.map +1 -0
  46. package/lib/module/core/address/country-name.js +38 -0
  47. package/lib/module/core/address/country-name.js.map +1 -0
  48. package/lib/module/core/address/country-names.generated.js +249 -0
  49. package/lib/module/core/address/country-names.generated.js.map +1 -0
  50. package/lib/module/core/address/engine.js +245 -0
  51. package/lib/module/core/address/engine.js.map +1 -0
  52. package/lib/module/core/address/engine.test.js +216 -0
  53. package/lib/module/core/address/engine.test.js.map +1 -0
  54. package/lib/module/core/address/form-state.js +409 -0
  55. package/lib/module/core/address/form-state.js.map +1 -0
  56. package/lib/module/core/address/form-state.test.js +516 -0
  57. package/lib/module/core/address/form-state.test.js.map +1 -0
  58. package/lib/module/core/address/places.js +36 -0
  59. package/lib/module/core/address/places.js.map +1 -0
  60. package/lib/module/core/address/required-coverage.test.js +57 -0
  61. package/lib/module/core/address/required-coverage.test.js.map +1 -0
  62. package/lib/module/core/address/suggest.js +102 -0
  63. package/lib/module/core/address/suggest.js.map +1 -0
  64. package/lib/module/core/address/suggest.test.js +156 -0
  65. package/lib/module/core/address/suggest.test.js.map +1 -0
  66. package/lib/module/core/address/use-suggestions.js +33 -0
  67. package/lib/module/core/address/use-suggestions.js.map +1 -0
  68. package/lib/module/core/payments/address-change.js +91 -0
  69. package/lib/module/core/payments/address-change.js.map +1 -0
  70. package/lib/module/core/payments/billing-merge.js +62 -0
  71. package/lib/module/core/payments/billing-merge.js.map +1 -0
  72. package/lib/module/core/payments/browser-info.js +42 -0
  73. package/lib/module/core/payments/browser-info.js.map +1 -0
  74. package/lib/module/core/payments/bt.js +151 -0
  75. package/lib/module/core/payments/bt.js.map +1 -0
  76. package/lib/module/core/payments/bt.test.js +23 -0
  77. package/lib/module/core/payments/bt.test.js.map +1 -0
  78. package/lib/module/core/payments/currency.js +37 -0
  79. package/lib/module/core/payments/currency.js.map +1 -0
  80. package/lib/module/core/payments/detail.js +159 -0
  81. package/lib/module/core/payments/detail.js.map +1 -0
  82. package/lib/module/core/payments/detail.test.js +225 -0
  83. package/lib/module/core/payments/detail.test.js.map +1 -0
  84. package/lib/module/core/payments/errors.js +115 -0
  85. package/lib/module/core/payments/errors.js.map +1 -0
  86. package/lib/module/core/payments/mint.js +89 -0
  87. package/lib/module/core/payments/mint.js.map +1 -0
  88. package/lib/module/core/payments/plan.js +131 -0
  89. package/lib/module/core/payments/plan.js.map +1 -0
  90. package/lib/module/core/payments/refusals.js +17 -0
  91. package/lib/module/core/payments/refusals.js.map +1 -0
  92. package/lib/module/core/payments/secure-fields.js +87 -0
  93. package/lib/module/core/payments/secure-fields.js.map +1 -0
  94. package/lib/module/core/payments/tax-id-catalog.js +616 -0
  95. package/lib/module/core/payments/tax-id-catalog.js.map +1 -0
  96. package/lib/module/core/payments/wallet-contact.js +42 -0
  97. package/lib/module/core/payments/wallet-contact.js.map +1 -0
  98. package/lib/module/core/payments/wallet-contact.test.js +77 -0
  99. package/lib/module/core/payments/wallet-contact.test.js.map +1 -0
  100. package/lib/module/elements/address.js +467 -0
  101. package/lib/module/elements/address.js.map +1 -0
  102. package/lib/module/elements/branding.js +114 -0
  103. package/lib/module/elements/branding.js.map +1 -0
  104. package/lib/module/elements/card-fields/context.js +254 -0
  105. package/lib/module/elements/card-fields/context.js.map +1 -0
  106. package/lib/module/elements/card-fields/fields.js +309 -0
  107. package/lib/module/elements/card-fields/fields.js.map +1 -0
  108. package/lib/module/elements/card-fields/index.js +30 -0
  109. package/lib/module/elements/card-fields/index.js.map +1 -0
  110. package/lib/module/elements/card.js +107 -0
  111. package/lib/module/elements/card.js.map +1 -0
  112. package/lib/module/elements/email.js +84 -0
  113. package/lib/module/elements/email.js.map +1 -0
  114. package/lib/module/elements/payment/declared-fields.js +186 -0
  115. package/lib/module/elements/payment/declared-fields.js.map +1 -0
  116. package/lib/module/elements/payment/index.js +448 -0
  117. package/lib/module/elements/payment/index.js.map +1 -0
  118. package/lib/module/elements/payment/wallet.js +132 -0
  119. package/lib/module/elements/payment/wallet.js.map +1 -0
  120. package/lib/module/elements/tax-id.js +100 -0
  121. package/lib/module/elements/tax-id.js.map +1 -0
  122. package/lib/module/i18n/catalogs.js +103 -0
  123. package/lib/module/i18n/catalogs.js.map +1 -0
  124. package/lib/module/i18n/index.js +45 -0
  125. package/lib/module/i18n/index.js.map +1 -0
  126. package/lib/module/index.js +27 -0
  127. package/lib/module/index.js.map +1 -0
  128. package/lib/module/namespace.js +174 -0
  129. package/lib/module/namespace.js.map +1 -0
  130. package/lib/module/native/index.js +128 -0
  131. package/lib/module/native/index.js.map +1 -0
  132. package/lib/module/package.json +1 -0
  133. package/lib/module/provider.js +56 -0
  134. package/lib/module/provider.js.map +1 -0
  135. package/lib/module/specs/NativeWhopAddressSuggestions.js +6 -0
  136. package/lib/module/specs/NativeWhopAddressSuggestions.js.map +1 -0
  137. package/lib/module/specs/NativeWhopAuthSession.js +10 -0
  138. package/lib/module/specs/NativeWhopAuthSession.js.map +1 -0
  139. package/lib/module/specs/NativeWhopPlatformPay.js +10 -0
  140. package/lib/module/specs/NativeWhopPlatformPay.js.map +1 -0
  141. package/lib/module/specs/WhopPayButtonNativeComponent.ts +22 -0
  142. package/lib/module/theme/appearance.js +85 -0
  143. package/lib/module/theme/appearance.js.map +1 -0
  144. package/lib/module/theme/appearance.test.js +124 -0
  145. package/lib/module/theme/appearance.test.js.map +1 -0
  146. package/lib/module/theme/provider.js +25 -0
  147. package/lib/module/theme/provider.js.map +1 -0
  148. package/lib/module/theme/resolve.js +69 -0
  149. package/lib/module/theme/resolve.js.map +1 -0
  150. package/lib/module/theme/scales.generated.js +419 -0
  151. package/lib/module/theme/scales.generated.js.map +1 -0
  152. package/lib/module/ui/element-frame.js +83 -0
  153. package/lib/module/ui/element-frame.js.map +1 -0
  154. package/lib/module/ui/payment-method-icon.js +69 -0
  155. package/lib/module/ui/payment-method-icon.js.map +1 -0
  156. package/lib/module/ui/primitives.js +266 -0
  157. package/lib/module/ui/primitives.js.map +1 -0
  158. package/lib/module/ui/select.js +281 -0
  159. package/lib/module/ui/select.js.map +1 -0
  160. package/lib/module/ui/suggestions.js +71 -0
  161. package/lib/module/ui/suggestions.js.map +1 -0
  162. package/lib/module/ui/whop-logo.js +42 -0
  163. package/lib/module/ui/whop-logo.js.map +1 -0
  164. package/lib/typescript/package.json +1 -0
  165. package/lib/typescript/src/api/client.d.ts +87 -0
  166. package/lib/typescript/src/api/client.d.ts.map +1 -0
  167. package/lib/typescript/src/api/types.d.ts +175 -0
  168. package/lib/typescript/src/api/types.d.ts.map +1 -0
  169. package/lib/typescript/src/controller/actions.d.ts +42 -0
  170. package/lib/typescript/src/controller/actions.d.ts.map +1 -0
  171. package/lib/typescript/src/controller/store.d.ts +90 -0
  172. package/lib/typescript/src/controller/store.d.ts.map +1 -0
  173. package/lib/typescript/src/core/address/country-data.d.ts +4 -0
  174. package/lib/typescript/src/core/address/country-data.d.ts.map +1 -0
  175. package/lib/typescript/src/core/address/country-name.d.ts +2 -0
  176. package/lib/typescript/src/core/address/country-name.d.ts.map +1 -0
  177. package/lib/typescript/src/core/address/country-names.generated.d.ts +2 -0
  178. package/lib/typescript/src/core/address/country-names.generated.d.ts.map +1 -0
  179. package/lib/typescript/src/core/address/engine.d.ts +97 -0
  180. package/lib/typescript/src/core/address/engine.d.ts.map +1 -0
  181. package/lib/typescript/src/core/address/form-state.d.ts +144 -0
  182. package/lib/typescript/src/core/address/form-state.d.ts.map +1 -0
  183. package/lib/typescript/src/core/address/places.d.ts +23 -0
  184. package/lib/typescript/src/core/address/places.d.ts.map +1 -0
  185. package/lib/typescript/src/core/address/suggest.d.ts +47 -0
  186. package/lib/typescript/src/core/address/suggest.d.ts.map +1 -0
  187. package/lib/typescript/src/core/address/use-suggestions.d.ts +3 -0
  188. package/lib/typescript/src/core/address/use-suggestions.d.ts.map +1 -0
  189. package/lib/typescript/src/core/payments/address-change.d.ts +52 -0
  190. package/lib/typescript/src/core/payments/address-change.d.ts.map +1 -0
  191. package/lib/typescript/src/core/payments/billing-merge.d.ts +39 -0
  192. package/lib/typescript/src/core/payments/billing-merge.d.ts.map +1 -0
  193. package/lib/typescript/src/core/payments/browser-info.d.ts +12 -0
  194. package/lib/typescript/src/core/payments/browser-info.d.ts.map +1 -0
  195. package/lib/typescript/src/core/payments/bt.d.ts +55 -0
  196. package/lib/typescript/src/core/payments/bt.d.ts.map +1 -0
  197. package/lib/typescript/src/core/payments/currency.d.ts +7 -0
  198. package/lib/typescript/src/core/payments/currency.d.ts.map +1 -0
  199. package/lib/typescript/src/core/payments/detail.d.ts +53 -0
  200. package/lib/typescript/src/core/payments/detail.d.ts.map +1 -0
  201. package/lib/typescript/src/core/payments/errors.d.ts +62 -0
  202. package/lib/typescript/src/core/payments/errors.d.ts.map +1 -0
  203. package/lib/typescript/src/core/payments/mint.d.ts +74 -0
  204. package/lib/typescript/src/core/payments/mint.d.ts.map +1 -0
  205. package/lib/typescript/src/core/payments/plan.d.ts +69 -0
  206. package/lib/typescript/src/core/payments/plan.d.ts.map +1 -0
  207. package/lib/typescript/src/core/payments/refusals.d.ts +12 -0
  208. package/lib/typescript/src/core/payments/refusals.d.ts.map +1 -0
  209. package/lib/typescript/src/core/payments/secure-fields.d.ts +33 -0
  210. package/lib/typescript/src/core/payments/secure-fields.d.ts.map +1 -0
  211. package/lib/typescript/src/core/payments/tax-id-catalog.d.ts +481 -0
  212. package/lib/typescript/src/core/payments/tax-id-catalog.d.ts.map +1 -0
  213. package/lib/typescript/src/core/payments/wallet-contact.d.ts +40 -0
  214. package/lib/typescript/src/core/payments/wallet-contact.d.ts.map +1 -0
  215. package/lib/typescript/src/elements/address.d.ts +55 -0
  216. package/lib/typescript/src/elements/address.d.ts.map +1 -0
  217. package/lib/typescript/src/elements/branding.d.ts +18 -0
  218. package/lib/typescript/src/elements/branding.d.ts.map +1 -0
  219. package/lib/typescript/src/elements/card-fields/context.d.ts +67 -0
  220. package/lib/typescript/src/elements/card-fields/context.d.ts.map +1 -0
  221. package/lib/typescript/src/elements/card-fields/fields.d.ts +15 -0
  222. package/lib/typescript/src/elements/card-fields/fields.d.ts.map +1 -0
  223. package/lib/typescript/src/elements/card-fields/index.d.ts +21 -0
  224. package/lib/typescript/src/elements/card-fields/index.d.ts.map +1 -0
  225. package/lib/typescript/src/elements/card.d.ts +21 -0
  226. package/lib/typescript/src/elements/card.d.ts.map +1 -0
  227. package/lib/typescript/src/elements/email.d.ts +31 -0
  228. package/lib/typescript/src/elements/email.d.ts.map +1 -0
  229. package/lib/typescript/src/elements/payment/declared-fields.d.ts +43 -0
  230. package/lib/typescript/src/elements/payment/declared-fields.d.ts.map +1 -0
  231. package/lib/typescript/src/elements/payment/index.d.ts +37 -0
  232. package/lib/typescript/src/elements/payment/index.d.ts.map +1 -0
  233. package/lib/typescript/src/elements/payment/wallet.d.ts +39 -0
  234. package/lib/typescript/src/elements/payment/wallet.d.ts.map +1 -0
  235. package/lib/typescript/src/elements/tax-id.d.ts +41 -0
  236. package/lib/typescript/src/elements/tax-id.d.ts.map +1 -0
  237. package/lib/typescript/src/i18n/catalogs.d.ts +7 -0
  238. package/lib/typescript/src/i18n/catalogs.d.ts.map +1 -0
  239. package/lib/typescript/src/i18n/index.d.ts +17 -0
  240. package/lib/typescript/src/i18n/index.d.ts.map +1 -0
  241. package/lib/typescript/src/index.d.ts +42 -0
  242. package/lib/typescript/src/index.d.ts.map +1 -0
  243. package/lib/typescript/src/namespace.d.ts +36 -0
  244. package/lib/typescript/src/namespace.d.ts.map +1 -0
  245. package/lib/typescript/src/native/index.d.ts +62 -0
  246. package/lib/typescript/src/native/index.d.ts.map +1 -0
  247. package/lib/typescript/src/provider.d.ts +37 -0
  248. package/lib/typescript/src/provider.d.ts.map +1 -0
  249. package/lib/typescript/src/specs/NativeWhopAddressSuggestions.d.ts +13 -0
  250. package/lib/typescript/src/specs/NativeWhopAddressSuggestions.d.ts.map +1 -0
  251. package/lib/typescript/src/specs/NativeWhopAuthSession.d.ts +20 -0
  252. package/lib/typescript/src/specs/NativeWhopAuthSession.d.ts.map +1 -0
  253. package/lib/typescript/src/specs/NativeWhopPlatformPay.d.ts +24 -0
  254. package/lib/typescript/src/specs/NativeWhopPlatformPay.d.ts.map +1 -0
  255. package/lib/typescript/src/specs/WhopPayButtonNativeComponent.d.ts +21 -0
  256. package/lib/typescript/src/specs/WhopPayButtonNativeComponent.d.ts.map +1 -0
  257. package/lib/typescript/src/theme/appearance.d.ts +71 -0
  258. package/lib/typescript/src/theme/appearance.d.ts.map +1 -0
  259. package/lib/typescript/src/theme/provider.d.ts +11 -0
  260. package/lib/typescript/src/theme/provider.d.ts.map +1 -0
  261. package/lib/typescript/src/theme/resolve.d.ts +19 -0
  262. package/lib/typescript/src/theme/resolve.d.ts.map +1 -0
  263. package/lib/typescript/src/theme/scales.generated.d.ts +18 -0
  264. package/lib/typescript/src/theme/scales.generated.d.ts.map +1 -0
  265. package/lib/typescript/src/ui/element-frame.d.ts +32 -0
  266. package/lib/typescript/src/ui/element-frame.d.ts.map +1 -0
  267. package/lib/typescript/src/ui/payment-method-icon.d.ts +21 -0
  268. package/lib/typescript/src/ui/payment-method-icon.d.ts.map +1 -0
  269. package/lib/typescript/src/ui/primitives.d.ts +94 -0
  270. package/lib/typescript/src/ui/primitives.d.ts.map +1 -0
  271. package/lib/typescript/src/ui/select.d.ts +25 -0
  272. package/lib/typescript/src/ui/select.d.ts.map +1 -0
  273. package/lib/typescript/src/ui/suggestions.d.ts +15 -0
  274. package/lib/typescript/src/ui/suggestions.d.ts.map +1 -0
  275. package/lib/typescript/src/ui/whop-logo.d.ts +4 -0
  276. package/lib/typescript/src/ui/whop-logo.d.ts.map +1 -0
  277. package/package.json +121 -0
  278. package/scripts/check-swift.sh +27 -0
  279. package/scripts/codegen-shims.mjs +409 -0
  280. package/scripts/gen-country-names.mjs +58 -0
  281. package/scripts/gen-theme.mjs +124 -0
  282. package/scripts/gen-wordmark.mjs +68 -0
  283. package/scripts/mirror.mjs +112 -0
  284. package/src/api/client.ts +202 -0
  285. package/src/api/types.ts +166 -0
  286. package/src/controller/actions.ts +197 -0
  287. package/src/controller/store.ts +201 -0
  288. package/src/core/address/country-data.ts +927 -0
  289. package/src/core/address/country-name.ts +36 -0
  290. package/src/core/address/country-names.generated.ts +246 -0
  291. package/src/core/address/engine.ts +349 -0
  292. package/src/core/address/form-state.ts +479 -0
  293. package/src/core/address/places.ts +39 -0
  294. package/src/core/address/suggest.ts +153 -0
  295. package/src/core/address/use-suggestions.ts +37 -0
  296. package/src/core/payments/address-change.ts +121 -0
  297. package/src/core/payments/billing-merge.ts +91 -0
  298. package/src/core/payments/browser-info.ts +43 -0
  299. package/src/core/payments/bt.ts +176 -0
  300. package/src/core/payments/currency.ts +54 -0
  301. package/src/core/payments/detail.ts +204 -0
  302. package/src/core/payments/errors.ts +171 -0
  303. package/src/core/payments/mint.ts +130 -0
  304. package/src/core/payments/plan.ts +198 -0
  305. package/src/core/payments/refusals.ts +24 -0
  306. package/src/core/payments/secure-fields.ts +85 -0
  307. package/src/core/payments/tax-id-catalog.ts +320 -0
  308. package/src/core/payments/wallet-contact.ts +56 -0
  309. package/src/elements/address.tsx +570 -0
  310. package/src/elements/branding.tsx +87 -0
  311. package/src/elements/card-fields/context.tsx +310 -0
  312. package/src/elements/card-fields/fields.tsx +281 -0
  313. package/src/elements/card-fields/index.tsx +37 -0
  314. package/src/elements/card.tsx +101 -0
  315. package/src/elements/email.tsx +100 -0
  316. package/src/elements/payment/declared-fields.tsx +238 -0
  317. package/src/elements/payment/index.tsx +497 -0
  318. package/src/elements/payment/wallet.tsx +155 -0
  319. package/src/elements/tax-id.tsx +143 -0
  320. package/src/i18n/catalogs.ts +100 -0
  321. package/src/i18n/index.tsx +46 -0
  322. package/src/index.ts +68 -0
  323. package/src/namespace.tsx +231 -0
  324. package/src/native/index.ts +173 -0
  325. package/src/provider.tsx +76 -0
  326. package/src/specs/NativeWhopAddressSuggestions.ts +14 -0
  327. package/src/specs/NativeWhopAuthSession.ts +21 -0
  328. package/src/specs/NativeWhopPlatformPay.ts +25 -0
  329. package/src/specs/WhopPayButtonNativeComponent.ts +22 -0
  330. package/src/theme/appearance.ts +150 -0
  331. package/src/theme/provider.tsx +28 -0
  332. package/src/theme/resolve.ts +68 -0
  333. package/src/theme/scales.generated.ts +427 -0
  334. package/src/ui/element-frame.tsx +94 -0
  335. package/src/ui/payment-method-icon.tsx +55 -0
  336. package/src/ui/primitives.tsx +269 -0
  337. package/src/ui/select.tsx +255 -0
  338. package/src/ui/suggestions.tsx +69 -0
  339. package/src/ui/whop-logo.tsx +37 -0
@@ -0,0 +1,36 @@
1
+ import { COUNTRY_NAMES_EN } from './country-names.generated';
2
+
3
+ /**
4
+ * Hermes ships no `Intl.DisplayNames`, and constructing it there throws
5
+ * "undefined cannot be used as a constructor" — so it is probed once rather than assumed.
6
+ *
7
+ * Where it exists the buyer gets names in their own locale; where it does not, the generated
8
+ * English table is the floor. The ISO code itself is the last resort, and only for a country the
9
+ * table does not carry.
10
+ */
11
+ function displayNamesFor(locale: string): Intl.DisplayNames | null {
12
+ try {
13
+ const ctor = (Intl as { DisplayNames?: new (l: string[], o: { type: string }) => Intl.DisplayNames })
14
+ .DisplayNames;
15
+ if (typeof ctor !== 'function') return null;
16
+ return new ctor([locale], { type: 'region' });
17
+ } catch {
18
+ return null;
19
+ }
20
+ }
21
+
22
+ const cache = new Map<string, Intl.DisplayNames | null>();
23
+
24
+ export function countryName(code: string, locale: string): string {
25
+ if (!cache.has(locale)) cache.set(locale, displayNamesFor(locale));
26
+ const display = cache.get(locale) ?? null;
27
+ if (display) {
28
+ try {
29
+ const name = display.of(code);
30
+ if (name && name !== code) return name;
31
+ } catch {
32
+ // a runtime that constructs but cannot resolve falls through to the table
33
+ }
34
+ }
35
+ return COUNTRY_NAMES_EN[code] ?? code;
36
+ }
@@ -0,0 +1,246 @@
1
+ // GENERATED by scripts/gen-country-names.mjs from Node's ICU. Run `pnpm country-names`.
2
+ //
3
+ // Hermes ships no Intl.DisplayNames, so this is the country selector's name source there.
4
+
5
+ export const COUNTRY_NAMES_EN: Record<string, string> = {
6
+ AD: "Andorra",
7
+ AE: "United Arab Emirates",
8
+ AF: "Afghanistan",
9
+ AG: "Antigua & Barbuda",
10
+ AI: "Anguilla",
11
+ AL: "Albania",
12
+ AM: "Armenia",
13
+ AN: "Curaçao",
14
+ AO: "Angola",
15
+ AQ: "Antarctica",
16
+ AR: "Argentina",
17
+ AS: "American Samoa",
18
+ AT: "Austria",
19
+ AU: "Australia",
20
+ AW: "Aruba",
21
+ AZ: "Azerbaijan",
22
+ BA: "Bosnia & Herzegovina",
23
+ BB: "Barbados",
24
+ BD: "Bangladesh",
25
+ BE: "Belgium",
26
+ BF: "Burkina Faso",
27
+ BG: "Bulgaria",
28
+ BH: "Bahrain",
29
+ BI: "Burundi",
30
+ BJ: "Benin",
31
+ BL: "St. Barthélemy",
32
+ BM: "Bermuda",
33
+ BN: "Brunei",
34
+ BO: "Bolivia",
35
+ BR: "Brazil",
36
+ BS: "Bahamas",
37
+ BT: "Bhutan",
38
+ BW: "Botswana",
39
+ BY: "Belarus",
40
+ BZ: "Belize",
41
+ CA: "Canada",
42
+ CC: "Cocos (Keeling) Islands",
43
+ CD: "Congo - Kinshasa",
44
+ CF: "Central African Republic",
45
+ CG: "Congo - Brazzaville",
46
+ CH: "Switzerland",
47
+ CI: "Côte d’Ivoire",
48
+ CK: "Cook Islands",
49
+ CL: "Chile",
50
+ CM: "Cameroon",
51
+ CN: "China",
52
+ CO: "Colombia",
53
+ CR: "Costa Rica",
54
+ CU: "Cuba",
55
+ CV: "Cape Verde",
56
+ CW: "Curaçao",
57
+ CX: "Christmas Island",
58
+ CY: "Cyprus",
59
+ CZ: "Czechia",
60
+ DE: "Germany",
61
+ DJ: "Djibouti",
62
+ DK: "Denmark",
63
+ DM: "Dominica",
64
+ DO: "Dominican Republic",
65
+ DZ: "Algeria",
66
+ EC: "Ecuador",
67
+ EE: "Estonia",
68
+ EG: "Egypt",
69
+ EH: "Western Sahara",
70
+ ES: "Spain",
71
+ ET: "Ethiopia",
72
+ FI: "Finland",
73
+ FJ: "Fiji",
74
+ FK: "Falkland Islands",
75
+ FM: "Micronesia",
76
+ FO: "Faroe Islands",
77
+ FR: "France",
78
+ GA: "Gabon",
79
+ GB: "United Kingdom",
80
+ GD: "Grenada",
81
+ GE: "Georgia",
82
+ GF: "French Guiana",
83
+ GG: "Guernsey",
84
+ GH: "Ghana",
85
+ GI: "Gibraltar",
86
+ GL: "Greenland",
87
+ GM: "Gambia",
88
+ GN: "Guinea",
89
+ GP: "Guadeloupe",
90
+ GQ: "Equatorial Guinea",
91
+ GR: "Greece",
92
+ GT: "Guatemala",
93
+ GU: "Guam",
94
+ GW: "Guinea-Bissau",
95
+ GY: "Guyana",
96
+ HK: "Hong Kong SAR China",
97
+ HN: "Honduras",
98
+ HR: "Croatia",
99
+ HT: "Haiti",
100
+ HU: "Hungary",
101
+ ID: "Indonesia",
102
+ IE: "Ireland",
103
+ IL: "Israel",
104
+ IM: "Isle of Man",
105
+ IN: "India",
106
+ IO: "British Indian Ocean Territory",
107
+ IQ: "Iraq",
108
+ IS: "Iceland",
109
+ IT: "Italy",
110
+ JE: "Jersey",
111
+ JM: "Jamaica",
112
+ JO: "Jordan",
113
+ JP: "Japan",
114
+ KE: "Kenya",
115
+ KG: "Kyrgyzstan",
116
+ KH: "Cambodia",
117
+ KI: "Kiribati",
118
+ KM: "Comoros",
119
+ KN: "St. Kitts & Nevis",
120
+ KR: "South Korea",
121
+ KW: "Kuwait",
122
+ KY: "Cayman Islands",
123
+ KZ: "Kazakhstan",
124
+ LA: "Laos",
125
+ LB: "Lebanon",
126
+ LC: "St. Lucia",
127
+ LI: "Liechtenstein",
128
+ LK: "Sri Lanka",
129
+ LR: "Liberia",
130
+ LS: "Lesotho",
131
+ LT: "Lithuania",
132
+ LU: "Luxembourg",
133
+ LV: "Latvia",
134
+ LY: "Libya",
135
+ MA: "Morocco",
136
+ MC: "Monaco",
137
+ MD: "Moldova",
138
+ ME: "Montenegro",
139
+ MF: "St. Martin",
140
+ MG: "Madagascar",
141
+ MH: "Marshall Islands",
142
+ MK: "North Macedonia",
143
+ ML: "Mali",
144
+ MM: "Myanmar (Burma)",
145
+ MN: "Mongolia",
146
+ MO: "Macao SAR China",
147
+ MP: "Northern Mariana Islands",
148
+ MQ: "Martinique",
149
+ MR: "Mauritania",
150
+ MS: "Montserrat",
151
+ MT: "Malta",
152
+ MU: "Mauritius",
153
+ MV: "Maldives",
154
+ MW: "Malawi",
155
+ MX: "Mexico",
156
+ MY: "Malaysia",
157
+ MZ: "Mozambique",
158
+ NA: "Namibia",
159
+ NC: "New Caledonia",
160
+ NE: "Niger",
161
+ NG: "Nigeria",
162
+ NI: "Nicaragua",
163
+ NL: "Netherlands",
164
+ NO: "Norway",
165
+ NP: "Nepal",
166
+ NR: "Nauru",
167
+ NU: "Niue",
168
+ NZ: "New Zealand",
169
+ OM: "Oman",
170
+ PA: "Panama",
171
+ PE: "Peru",
172
+ PF: "French Polynesia",
173
+ PG: "Papua New Guinea",
174
+ PH: "Philippines",
175
+ PK: "Pakistan",
176
+ PL: "Poland",
177
+ PM: "St. Pierre & Miquelon",
178
+ PN: "Pitcairn Islands",
179
+ PR: "Puerto Rico",
180
+ PS: "Palestinian Territories",
181
+ PT: "Portugal",
182
+ PW: "Palau",
183
+ PY: "Paraguay",
184
+ QA: "Qatar",
185
+ RE: "Réunion",
186
+ RO: "Romania",
187
+ RS: "Serbia",
188
+ RU: "Russia",
189
+ RW: "Rwanda",
190
+ SA: "Saudi Arabia",
191
+ SB: "Solomon Islands",
192
+ SC: "Seychelles",
193
+ SD: "Sudan",
194
+ SE: "Sweden",
195
+ SG: "Singapore",
196
+ SH: "St. Helena",
197
+ SI: "Slovenia",
198
+ SJ: "Svalbard & Jan Mayen",
199
+ SK: "Slovakia",
200
+ SL: "Sierra Leone",
201
+ SM: "San Marino",
202
+ SN: "Senegal",
203
+ SO: "Somalia",
204
+ SR: "Suriname",
205
+ SS: "South Sudan",
206
+ ST: "São Tomé & Príncipe",
207
+ SV: "El Salvador",
208
+ SX: "Sint Maarten",
209
+ SZ: "Eswatini",
210
+ TC: "Turks & Caicos Islands",
211
+ TD: "Chad",
212
+ TG: "Togo",
213
+ TH: "Thailand",
214
+ TJ: "Tajikistan",
215
+ TK: "Tokelau",
216
+ TL: "Timor-Leste",
217
+ TM: "Turkmenistan",
218
+ TN: "Tunisia",
219
+ TO: "Tonga",
220
+ TR: "Türkiye",
221
+ TT: "Trinidad & Tobago",
222
+ TV: "Tuvalu",
223
+ TW: "Taiwan",
224
+ TZ: "Tanzania",
225
+ UA: "Ukraine",
226
+ UG: "Uganda",
227
+ UM: "U.S. Outlying Islands",
228
+ US: "United States",
229
+ UY: "Uruguay",
230
+ UZ: "Uzbekistan",
231
+ VA: "Vatican City",
232
+ VC: "St. Vincent & Grenadines",
233
+ VE: "Venezuela",
234
+ VG: "British Virgin Islands",
235
+ VI: "U.S. Virgin Islands",
236
+ VN: "Vietnam",
237
+ VU: "Vanuatu",
238
+ WF: "Wallis & Futuna",
239
+ WS: "Samoa",
240
+ XK: "Kosovo",
241
+ YE: "Yemen",
242
+ YT: "Mayotte",
243
+ ZA: "South Africa",
244
+ ZM: "Zambia",
245
+ ZW: "Zimbabwe",
246
+ };
@@ -0,0 +1,349 @@
1
+ // ported from frontend/apps/web/src/elements/address-form/engine.ts — keep in sync when the web
2
+ // element changes. One React Native delta: loadCountryCatalog imports the dataset statically.
3
+
4
+ import COUNTRY_CATALOG from './country-data';
5
+
6
+ /**
7
+ * The Chromium libaddressinput format engine, ported AS DATA from the developer-platform
8
+ * address-form fork (parse-remote-country-data). Three deliberate fixes over the fork:
9
+ * - `zipRegex` is ENFORCED (validateAddressForm) — it was parsed-but-dead there;
10
+ * - per-country `upper` flags apply at EMIT (emitAddress), never scattered through the UI;
11
+ * - ISO2 is the ONE country boundary — uppercased once at the edge (normalizeCountry), and the
12
+ * subdivision iso codes read the dataset's real `sub_isoids` key (the fork read a
13
+ * `sub_iso_codes` field that never existed in the data).
14
+ */
15
+
16
+ export interface RemoteCountryData {
17
+ /** Field order + availability: %-prefixed tokens (%N %O %A %C %S %Z %D %X, %n = newline)
18
+ * mixed with literal text the postal service prints ("SE-", "SINGAPORE"). */
19
+ fmt?: string;
20
+ /** Latin variant of fmt for countries whose native script is non-latin. */
21
+ lfmt?: string;
22
+ /** Required-field flag characters (e.g. "ACSZ"). */
23
+ require?: string;
24
+ /** Fields the postal service expects uppercased (e.g. "CS"). */
25
+ upper?: string;
26
+ /** Country-level postal-code regex (unanchored in the dataset). */
27
+ zip?: string;
28
+ /** Example postal codes, comma-separated. */
29
+ zipex?: string;
30
+ zip_name_type?: string;
31
+ state_name_type?: string;
32
+ /** Subdivision keys / display names / latin names / iso codes, '~'-separated. */
33
+ sub_keys?: string;
34
+ sub_names?: string;
35
+ sub_lnames?: string;
36
+ sub_isoids?: string;
37
+ }
38
+
39
+ type FormatFieldType =
40
+ | 'name'
41
+ | 'organization'
42
+ | 'line1'
43
+ | 'city'
44
+ | 'state'
45
+ | 'postal_code'
46
+ | 'dependent_locality'
47
+ | 'sorting_code';
48
+
49
+ export interface StateOption {
50
+ key: string;
51
+ name: string;
52
+ iso?: string;
53
+ }
54
+
55
+ export interface FormatField {
56
+ type: FormatFieldType;
57
+ required: boolean;
58
+ upper: boolean;
59
+ postalPlaceholder?: string;
60
+ }
61
+
62
+ export interface CountryFormat {
63
+ country: string;
64
+ fields: FormatField[];
65
+ zipRegex?: string;
66
+ stateOptions: StateOption[];
67
+ stateLabel: StateLabelKind;
68
+ postalLabel: PostalLabelKind;
69
+ }
70
+
71
+ const FIELD_TYPE_BY_TOKEN: Partial<Record<string, FormatFieldType>> = {
72
+ N: 'name',
73
+ O: 'organization',
74
+ A: 'line1',
75
+ C: 'city',
76
+ S: 'state',
77
+ Z: 'postal_code',
78
+ D: 'dependent_locality',
79
+ X: 'sorting_code',
80
+ };
81
+
82
+ const STATE_LABELS = [
83
+ 'province',
84
+ 'state',
85
+ 'county',
86
+ 'area',
87
+ 'emirate',
88
+ 'island',
89
+ 'parish',
90
+ 'prefecture',
91
+ 'oblast',
92
+ 'department',
93
+ 'do_si',
94
+ ] as const;
95
+ export type StateLabelKind = (typeof STATE_LABELS)[number];
96
+
97
+ const POSTAL_LABELS = ['postal', 'zip', 'pin', 'eircode'] as const;
98
+ export type PostalLabelKind = (typeof POSTAL_LABELS)[number];
99
+
100
+ // Dataset gaps the fork patched: missing subdivisions, and a postal format AR does not use.
101
+ const COUNTRY_DATA_OVERRIDES: Record<string, RemoteCountryData | undefined> = {
102
+ AR: {
103
+ zip: '\\d{4}|[A-HJ-NP-Z]\\d{4}([A-Z]{3})?',
104
+ },
105
+ HN: {
106
+ sub_keys:
107
+ 'Atlántida~Choluteca~Colón~Comayagua~Copán~Cortés~El Paraíso~Francisco Morazán~Gracias a Dios~Intibucá~Islas de la Bahía~La Paz~Lempira~Ocotepeque~Olancho~Santa Bárbara~Valle~Yoro',
108
+ sub_names:
109
+ 'Atlántida~Choluteca~Colón~Comayagua~Copán~Cortés~El Paraíso~Francisco Morazán~Gracias a Dios~Intibucá~Islas de la Bahía~La Paz~Lempira~Ocotepeque~Olancho~Santa Bárbara~Valle~Yoro',
110
+ },
111
+ CR: {
112
+ sub_keys: 'Alajuela~Cartago~Guanacaste~Heredia~Limón~Puntarenas~San José',
113
+ sub_names: 'Alajuela~Cartago~Guanacaste~Heredia~Limón~Puntarenas~San José',
114
+ },
115
+ // English names ordered to the dataset's KEPT sub_isoids (AN~BU~…~QR~…~TK~TO~XO) — the
116
+ // override replaces keys/names only, so its order must match the iso column it rides with.
117
+ UZ: {
118
+ sub_keys:
119
+ 'Andijan Region~Bukhara Region~Fergana Region~Jizzakh Region~Namangan Region~Navoiy Region~Qashqadaryo Region~Karakalpakstan~Samarqand Region~Sirdaryo Region~Surxondaryo Region~Tashkent~Tashkent Region~Xorazm Region',
120
+ sub_names:
121
+ 'Andijan Region~Bukhara Region~Fergana Region~Jizzakh Region~Namangan Region~Navoiy Region~Qashqadaryo Region~Karakalpakstan~Samarqand Region~Sirdaryo Region~Surxondaryo Region~Tashkent~Tashkent Region~Xorazm Region',
122
+ },
123
+ };
124
+
125
+ export function normalizeCountry(code: string | undefined): string | undefined {
126
+ const upper = code?.trim().toUpperCase();
127
+ return upper && /^[A-Z]{2}$/.test(upper) ? upper : undefined;
128
+ }
129
+
130
+ function parseStateOptions(data: RemoteCountryData): StateOption[] {
131
+ const keys = data.sub_keys?.split('~') ?? [];
132
+ const names = data.sub_names?.split('~') ?? [];
133
+ const latinNames = data.sub_lnames?.split('~') ?? [];
134
+ const isoCodes = data.sub_isoids?.split('~') ?? [];
135
+ const options: StateOption[] = [];
136
+ for (let i = 0; i < keys.length; i++) {
137
+ const key = keys[i];
138
+ if (!key) continue;
139
+ options.push({
140
+ key,
141
+ name: [names[i] || key, latinNames[i]].filter(Boolean).join(' — '),
142
+ iso: isoCodes[i] || undefined,
143
+ });
144
+ }
145
+ return options;
146
+ }
147
+
148
+ export function parseCountryFormat(countryCode: string, rawData: RemoteCountryData | undefined): CountryFormat {
149
+ const country = normalizeCountry(countryCode) ?? 'ZZ';
150
+ const data = { ...rawData, ...COUNTRY_DATA_OVERRIDES[country] };
151
+ const format = data.lfmt ?? data.fmt;
152
+ const stateLabel =
153
+ data.state_name_type && (STATE_LABELS as readonly string[]).includes(data.state_name_type)
154
+ ? (data.state_name_type as StateLabelKind)
155
+ : 'province';
156
+ const postalLabel =
157
+ data.zip_name_type && (POSTAL_LABELS as readonly string[]).includes(data.zip_name_type)
158
+ ? (data.zip_name_type as PostalLabelKind)
159
+ : 'postal';
160
+
161
+ if (!format) {
162
+ return {
163
+ country,
164
+ fields: [
165
+ { type: 'line1', required: true, upper: false },
166
+ { type: 'postal_code', required: false, upper: false },
167
+ { type: 'city', required: false, upper: false },
168
+ ],
169
+ zipRegex: data.zip,
170
+ stateOptions: [],
171
+ stateLabel,
172
+ postalLabel,
173
+ };
174
+ }
175
+
176
+ const fields: FormatField[] = [];
177
+ for (let i = 0; i < format.length; i++) {
178
+ // Only %-prefixed chars are field tokens; bare letters are literal print text ("SE-",
179
+ // "SINGAPORE") — reading them as tokens minted spurious state fields for SE/SG/GG.
180
+ if (format[i] !== '%') continue;
181
+ i += 1;
182
+ const token = format[i] ?? '';
183
+ const fieldType = FIELD_TYPE_BY_TOKEN[token];
184
+ if (!fieldType || fields.some((field) => field.type === fieldType)) continue;
185
+ fields.push({
186
+ type: fieldType,
187
+ required: data.require?.includes(token) ?? false,
188
+ upper: data.upper?.includes(token) ?? false,
189
+ postalPlaceholder: fieldType === 'postal_code' ? data.zipex?.split(',')[0] : undefined,
190
+ });
191
+ }
192
+ return {
193
+ country,
194
+ fields,
195
+ zipRegex: data.zip,
196
+ stateOptions: fields.some((field) => field.type === 'state') ? parseStateOptions(data) : [],
197
+ stateLabel,
198
+ postalLabel,
199
+ };
200
+ }
201
+
202
+ /**
203
+ * Statically imported, unlike the web element's lazy chunk.
204
+ *
205
+ * Metro produces one bundle with no async chunks, so a dynamic `import()` fails at runtime with
206
+ * "Could not load bundle". Nothing is saved by deferring it either: the data ships in the bundle
207
+ * either way.
208
+ */
209
+ export function loadCountryCatalog(): Promise<Record<string, RemoteCountryData>> {
210
+ return Promise.resolve(COUNTRY_CATALOG);
211
+ }
212
+
213
+ export function postalCodeMatches(zipRegex: string | undefined, value: string): boolean {
214
+ if (!zipRegex || !value) return true;
215
+ try {
216
+ return new RegExp(`^(?:${zipRegex})$`, 'i').test(value);
217
+ } catch {
218
+ return true;
219
+ }
220
+ }
221
+
222
+ export interface EmittedAddress {
223
+ name?: string;
224
+ first_name?: string;
225
+ last_name?: string;
226
+ organization?: string;
227
+ organization_type?: 'business' | 'individual';
228
+ line1?: string;
229
+ line2?: string;
230
+ city?: string;
231
+ state?: string;
232
+ postal_code?: string;
233
+ country: string;
234
+ }
235
+
236
+ type UppercasableKey = 'name' | 'organization' | 'line1' | 'city' | 'state' | 'postal_code';
237
+
238
+ const UPPER_KEY_BY_FIELD: Partial<Record<FormatFieldType, UppercasableKey>> = {
239
+ name: 'name',
240
+ organization: 'organization',
241
+ line1: 'line1',
242
+ city: 'city',
243
+ state: 'state',
244
+ postal_code: 'postal_code',
245
+ };
246
+
247
+ /** The ONE emit boundary: trims, applies the country's upper flags, uppercases ISO2, and maps
248
+ * internal values onto the frozen contract keys (postal_code naming matches ctok
249
+ * billing_details 1:1). Empty values are dropped except the always-present country. */
250
+ export function emitAddress(
251
+ format: CountryFormat,
252
+ values: {
253
+ name?: string;
254
+ first_name?: string;
255
+ last_name?: string;
256
+ organization?: string;
257
+ organization_type?: 'business' | 'individual' | '';
258
+ line1?: string;
259
+ line2?: string;
260
+ city?: string;
261
+ state?: string;
262
+ postal_code?: string;
263
+ },
264
+ ): EmittedAddress {
265
+ const out: EmittedAddress = { country: format.country };
266
+ const put = (key: Exclude<keyof EmittedAddress, 'country' | 'organization_type'>, raw: string | undefined) => {
267
+ const value = raw?.trim();
268
+ if (value) out[key] = value;
269
+ };
270
+ put('name', values.name);
271
+ put('first_name', values.first_name);
272
+ put('last_name', values.last_name);
273
+ put('organization', values.organization);
274
+ put('line1', values.line1);
275
+ put('line2', values.line2);
276
+ put('city', values.city);
277
+ put('state', values.state);
278
+ put('postal_code', values.postal_code);
279
+ if (out.organization && (values.organization_type === 'business' || values.organization_type === 'individual')) {
280
+ out.organization_type = values.organization_type;
281
+ }
282
+ for (const field of format.fields) {
283
+ const key = field.upper ? UPPER_KEY_BY_FIELD[field.type] : undefined;
284
+ const value = key ? out[key] : undefined;
285
+ if (key && value) out[key] = value.toUpperCase();
286
+ }
287
+ if (format.fields.some((field) => field.type === 'name' && field.upper)) {
288
+ if (out.first_name) out.first_name = out.first_name.toUpperCase();
289
+ if (out.last_name) out.last_name = out.last_name.toUpperCase();
290
+ }
291
+ return out;
292
+ }
293
+
294
+ /** Single-country currencies → the country, for the detect-country fallback chain
295
+ * (defaultValues > IP country > this > US). Multi-country currencies (eur, xof, …) stay out. */
296
+ const CURRENCY_COUNTRY: Record<string, string> = {
297
+ usd: 'US',
298
+ gbp: 'GB',
299
+ cad: 'CA',
300
+ aud: 'AU',
301
+ nzd: 'NZ',
302
+ jpy: 'JP',
303
+ brl: 'BR',
304
+ mxn: 'MX',
305
+ inr: 'IN',
306
+ pln: 'PL',
307
+ chf: 'CH',
308
+ sek: 'SE',
309
+ nok: 'NO',
310
+ dkk: 'DK',
311
+ czk: 'CZ',
312
+ huf: 'HU',
313
+ ron: 'RO',
314
+ bgn: 'BG',
315
+ try: 'TR',
316
+ uah: 'UA',
317
+ ils: 'IL',
318
+ aed: 'AE',
319
+ sar: 'SA',
320
+ qar: 'QA',
321
+ kwd: 'KW',
322
+ zar: 'ZA',
323
+ ngn: 'NG',
324
+ kes: 'KE',
325
+ egp: 'EG',
326
+ mad: 'MA',
327
+ sgd: 'SG',
328
+ hkd: 'HK',
329
+ twd: 'TW',
330
+ krw: 'KR',
331
+ thb: 'TH',
332
+ php: 'PH',
333
+ idr: 'ID',
334
+ myr: 'MY',
335
+ vnd: 'VN',
336
+ pkr: 'PK',
337
+ bdt: 'BD',
338
+ lkr: 'LK',
339
+ clp: 'CL',
340
+ cop: 'CO',
341
+ pen: 'PE',
342
+ ars: 'AR',
343
+ uyu: 'UY',
344
+ isk: 'IS',
345
+ };
346
+
347
+ export function currencyCountry(currency: string | undefined): string | undefined {
348
+ return currency ? CURRENCY_COUNTRY[currency.toLowerCase()] : undefined;
349
+ }