@reventlessdev/reventless-spec 3.0.0-alpha.122 → 3.0.0-alpha.124

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.
@@ -1,9 +1,9 @@
1
1
  // AUTO-GENERATED from ISO 4217 (published 2026-01-01) — do not edit.
2
- // Run `pnpm --filter @reventlessdev/reventless-spec run generate:currency`,
3
- // or see `scripts/generate-currency.mjs` to update the source table first.
2
+ // Run `pnpm run generate:currency`, or see `scripts/GenerateCurrency.res` to
3
+ // change which codes are admitted or to update the source table first.
4
4
 
5
5
  /**
6
- A currency, closed to the 165 codes ISO 4217 defines a minor unit for.
6
+ A currency, closed to the 10 codes this framework admits today.
7
7
 
8
8
  ## Why a type and not a three-letter string
9
9
 
@@ -12,563 +12,574 @@ currency is a class of bug that reads as a data problem long after it became a
12
12
  correctness problem — the values are present, and they simply never match. A
13
13
  closed type makes the second spelling unwritable.
14
14
 
15
- ## Why generated, and why every code
15
+ ## Why generated, and why a curated set
16
16
 
17
- The alternative was a curated handful (EUR, USD, GBP, JPY, …), which is small
18
- and readable and wrong the first time an application needs a currency nobody
19
- listed — a compile error in someone else's domain, fixable only by a framework
20
- release. The thing being avoided by curating is 165 constructors that are
21
- machine-written and never read in full; the thing being risked is a release.
17
+ Generation buys the property that makes this type worth having: `exponent` comes
18
+ from the *same* source as the codes, so it cannot drift from them (1×0, 9×2 decimal
19
+ places across the set). That is what lets `Money` derive how many decimals an
20
+ amount may carry instead of hardcoding two, and therefore what makes it correct
21
+ for JPY without anyone remembering that JPY is special.
22
22
 
23
- Generation also buys the property that makes this type worth having: `exponent`
24
- comes from the *same* source as the codes, so it cannot drift from them
25
- (17×0, 139×2, 7×3, 2×4 decimal places across the set). That is what lets
26
- `Money.format` derive its decimal placement instead of hardcoding `/100`, and
27
- therefore what makes it correct for JPY and TND without anyone remembering that
28
- those two are special.
23
+ The set is curated because the whole table is not a choice anyone makes: a picker
24
+ holding 165 codes asks a person to find theirs in a list nobody reads, and a
25
+ domain that deals in ten does not become more correct for admitting the other 155.
26
+
27
+ Every one of those is written out below, commented, in each of the four blocks
28
+ that mention a code — so admitting one is uncommenting four lines, or adding it
29
+ to `active` in `scripts/GenerateCurrency.res` and regenerating. What a curated
30
+ list used to risk was a framework release to fix someone else's compile error;
31
+ keeping the rest in the file is what buys that back.
29
32
 
30
33
  ## What is deliberately absent
31
34
 
32
- The 13 entries ISO lists with no minor unit: the precious metals
35
+ The 13 entries ISO lists with no minor unit at all: the precious metals
33
36
  (XAG, XAU, XPD, XPT), the bond market units (XBA, XBB, XBC, XBD), the accounting
34
- units (XDR, XSU, XUA), the testing code XTS, and the "no currency"
35
- sentinel XXX. Each would make `exponent` partial, and a weight of gold is not
36
- an amount of money. The standard's own table draws that line, so it is not a
37
- curated opinion after all.
37
+ units (XDR, XSU, XUA), the testing code XTS, and the "no currency" sentinel
38
+ XXX. Each would make `exponent` partial, and a weight of gold is not an amount
39
+ of money. Those are absent from the dormant list too — the standard's own table
40
+ draws that line, so it is not a curated opinion after all.
38
41
 
39
42
  ## The wire form
40
43
 
41
44
  A payload-less variant, so the stored and transmitted form is the three-letter
42
- code itself — `{"amount": 1000, "currency": "EUR"}`. Standard at the boundary,
45
+ code itself — `{"amount": 10.5, "currency": "EUR"}`. Standard at the boundary,
43
46
  a checked type in the domain.
44
47
  */
45
48
  @schema
46
49
  type t =
47
- | /** UAE Dirham */ AED
48
- | /** Afghani */ AFN
49
- | /** Lek */ ALL
50
- | /** Armenian Dram */ AMD
51
- | /** Kwanza */ AOA
52
- | /** Argentine Peso */ ARS
53
50
  | /** Australian Dollar */ AUD
54
- | /** Aruban Florin */ AWG
55
- | /** Azerbaijan Manat */ AZN
56
- | /** Convertible Mark */ BAM
57
- | /** Barbados Dollar */ BBD
58
- | /** Taka */ BDT
59
- | /** Bahraini Dinar */ BHD
60
- | /** Burundi Franc */ BIF
61
- | /** Bermudian Dollar */ BMD
62
- | /** Brunei Dollar */ BND
63
- | /** Boliviano */ BOB
64
- | /** undefined */ BOV
65
- | /** Brazilian Real */ BRL
66
- | /** Bahamian Dollar */ BSD
67
- | /** Ngultrum */ BTN
68
- | /** Pula */ BWP
69
- | /** Belarusian Ruble */ BYN
70
- | /** Belize Dollar */ BZD
71
51
  | /** Canadian Dollar */ CAD
72
- | /** Congolese Franc */ CDF
73
- | /** undefined */ CHE
74
52
  | /** Swiss Franc */ CHF
75
- | /** undefined */ CHW
76
- | /** undefined */ CLF
77
- | /** Chilean Peso */ CLP
78
53
  | /** Yuan Renminbi */ CNY
79
- | /** Colombian Peso */ COP
80
- | /** undefined */ COU
81
- | /** Costa Rican Colon */ CRC
82
- | /** Cuban Peso */ CUP
83
- | /** Cabo Verde Escudo */ CVE
84
- | /** Czech Koruna */ CZK
85
- | /** Djibouti Franc */ DJF
86
- | /** Danish Krone */ DKK
87
- | /** Dominican Peso */ DOP
88
- | /** Algerian Dinar */ DZD
89
- | /** Egyptian Pound */ EGP
90
- | /** Nakfa */ ERN
91
- | /** Ethiopian Birr */ ETB
92
54
  | /** Euro */ EUR
93
- | /** Fiji Dollar */ FJD
94
- | /** Falkland Islands Pound */ FKP
95
55
  | /** Pound Sterling */ GBP
96
- | /** Lari */ GEL
97
- | /** Ghana Cedi */ GHS
98
- | /** Gibraltar Pound */ GIP
99
- | /** Dalasi */ GMD
100
- | /** Guinean Franc */ GNF
101
- | /** Quetzal */ GTQ
102
- | /** Guyana Dollar */ GYD
103
- | /** Hong Kong Dollar */ HKD
104
- | /** Lempira */ HNL
105
- | /** Gourde */ HTG
106
- | /** Forint */ HUF
107
- | /** Rupiah */ IDR
108
- | /** New Israeli Sheqel */ ILS
109
- | /** Indian Rupee */ INR
110
- | /** Iraqi Dinar */ IQD
111
- | /** Iranian Rial */ IRR
112
- | /** Iceland Krona */ ISK
113
- | /** Jamaican Dollar */ JMD
114
- | /** Jordanian Dinar */ JOD
115
56
  | /** Yen */ JPY
116
- | /** Kenyan Shilling */ KES
117
- | /** Som */ KGS
118
- | /** Riel */ KHR
119
- | /** Comorian Franc */ KMF
120
- | /** North Korean Won */ KPW
121
- | /** Won */ KRW
122
- | /** Kuwaiti Dinar */ KWD
123
- | /** Cayman Islands Dollar */ KYD
124
- | /** Tenge */ KZT
125
- | /** Lao Kip */ LAK
126
- | /** Lebanese Pound */ LBP
127
- | /** Sri Lanka Rupee */ LKR
128
- | /** Liberian Dollar */ LRD
129
- | /** Loti */ LSL
130
- | /** Libyan Dinar */ LYD
131
- | /** Moroccan Dirham */ MAD
132
- | /** Moldovan Leu */ MDL
133
- | /** Malagasy Ariary */ MGA
134
- | /** Denar */ MKD
135
- | /** Kyat */ MMK
136
- | /** Tugrik */ MNT
137
- | /** Pataca */ MOP
138
- | /** Ouguiya */ MRU
139
- | /** Mauritius Rupee */ MUR
140
- | /** Rufiyaa */ MVR
141
- | /** Malawi Kwacha */ MWK
142
- | /** Mexican Peso */ MXN
143
- | /** undefined */ MXV
144
- | /** Malaysian Ringgit */ MYR
145
- | /** Mozambique Metical */ MZN
146
- | /** Namibia Dollar */ NAD
147
- | /** Naira */ NGN
148
- | /** Cordoba Oro */ NIO
149
57
  | /** Norwegian Krone */ NOK
150
- | /** Nepalese Rupee */ NPR
151
- | /** New Zealand Dollar */ NZD
152
- | /** Rial Omani */ OMR
153
- | /** Balboa */ PAB
154
- | /** Sol */ PEN
155
- | /** Kina */ PGK
156
- | /** Philippine Peso */ PHP
157
- | /** Pakistan Rupee */ PKR
158
- | /** Zloty */ PLN
159
- | /** Guarani */ PYG
160
- | /** Qatari Rial */ QAR
161
- | /** Romanian Leu */ RON
162
- | /** Serbian Dinar */ RSD
163
- | /** Russian Ruble */ RUB
164
- | /** Rwanda Franc */ RWF
165
- | /** Saudi Riyal */ SAR
166
- | /** Solomon Islands Dollar */ SBD
167
- | /** Seychelles Rupee */ SCR
168
- | /** Sudanese Pound */ SDG
169
58
  | /** Swedish Krona */ SEK
170
- | /** Singapore Dollar */ SGD
171
- | /** Saint Helena Pound */ SHP
172
- | /** Leone */ SLE
173
- | /** Somali Shilling */ SOS
174
- | /** Surinam Dollar */ SRD
175
- | /** South Sudanese Pound */ SSP
176
- | /** Dobra */ STN
177
- | /** El Salvador Colon */ SVC
178
- | /** Syrian Pound */ SYP
179
- | /** Lilangeni */ SZL
180
- | /** Baht */ THB
181
- | /** Somoni */ TJS
182
- | /** Turkmenistan New Manat */ TMT
183
- | /** Tunisian Dinar */ TND
184
- | /** Pa’anga */ TOP
185
- | /** Turkish Lira */ TRY
186
- | /** Trinidad and Tobago Dollar */ TTD
187
- | /** New Taiwan Dollar */ TWD
188
- | /** Tanzanian Shilling */ TZS
189
- | /** Hryvnia */ UAH
190
- | /** Uganda Shilling */ UGX
191
59
  | /** US Dollar */ USD
192
- | /** undefined */ USN
193
- | /** undefined */ UYI
194
- | /** Peso Uruguayo */ UYU
195
- | /** Unidad Previsional */ UYW
196
- | /** Uzbekistan Sum */ UZS
197
- | /** Bolívar Soberano */ VED
198
- | /** Bolívar Soberano */ VES
199
- | /** Dong */ VND
200
- | /** Vatu */ VUV
201
- | /** Tala */ WST
202
- | /** Arab Accounting Dinar */ XAD
203
- | /** CFA Franc BEAC */ XAF
204
- | /** East Caribbean Dollar */ XCD
205
- | /** Caribbean Guilder */ XCG
206
- | /** CFA Franc BCEAO */ XOF
207
- | /** CFP Franc */ XPF
208
- | /** Yemeni Rial */ YER
209
- | /** Rand */ ZAR
210
- | /** Zambian Kwacha */ ZMW
211
- | /** Zimbabwe Gold */ ZWG
212
60
 
213
- /** Every currency, in code order. `fromString` is derived from this, so a code
214
- that parses and a code that exists are the same set by construction. */
61
+ // ── Dormant ─────────────────────────────────────────────────────────────
62
+ // The rest of ISO 4217, kept for the day one of them is needed. Uncomment
63
+ // the code here and in the other three blocks — or add it to `active` in
64
+ // scripts/GenerateCurrency.res and regenerate — to admit it.
65
+ // | /** UAE Dirham */ AED
66
+ // | /** Afghani */ AFN
67
+ // | /** Lek */ ALL
68
+ // | /** Armenian Dram */ AMD
69
+ // | /** Kwanza */ AOA
70
+ // | /** Argentine Peso */ ARS
71
+ // | /** Aruban Florin */ AWG
72
+ // | /** Azerbaijan Manat */ AZN
73
+ // | /** Convertible Mark */ BAM
74
+ // | /** Barbados Dollar */ BBD
75
+ // | /** Taka */ BDT
76
+ // | /** Bahraini Dinar */ BHD
77
+ // | /** Burundi Franc */ BIF
78
+ // | /** Bermudian Dollar */ BMD
79
+ // | /** Brunei Dollar */ BND
80
+ // | /** Boliviano */ BOB
81
+ // | /** BOV */ BOV
82
+ // | /** Brazilian Real */ BRL
83
+ // | /** Bahamian Dollar */ BSD
84
+ // | /** Ngultrum */ BTN
85
+ // | /** Pula */ BWP
86
+ // | /** Belarusian Ruble */ BYN
87
+ // | /** Belize Dollar */ BZD
88
+ // | /** Congolese Franc */ CDF
89
+ // | /** CHE */ CHE
90
+ // | /** CHW */ CHW
91
+ // | /** CLF */ CLF
92
+ // | /** Chilean Peso */ CLP
93
+ // | /** Colombian Peso */ COP
94
+ // | /** COU */ COU
95
+ // | /** Costa Rican Colon */ CRC
96
+ // | /** Cuban Peso */ CUP
97
+ // | /** Cabo Verde Escudo */ CVE
98
+ // | /** Czech Koruna */ CZK
99
+ // | /** Djibouti Franc */ DJF
100
+ // | /** Danish Krone */ DKK
101
+ // | /** Dominican Peso */ DOP
102
+ // | /** Algerian Dinar */ DZD
103
+ // | /** Egyptian Pound */ EGP
104
+ // | /** Nakfa */ ERN
105
+ // | /** Ethiopian Birr */ ETB
106
+ // | /** Fiji Dollar */ FJD
107
+ // | /** Falkland Islands Pound */ FKP
108
+ // | /** Lari */ GEL
109
+ // | /** Ghana Cedi */ GHS
110
+ // | /** Gibraltar Pound */ GIP
111
+ // | /** Dalasi */ GMD
112
+ // | /** Guinean Franc */ GNF
113
+ // | /** Quetzal */ GTQ
114
+ // | /** Guyana Dollar */ GYD
115
+ // | /** Hong Kong Dollar */ HKD
116
+ // | /** Lempira */ HNL
117
+ // | /** Gourde */ HTG
118
+ // | /** Forint */ HUF
119
+ // | /** Rupiah */ IDR
120
+ // | /** New Israeli Sheqel */ ILS
121
+ // | /** Indian Rupee */ INR
122
+ // | /** Iraqi Dinar */ IQD
123
+ // | /** Iranian Rial */ IRR
124
+ // | /** Iceland Krona */ ISK
125
+ // | /** Jamaican Dollar */ JMD
126
+ // | /** Jordanian Dinar */ JOD
127
+ // | /** Kenyan Shilling */ KES
128
+ // | /** Som */ KGS
129
+ // | /** Riel */ KHR
130
+ // | /** Comorian Franc */ KMF
131
+ // | /** North Korean Won */ KPW
132
+ // | /** Won */ KRW
133
+ // | /** Kuwaiti Dinar */ KWD
134
+ // | /** Cayman Islands Dollar */ KYD
135
+ // | /** Tenge */ KZT
136
+ // | /** Lao Kip */ LAK
137
+ // | /** Lebanese Pound */ LBP
138
+ // | /** Sri Lanka Rupee */ LKR
139
+ // | /** Liberian Dollar */ LRD
140
+ // | /** Loti */ LSL
141
+ // | /** Libyan Dinar */ LYD
142
+ // | /** Moroccan Dirham */ MAD
143
+ // | /** Moldovan Leu */ MDL
144
+ // | /** Malagasy Ariary */ MGA
145
+ // | /** Denar */ MKD
146
+ // | /** Kyat */ MMK
147
+ // | /** Tugrik */ MNT
148
+ // | /** Pataca */ MOP
149
+ // | /** Ouguiya */ MRU
150
+ // | /** Mauritius Rupee */ MUR
151
+ // | /** Rufiyaa */ MVR
152
+ // | /** Malawi Kwacha */ MWK
153
+ // | /** Mexican Peso */ MXN
154
+ // | /** MXV */ MXV
155
+ // | /** Malaysian Ringgit */ MYR
156
+ // | /** Mozambique Metical */ MZN
157
+ // | /** Namibia Dollar */ NAD
158
+ // | /** Naira */ NGN
159
+ // | /** Cordoba Oro */ NIO
160
+ // | /** Nepalese Rupee */ NPR
161
+ // | /** New Zealand Dollar */ NZD
162
+ // | /** Rial Omani */ OMR
163
+ // | /** Balboa */ PAB
164
+ // | /** Sol */ PEN
165
+ // | /** Kina */ PGK
166
+ // | /** Philippine Peso */ PHP
167
+ // | /** Pakistan Rupee */ PKR
168
+ // | /** Zloty */ PLN
169
+ // | /** Guarani */ PYG
170
+ // | /** Qatari Rial */ QAR
171
+ // | /** Romanian Leu */ RON
172
+ // | /** Serbian Dinar */ RSD
173
+ // | /** Russian Ruble */ RUB
174
+ // | /** Rwanda Franc */ RWF
175
+ // | /** Saudi Riyal */ SAR
176
+ // | /** Solomon Islands Dollar */ SBD
177
+ // | /** Seychelles Rupee */ SCR
178
+ // | /** Sudanese Pound */ SDG
179
+ // | /** Singapore Dollar */ SGD
180
+ // | /** Saint Helena Pound */ SHP
181
+ // | /** Leone */ SLE
182
+ // | /** Somali Shilling */ SOS
183
+ // | /** Surinam Dollar */ SRD
184
+ // | /** South Sudanese Pound */ SSP
185
+ // | /** Dobra */ STN
186
+ // | /** El Salvador Colon */ SVC
187
+ // | /** Syrian Pound */ SYP
188
+ // | /** Lilangeni */ SZL
189
+ // | /** Baht */ THB
190
+ // | /** Somoni */ TJS
191
+ // | /** Turkmenistan New Manat */ TMT
192
+ // | /** Tunisian Dinar */ TND
193
+ // | /** Pa’anga */ TOP
194
+ // | /** Turkish Lira */ TRY
195
+ // | /** Trinidad and Tobago Dollar */ TTD
196
+ // | /** New Taiwan Dollar */ TWD
197
+ // | /** Tanzanian Shilling */ TZS
198
+ // | /** Hryvnia */ UAH
199
+ // | /** Uganda Shilling */ UGX
200
+ // | /** USN */ USN
201
+ // | /** UYI */ UYI
202
+ // | /** Peso Uruguayo */ UYU
203
+ // | /** Unidad Previsional */ UYW
204
+ // | /** Uzbekistan Sum */ UZS
205
+ // | /** Bolívar Soberano */ VED
206
+ // | /** Bolívar Soberano */ VES
207
+ // | /** Dong */ VND
208
+ // | /** Vatu */ VUV
209
+ // | /** Tala */ WST
210
+ // | /** Arab Accounting Dinar */ XAD
211
+ // | /** CFA Franc BEAC */ XAF
212
+ // | /** East Caribbean Dollar */ XCD
213
+ // | /** Caribbean Guilder */ XCG
214
+ // | /** CFA Franc BCEAO */ XOF
215
+ // | /** CFP Franc */ XPF
216
+ // | /** Yemeni Rial */ YER
217
+ // | /** Rand */ ZAR
218
+ // | /** Zambian Kwacha */ ZMW
219
+ // | /** Zimbabwe Gold */ ZWG
220
+
221
+ /** Every currency the type admits, in code order. `fromString` is derived from
222
+ this, so a code that parses and a code that exists are the same set by
223
+ construction. */
215
224
  let all: array<t> = [
216
- AED, AFN, ALL, AMD, AOA, ARS, AUD, AWG, AZN, BAM, BBD, BDT, BHD, BIF, BMD, BND, BOB, BOV, BRL,
217
- BSD, BTN, BWP, BYN, BZD, CAD, CDF, CHE, CHF, CHW, CLF, CLP, CNY, COP, COU, CRC, CUP, CVE, CZK,
218
- DJF, DKK, DOP, DZD, EGP, ERN, ETB, EUR, FJD, FKP, GBP, GEL, GHS, GIP, GMD, GNF, GTQ, GYD, HKD,
219
- HNL, HTG, HUF, IDR, ILS, INR, IQD, IRR, ISK, JMD, JOD, JPY, KES, KGS, KHR, KMF, KPW, KRW, KWD,
220
- KYD, KZT, LAK, LBP, LKR, LRD, LSL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRU, MUR, MVR, MWK,
221
- MXN, MXV, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR,
222
- RON, RSD, RUB, RWF, SAR, SBD, SCR, SDG, SEK, SGD, SHP, SLE, SOS, SRD, SSP, STN, SVC, SYP, SZL,
223
- THB, TJS, TMT, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, USD, USN, UYI, UYU, UYW, UZS, VED, VES,
224
- VND, VUV, WST, XAD, XAF, XCD, XCG, XOF, XPF, YER, ZAR, ZMW, ZWG,
225
+ AUD, CAD, CHF, CNY, EUR, GBP, JPY, NOK, SEK, USD,
226
+ // AED, AFN, ALL, AMD, AOA, ARS, AWG, AZN, BAM, BBD, BDT, BHD, BIF, BMD, BND, BOB, BOV, BRL,
227
+ // BSD, BTN, BWP, BYN, BZD, CDF, CHE, CHW, CLF, CLP, COP, COU, CRC, CUP, CVE, CZK, DJF, DKK,
228
+ // DOP, DZD, EGP, ERN, ETB, FJD, FKP, GEL, GHS, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HTG, HUF,
229
+ // IDR, ILS, INR, IQD, IRR, ISK, JMD, JOD, KES, KGS, KHR, KMF, KPW, KRW, KWD, KYD, KZT, LAK,
230
+ // LBP, LKR, LRD, LSL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRU, MUR, MVR, MWK, MXN, MXV,
231
+ // MYR, MZN, NAD, NGN, NIO, NPR, NZD, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD,
232
+ // RUB, RWF, SAR, SBD, SCR, SDG, SGD, SHP, SLE, SOS, SRD, SSP, STN, SVC, SYP, SZL, THB, TJS,
233
+ // TMT, TND, TOP, TRY, TTD, TWD, TZS, UAH, UGX, USN, UYI, UYU, UYW, UZS, VED, VES, VND, VUV,
234
+ // WST, XAD, XAF, XCD, XCG, XOF, XPF, YER, ZAR, ZMW, ZWG,
225
235
  ]
226
236
 
227
237
  /** The currency's ISO 4217 alphabetic code. */
228
238
  let toString = (currency: t): string =>
229
239
  switch currency {
230
- | AED => "AED"
231
- | AFN => "AFN"
232
- | ALL => "ALL"
233
- | AMD => "AMD"
234
- | AOA => "AOA"
235
- | ARS => "ARS"
236
240
  | AUD => "AUD"
237
- | AWG => "AWG"
238
- | AZN => "AZN"
239
- | BAM => "BAM"
240
- | BBD => "BBD"
241
- | BDT => "BDT"
242
- | BHD => "BHD"
243
- | BIF => "BIF"
244
- | BMD => "BMD"
245
- | BND => "BND"
246
- | BOB => "BOB"
247
- | BOV => "BOV"
248
- | BRL => "BRL"
249
- | BSD => "BSD"
250
- | BTN => "BTN"
251
- | BWP => "BWP"
252
- | BYN => "BYN"
253
- | BZD => "BZD"
254
241
  | CAD => "CAD"
255
- | CDF => "CDF"
256
- | CHE => "CHE"
257
242
  | CHF => "CHF"
258
- | CHW => "CHW"
259
- | CLF => "CLF"
260
- | CLP => "CLP"
261
243
  | CNY => "CNY"
262
- | COP => "COP"
263
- | COU => "COU"
264
- | CRC => "CRC"
265
- | CUP => "CUP"
266
- | CVE => "CVE"
267
- | CZK => "CZK"
268
- | DJF => "DJF"
269
- | DKK => "DKK"
270
- | DOP => "DOP"
271
- | DZD => "DZD"
272
- | EGP => "EGP"
273
- | ERN => "ERN"
274
- | ETB => "ETB"
275
244
  | EUR => "EUR"
276
- | FJD => "FJD"
277
- | FKP => "FKP"
278
245
  | GBP => "GBP"
279
- | GEL => "GEL"
280
- | GHS => "GHS"
281
- | GIP => "GIP"
282
- | GMD => "GMD"
283
- | GNF => "GNF"
284
- | GTQ => "GTQ"
285
- | GYD => "GYD"
286
- | HKD => "HKD"
287
- | HNL => "HNL"
288
- | HTG => "HTG"
289
- | HUF => "HUF"
290
- | IDR => "IDR"
291
- | ILS => "ILS"
292
- | INR => "INR"
293
- | IQD => "IQD"
294
- | IRR => "IRR"
295
- | ISK => "ISK"
296
- | JMD => "JMD"
297
- | JOD => "JOD"
298
246
  | JPY => "JPY"
299
- | KES => "KES"
300
- | KGS => "KGS"
301
- | KHR => "KHR"
302
- | KMF => "KMF"
303
- | KPW => "KPW"
304
- | KRW => "KRW"
305
- | KWD => "KWD"
306
- | KYD => "KYD"
307
- | KZT => "KZT"
308
- | LAK => "LAK"
309
- | LBP => "LBP"
310
- | LKR => "LKR"
311
- | LRD => "LRD"
312
- | LSL => "LSL"
313
- | LYD => "LYD"
314
- | MAD => "MAD"
315
- | MDL => "MDL"
316
- | MGA => "MGA"
317
- | MKD => "MKD"
318
- | MMK => "MMK"
319
- | MNT => "MNT"
320
- | MOP => "MOP"
321
- | MRU => "MRU"
322
- | MUR => "MUR"
323
- | MVR => "MVR"
324
- | MWK => "MWK"
325
- | MXN => "MXN"
326
- | MXV => "MXV"
327
- | MYR => "MYR"
328
- | MZN => "MZN"
329
- | NAD => "NAD"
330
- | NGN => "NGN"
331
- | NIO => "NIO"
332
247
  | NOK => "NOK"
333
- | NPR => "NPR"
334
- | NZD => "NZD"
335
- | OMR => "OMR"
336
- | PAB => "PAB"
337
- | PEN => "PEN"
338
- | PGK => "PGK"
339
- | PHP => "PHP"
340
- | PKR => "PKR"
341
- | PLN => "PLN"
342
- | PYG => "PYG"
343
- | QAR => "QAR"
344
- | RON => "RON"
345
- | RSD => "RSD"
346
- | RUB => "RUB"
347
- | RWF => "RWF"
348
- | SAR => "SAR"
349
- | SBD => "SBD"
350
- | SCR => "SCR"
351
- | SDG => "SDG"
352
248
  | SEK => "SEK"
353
- | SGD => "SGD"
354
- | SHP => "SHP"
355
- | SLE => "SLE"
356
- | SOS => "SOS"
357
- | SRD => "SRD"
358
- | SSP => "SSP"
359
- | STN => "STN"
360
- | SVC => "SVC"
361
- | SYP => "SYP"
362
- | SZL => "SZL"
363
- | THB => "THB"
364
- | TJS => "TJS"
365
- | TMT => "TMT"
366
- | TND => "TND"
367
- | TOP => "TOP"
368
- | TRY => "TRY"
369
- | TTD => "TTD"
370
- | TWD => "TWD"
371
- | TZS => "TZS"
372
- | UAH => "UAH"
373
- | UGX => "UGX"
374
249
  | USD => "USD"
375
- | USN => "USN"
376
- | UYI => "UYI"
377
- | UYU => "UYU"
378
- | UYW => "UYW"
379
- | UZS => "UZS"
380
- | VED => "VED"
381
- | VES => "VES"
382
- | VND => "VND"
383
- | VUV => "VUV"
384
- | WST => "WST"
385
- | XAD => "XAD"
386
- | XAF => "XAF"
387
- | XCD => "XCD"
388
- | XCG => "XCG"
389
- | XOF => "XOF"
390
- | XPF => "XPF"
391
- | YER => "YER"
392
- | ZAR => "ZAR"
393
- | ZMW => "ZMW"
394
- | ZWG => "ZWG"
250
+ // | AED => "AED"
251
+ // | AFN => "AFN"
252
+ // | ALL => "ALL"
253
+ // | AMD => "AMD"
254
+ // | AOA => "AOA"
255
+ // | ARS => "ARS"
256
+ // | AWG => "AWG"
257
+ // | AZN => "AZN"
258
+ // | BAM => "BAM"
259
+ // | BBD => "BBD"
260
+ // | BDT => "BDT"
261
+ // | BHD => "BHD"
262
+ // | BIF => "BIF"
263
+ // | BMD => "BMD"
264
+ // | BND => "BND"
265
+ // | BOB => "BOB"
266
+ // | BOV => "BOV"
267
+ // | BRL => "BRL"
268
+ // | BSD => "BSD"
269
+ // | BTN => "BTN"
270
+ // | BWP => "BWP"
271
+ // | BYN => "BYN"
272
+ // | BZD => "BZD"
273
+ // | CDF => "CDF"
274
+ // | CHE => "CHE"
275
+ // | CHW => "CHW"
276
+ // | CLF => "CLF"
277
+ // | CLP => "CLP"
278
+ // | COP => "COP"
279
+ // | COU => "COU"
280
+ // | CRC => "CRC"
281
+ // | CUP => "CUP"
282
+ // | CVE => "CVE"
283
+ // | CZK => "CZK"
284
+ // | DJF => "DJF"
285
+ // | DKK => "DKK"
286
+ // | DOP => "DOP"
287
+ // | DZD => "DZD"
288
+ // | EGP => "EGP"
289
+ // | ERN => "ERN"
290
+ // | ETB => "ETB"
291
+ // | FJD => "FJD"
292
+ // | FKP => "FKP"
293
+ // | GEL => "GEL"
294
+ // | GHS => "GHS"
295
+ // | GIP => "GIP"
296
+ // | GMD => "GMD"
297
+ // | GNF => "GNF"
298
+ // | GTQ => "GTQ"
299
+ // | GYD => "GYD"
300
+ // | HKD => "HKD"
301
+ // | HNL => "HNL"
302
+ // | HTG => "HTG"
303
+ // | HUF => "HUF"
304
+ // | IDR => "IDR"
305
+ // | ILS => "ILS"
306
+ // | INR => "INR"
307
+ // | IQD => "IQD"
308
+ // | IRR => "IRR"
309
+ // | ISK => "ISK"
310
+ // | JMD => "JMD"
311
+ // | JOD => "JOD"
312
+ // | KES => "KES"
313
+ // | KGS => "KGS"
314
+ // | KHR => "KHR"
315
+ // | KMF => "KMF"
316
+ // | KPW => "KPW"
317
+ // | KRW => "KRW"
318
+ // | KWD => "KWD"
319
+ // | KYD => "KYD"
320
+ // | KZT => "KZT"
321
+ // | LAK => "LAK"
322
+ // | LBP => "LBP"
323
+ // | LKR => "LKR"
324
+ // | LRD => "LRD"
325
+ // | LSL => "LSL"
326
+ // | LYD => "LYD"
327
+ // | MAD => "MAD"
328
+ // | MDL => "MDL"
329
+ // | MGA => "MGA"
330
+ // | MKD => "MKD"
331
+ // | MMK => "MMK"
332
+ // | MNT => "MNT"
333
+ // | MOP => "MOP"
334
+ // | MRU => "MRU"
335
+ // | MUR => "MUR"
336
+ // | MVR => "MVR"
337
+ // | MWK => "MWK"
338
+ // | MXN => "MXN"
339
+ // | MXV => "MXV"
340
+ // | MYR => "MYR"
341
+ // | MZN => "MZN"
342
+ // | NAD => "NAD"
343
+ // | NGN => "NGN"
344
+ // | NIO => "NIO"
345
+ // | NPR => "NPR"
346
+ // | NZD => "NZD"
347
+ // | OMR => "OMR"
348
+ // | PAB => "PAB"
349
+ // | PEN => "PEN"
350
+ // | PGK => "PGK"
351
+ // | PHP => "PHP"
352
+ // | PKR => "PKR"
353
+ // | PLN => "PLN"
354
+ // | PYG => "PYG"
355
+ // | QAR => "QAR"
356
+ // | RON => "RON"
357
+ // | RSD => "RSD"
358
+ // | RUB => "RUB"
359
+ // | RWF => "RWF"
360
+ // | SAR => "SAR"
361
+ // | SBD => "SBD"
362
+ // | SCR => "SCR"
363
+ // | SDG => "SDG"
364
+ // | SGD => "SGD"
365
+ // | SHP => "SHP"
366
+ // | SLE => "SLE"
367
+ // | SOS => "SOS"
368
+ // | SRD => "SRD"
369
+ // | SSP => "SSP"
370
+ // | STN => "STN"
371
+ // | SVC => "SVC"
372
+ // | SYP => "SYP"
373
+ // | SZL => "SZL"
374
+ // | THB => "THB"
375
+ // | TJS => "TJS"
376
+ // | TMT => "TMT"
377
+ // | TND => "TND"
378
+ // | TOP => "TOP"
379
+ // | TRY => "TRY"
380
+ // | TTD => "TTD"
381
+ // | TWD => "TWD"
382
+ // | TZS => "TZS"
383
+ // | UAH => "UAH"
384
+ // | UGX => "UGX"
385
+ // | USN => "USN"
386
+ // | UYI => "UYI"
387
+ // | UYU => "UYU"
388
+ // | UYW => "UYW"
389
+ // | UZS => "UZS"
390
+ // | VED => "VED"
391
+ // | VES => "VES"
392
+ // | VND => "VND"
393
+ // | VUV => "VUV"
394
+ // | WST => "WST"
395
+ // | XAD => "XAD"
396
+ // | XAF => "XAF"
397
+ // | XCD => "XCD"
398
+ // | XCG => "XCG"
399
+ // | XOF => "XOF"
400
+ // | XPF => "XPF"
401
+ // | YER => "YER"
402
+ // | ZAR => "ZAR"
403
+ // | ZMW => "ZMW"
404
+ // | ZWG => "ZWG"
395
405
  }
396
406
 
397
407
  /**
398
- How many decimal places the currency's minor unit is: 2 for EUR, **0 for JPY**,
399
- **3 for TND**, 4 for the Chilean Unidad de Fomento.
408
+ How many decimal places the currency's minor unit is: 2 for EUR, **0 for JPY**.
409
+ Among the dormant codes it reaches 3 (TND) and 4 (the Chilean Unidad de
410
+ Fomento), which is why nothing here may assume two.
400
411
 
401
412
  Total by construction — this is the whole reason the type is closed and the
402
- table is generated. An amount is stored in integer minor units, so this is the
403
- only thing that says where its decimal point goes.
413
+ table is generated. An amount carries exactly this many decimals, so this is the
414
+ only thing that says how precise one may be.
404
415
  */
405
416
  let exponent = (currency: t): int =>
406
417
  switch currency {
407
- | AED => 2
408
- | AFN => 2
409
- | ALL => 2
410
- | AMD => 2
411
- | AOA => 2
412
- | ARS => 2
413
418
  | AUD => 2
414
- | AWG => 2
415
- | AZN => 2
416
- | BAM => 2
417
- | BBD => 2
418
- | BDT => 2
419
- | BHD => 3
420
- | BIF => 0
421
- | BMD => 2
422
- | BND => 2
423
- | BOB => 2
424
- | BOV => 2
425
- | BRL => 2
426
- | BSD => 2
427
- | BTN => 2
428
- | BWP => 2
429
- | BYN => 2
430
- | BZD => 2
431
419
  | CAD => 2
432
- | CDF => 2
433
- | CHE => 2
434
420
  | CHF => 2
435
- | CHW => 2
436
- | CLF => 4
437
- | CLP => 0
438
421
  | CNY => 2
439
- | COP => 2
440
- | COU => 2
441
- | CRC => 2
442
- | CUP => 2
443
- | CVE => 2
444
- | CZK => 2
445
- | DJF => 0
446
- | DKK => 2
447
- | DOP => 2
448
- | DZD => 2
449
- | EGP => 2
450
- | ERN => 2
451
- | ETB => 2
452
422
  | EUR => 2
453
- | FJD => 2
454
- | FKP => 2
455
423
  | GBP => 2
456
- | GEL => 2
457
- | GHS => 2
458
- | GIP => 2
459
- | GMD => 2
460
- | GNF => 0
461
- | GTQ => 2
462
- | GYD => 2
463
- | HKD => 2
464
- | HNL => 2
465
- | HTG => 2
466
- | HUF => 2
467
- | IDR => 2
468
- | ILS => 2
469
- | INR => 2
470
- | IQD => 3
471
- | IRR => 2
472
- | ISK => 0
473
- | JMD => 2
474
- | JOD => 3
475
424
  | JPY => 0
476
- | KES => 2
477
- | KGS => 2
478
- | KHR => 2
479
- | KMF => 0
480
- | KPW => 2
481
- | KRW => 0
482
- | KWD => 3
483
- | KYD => 2
484
- | KZT => 2
485
- | LAK => 2
486
- | LBP => 2
487
- | LKR => 2
488
- | LRD => 2
489
- | LSL => 2
490
- | LYD => 3
491
- | MAD => 2
492
- | MDL => 2
493
- | MGA => 2
494
- | MKD => 2
495
- | MMK => 2
496
- | MNT => 2
497
- | MOP => 2
498
- | MRU => 2
499
- | MUR => 2
500
- | MVR => 2
501
- | MWK => 2
502
- | MXN => 2
503
- | MXV => 2
504
- | MYR => 2
505
- | MZN => 2
506
- | NAD => 2
507
- | NGN => 2
508
- | NIO => 2
509
425
  | NOK => 2
510
- | NPR => 2
511
- | NZD => 2
512
- | OMR => 3
513
- | PAB => 2
514
- | PEN => 2
515
- | PGK => 2
516
- | PHP => 2
517
- | PKR => 2
518
- | PLN => 2
519
- | PYG => 0
520
- | QAR => 2
521
- | RON => 2
522
- | RSD => 2
523
- | RUB => 2
524
- | RWF => 0
525
- | SAR => 2
526
- | SBD => 2
527
- | SCR => 2
528
- | SDG => 2
529
426
  | SEK => 2
530
- | SGD => 2
531
- | SHP => 2
532
- | SLE => 2
533
- | SOS => 2
534
- | SRD => 2
535
- | SSP => 2
536
- | STN => 2
537
- | SVC => 2
538
- | SYP => 2
539
- | SZL => 2
540
- | THB => 2
541
- | TJS => 2
542
- | TMT => 2
543
- | TND => 3
544
- | TOP => 2
545
- | TRY => 2
546
- | TTD => 2
547
- | TWD => 2
548
- | TZS => 2
549
- | UAH => 2
550
- | UGX => 0
551
427
  | USD => 2
552
- | USN => 2
553
- | UYI => 0
554
- | UYU => 2
555
- | UYW => 4
556
- | UZS => 2
557
- | VED => 2
558
- | VES => 2
559
- | VND => 0
560
- | VUV => 0
561
- | WST => 2
562
- | XAD => 2
563
- | XAF => 0
564
- | XCD => 2
565
- | XCG => 2
566
- | XOF => 0
567
- | XPF => 0
568
- | YER => 2
569
- | ZAR => 2
570
- | ZMW => 2
571
- | ZWG => 2
428
+ // | AED => 2
429
+ // | AFN => 2
430
+ // | ALL => 2
431
+ // | AMD => 2
432
+ // | AOA => 2
433
+ // | ARS => 2
434
+ // | AWG => 2
435
+ // | AZN => 2
436
+ // | BAM => 2
437
+ // | BBD => 2
438
+ // | BDT => 2
439
+ // | BHD => 3
440
+ // | BIF => 0
441
+ // | BMD => 2
442
+ // | BND => 2
443
+ // | BOB => 2
444
+ // | BOV => 2
445
+ // | BRL => 2
446
+ // | BSD => 2
447
+ // | BTN => 2
448
+ // | BWP => 2
449
+ // | BYN => 2
450
+ // | BZD => 2
451
+ // | CDF => 2
452
+ // | CHE => 2
453
+ // | CHW => 2
454
+ // | CLF => 4
455
+ // | CLP => 0
456
+ // | COP => 2
457
+ // | COU => 2
458
+ // | CRC => 2
459
+ // | CUP => 2
460
+ // | CVE => 2
461
+ // | CZK => 2
462
+ // | DJF => 0
463
+ // | DKK => 2
464
+ // | DOP => 2
465
+ // | DZD => 2
466
+ // | EGP => 2
467
+ // | ERN => 2
468
+ // | ETB => 2
469
+ // | FJD => 2
470
+ // | FKP => 2
471
+ // | GEL => 2
472
+ // | GHS => 2
473
+ // | GIP => 2
474
+ // | GMD => 2
475
+ // | GNF => 0
476
+ // | GTQ => 2
477
+ // | GYD => 2
478
+ // | HKD => 2
479
+ // | HNL => 2
480
+ // | HTG => 2
481
+ // | HUF => 2
482
+ // | IDR => 2
483
+ // | ILS => 2
484
+ // | INR => 2
485
+ // | IQD => 3
486
+ // | IRR => 2
487
+ // | ISK => 0
488
+ // | JMD => 2
489
+ // | JOD => 3
490
+ // | KES => 2
491
+ // | KGS => 2
492
+ // | KHR => 2
493
+ // | KMF => 0
494
+ // | KPW => 2
495
+ // | KRW => 0
496
+ // | KWD => 3
497
+ // | KYD => 2
498
+ // | KZT => 2
499
+ // | LAK => 2
500
+ // | LBP => 2
501
+ // | LKR => 2
502
+ // | LRD => 2
503
+ // | LSL => 2
504
+ // | LYD => 3
505
+ // | MAD => 2
506
+ // | MDL => 2
507
+ // | MGA => 2
508
+ // | MKD => 2
509
+ // | MMK => 2
510
+ // | MNT => 2
511
+ // | MOP => 2
512
+ // | MRU => 2
513
+ // | MUR => 2
514
+ // | MVR => 2
515
+ // | MWK => 2
516
+ // | MXN => 2
517
+ // | MXV => 2
518
+ // | MYR => 2
519
+ // | MZN => 2
520
+ // | NAD => 2
521
+ // | NGN => 2
522
+ // | NIO => 2
523
+ // | NPR => 2
524
+ // | NZD => 2
525
+ // | OMR => 3
526
+ // | PAB => 2
527
+ // | PEN => 2
528
+ // | PGK => 2
529
+ // | PHP => 2
530
+ // | PKR => 2
531
+ // | PLN => 2
532
+ // | PYG => 0
533
+ // | QAR => 2
534
+ // | RON => 2
535
+ // | RSD => 2
536
+ // | RUB => 2
537
+ // | RWF => 0
538
+ // | SAR => 2
539
+ // | SBD => 2
540
+ // | SCR => 2
541
+ // | SDG => 2
542
+ // | SGD => 2
543
+ // | SHP => 2
544
+ // | SLE => 2
545
+ // | SOS => 2
546
+ // | SRD => 2
547
+ // | SSP => 2
548
+ // | STN => 2
549
+ // | SVC => 2
550
+ // | SYP => 2
551
+ // | SZL => 2
552
+ // | THB => 2
553
+ // | TJS => 2
554
+ // | TMT => 2
555
+ // | TND => 3
556
+ // | TOP => 2
557
+ // | TRY => 2
558
+ // | TTD => 2
559
+ // | TWD => 2
560
+ // | TZS => 2
561
+ // | UAH => 2
562
+ // | UGX => 0
563
+ // | USN => 2
564
+ // | UYI => 0
565
+ // | UYU => 2
566
+ // | UYW => 4
567
+ // | UZS => 2
568
+ // | VED => 2
569
+ // | VES => 2
570
+ // | VND => 0
571
+ // | VUV => 0
572
+ // | WST => 2
573
+ // | XAD => 2
574
+ // | XAF => 0
575
+ // | XCD => 2
576
+ // | XCG => 2
577
+ // | XOF => 0
578
+ // | XPF => 0
579
+ // | YER => 2
580
+ // | ZAR => 2
581
+ // | ZMW => 2
582
+ // | ZWG => 2
572
583
  }
573
584
 
574
585
  let byCode: dict<t> = {
@@ -585,13 +596,19 @@ exists because a silent case mismatch is expensive to find, and quietly
585
596
  accepting the wrong spelling at the boundary would put it back — a producer
586
597
  sending lowercase codes should learn that at its first request, not at the first
587
598
  report that two halves of a ledger disagree.
599
+
600
+ A code the standard defines but this type does not admit is rejected the same
601
+ way, and the message says so: the caller's next move is to admit it, not to
602
+ correct the spelling.
588
603
  */
589
604
  let fromString = (raw: string): result<t, string> =>
590
605
  switch byCode->Dict.get(raw) {
591
606
  | Some(c) => Ok(c)
592
607
  | None =>
593
608
  Error(
594
- `expected an ISO 4217 currency code such as "EUR", got ${raw
609
+ `expected one of the ISO 4217 codes this framework admits (${all
610
+ ->Array.map(toString)
611
+ ->Array.join(", ")}), got ${raw
595
612
  ->JSON.Encode.string
596
613
  ->JSON.stringify}. Codes are upper-case and exactly three letters.`,
597
614
  )