@lightsparkdev/core 1.0.4 → 1.0.6

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.
@@ -0,0 +1,272 @@
1
+ /* From https://github.com/tadeegan/locale-currency. For now only USD conversion from
2
+ BTC is supported by sparkcore, strip additional currency codes from the bundle: */
3
+ export const countryCodesToCurrencyCodes = {
4
+ AD: "EUR",
5
+ // AE: "AED",
6
+ // AF: "AFN",
7
+ // AG: "XCD",
8
+ // AI: "XCD",
9
+ // AL: "ALL",
10
+ // AM: "AMD",
11
+ // AO: "AOA",
12
+ AR: "ARS",
13
+ AS: "USD",
14
+ AT: "EUR",
15
+ AU: "AUD",
16
+ // AW: "AWG",
17
+ AX: "EUR",
18
+ // AZ: "AZN",
19
+ // BA: "BAM",
20
+ // BB: "BBD",
21
+ // BD: "BDT",
22
+ BE: "EUR",
23
+ // BF: "XOF",
24
+ // BG: "BGN",
25
+ // BH: "BHD",
26
+ // BI: "BIF",
27
+ // BJ: "XOF",
28
+ BL: "EUR",
29
+ // BM: "BMD",
30
+ // BN: "BND",
31
+ // BO: "BOB",
32
+ BQ: "USD",
33
+ BR: "BRL",
34
+ // BS: "BSD",
35
+ // BT: "BTN",
36
+ // BV: "NOK",
37
+ // BW: "BWP",
38
+ // BY: "BYN",
39
+ // BZ: "BZD",
40
+ CA: "CAD",
41
+ // CC: "AUD",
42
+ // CD: "CDF",
43
+ // CF: "XAF",
44
+ // CG: "XAF",
45
+ // CH: "CHF",
46
+ // CI: "XOF",
47
+ // CK: "NZD",
48
+ // CL: "CLP",
49
+ // CM: "XAF",
50
+ // CN: "CNY",
51
+ CO: "COP",
52
+ // CR: "CRC",
53
+ // CU: "CUP",
54
+ // CV: "CVE",
55
+ // CW: "ANG",
56
+ // CX: "AUD",
57
+ CY: "EUR",
58
+ // CZ: "CZK",
59
+ DE: "EUR",
60
+ // DJ: "DJF",
61
+ // DK: "DKK",
62
+ // DM: "XCD",
63
+ // DO: "DOP",
64
+ // DZ: "DZD",
65
+ EC: "USD",
66
+ EE: "EUR",
67
+ // EG: "EGP",
68
+ // EH: "MAD",
69
+ // ER: "ERN",
70
+ ES: "EUR",
71
+ // ET: "ETB",
72
+ FI: "EUR",
73
+ // FJ: "FJD",
74
+ // FK: "FKP",
75
+ FM: "USD",
76
+ // FO: "DKK",
77
+ FR: "EUR",
78
+ // GA: "XAF",
79
+ GB: "GBP",
80
+ // GD: "XCD",
81
+ // GE: "GEL",
82
+ GF: "EUR",
83
+ GG: "GBP",
84
+ // GH: "GHS",
85
+ // GI: "GIP",
86
+ // GL: "DKK",
87
+ // GM: "GMD",
88
+ // GN: "GNF",
89
+ GP: "EUR",
90
+ // GQ: "XAF",
91
+ GR: "EUR",
92
+ GS: "GBP",
93
+ // GT: "GTQ",
94
+ GU: "USD",
95
+ // GW: "XOF",
96
+ // GY: "GYD",
97
+ // HK: "HKD",
98
+ // HM: "AUD",
99
+ // HN: "HNL",
100
+ // HR: "HRK",
101
+ // HT: "HTG",
102
+ // HU: "HUF",
103
+ // ID: "IDR",
104
+ IE: "EUR",
105
+ // IL: "ILS",
106
+ IM: "GBP",
107
+ IN: "INR",
108
+ IO: "USD",
109
+ // IQ: "IQD",
110
+ // IR: "IRR",
111
+ // IS: "ISK",
112
+ IT: "EUR",
113
+ JE: "GBP",
114
+ // JM: "JMD",
115
+ // JO: "JOD",
116
+ // JP: "JPY",
117
+ // KE: "KES",
118
+ // KG: "KGS",
119
+ // KH: "KHR",
120
+ // KI: "AUD",
121
+ // KM: "KMF",
122
+ // KN: "XCD",
123
+ // KP: "KPW",
124
+ // KR: "KRW",
125
+ // KW: "KWD",
126
+ // KY: "KYD",
127
+ // KZ: "KZT",
128
+ // LA: "LAK",
129
+ // LB: "LBP",
130
+ // LC: "XCD",
131
+ // LI: "CHF",
132
+ // LK: "LKR",
133
+ // LR: "LRD",
134
+ // LS: "LSL",
135
+ LT: "EUR",
136
+ LU: "EUR",
137
+ LV: "EUR",
138
+ // LY: "LYD",
139
+ // MA: "MAD",
140
+ MC: "EUR",
141
+ // MD: "MDL",
142
+ ME: "EUR",
143
+ MF: "EUR",
144
+ // MG: "MGA",
145
+ MH: "USD",
146
+ // MK: "MKD",
147
+ // ML: "XOF",
148
+ // MM: "MMK",
149
+ // MN: "MNT",
150
+ // MO: "MOP",
151
+ MP: "USD",
152
+ MQ: "EUR",
153
+ // MR: "MRO",
154
+ // MS: "XCD",
155
+ MT: "EUR",
156
+ // MU: "MUR",
157
+ // MV: "MVR",
158
+ // MW: "MWK",
159
+ MX: "MXN",
160
+ // MY: "MYR",
161
+ // MZ: "MZN",
162
+ // NA: "NAD",
163
+ // NC: "XPF",
164
+ // NE: "XOF",
165
+ NF: "AUD",
166
+ // NG: "NGN",
167
+ // NI: "NIO",
168
+ NL: "EUR",
169
+ // NO: "NOK",
170
+ // NP: "NPR",
171
+ NR: "AUD",
172
+ // NU: "NZD",
173
+ // NZ: "NZD",
174
+ // OM: "OMR",
175
+ // PA: "PAB",
176
+ // PE: "PEN",
177
+ // PF: "XPF",
178
+ // PG: "PGK",
179
+ // PH: "PHP",
180
+ // PK: "PKR",
181
+ // PL: "PLN",
182
+ PM: "EUR",
183
+ // PN: "NZD",
184
+ PR: "USD",
185
+ // PS: "ILS",
186
+ PT: "EUR",
187
+ PW: "USD",
188
+ // PY: "PYG",
189
+ // QA: "QAR",
190
+ RE: "EUR",
191
+ // RO: "RON",
192
+ // RS: "RSD",
193
+ // RU: "RUB",
194
+ // RW: "RWF",
195
+ // SA: "SAR",
196
+ // SB: "SBD",
197
+ // SC: "SCR",
198
+ // SD: "SDG",
199
+ // SE: "SEK",
200
+ // SG: "SGD",
201
+ // SH: "SHP",
202
+ SI: "EUR",
203
+ // SJ: "NOK",
204
+ SK: "EUR",
205
+ // SL: "SLL",
206
+ SM: "EUR",
207
+ // SN: "XOF",
208
+ // SO: "SOS",
209
+ // SR: "SRD",
210
+ // ST: "STD",
211
+ // SV: "SVC",
212
+ // SX: "ANG",
213
+ // SY: "SYP",
214
+ // SZ: "SZL",
215
+ TC: "USD",
216
+ // TD: "XAF",
217
+ TF: "EUR",
218
+ // TG: "XOF",
219
+ // TH: "THB",
220
+ // TJ: "TJS",
221
+ // TK: "NZD",
222
+ TL: "USD",
223
+ // TM: "TMT",
224
+ // TN: "TND",
225
+ // TO: "TOP",
226
+ // TR: "TRY",
227
+ // TT: "TTD",
228
+ TV: "AUD",
229
+ // TW: "TWD",
230
+ // TZ: "TZS",
231
+ // UA: "UAH",
232
+ // UG: "UGX",
233
+ UM: "USD",
234
+ US: "USD",
235
+ // UY: "UYU",
236
+ // UZ: "UZS",
237
+ VA: "EUR",
238
+ // VC: "XCD",
239
+ // VE: "VEF",
240
+ VG: "USD",
241
+ VI: "USD",
242
+ // VN: "VND",
243
+ // VU: "VUV",
244
+ // WF: "XPF",
245
+ // WS: "WST",
246
+ // YE: "YER",
247
+ YT: "EUR",
248
+ // ZA: "ZAR",
249
+ // ZM: "ZMW",
250
+ // ZW: "ZWL",
251
+ } as const;
252
+
253
+ export type CurrencyLocales = keyof typeof countryCodesToCurrencyCodes;
254
+ export type CurrencyCodes =
255
+ (typeof countryCodesToCurrencyCodes)[CurrencyLocales];
256
+
257
+ function getCountryCode(localeString: string) {
258
+ let components = localeString.split("_");
259
+ if (components.length === 2) {
260
+ return components.pop() as string;
261
+ }
262
+ components = localeString.split("-");
263
+ if (components.length === 2) {
264
+ return components.pop() as string;
265
+ }
266
+ return localeString;
267
+ }
268
+
269
+ export function localeToCurrencyCode(locale: string): CurrencyCodes {
270
+ const countryCode = getCountryCode(locale) as CurrencyLocales;
271
+ return countryCodesToCurrencyCodes[countryCode];
272
+ }
@@ -0,0 +1,32 @@
1
+ export function clamp(val: number, min: number, max: number): number {
2
+ return val > max ? max : val < min ? min : val;
3
+ }
4
+
5
+ export function linearInterpolate(
6
+ value: number,
7
+ fromRangeStart: number,
8
+ fromRangeEnd: number,
9
+ toRangeStart: number,
10
+ toRangeEnd: number,
11
+ ) {
12
+ const fromRangeMax = fromRangeEnd - fromRangeStart;
13
+ const fromRangeVal = value - fromRangeStart;
14
+ const toRangeMax = toRangeEnd - toRangeStart;
15
+ const val = (fromRangeVal / fromRangeMax) * toRangeMax + toRangeStart;
16
+ return clamp(
17
+ val,
18
+ Math.min(toRangeStart, toRangeEnd),
19
+ Math.max(toRangeStart, toRangeEnd),
20
+ );
21
+ }
22
+
23
+ /* https://stackoverflow.com/a/48764436 */
24
+ export function round(num: number, decimalPlaces = 0) {
25
+ const p = Math.pow(10, decimalPlaces);
26
+ const n = num * p * (1 + Number.EPSILON);
27
+ return Math.round(n) / p;
28
+ }
29
+
30
+ export function isNumber(value: unknown): value is number {
31
+ return typeof value === "number";
32
+ }
@@ -0,0 +1,190 @@
1
+ // add tests for convertCurrencyAmountValue function
2
+
3
+ import {
4
+ convertCurrencyAmountValue,
5
+ CurrencyUnit,
6
+ localeToCurrencySymbol,
7
+ mapCurrencyAmount,
8
+ } from "../currency.js";
9
+
10
+ describe("convertCurrencyAmountValue", () => {
11
+ it("should return the same value if the currency is the same", () => {
12
+ expect(
13
+ convertCurrencyAmountValue(CurrencyUnit.USD, CurrencyUnit.USD, 10),
14
+ ).toBe(10);
15
+ });
16
+ it("should convert from SAT to mSAT", () => {
17
+ expect(
18
+ convertCurrencyAmountValue(
19
+ CurrencyUnit.SATOSHI,
20
+ CurrencyUnit.MILLISATOSHI,
21
+ 100_000,
22
+ ),
23
+ ).toBe(100_000_000);
24
+ });
25
+ it("should convert from SAT to BTC", () => {
26
+ expect(
27
+ convertCurrencyAmountValue(
28
+ CurrencyUnit.SATOSHI,
29
+ CurrencyUnit.BITCOIN,
30
+ 100000000,
31
+ ),
32
+ ).toBe(1);
33
+ });
34
+ it("should convert from SAT to USD", () => {
35
+ expect(
36
+ convertCurrencyAmountValue(
37
+ CurrencyUnit.SATOSHI,
38
+ CurrencyUnit.USD,
39
+ 100_000,
40
+ 25_000_00,
41
+ ),
42
+ ).toBe(25_00);
43
+ });
44
+ it("should convert from USD to mSAT", () => {
45
+ expect(
46
+ convertCurrencyAmountValue(
47
+ CurrencyUnit.USD,
48
+ CurrencyUnit.MILLISATOSHI,
49
+ 25_00,
50
+ 25_000_00,
51
+ ),
52
+ ).toBe(100_000_000);
53
+ });
54
+ it("should convert from USD to SAT", () => {
55
+ expect(
56
+ convertCurrencyAmountValue(
57
+ CurrencyUnit.USD,
58
+ CurrencyUnit.SATOSHI,
59
+ 25_00,
60
+ 25_000_00,
61
+ ),
62
+ ).toBe(100_000);
63
+ });
64
+ it("should convert from USD to BTC", () => {
65
+ expect(
66
+ convertCurrencyAmountValue(
67
+ CurrencyUnit.USD,
68
+ CurrencyUnit.BITCOIN,
69
+ 25_000_00,
70
+ 25_000_00,
71
+ ),
72
+ ).toBe(1);
73
+ });
74
+ it("should convert from BTC to USD", () => {
75
+ expect(
76
+ convertCurrencyAmountValue(
77
+ CurrencyUnit.BITCOIN,
78
+ CurrencyUnit.USD,
79
+ 1,
80
+ 25_000_00,
81
+ ),
82
+ ).toBe(25_000_00);
83
+ });
84
+ it("should convert from BTC to mSAT", () => {
85
+ expect(
86
+ convertCurrencyAmountValue(
87
+ CurrencyUnit.BITCOIN,
88
+ CurrencyUnit.MILLISATOSHI,
89
+ 1,
90
+ ),
91
+ ).toBe(100_000_000_000);
92
+ });
93
+ it("should convert from BTC to SAT", () => {
94
+ expect(
95
+ convertCurrencyAmountValue(CurrencyUnit.BITCOIN, CurrencyUnit.SATOSHI, 1),
96
+ ).toBe(100000000);
97
+ });
98
+ it("should convert from mSAT to BTC", () => {
99
+ expect(
100
+ convertCurrencyAmountValue(
101
+ CurrencyUnit.MILLISATOSHI,
102
+ CurrencyUnit.BITCOIN,
103
+ 100_000_000_000,
104
+ ),
105
+ ).toBe(1);
106
+ });
107
+ it("should convert from mSAT to USD", () => {
108
+ expect(
109
+ convertCurrencyAmountValue(
110
+ CurrencyUnit.MILLISATOSHI,
111
+ CurrencyUnit.USD,
112
+ 100_000_000,
113
+ 25_000_00,
114
+ ),
115
+ ).toBe(25_00);
116
+ });
117
+ it("should convert from mSAT to SAT", () => {
118
+ expect(
119
+ convertCurrencyAmountValue(
120
+ CurrencyUnit.MILLISATOSHI,
121
+ CurrencyUnit.SATOSHI,
122
+ 100_000_000,
123
+ ),
124
+ ).toBe(100_000);
125
+ });
126
+
127
+ it("should round properly", () => {
128
+ expect(
129
+ convertCurrencyAmountValue(
130
+ CurrencyUnit.SATOSHI,
131
+ CurrencyUnit.USD,
132
+ 23_952_251,
133
+ 25_124_19,
134
+ ),
135
+ ).toBe(6017_81); // 6017_80.90505169
136
+ });
137
+ });
138
+
139
+ describe("mapCurrencyAmount", () => {
140
+ it("should return the expected value for a CurrencyAmountObj", () => {
141
+ const currencyMap = mapCurrencyAmount(
142
+ {
143
+ value: 100_000_000,
144
+ unit: CurrencyUnit.SATOSHI,
145
+ },
146
+ 25_000_00,
147
+ );
148
+ expect(currencyMap.btc).toBe(1);
149
+ expect(currencyMap.USD).toBe(25_000_00);
150
+ expect(currencyMap.sats).toBe(100_000_000);
151
+ expect(currencyMap.msats).toBe(100_000_000_000);
152
+ expect(currencyMap.formatted.btc).toBe("1");
153
+ expect(currencyMap.formatted.USD).toBe("$25,000.00");
154
+ expect(currencyMap.formatted.sats).toBe("100,000,000");
155
+ expect(currencyMap.formatted.msats).toBe("100,000,000,000");
156
+ expect(currencyMap.isEqualTo(currencyMap)).toBe(true);
157
+
158
+ const smallerCurrencyMap = mapCurrencyAmount(
159
+ {
160
+ value: 100_000,
161
+ unit: CurrencyUnit.SATOSHI,
162
+ },
163
+ 25_000_00,
164
+ );
165
+
166
+ expect(currencyMap.isEqualTo(smallerCurrencyMap)).toBe(false);
167
+ expect(currencyMap.isGreaterThan(smallerCurrencyMap)).toBe(true);
168
+ expect(currencyMap.isLessThan(smallerCurrencyMap)).toBe(false);
169
+ expect(smallerCurrencyMap.isGreaterThan(currencyMap)).toBe(false);
170
+ expect(smallerCurrencyMap.isLessThan(currencyMap)).toBe(true);
171
+ });
172
+ });
173
+
174
+ describe("getCurrencySymbol", () => {
175
+ it("should return the expected currency symbol", () => {
176
+ expect(localeToCurrencySymbol("en-US")).toBe("$");
177
+ expect(localeToCurrencySymbol("en-GB")).toBe("£");
178
+ expect(localeToCurrencySymbol("en-CA")).toBe("$");
179
+ expect(localeToCurrencySymbol("en-AU")).toBe("$");
180
+ expect(localeToCurrencySymbol("en-IN")).toBe("₹");
181
+ expect(localeToCurrencySymbol("en-IE")).toBe("€");
182
+ expect(localeToCurrencySymbol("en-DE")).toBe("€");
183
+ expect(localeToCurrencySymbol("en-FR")).toBe("€");
184
+ expect(localeToCurrencySymbol("en-IT")).toBe("€");
185
+ expect(localeToCurrencySymbol("es-MX")).toBe("$");
186
+ expect(localeToCurrencySymbol("es-CO")).toBe("$");
187
+ expect(localeToCurrencySymbol("pt-BR")).toBe("R$");
188
+ expect(localeToCurrencySymbol("es-AR")).toBe("$");
189
+ });
190
+ });