n2words 2.0.0 → 3.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 (335) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +86 -188
  3. package/dist/languages/am-Latn.js +3 -0
  4. package/dist/languages/am-Latn.js.map +1 -0
  5. package/dist/languages/am.js +3 -0
  6. package/dist/languages/am.js.map +1 -0
  7. package/dist/languages/ar.js +3 -0
  8. package/dist/languages/ar.js.map +1 -0
  9. package/dist/languages/az.js +3 -0
  10. package/dist/languages/az.js.map +1 -0
  11. package/dist/languages/bn.js +3 -0
  12. package/dist/languages/bn.js.map +1 -0
  13. package/dist/languages/cs.js +3 -0
  14. package/dist/languages/cs.js.map +1 -0
  15. package/dist/languages/da.js +3 -0
  16. package/dist/languages/da.js.map +1 -0
  17. package/dist/languages/de.js +3 -0
  18. package/dist/languages/de.js.map +1 -0
  19. package/dist/languages/el.js +3 -0
  20. package/dist/languages/el.js.map +1 -0
  21. package/dist/languages/en.js +3 -0
  22. package/dist/languages/en.js.map +1 -0
  23. package/dist/languages/es.js +3 -0
  24. package/dist/languages/es.js.map +1 -0
  25. package/dist/languages/fa.js +3 -0
  26. package/dist/languages/fa.js.map +1 -0
  27. package/dist/languages/fi.js +3 -0
  28. package/dist/languages/fi.js.map +1 -0
  29. package/dist/languages/fil.js +3 -0
  30. package/dist/languages/fil.js.map +1 -0
  31. package/dist/languages/fr-BE.js +3 -0
  32. package/dist/languages/fr-BE.js.map +1 -0
  33. package/dist/languages/fr.js +3 -0
  34. package/dist/languages/fr.js.map +1 -0
  35. package/dist/languages/gu.js +3 -0
  36. package/dist/languages/gu.js.map +1 -0
  37. package/dist/languages/ha.js +3 -0
  38. package/dist/languages/ha.js.map +1 -0
  39. package/dist/languages/hbo.js +3 -0
  40. package/dist/languages/hbo.js.map +1 -0
  41. package/dist/languages/he.js +3 -0
  42. package/dist/languages/he.js.map +1 -0
  43. package/dist/languages/hi.js +3 -0
  44. package/dist/languages/hi.js.map +1 -0
  45. package/dist/languages/hr.js +3 -0
  46. package/dist/languages/hr.js.map +1 -0
  47. package/dist/languages/hu.js +3 -0
  48. package/dist/languages/hu.js.map +1 -0
  49. package/dist/languages/id.js +3 -0
  50. package/dist/languages/id.js.map +1 -0
  51. package/dist/languages/it.js +3 -0
  52. package/dist/languages/it.js.map +1 -0
  53. package/dist/languages/ja.js +3 -0
  54. package/dist/languages/ja.js.map +1 -0
  55. package/dist/languages/ka.js +3 -0
  56. package/dist/languages/ka.js.map +1 -0
  57. package/dist/languages/kn.js +3 -0
  58. package/dist/languages/kn.js.map +1 -0
  59. package/dist/languages/ko.js +3 -0
  60. package/dist/languages/ko.js.map +1 -0
  61. package/dist/languages/lt.js +3 -0
  62. package/dist/languages/lt.js.map +1 -0
  63. package/dist/languages/lv.js +3 -0
  64. package/dist/languages/lv.js.map +1 -0
  65. package/dist/languages/mr.js +3 -0
  66. package/dist/languages/mr.js.map +1 -0
  67. package/dist/languages/ms.js +3 -0
  68. package/dist/languages/ms.js.map +1 -0
  69. package/dist/languages/nb.js +3 -0
  70. package/dist/languages/nb.js.map +1 -0
  71. package/dist/languages/nl.js +3 -0
  72. package/dist/languages/nl.js.map +1 -0
  73. package/dist/languages/pa.js +3 -0
  74. package/dist/languages/pa.js.map +1 -0
  75. package/dist/languages/pl.js +3 -0
  76. package/dist/languages/pl.js.map +1 -0
  77. package/dist/languages/pt.js +3 -0
  78. package/dist/languages/pt.js.map +1 -0
  79. package/dist/languages/ro.js +3 -0
  80. package/dist/languages/ro.js.map +1 -0
  81. package/dist/languages/ru.js +3 -0
  82. package/dist/languages/ru.js.map +1 -0
  83. package/dist/languages/sr-Cyrl.js +3 -0
  84. package/dist/languages/sr-Cyrl.js.map +1 -0
  85. package/dist/languages/sr-Latn.js +3 -0
  86. package/dist/languages/sr-Latn.js.map +1 -0
  87. package/dist/languages/sv.js +3 -0
  88. package/dist/languages/sv.js.map +1 -0
  89. package/dist/languages/sw.js +3 -0
  90. package/dist/languages/sw.js.map +1 -0
  91. package/dist/languages/ta.js +3 -0
  92. package/dist/languages/ta.js.map +1 -0
  93. package/dist/languages/te.js +3 -0
  94. package/dist/languages/te.js.map +1 -0
  95. package/dist/languages/th.js +3 -0
  96. package/dist/languages/th.js.map +1 -0
  97. package/dist/languages/tr.js +3 -0
  98. package/dist/languages/tr.js.map +1 -0
  99. package/dist/languages/uk.js +3 -0
  100. package/dist/languages/uk.js.map +1 -0
  101. package/dist/languages/ur.js +3 -0
  102. package/dist/languages/ur.js.map +1 -0
  103. package/dist/languages/vi.js +3 -0
  104. package/dist/languages/vi.js.map +1 -0
  105. package/dist/languages/yo.js +3 -0
  106. package/dist/languages/yo.js.map +1 -0
  107. package/dist/languages/zh-Hans.js +3 -0
  108. package/dist/languages/zh-Hans.js.map +1 -0
  109. package/dist/languages/zh-Hant.js +3 -0
  110. package/dist/languages/zh-Hant.js.map +1 -0
  111. package/dist/n2words.js +2 -2
  112. package/dist/n2words.js.map +1 -1
  113. package/lib/languages/am-Latn.d.ts +7 -0
  114. package/lib/languages/am-Latn.js +159 -0
  115. package/lib/languages/am.d.ts +7 -0
  116. package/lib/languages/am.js +159 -0
  117. package/lib/languages/ar.d.ts +14 -27
  118. package/lib/languages/ar.js +175 -129
  119. package/lib/languages/az.d.ts +4 -9
  120. package/lib/languages/az.js +166 -37
  121. package/lib/languages/bn.d.ts +4 -8
  122. package/lib/languages/bn.js +159 -124
  123. package/lib/languages/cs.d.ts +15 -85
  124. package/lib/languages/cs.js +293 -114
  125. package/lib/languages/da.d.ts +11 -12
  126. package/lib/languages/da.js +269 -101
  127. package/lib/languages/de.d.ts +14 -11
  128. package/lib/languages/de.js +305 -86
  129. package/lib/languages/el.d.ts +11 -11
  130. package/lib/languages/el.js +224 -78
  131. package/lib/languages/en.d.ts +14 -13
  132. package/lib/languages/en.js +228 -72
  133. package/lib/languages/es.d.ts +18 -12
  134. package/lib/languages/es.js +297 -103
  135. package/lib/languages/fa.d.ts +4 -44
  136. package/lib/languages/fa.js +112 -122
  137. package/lib/languages/fi.d.ts +14 -0
  138. package/lib/languages/fi.js +238 -0
  139. package/lib/languages/fil.d.ts +4 -13
  140. package/lib/languages/fil.js +196 -106
  141. package/lib/languages/fr-BE.d.ts +8 -8
  142. package/lib/languages/fr-BE.js +285 -19
  143. package/lib/languages/fr.d.ts +18 -12
  144. package/lib/languages/fr.js +339 -89
  145. package/lib/languages/gu.d.ts +4 -8
  146. package/lib/languages/gu.js +143 -125
  147. package/lib/languages/ha.d.ts +7 -0
  148. package/lib/languages/ha.js +225 -0
  149. package/lib/languages/hbo.d.ts +10 -110
  150. package/lib/languages/hbo.js +245 -214
  151. package/lib/languages/he.d.ts +10 -77
  152. package/lib/languages/he.js +231 -172
  153. package/lib/languages/hi.d.ts +4 -8
  154. package/lib/languages/hi.js +163 -124
  155. package/lib/languages/hr.d.ts +8 -77
  156. package/lib/languages/hr.js +200 -89
  157. package/lib/languages/hu.d.ts +4 -19
  158. package/lib/languages/hu.js +198 -119
  159. package/lib/languages/id.d.ts +4 -34
  160. package/lib/languages/id.js +166 -129
  161. package/lib/languages/it.d.ts +16 -34
  162. package/lib/languages/it.js +307 -97
  163. package/lib/languages/ja.d.ts +14 -14
  164. package/lib/languages/ja.js +221 -111
  165. package/lib/languages/ka.d.ts +17 -0
  166. package/lib/languages/ka.js +291 -0
  167. package/lib/languages/kn.d.ts +4 -8
  168. package/lib/languages/kn.js +143 -35
  169. package/lib/languages/ko.d.ts +11 -11
  170. package/lib/languages/ko.js +250 -49
  171. package/lib/languages/lt.d.ts +15 -67
  172. package/lib/languages/lt.js +287 -122
  173. package/lib/languages/lv.d.ts +15 -67
  174. package/lib/languages/lv.js +288 -106
  175. package/lib/languages/mr.d.ts +4 -8
  176. package/lib/languages/mr.js +143 -125
  177. package/lib/languages/ms.d.ts +4 -28
  178. package/lib/languages/ms.js +166 -116
  179. package/lib/languages/nb.d.ts +11 -9
  180. package/lib/languages/nb.js +272 -87
  181. package/lib/languages/nl.d.ts +23 -13
  182. package/lib/languages/nl.js +299 -133
  183. package/lib/languages/pa.d.ts +4 -8
  184. package/lib/languages/pa.js +151 -124
  185. package/lib/languages/pl.d.ts +19 -77
  186. package/lib/languages/pl.js +294 -87
  187. package/lib/languages/pt.d.ts +14 -26
  188. package/lib/languages/pt.js +272 -92
  189. package/lib/languages/ro.d.ts +15 -155
  190. package/lib/languages/ro.js +219 -235
  191. package/lib/languages/ru.d.ts +8 -82
  192. package/lib/languages/ru.js +239 -90
  193. package/lib/languages/sr-Cyrl.d.ts +8 -77
  194. package/lib/languages/sr-Cyrl.js +197 -89
  195. package/lib/languages/sr-Latn.d.ts +8 -77
  196. package/lib/languages/sr-Latn.js +197 -89
  197. package/lib/languages/sv.d.ts +11 -11
  198. package/lib/languages/sv.js +278 -74
  199. package/lib/languages/sw.d.ts +4 -36
  200. package/lib/languages/sw.js +133 -106
  201. package/lib/languages/ta.d.ts +4 -17
  202. package/lib/languages/ta.js +143 -202
  203. package/lib/languages/te.d.ts +4 -19
  204. package/lib/languages/te.js +133 -196
  205. package/lib/languages/th.d.ts +4 -14
  206. package/lib/languages/th.js +135 -91
  207. package/lib/languages/tr.d.ts +15 -9
  208. package/lib/languages/tr.js +245 -49
  209. package/lib/languages/uk.d.ts +8 -82
  210. package/lib/languages/uk.js +206 -78
  211. package/lib/languages/ur.d.ts +4 -8
  212. package/lib/languages/ur.js +151 -124
  213. package/lib/languages/vi.d.ts +14 -69
  214. package/lib/languages/vi.js +278 -129
  215. package/lib/languages/yo.d.ts +7 -0
  216. package/lib/languages/yo.js +303 -0
  217. package/lib/languages/zh-Hans.d.ts +8 -18
  218. package/lib/languages/zh-Hans.js +163 -92
  219. package/lib/languages/zh-Hant.d.ts +8 -18
  220. package/lib/languages/zh-Hant.js +181 -90
  221. package/lib/n2words.d.ts +55 -209
  222. package/lib/n2words.js +115 -530
  223. package/lib/utils/is-plain-object.d.ts +13 -0
  224. package/lib/utils/is-plain-object.js +17 -0
  225. package/lib/utils/parse-numeric.d.ts +17 -0
  226. package/lib/utils/parse-numeric.js +108 -0
  227. package/lib/utils/validate-options.d.ts +8 -0
  228. package/lib/utils/validate-options.js +16 -0
  229. package/package.json +26 -14
  230. package/dist/ArabicConverter.js +0 -3
  231. package/dist/ArabicConverter.js.map +0 -1
  232. package/dist/AzerbaijaniConverter.js +0 -3
  233. package/dist/AzerbaijaniConverter.js.map +0 -1
  234. package/dist/BanglaConverter.js +0 -3
  235. package/dist/BanglaConverter.js.map +0 -1
  236. package/dist/BiblicalHebrewConverter.js +0 -3
  237. package/dist/BiblicalHebrewConverter.js.map +0 -1
  238. package/dist/CroatianConverter.js +0 -3
  239. package/dist/CroatianConverter.js.map +0 -1
  240. package/dist/CzechConverter.js +0 -3
  241. package/dist/CzechConverter.js.map +0 -1
  242. package/dist/DanishConverter.js +0 -3
  243. package/dist/DanishConverter.js.map +0 -1
  244. package/dist/DutchConverter.js +0 -3
  245. package/dist/DutchConverter.js.map +0 -1
  246. package/dist/EnglishConverter.js +0 -3
  247. package/dist/EnglishConverter.js.map +0 -1
  248. package/dist/FilipinoConverter.js +0 -3
  249. package/dist/FilipinoConverter.js.map +0 -1
  250. package/dist/FrenchBelgiumConverter.js +0 -3
  251. package/dist/FrenchBelgiumConverter.js.map +0 -1
  252. package/dist/FrenchConverter.js +0 -3
  253. package/dist/FrenchConverter.js.map +0 -1
  254. package/dist/GermanConverter.js +0 -3
  255. package/dist/GermanConverter.js.map +0 -1
  256. package/dist/GreekConverter.js +0 -3
  257. package/dist/GreekConverter.js.map +0 -1
  258. package/dist/GujaratiConverter.js +0 -3
  259. package/dist/GujaratiConverter.js.map +0 -1
  260. package/dist/HebrewConverter.js +0 -3
  261. package/dist/HebrewConverter.js.map +0 -1
  262. package/dist/HindiConverter.js +0 -3
  263. package/dist/HindiConverter.js.map +0 -1
  264. package/dist/HungarianConverter.js +0 -3
  265. package/dist/HungarianConverter.js.map +0 -1
  266. package/dist/IndonesianConverter.js +0 -3
  267. package/dist/IndonesianConverter.js.map +0 -1
  268. package/dist/ItalianConverter.js +0 -3
  269. package/dist/ItalianConverter.js.map +0 -1
  270. package/dist/JapaneseConverter.js +0 -3
  271. package/dist/JapaneseConverter.js.map +0 -1
  272. package/dist/KannadaConverter.js +0 -3
  273. package/dist/KannadaConverter.js.map +0 -1
  274. package/dist/KoreanConverter.js +0 -3
  275. package/dist/KoreanConverter.js.map +0 -1
  276. package/dist/LatvianConverter.js +0 -3
  277. package/dist/LatvianConverter.js.map +0 -1
  278. package/dist/LithuanianConverter.js +0 -3
  279. package/dist/LithuanianConverter.js.map +0 -1
  280. package/dist/MalayConverter.js +0 -3
  281. package/dist/MalayConverter.js.map +0 -1
  282. package/dist/MarathiConverter.js +0 -3
  283. package/dist/MarathiConverter.js.map +0 -1
  284. package/dist/NorwegianBokmalConverter.js +0 -3
  285. package/dist/NorwegianBokmalConverter.js.map +0 -1
  286. package/dist/PersianConverter.js +0 -3
  287. package/dist/PersianConverter.js.map +0 -1
  288. package/dist/PolishConverter.js +0 -3
  289. package/dist/PolishConverter.js.map +0 -1
  290. package/dist/PortugueseConverter.js +0 -3
  291. package/dist/PortugueseConverter.js.map +0 -1
  292. package/dist/PunjabiConverter.js +0 -3
  293. package/dist/PunjabiConverter.js.map +0 -1
  294. package/dist/RomanianConverter.js +0 -3
  295. package/dist/RomanianConverter.js.map +0 -1
  296. package/dist/RussianConverter.js +0 -3
  297. package/dist/RussianConverter.js.map +0 -1
  298. package/dist/SerbianCyrillicConverter.js +0 -3
  299. package/dist/SerbianCyrillicConverter.js.map +0 -1
  300. package/dist/SerbianLatinConverter.js +0 -3
  301. package/dist/SerbianLatinConverter.js.map +0 -1
  302. package/dist/SimplifiedChineseConverter.js +0 -3
  303. package/dist/SimplifiedChineseConverter.js.map +0 -1
  304. package/dist/SpanishConverter.js +0 -3
  305. package/dist/SpanishConverter.js.map +0 -1
  306. package/dist/SwahiliConverter.js +0 -3
  307. package/dist/SwahiliConverter.js.map +0 -1
  308. package/dist/SwedishConverter.js +0 -3
  309. package/dist/SwedishConverter.js.map +0 -1
  310. package/dist/TamilConverter.js +0 -3
  311. package/dist/TamilConverter.js.map +0 -1
  312. package/dist/TeluguConverter.js +0 -3
  313. package/dist/TeluguConverter.js.map +0 -1
  314. package/dist/ThaiConverter.js +0 -3
  315. package/dist/ThaiConverter.js.map +0 -1
  316. package/dist/TraditionalChineseConverter.js +0 -3
  317. package/dist/TraditionalChineseConverter.js.map +0 -1
  318. package/dist/TurkishConverter.js +0 -3
  319. package/dist/TurkishConverter.js.map +0 -1
  320. package/dist/UkrainianConverter.js +0 -3
  321. package/dist/UkrainianConverter.js.map +0 -1
  322. package/dist/UrduConverter.js +0 -3
  323. package/dist/UrduConverter.js.map +0 -1
  324. package/dist/VietnameseConverter.js +0 -3
  325. package/dist/VietnameseConverter.js.map +0 -1
  326. package/lib/classes/abstract-language.d.ts +0 -178
  327. package/lib/classes/abstract-language.js +0 -268
  328. package/lib/classes/greedy-scale-language.d.ts +0 -109
  329. package/lib/classes/greedy-scale-language.js +0 -201
  330. package/lib/classes/slavic-language.d.ts +0 -148
  331. package/lib/classes/slavic-language.js +0 -281
  332. package/lib/classes/south-asian-language.d.ts +0 -70
  333. package/lib/classes/south-asian-language.js +0 -154
  334. package/lib/classes/turkic-language.d.ts +0 -26
  335. package/lib/classes/turkic-language.js +0 -59
package/lib/n2words.js CHANGED
@@ -1,541 +1,126 @@
1
1
  /**
2
- * n2words - Convert numbers to words in multiple languages
2
+ * n2words - Number to words converter
3
3
  *
4
- * This file is the main entry point for the n2words library.
5
- * It exports converter functions for all supported languages.
4
+ * This module re-exports all language converters as named exports.
5
+ * Each export is a `toWords(value, options?)` function.
6
6
  *
7
- * ## For Contributors
7
+ * Export names use normalized BCP 47 codes (hyphens → camelCase):
8
+ * - `en`, `fr`, `de` (simple codes unchanged)
9
+ * - `zhHans` (zh-Hans), `frBE` (fr-BE), `srCyrl` (sr-Cyrl)
8
10
  *
9
- * When adding a new language, this file must be updated in THREE sections:
10
- * 1. Language Imports - Add import statement (alphabetically sorted)
11
- * 2. Language Converters - Create converter with makeConverter() (alphabetically sorted)
12
- * 3. Exports - Add to export list (alphabetically sorted)
13
- *
14
- * Use the scaffolding tool to automate this process:
15
- * npm run lang:add <language-code>
16
- *
17
- * ## Public API Structure
18
- *
19
- * Each language exports a converter function:
20
- * - Name: `{LanguageName}Converter` (e.g., EnglishConverter, SpanishConverter)
21
- * - Signature: `(value: NumericValue, options?: Options) => string`
22
- * - Input: number, bigint, or string (numeric strings only)
23
- * - Output: Words representing the number in the target language
24
- *
25
- * Languages without options use signature: `(value: NumericValue) => string`
26
- * Languages with options define a typedef (e.g., ArabicOptions) and use: `(value: NumericValue, options?: ArabicOptions) => string`
11
+ * Imports and exports are alphabetically sorted by normalized name.
27
12
  *
28
13
  * @module n2words
29
14
  */
30
15
 
31
- // ============================================================================
32
- // Language Imports
33
- // ============================================================================
34
-
35
- import { Arabic } from './languages/ar.js'
36
- import { Azerbaijani } from './languages/az.js'
37
- import { Bangla } from './languages/bn.js'
38
- import { Czech } from './languages/cs.js'
39
- import { Danish } from './languages/da.js'
40
- import { German } from './languages/de.js'
41
- import { Greek } from './languages/el.js'
42
- import { English } from './languages/en.js'
43
- import { Spanish } from './languages/es.js'
44
- import { Persian } from './languages/fa.js'
45
- import { Filipino } from './languages/fil.js'
46
- import { French } from './languages/fr.js'
47
- import { FrenchBelgium } from './languages/fr-BE.js'
48
- import { Gujarati } from './languages/gu.js'
49
- import { Hebrew } from './languages/he.js'
50
- import { BiblicalHebrew } from './languages/hbo.js'
51
- import { Hindi } from './languages/hi.js'
52
- import { Croatian } from './languages/hr.js'
53
- import { Hungarian } from './languages/hu.js'
54
- import { Indonesian } from './languages/id.js'
55
- import { Italian } from './languages/it.js'
56
- import { Japanese } from './languages/ja.js'
57
- import { Kannada } from './languages/kn.js'
58
- import { Korean } from './languages/ko.js'
59
- import { Lithuanian } from './languages/lt.js'
60
- import { Latvian } from './languages/lv.js'
61
- import { Marathi } from './languages/mr.js'
62
- import { Malay } from './languages/ms.js'
63
- import { Dutch } from './languages/nl.js'
64
- import { NorwegianBokmal } from './languages/nb.js'
65
- import { Punjabi } from './languages/pa.js'
66
- import { Polish } from './languages/pl.js'
67
- import { Portuguese } from './languages/pt.js'
68
- import { Romanian } from './languages/ro.js'
69
- import { Russian } from './languages/ru.js'
70
- import { SerbianCyrillic } from './languages/sr-Cyrl.js'
71
- import { SerbianLatin } from './languages/sr-Latn.js'
72
- import { Swedish } from './languages/sv.js'
73
- import { Swahili } from './languages/sw.js'
74
- import { Tamil } from './languages/ta.js'
75
- import { Telugu } from './languages/te.js'
76
- import { Thai } from './languages/th.js'
77
- import { Turkish } from './languages/tr.js'
78
- import { Ukrainian } from './languages/uk.js'
79
- import { Urdu } from './languages/ur.js'
80
- import { Vietnamese } from './languages/vi.js'
81
- import { SimplifiedChinese } from './languages/zh-Hans.js'
82
- import { TraditionalChinese } from './languages/zh-Hant.js'
83
-
84
- // ============================================================================
85
- // Type Definitions
86
- // ============================================================================
87
- //
88
- // This section defines TypeScript-compatible JSDoc types for:
89
- // - NumericValue: The input types accepted by all converters
90
- // - {Language}Options: Optional configuration for languages that support it
91
- //
92
- // Keep options typedefs alphabetically sorted for maintainability.
93
- // ============================================================================
94
-
95
- /**
96
- * Numeric value that can be converted to words.
97
- * Accepts number, bigint, or numeric string representations.
98
- * @typedef {number | bigint | string} NumericValue
99
- */
100
-
101
- /**
102
- * @typedef {Object} ArabicOptions
103
- * @property {string} [negativeWord] Word for negative numbers
104
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
105
- */
106
-
107
- /**
108
- * @typedef {Object} BiblicalHebrewOptions
109
- * @property {string} [andWord='ו'] Conjunction character (typically 'ו' for and)
110
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
111
- */
112
-
113
- /**
114
- * @typedef {Object} CroatianOptions
115
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
116
- */
117
-
118
- /**
119
- * @typedef {Object} CzechOptions
120
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
121
- */
122
-
123
- /**
124
- * @typedef {Object} DanishOptions
125
- * @property {boolean} [ordFlag=false] Enable ordinal number conversion
126
- */
127
-
128
- /**
129
- * @typedef {Object} DutchOptions
130
- * @property {boolean} [includeOptionalAnd=false] Include optional "en" separator
131
- * @property {boolean} [noHundredPairing=false] Disable hundred-pairing (e.g., "twelve hundred" becomes "one thousand two hundred")
132
- * @property {boolean} [accentOne=true] Use accented "één" for one
133
- */
134
-
135
- /**
136
- * @typedef {Object} FrenchOptions
137
- * @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds
138
- */
139
-
140
- /**
141
- * @typedef {Object} FrenchBelgiumOptions
142
- * @property {boolean} [withHyphenSeparator=false] Use hyphens (true) instead of spaces (false) in compounds
143
- */
144
-
145
- /**
146
- * @typedef {Object} HebrewOptions
147
- * @property {string} [andWord='ו'] Conjunction character (typically 'ו' for and)
148
- */
149
-
150
- /**
151
- * @typedef {Object} LatvianOptions
152
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
153
- */
154
-
155
- /**
156
- * @typedef {Object} LithuanianOptions
157
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
158
- */
159
-
160
- /**
161
- * @typedef {Object} PolishOptions
162
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
163
- */
164
-
165
- /**
166
- * @typedef {Object} RomanianOptions
167
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
168
- */
169
-
170
- /**
171
- * @typedef {Object} RussianOptions
172
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
173
- */
174
-
175
- /**
176
- * @typedef {Object} SerbianCyrillicOptions
177
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
178
- */
179
-
180
- /**
181
- * @typedef {Object} SerbianLatinOptions
182
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
183
- */
184
-
185
- /**
186
- * @typedef {Object} SimplifiedChineseOptions
187
- * @property {boolean} [formal=true] Use formal/financial numerals (壹贰叁) vs. common numerals (一二三)
188
- */
189
-
190
- /**
191
- * @typedef {Object} SpanishOptions
192
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
193
- */
194
-
195
- /**
196
- * @typedef {Object} TraditionalChineseOptions
197
- * @property {boolean} [formal=true] Use formal/financial numerals (壹貳參) vs. common numerals (一二三)
198
- */
199
-
200
- /**
201
- * @typedef {Object} TurkishOptions
202
- * @property {boolean} [dropSpaces=false] Remove spaces between words if true
203
- */
204
-
205
- /**
206
- * @typedef {Object} UkrainianOptions
207
- * @property {('masculine'|'feminine')} [gender='masculine'] Grammatical gender for number forms
208
- */
209
-
210
- // ============================================================================
211
- // Converter Factory
212
- // ============================================================================
213
- //
214
- // makeConverter() is a factory function that creates converter functions from
215
- // language classes. It provides a consistent functional API for all languages:
216
- //
217
- // const result = EnglishConverter(42) // "forty-two"
218
- // const result = ArabicConverter(1, {gender: 'feminine'}) // "واحدة"
219
- //
220
- // This design:
221
- // - Hides class instantiation details from public API
222
- // - Ensures each conversion uses a fresh instance
223
- // - Maintains immutability (no shared state between conversions)
224
- // ============================================================================
225
-
226
- /**
227
- * Creates a converter function for a language class.
228
- *
229
- * This factory handles all input validation and normalization at the public API
230
- * boundary, then delegates to the language class with pre-processed data.
231
- *
232
- * @template {Object} [TOptions={}]
233
- * @param {new (options?: TOptions) => { toWords: (isNegative: boolean, integerPart: bigint, decimalPart?: string) => string }} LanguageClass - Language class constructor
234
- * @returns {(value: NumericValue, options?: TOptions) => string} Converter function
235
- */
236
- function makeConverter (LanguageClass) {
237
- /**
238
- * @param {NumericValue} value
239
- * @param {TOptions} [options]
240
- * @returns {string}
241
- */
242
- return function convertToWords (value, options) {
243
- if (options !== undefined && !isPlainObject(options)) {
244
- throw new TypeError('options must be a plain object if provided')
245
- }
246
-
247
- const { isNegative, integerPart, decimalPart } = parseNumericValue(value)
248
- return new LanguageClass(options).toWords(isNegative, integerPart, decimalPart)
249
- }
250
- }
251
-
252
- // ============================================================================
253
- // Input Parsing Utilities
254
- // ============================================================================
255
-
256
- /**
257
- * @typedef {Object} ParsedNumericValue
258
- * @property {boolean} isNegative - Whether the value is negative
259
- * @property {bigint} integerPart - The absolute integer part
260
- * @property {string} [decimalPart] - The decimal digits (without the point)
261
- */
262
-
263
- /**
264
- * Parses and validates a numeric value into its components.
265
- * Handles number, string, and bigint inputs uniformly.
266
- *
267
- * @param {NumericValue} value The value to parse
268
- * @returns {ParsedNumericValue} The parsed components
269
- * @throws {TypeError} If value is not a valid numeric type
270
- * @throws {Error} If value is not a valid number format
271
- */
272
- function parseNumericValue (value) {
273
- const type = typeof value
274
-
275
- // BigInt: simplest case - no decimals, no scientific notation
276
- if (type === 'bigint') {
277
- return value < 0n
278
- ? { isNegative: true, integerPart: -value }
279
- : { isNegative: false, integerPart: value }
280
- }
281
-
282
- // Reject invalid types early
283
- if (type !== 'number' && type !== 'string') {
284
- throw new TypeError(
285
- `Invalid value type: expected number, string, or bigint, received ${type}`
286
- )
287
- }
288
-
289
- // Convert to normalized string
290
- const str = type === 'number'
291
- ? numberToString(value)
292
- : stringToNormalizedForm(value)
293
-
294
- return parseNumericString(str)
295
- }
296
-
297
- /**
298
- * Converts a JavaScript number to a decimal string.
299
- * Handles special cases: Infinity, NaN, and scientific notation.
300
- *
301
- * @param {number} value The number to convert
302
- * @returns {string} Decimal string representation
303
- * @throws {Error} If value is not finite
304
- */
305
- function numberToString (value) {
306
- if (!Number.isFinite(value)) {
307
- throw new Error('Number must be finite (NaN and Infinity are not supported)')
308
- }
309
-
310
- const str = value.toString()
311
-
312
- // Expand scientific notation (used for values >= 1e21 or < 1e-6)
313
- if (str.includes('e') || str.includes('E')) {
314
- return expandScientificNotation(str)
315
- }
316
-
317
- return str
318
- }
319
-
320
- /**
321
- * Validates and normalizes a string numeric input.
322
- *
323
- * @param {string} value The string to validate
324
- * @returns {string} Trimmed and validated string
325
- * @throws {Error} If string is empty or not a valid number format
326
- */
327
- function stringToNormalizedForm (value) {
328
- const trimmed = value.trim()
329
-
330
- if (trimmed.length === 0) {
331
- throw new Error(`Invalid number format: "${value}"`)
332
- }
333
-
334
- // Validate by attempting conversion (handles edge cases like "1e21", "-.5", etc.)
335
- if (Number.isNaN(Number(trimmed))) {
336
- throw new Error(`Invalid number format: "${value}"`)
337
- }
338
-
339
- // Expand scientific notation if present
340
- if (trimmed.includes('e') || trimmed.includes('E')) {
341
- return expandScientificNotation(trimmed)
342
- }
343
-
344
- return trimmed
345
- }
346
-
347
- /**
348
- * Parses a normalized numeric string into its components.
349
- *
350
- * @param {string} str A normalized decimal string (no scientific notation)
351
- * @returns {ParsedNumericValue} The parsed components
352
- */
353
- function parseNumericString (str) {
354
- // Extract sign
355
- const isNegative = str[0] === '-'
356
- if (isNegative) {
357
- str = str.slice(1)
358
- }
359
-
360
- // Split into integer and decimal parts
361
- const dotIndex = str.indexOf('.')
362
- if (dotIndex === -1) {
363
- return { isNegative, integerPart: BigInt(str) }
364
- }
365
-
366
- const integerStr = str.slice(0, dotIndex) || '0'
367
- const decimalPart = str.slice(dotIndex + 1)
368
-
369
- return { isNegative, integerPart: BigInt(integerStr), decimalPart }
370
- }
371
-
372
- /**
373
- * Expands scientific notation to decimal form.
374
- * JavaScript uses scientific notation for values >= 1e21 or < 1e-6.
375
- *
376
- * @param {string} str String possibly in scientific notation (e.g., "1e+21")
377
- * @returns {string} Decimal form (e.g., "1000000000000000000000")
378
- */
379
- function expandScientificNotation (str) {
380
- const [mantissa, expStr] = str.toLowerCase().split('e')
381
- const exp = parseInt(expStr, 10)
382
-
383
- // Extract digits and determine original decimal position
384
- const dotIndex = mantissa.indexOf('.')
385
- const digits = dotIndex === -1
386
- ? mantissa
387
- : mantissa.slice(0, dotIndex) + mantissa.slice(dotIndex + 1)
388
- const integerLength = dotIndex === -1 ? mantissa.length : dotIndex
389
-
390
- // Calculate new decimal position after applying exponent
391
- const newDotPosition = integerLength + exp
392
-
393
- if (newDotPosition >= digits.length) {
394
- // Pure integer: pad with trailing zeros
395
- return digits + '0'.repeat(newDotPosition - digits.length)
396
- }
397
-
398
- if (newDotPosition <= 0) {
399
- // Pure decimal: pad with leading zeros after decimal point
400
- return '0.' + '0'.repeat(-newDotPosition) + digits
401
- }
402
-
403
- // Mixed: insert decimal point at new position
404
- return digits.slice(0, newDotPosition) + '.' + digits.slice(newDotPosition)
405
- }
406
-
407
- /**
408
- * Checks if a value is a plain object (not null, array, or other object types).
409
- *
410
- * @param {*} value Value to check
411
- * @returns {boolean} True if value is a plain object
412
- */
413
- function isPlainObject (value) {
414
- if (value === null || typeof value !== 'object') return false
415
- const proto = Object.getPrototypeOf(value)
416
- return proto === Object.prototype || proto === null
417
- }
418
-
419
- // ============================================================================
420
- // Language Converters
421
- // ============================================================================
422
- //
423
- // Each converter is created using makeConverter() with explicit type annotations.
424
- //
425
- // Pattern for languages WITHOUT options:
426
- // const LanguageConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Language))
427
- //
428
- // Pattern for languages WITH options:
429
- // const LanguageConverter = /** @type {(value: NumericValue, options?: LanguageOptions) => string} */ (makeConverter(Language))
430
- //
431
- // IMPORTANT: Keep converters alphabetically sorted by converter name.
432
- // ============================================================================
433
-
434
- const ArabicConverter = /** @type {(value: NumericValue, options?: ArabicOptions) => string} */ (makeConverter(Arabic))
435
- const AzerbaijaniConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Azerbaijani))
436
- const BanglaConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Bangla))
437
- const BiblicalHebrewConverter = /** @type {(value: NumericValue, options?: BiblicalHebrewOptions) => string} */ (makeConverter(BiblicalHebrew))
438
- const CroatianConverter = /** @type {(value: NumericValue, options?: CroatianOptions) => string} */ (makeConverter(Croatian))
439
- const CzechConverter = /** @type {(value: NumericValue, options?: CzechOptions) => string} */ (makeConverter(Czech))
440
- const DanishConverter = /** @type {(value: NumericValue, options?: DanishOptions) => string} */ (makeConverter(Danish))
441
- const DutchConverter = /** @type {(value: NumericValue, options?: DutchOptions) => string} */ (makeConverter(Dutch))
442
- const EnglishConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(English))
443
- const FilipinoConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Filipino))
444
- const FrenchConverter = /** @type {(value: NumericValue, options?: FrenchOptions) => string} */ (makeConverter(French))
445
- const FrenchBelgiumConverter = /** @type {(value: NumericValue, options?: FrenchBelgiumOptions) => string} */ (makeConverter(FrenchBelgium))
446
- const GermanConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(German))
447
- const GreekConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Greek))
448
- const GujaratiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Gujarati))
449
- const HebrewConverter = /** @type {(value: NumericValue, options?: HebrewOptions) => string} */ (makeConverter(Hebrew))
450
- const HindiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Hindi))
451
- const HungarianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Hungarian))
452
- const IndonesianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Indonesian))
453
- const ItalianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Italian))
454
- const JapaneseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Japanese))
455
- const KannadaConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Kannada))
456
- const KoreanConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Korean))
457
- const LatvianConverter = /** @type {(value: NumericValue, options?: LatvianOptions) => string} */ (makeConverter(Latvian))
458
- const LithuanianConverter = /** @type {(value: NumericValue, options?: LithuanianOptions) => string} */ (makeConverter(Lithuanian))
459
- const MalayConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Malay))
460
- const MarathiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Marathi))
461
- const NorwegianBokmalConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(NorwegianBokmal))
462
- const PersianConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Persian))
463
- const PolishConverter = /** @type {(value: NumericValue, options?: PolishOptions) => string} */ (makeConverter(Polish))
464
- const PortugueseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Portuguese))
465
- const PunjabiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Punjabi))
466
- const RomanianConverter = /** @type {(value: NumericValue, options?: RomanianOptions) => string} */ (makeConverter(Romanian))
467
- const RussianConverter = /** @type {(value: NumericValue, options?: RussianOptions) => string} */ (makeConverter(Russian))
468
- const SerbianCyrillicConverter = /** @type {(value: NumericValue, options?: SerbianCyrillicOptions) => string} */ (makeConverter(SerbianCyrillic))
469
- const SerbianLatinConverter = /** @type {(value: NumericValue, options?: SerbianLatinOptions) => string} */ (makeConverter(SerbianLatin))
470
- const SimplifiedChineseConverter = /** @type {(value: NumericValue, options?: SimplifiedChineseOptions) => string} */ (makeConverter(SimplifiedChinese))
471
- const SpanishConverter = /** @type {(value: NumericValue, options?: SpanishOptions) => string} */ (makeConverter(Spanish))
472
- const SwahiliConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Swahili))
473
- const SwedishConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Swedish))
474
- const TamilConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Tamil))
475
- const TeluguConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Telugu))
476
- const ThaiConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Thai))
477
- const TraditionalChineseConverter = /** @type {(value: NumericValue, options?: TraditionalChineseOptions) => string} */ (makeConverter(TraditionalChinese))
478
- const TurkishConverter = /** @type {(value: NumericValue, options?: TurkishOptions) => string} */ (makeConverter(Turkish))
479
- const UkrainianConverter = /** @type {(value: NumericValue, options?: UkrainianOptions) => string} */ (makeConverter(Ukrainian))
480
- const UrduConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Urdu))
481
- const VietnameseConverter = /** @type {(value: NumericValue) => string} */ (makeConverter(Vietnamese))
482
-
483
- // ============================================================================
484
- // Exports
485
- // ============================================================================
486
- //
487
- // All converter functions are exported for public use.
488
- //
489
- // IMPORTANT: Keep exports alphabetically sorted for maintainability.
490
- // ============================================================================
16
+ import { toWords as am } from './languages/am.js'
17
+ import { toWords as amLatn } from './languages/am-Latn.js'
18
+ import { toWords as ar } from './languages/ar.js'
19
+ import { toWords as az } from './languages/az.js'
20
+ import { toWords as bn } from './languages/bn.js'
21
+ import { toWords as cs } from './languages/cs.js'
22
+ import { toWords as da } from './languages/da.js'
23
+ import { toWords as de } from './languages/de.js'
24
+ import { toWords as el } from './languages/el.js'
25
+ import { toWords as en } from './languages/en.js'
26
+ import { toWords as es } from './languages/es.js'
27
+ import { toWords as fa } from './languages/fa.js'
28
+ import { toWords as fi } from './languages/fi.js'
29
+ import { toWords as fil } from './languages/fil.js'
30
+ import { toWords as fr } from './languages/fr.js'
31
+ import { toWords as frBE } from './languages/fr-BE.js'
32
+ import { toWords as gu } from './languages/gu.js'
33
+ import { toWords as ha } from './languages/ha.js'
34
+ import { toWords as hbo } from './languages/hbo.js'
35
+ import { toWords as he } from './languages/he.js'
36
+ import { toWords as hi } from './languages/hi.js'
37
+ import { toWords as hr } from './languages/hr.js'
38
+ import { toWords as hu } from './languages/hu.js'
39
+ import { toWords as id } from './languages/id.js'
40
+ import { toWords as it } from './languages/it.js'
41
+ import { toWords as ja } from './languages/ja.js'
42
+ import { toWords as ka } from './languages/ka.js'
43
+ import { toWords as kn } from './languages/kn.js'
44
+ import { toWords as ko } from './languages/ko.js'
45
+ import { toWords as lt } from './languages/lt.js'
46
+ import { toWords as lv } from './languages/lv.js'
47
+ import { toWords as mr } from './languages/mr.js'
48
+ import { toWords as ms } from './languages/ms.js'
49
+ import { toWords as nb } from './languages/nb.js'
50
+ import { toWords as nl } from './languages/nl.js'
51
+ import { toWords as pa } from './languages/pa.js'
52
+ import { toWords as pl } from './languages/pl.js'
53
+ import { toWords as pt } from './languages/pt.js'
54
+ import { toWords as ro } from './languages/ro.js'
55
+ import { toWords as ru } from './languages/ru.js'
56
+ import { toWords as srCyrl } from './languages/sr-Cyrl.js'
57
+ import { toWords as srLatn } from './languages/sr-Latn.js'
58
+ import { toWords as sv } from './languages/sv.js'
59
+ import { toWords as sw } from './languages/sw.js'
60
+ import { toWords as ta } from './languages/ta.js'
61
+ import { toWords as te } from './languages/te.js'
62
+ import { toWords as th } from './languages/th.js'
63
+ import { toWords as tr } from './languages/tr.js'
64
+ import { toWords as uk } from './languages/uk.js'
65
+ import { toWords as ur } from './languages/ur.js'
66
+ import { toWords as vi } from './languages/vi.js'
67
+ import { toWords as yo } from './languages/yo.js'
68
+ import { toWords as zhHans } from './languages/zh-Hans.js'
69
+ import { toWords as zhHant } from './languages/zh-Hant.js'
491
70
 
492
71
  export {
493
- ArabicConverter,
494
- AzerbaijaniConverter,
495
- BanglaConverter,
496
- BiblicalHebrewConverter,
497
- CroatianConverter,
498
- CzechConverter,
499
- DanishConverter,
500
- DutchConverter,
501
- EnglishConverter,
502
- FilipinoConverter,
503
- FrenchConverter,
504
- FrenchBelgiumConverter,
505
- GermanConverter,
506
- GreekConverter,
507
- GujaratiConverter,
508
- HebrewConverter,
509
- HindiConverter,
510
- HungarianConverter,
511
- IndonesianConverter,
512
- ItalianConverter,
513
- JapaneseConverter,
514
- KannadaConverter,
515
- KoreanConverter,
516
- LatvianConverter,
517
- LithuanianConverter,
518
- MalayConverter,
519
- MarathiConverter,
520
- NorwegianBokmalConverter,
521
- PersianConverter,
522
- PolishConverter,
523
- PortugueseConverter,
524
- PunjabiConverter,
525
- RomanianConverter,
526
- RussianConverter,
527
- SerbianCyrillicConverter,
528
- SerbianLatinConverter,
529
- SimplifiedChineseConverter,
530
- SpanishConverter,
531
- SwahiliConverter,
532
- SwedishConverter,
533
- TamilConverter,
534
- TeluguConverter,
535
- ThaiConverter,
536
- TraditionalChineseConverter,
537
- TurkishConverter,
538
- UkrainianConverter,
539
- UrduConverter,
540
- VietnameseConverter
72
+ am,
73
+ amLatn,
74
+ ar,
75
+ az,
76
+ bn,
77
+ cs,
78
+ da,
79
+ de,
80
+ el,
81
+ en,
82
+ es,
83
+ fa,
84
+ fi,
85
+ fil,
86
+ fr,
87
+ frBE,
88
+ gu,
89
+ ha,
90
+ hbo,
91
+ he,
92
+ hi,
93
+ hr,
94
+ hu,
95
+ id,
96
+ it,
97
+ ja,
98
+ ka,
99
+ kn,
100
+ ko,
101
+ lt,
102
+ lv,
103
+ mr,
104
+ ms,
105
+ nb,
106
+ nl,
107
+ pa,
108
+ pl,
109
+ pt,
110
+ ro,
111
+ ru,
112
+ srCyrl,
113
+ srLatn,
114
+ sv,
115
+ sw,
116
+ ta,
117
+ te,
118
+ th,
119
+ tr,
120
+ uk,
121
+ ur,
122
+ vi,
123
+ yo,
124
+ zhHans,
125
+ zhHant
541
126
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Checks if a value is a plain object (not null, array, or other object types).
3
+ *
4
+ * A plain object is one created by:
5
+ * - Object literal: `{}`
6
+ * - Object.create(null): null-prototype object
7
+ *
8
+ * This excludes arrays, class instances, Map, Set, and other object types.
9
+ *
10
+ * @param {*} value Value to check
11
+ * @returns {boolean} True if value is a plain object
12
+ */
13
+ export function isPlainObject(value: any): boolean;