exchange-rate-sdk 0.0.1

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.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025 chengzuopeng
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # Exchange Rate SDK
2
+
3
+ 一个轻量级、跨平台的汇率查询的 JavaScript SDK,支持浏览器和 Node.js 环境运行。
4
+
5
+ A lightweight, cross-platform exchange rate JavaScript SDK for browser and Node.js.
6
+
7
+ ## ✨ 特性 / Features
8
+
9
+ - 🌍 **跨平台支持** - 同时支持浏览器和 Node.js 环境
10
+ - 💾 **智能缓存** - 浏览器使用 localStorage + 内存双层缓存,Node.js 使用内存缓存
11
+ - 🔄 **自动重试** - 网络请求失败时自动重试,支持指数退避
12
+ - 📦 **零运行时依赖** - 不依赖任何第三方库
13
+ - 🌐 **离线货币信息** - 内置 168 种货币信息,离线可查
14
+ - 🔍 **货币搜索** - 支持中英文搜索货币
15
+
16
+ ## 📦 安装 / Installation
17
+
18
+ ```bash
19
+ yarn add exchange-rate-sdk
20
+ # or
21
+ npm install exchange-rate-sdk
22
+ ```
23
+
24
+ ## 🚀 快速开始 / Quick Start
25
+
26
+ ### 浏览器 (ESM)
27
+
28
+ ```html
29
+ <script type="module">
30
+ import { ExchangeRateClient } from 'https://unpkg.com/exchange-rate-sdk';
31
+
32
+ const client = new ExchangeRateClient();
33
+ const rate = await client.getRate('USD', 'CNY');
34
+ console.log(`1 USD = ${rate} CNY`);
35
+ </script>
36
+ ```
37
+
38
+ ### Node.js (CommonJS)
39
+
40
+ ```javascript
41
+ const { ExchangeRateClient } = require('exchange-rate-sdk');
42
+
43
+ const client = new ExchangeRateClient();
44
+ client.convert(100, 'USD', 'CNY').then(result => {
45
+ console.log(`100 USD = ${result.amount} CNY`);
46
+ });
47
+ ```
48
+
49
+ ### Node.js (ES Module)
50
+
51
+ ```javascript
52
+ import { ExchangeRateClient } from 'exchange-rate-sdk';
53
+
54
+ const client = new ExchangeRateClient();
55
+ const rate = await client.getRate('USD', 'CNY');
56
+ console.log(`1 USD = ${rate} CNY`);
57
+ ```
58
+
59
+ ## ⚙️ 配置选项 / Configuration
60
+
61
+ ```typescript
62
+ import { ExchangeRateClient } from 'exchange-rate-sdk';
63
+
64
+ const client = new ExchangeRateClient({
65
+ // 缓存过期时间(毫秒),默认 24 小时
66
+ cacheTTL: 24 * 60 * 60 * 1000,
67
+
68
+ // 请求超时时间(毫秒),默认 10 秒
69
+ timeout: 10000,
70
+
71
+ // API 基础 URL,默认使用 exchangerate-api.com
72
+ baseUrl: 'https://api.exchangerate-api.com/v4/latest',
73
+
74
+ // 最大重试次数,默认 3 次
75
+ maxRetries: 3,
76
+
77
+ // 重试延迟基数(毫秒),默认 1000,使用指数退避
78
+ retryDelay: 1000,
79
+ });
80
+ ```
81
+
82
+ ## 📖 API 文档 / API Reference
83
+
84
+ ### `getRate(from: string, to: string): Promise<number>`
85
+
86
+ 获取两种货币之间的汇率。
87
+
88
+ ```typescript
89
+ const rate = await client.getRate('USD', 'CNY');
90
+ // => 7.25
91
+ ```
92
+
93
+ ### `convert(amount: number, from: string, to: string): Promise<ConvertResult>`
94
+
95
+ 货币金额转换。
96
+
97
+ ```typescript
98
+ const result = await client.convert(100, 'USD', 'CNY');
99
+ // => { amount: 725, from: 'USD', to: 'CNY', rate: 7.25 }
100
+ ```
101
+
102
+ ### `getRates(base: string): Promise<RatesResponse>`
103
+
104
+ 获取某货币对所有其他货币的汇率。
105
+
106
+ ```typescript
107
+ const rates = await client.getRates('USD');
108
+ // => { base: 'USD', date: '2024-01-01', rates: { CNY: 7.25, EUR: 0.92, ... } }
109
+ ```
110
+
111
+ ### `getCurrency(code: string): Currency | undefined`
112
+
113
+ 获取单个货币的详细信息(离线可用)。
114
+
115
+ ```typescript
116
+ const info = client.getCurrency('USD');
117
+ // => { code: 'USD', name: 'United States Dollar', name_cn: '美元',
118
+ // country: 'United States', country_cn: '美国' }
119
+ ```
120
+
121
+ ### `getCurrencies(): Currency[]`
122
+
123
+ 获取所有支持的货币列表(离线可用)。
124
+
125
+ ```typescript
126
+ const currencies = client.getCurrencies();
127
+ // => [{ code: 'USD', ... }, { code: 'CNY', ... }, ...]
128
+ ```
129
+
130
+ ### `searchCurrency(keyword: string): Currency[]`
131
+
132
+ 搜索货币,支持中英文(离线可用)。
133
+
134
+ ```typescript
135
+ // 按货币代码搜索
136
+ const results1 = client.searchCurrency('USD');
137
+
138
+ // 按英文名称搜索
139
+ const results2 = client.searchCurrency('Dollar');
140
+
141
+ // 按中文名称搜索
142
+ const results3 = client.searchCurrency('人民币');
143
+ // => [{ code: 'CNY', name_cn: '人民币', ... }]
144
+ ```
145
+
146
+ ### `clearCache(): void`
147
+
148
+ 清空所有缓存。
149
+
150
+ ```typescript
151
+ client.clearCache();
152
+ ```
153
+
154
+ ### `setCacheTTL(ttl: number): void`
155
+
156
+ 更新缓存过期时间。
157
+
158
+ ```typescript
159
+ client.setCacheTTL(60 * 60 * 1000); // 设置为 1 小时
160
+ ```
161
+
162
+ ## 📋 类型定义 / Type Definitions
163
+
164
+ ```typescript
165
+ interface ExchangeRateClientOptions {
166
+ cacheTTL?: number; // 缓存过期时间(毫秒)
167
+ timeout?: number; // 请求超时(毫秒)
168
+ baseUrl?: string; // API 基础 URL
169
+ maxRetries?: number; // 最大重试次数
170
+ retryDelay?: number; // 重试延迟基数
171
+ }
172
+
173
+ interface Currency {
174
+ code: string; // 货币代码 e.g. 'USD'
175
+ name: string; // 英文名称
176
+ name_cn: string; // 中文名称
177
+ country: string; // 国家/地区英文名
178
+ country_cn: string; // 国家/地区中文名
179
+ }
180
+
181
+ interface RatesResponse {
182
+ base: string; // 基准货币
183
+ date: string; // 汇率日期
184
+ rates: Record<string, number>; // 汇率映射
185
+ }
186
+
187
+ interface ConvertResult {
188
+ amount: number; // 转换后金额
189
+ from: string; // 源货币
190
+ to: string; // 目标货币
191
+ rate: number; // 使用的汇率
192
+ }
193
+ ```
194
+
195
+ ## ❌ 错误处理 / Error Handling
196
+
197
+ SDK 使用统一的错误类型,所有错误都包含 `code` 属性:
198
+
199
+ ```typescript
200
+ import { ExchangeRateClient, isSDKError } from 'exchange-rate-sdk';
201
+
202
+ const client = new ExchangeRateClient();
203
+
204
+ try {
205
+ await client.getRate('INVALID', 'USD');
206
+ } catch (error) {
207
+ if (isSDKError(error)) {
208
+ switch (error.code) {
209
+ case 'INVALID_CURRENCY_CODE':
210
+ console.error('无效的货币代码');
211
+ break;
212
+ case 'NETWORK_ERROR':
213
+ console.error('网络请求失败');
214
+ break;
215
+ case 'TIMEOUT_ERROR':
216
+ console.error('请求超时');
217
+ break;
218
+ case 'API_ERROR':
219
+ console.error('API 返回错误');
220
+ break;
221
+ default:
222
+ console.error('未知错误');
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### 错误代码 / Error Codes
229
+
230
+ | 错误代码 | 说明 |
231
+ |---------|------|
232
+ | `INVALID_CURRENCY_CODE` | 无效的货币代码(不在支持列表中) |
233
+ | `NETWORK_ERROR` | 网络请求失败 |
234
+ | `TIMEOUT_ERROR` | 请求超时 |
235
+ | `API_ERROR` | API 返回错误或响应格式无效 |
236
+ | `PARSE_ERROR` | 数据解析失败 |
237
+ | `UNKNOWN_ERROR` | 未知错误 |
238
+
239
+ ## 🔄 重试机制 / Retry Mechanism
240
+
241
+ SDK 内置了智能重试机制:
242
+
243
+ - **可重试的情况**:
244
+ - 网络错误
245
+ - 请求超时
246
+ - HTTP 5xx 服务器错误
247
+ - HTTP 429 请求过多
248
+
249
+ - **重试策略**:使用指数退避算法,每次重试延迟加倍
250
+
251
+ ```typescript
252
+ const client = new ExchangeRateClient({
253
+ maxRetries: 3, // 最多重试 3 次
254
+ retryDelay: 1000, // 第一次重试等待 1 秒,第二次 2 秒,第三次 4 秒
255
+ });
256
+ ```
257
+
258
+ ## 💾 缓存机制 / Caching
259
+
260
+ ### 浏览器环境
261
+
262
+ - 使用 **localStorage + 内存双层缓存**
263
+ - localStorage 持久化存储,刷新页面后仍然有效
264
+ - 内存缓存提供更快的访问速度
265
+
266
+ ### Node.js 环境
267
+
268
+ - 使用**内存缓存**(Map)
269
+ - 进程重启后缓存失效
270
+
271
+ ### 缓存键格式
272
+
273
+ 缓存使用 `exchange_rate_sdk_rates_{CURRENCY_CODE}` 格式存储。
274
+
275
+ ## 🌐 支持的货币 / Supported Currencies
276
+
277
+ SDK 内置了 168 种货币信息,包括:
278
+
279
+ - 主要货币:USD, EUR, GBP, JPY, CNY 等
280
+ - 各国法定货币
281
+ - 部分虚拟货币和特别提款权 (SDR)
282
+
283
+ 使用 `getCurrencies()` 方法获取完整列表。
284
+
285
+ ## 🛠️ 开发 / Development
286
+
287
+ ```bash
288
+ # 安装依赖
289
+ yarn install
290
+
291
+ # 构建
292
+ yarn build
293
+
294
+ # 运行测试
295
+ yarn test
296
+
297
+ # 测试覆盖率
298
+ yarn test:coverage
299
+ ```
300
+
301
+ ## 📄 许可证 / License
302
+
303
+ ISC
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 缓存管理器
3
+ * 浏览器环境使用 localStorage + 内存双层缓存
4
+ * Node.js 环境使用内存缓存
5
+ */
6
+ export declare class CacheManager {
7
+ private memoryCache;
8
+ private ttl;
9
+ constructor(ttl: number);
10
+ /**
11
+ * 获取缓存
12
+ */
13
+ get<T>(key: string): T | null;
14
+ /**
15
+ * 设置缓存
16
+ */
17
+ set<T>(key: string, data: T): void;
18
+ /**
19
+ * 删除指定缓存
20
+ */
21
+ delete(key: string): void;
22
+ /**
23
+ * 清空所有缓存
24
+ */
25
+ clear(): void;
26
+ /**
27
+ * 更新 TTL
28
+ */
29
+ setTTL(ttl: number): void;
30
+ }
@@ -0,0 +1,51 @@
1
+ import type { ExchangeRateClientOptions, Currency, RatesResponse, ConvertResult } from './types';
2
+ /**
3
+ * 汇率查询 SDK 核心类
4
+ */
5
+ export declare class ExchangeRateClient {
6
+ private cacheTTL;
7
+ private timeout;
8
+ private baseUrl;
9
+ private maxRetries;
10
+ private retryDelay;
11
+ private cache;
12
+ private currencies;
13
+ private currencyCodeSet;
14
+ constructor(options?: ExchangeRateClientOptions);
15
+ /**
16
+ * 验证货币代码是否有效
17
+ */
18
+ private validateCurrencyCode;
19
+ /**
20
+ * 获取指定基准货币的所有汇率
21
+ */
22
+ getRates(base: string): Promise<RatesResponse>;
23
+ /**
24
+ * 获取两种货币间的汇率
25
+ */
26
+ getRate(from: string, to: string): Promise<number>;
27
+ /**
28
+ * 货币转换
29
+ */
30
+ convert(amount: number, from: string, to: string): Promise<ConvertResult>;
31
+ /**
32
+ * 获取单个货币信息(离线可用)
33
+ */
34
+ getCurrency(code: string): Currency | undefined;
35
+ /**
36
+ * 获取所有货币列表(离线可用)
37
+ */
38
+ getCurrencies(): Currency[];
39
+ /**
40
+ * 搜索货币(支持中英文,离线可用)
41
+ */
42
+ searchCurrency(keyword: string): Currency[];
43
+ /**
44
+ * 清空缓存
45
+ */
46
+ clearCache(): void;
47
+ /**
48
+ * 更新缓存 TTL
49
+ */
50
+ setCacheTTL(ttl: number): void;
51
+ }
@@ -0,0 +1,9 @@
1
+ import type { Currency } from './types';
2
+ /**
3
+ * 解析 CSV 字符串为货币列表
4
+ */
5
+ export declare function parseCurrenciesCSV(csvText: string): Currency[];
6
+ /**
7
+ * 获取内置货币列表
8
+ */
9
+ export declare function getBuiltInCurrencies(): Currency[];
@@ -0,0 +1 @@
1
+ export declare const currencyList = "code,name,name_cn,country,country_cn\nAED,UAE Dirham,\u963F\u8054\u914B\u8FEA\u62C9\u59C6,United Arab Emirates,\u963F\u8054\u914B\nAFN,Afghan Afghani,\u963F\u5BCC\u6C57\u5C3C,Afghanistan,\u963F\u5BCC\u6C57\nALL,Albanian Lek,\u963F\u5C14\u5DF4\u5C3C\u4E9A\u5217\u514B,Albania,\u963F\u5C14\u5DF4\u5C3C\u4E9A\nAMD,Armenian Dram,\u4E9A\u7F8E\u5C3C\u4E9A\u5FB7\u62C9\u59C6,Armenia,\u4E9A\u7F8E\u5C3C\u4E9A\nANG,Netherlands Antillian Guilder,\u8377\u5C5E\u5B89\u7684\u5217\u65AF\u76FE,Netherlands Antilles,\u8377\u5C5E\u5B89\u7684\u5217\u65AF\nAOA,Angolan Kwanza,\u5B89\u54E5\u62C9\u5BBD\u624E,Angola,\u5B89\u54E5\u62C9\nARS,Argentine Peso,\u963F\u6839\u5EF7\u6BD4\u7D22,Argentina,\u963F\u6839\u5EF7\nAUD,Australian Dollar,\u6FB3\u5927\u5229\u4E9A\u5143,Australia,\u6FB3\u5927\u5229\u4E9A\nAWG,Aruban Florin,\u963F\u9C81\u5DF4\u5F17\u7F57\u6797,Aruba,\u963F\u9C81\u5DF4\nAZN,Azerbaijani Manat,\u963F\u585E\u62DC\u7586\u9A6C\u7EB3\u7279,Azerbaijan,\u963F\u585E\u62DC\u7586\nBAM,Bosnia and Herzegovina Convertible Mark,\u6CE2\u9ED1\u53EF\u5151\u6362\u9A6C\u514B,Bosnia and Herzegovina,\u6CE2\u65AF\u5C3C\u4E9A\u548C\u9ED1\u585E\u54E5\u7EF4\u90A3\nBBD,Barbados Dollar,\u5DF4\u5DF4\u591A\u65AF\u5143,Barbados,\u5DF4\u5DF4\u591A\u65AF\nBDT,Bangladeshi Taka,\u5B5F\u52A0\u62C9\u5854\u5361,Bangladesh,\u5B5F\u52A0\u62C9\u56FD\nBGN,Bulgarian Lev,\u4FDD\u52A0\u5229\u4E9A\u5217\u5F17,Bulgaria,\u4FDD\u52A0\u5229\u4E9A\nBHD,Bahraini Dinar,\u5DF4\u6797\u7B2C\u7EB3\u5C14,Bahrain,\u5DF4\u6797\nBIF,Burundian Franc,\u5E03\u9686\u8FEA\u6CD5\u90CE,Burundi,\u5E03\u9686\u8FEA\nBMD,Bermudian Dollar,\u767E\u6155\u5927\u5143,Bermuda,\u767E\u6155\u5927\nBND,Brunei Dollar,\u6587\u83B1\u5143,Brunei,\u6587\u83B1\nBOB,Bolivian Boliviano,\u73BB\u5229\u7EF4\u4E9A\u8BFA,Bolivia,\u73BB\u5229\u7EF4\u4E9A\nBRL,Brazilian Real,\u5DF4\u897F\u96F7\u4E9A\u5C14,Brazil,\u5DF4\u897F\nBSD,Bahamian Dollar,\u5DF4\u54C8\u9A6C\u5143,Bahamas,\u5DF4\u54C8\u9A6C\nBTN,Bhutanese Ngultrum,\u4E0D\u4E39\u52AA\u5C14\u7279\u9C81\u59C6,Bhutan,\u4E0D\u4E39\nBWP,Botswana Pula,\u535A\u8328\u74E6\u7EB3\u666E\u62C9,Botswana,\u535A\u8328\u74E6\u7EB3\nBYN,Belarusian Ruble,\u767D\u4FC4\u7F57\u65AF\u5362\u5E03,Belarus,\u767D\u4FC4\u7F57\u65AF\nBZD,Belize Dollar,\u4F2F\u5229\u5179\u5143,Belize,\u4F2F\u5229\u5179\nCAD,Canadian Dollar,\u52A0\u62FF\u5927\u5143,Canada,\u52A0\u62FF\u5927\nCDF,Congolese Franc,\u521A\u679C\u6CD5\u90CE,Democratic Republic of the Congo,\u521A\u679C\u6C11\u4E3B\u5171\u548C\u56FD\nCHF,Swiss Franc,\u745E\u58EB\u6CD5\u90CE,Switzerland,\u745E\u58EB\nCLF,Chilean Unidad de Fomento,\u667A\u5229\u53D1\u5C55\u5355\u4F4D,Chile,\u667A\u5229\nCLP,Chilean Peso,\u667A\u5229\u6BD4\u7D22,Chile,\u667A\u5229\nCNH,Offshore Chinese Renminbi,\u79BB\u5CB8\u4EBA\u6C11\u5E01,China,\u4E2D\u56FD\nCNY,Chinese Renminbi,\u4EBA\u6C11\u5E01,China,\u4E2D\u56FD\nCOP,Colombian Peso,\u54E5\u4F26\u6BD4\u4E9A\u6BD4\u7D22,Colombia,\u54E5\u4F26\u6BD4\u4E9A\nCRC,Costa Rican Colon,\u54E5\u65AF\u8FBE\u9ECE\u52A0\u79D1\u6717,Costa Rica,\u54E5\u65AF\u8FBE\u9ECE\u52A0\nCUP,Cuban Peso,\u53E4\u5DF4\u6BD4\u7D22,Cuba,\u53E4\u5DF4\nCVE,Cape Verdean Escudo,\u4F5B\u5F97\u89D2\u57C3\u65AF\u5E93\u591A,Cape Verde,\u4F5B\u5F97\u89D2\nCZK,Czech Koruna,\u6377\u514B\u514B\u6717,Czech Republic,\u6377\u514B\nDJF,Djiboutian Franc,\u5409\u5E03\u63D0\u6CD5\u90CE,Djibouti,\u5409\u5E03\u63D0\nDKK,Danish Krone,\u4E39\u9EA6\u514B\u6717,Denmark,\u4E39\u9EA6\nDOP,Dominican Peso,\u591A\u7C73\u5C3C\u52A0\u6BD4\u7D22,Dominican Republic,\u591A\u7C73\u5C3C\u52A0\nDZD,Algerian Dinar,\u963F\u5C14\u53CA\u5229\u4E9A\u7B2C\u7EB3\u5C14,Algeria,\u963F\u5C14\u53CA\u5229\u4E9A\nEGP,Egyptian Pound,\u57C3\u53CA\u9551,Egypt,\u57C3\u53CA\nERN,Eritrean Nakfa,\u5384\u7ACB\u7279\u91CC\u4E9A\u7EB3\u514B\u6CD5,Eritrea,\u5384\u7ACB\u7279\u91CC\u4E9A\nETB,Ethiopian Birr,\u57C3\u585E\u4FC4\u6BD4\u4E9A\u6BD4\u5C14,Ethiopia,\u57C3\u585E\u4FC4\u6BD4\u4E9A\nEUR,Euro,\u6B27\u5143,European Union,\u6B27\u76DF\nFJD,Fiji Dollar,\u6590\u6D4E\u5143,Fiji,\u6590\u6D4E\nFKP,Falkland Islands Pound,\u798F\u514B\u5170\u7FA4\u5C9B\u9551,Falkland Islands,\u798F\u514B\u5170\u7FA4\u5C9B\nFOK,Faroese Kr\u00F3na,\u6CD5\u7F57\u514B\u6717,Faroe Islands,\u6CD5\u7F57\u7FA4\u5C9B\nGBP,Pound Sterling,\u82F1\u9551,United Kingdom,\u82F1\u56FD\nGEL,Georgian Lari,\u683C\u9C81\u5409\u4E9A\u62C9\u91CC,Georgia,\u683C\u9C81\u5409\u4E9A\nGGP,Guernsey Pound,\u6839\u897F\u5C9B\u9551,Guernsey,\u6839\u897F\u5C9B\nGHS,Ghanaian Cedi,\u52A0\u7EB3\u585E\u5730,Ghana,\u52A0\u7EB3\nGIP,Gibraltar Pound,\u76F4\u5E03\u7F57\u9640\u9551,Gibraltar,\u76F4\u5E03\u7F57\u9640\nGMD,Gambian Dalasi,\u5188\u6BD4\u4E9A\u8FBE\u62C9\u897F,Gambia,\u5188\u6BD4\u4E9A\nGNF,Guinean Franc,\u51E0\u5185\u4E9A\u6CD5\u90CE,Guinea,\u51E0\u5185\u4E9A\nGTQ,Guatemalan Quetzal,\u5371\u5730\u9A6C\u62C9\u683C\u67E5\u5C14,Guatemala,\u5371\u5730\u9A6C\u62C9\nGYD,Guyanese Dollar,\u572D\u4E9A\u90A3\u5143,Guyana,\u572D\u4E9A\u90A3\nHKD,Hong Kong Dollar,\u6E2F\u5143,Hong Kong,\u4E2D\u56FD\u9999\u6E2F\nHNL,Honduran Lempira,\u6D2A\u90FD\u62C9\u65AF\u4F26\u76AE\u62C9,Honduras,\u6D2A\u90FD\u62C9\u65AF\nHRK,Croatian Kuna,\u514B\u7F57\u5730\u4E9A\u5E93\u7EB3,Croatia,\u514B\u7F57\u5730\u4E9A\nHTG,Haitian Gourde,\u6D77\u5730\u53E4\u5FB7,Haiti,\u6D77\u5730\nHUF,Hungarian Forint,\u5308\u7259\u5229\u798F\u6797,Hungary,\u5308\u7259\u5229\nIDR,Indonesian Rupiah,\u5370\u5C3C\u76FE,Indonesia,\u5370\u5EA6\u5C3C\u897F\u4E9A\nILS,Israeli New Shekel,\u4EE5\u8272\u5217\u65B0\u8C22\u514B\u5C14,Israel,\u4EE5\u8272\u5217\nIMP,Manx Pound,\u9A6C\u6069\u5C9B\u9551,Isle of Man,\u9A6C\u6069\u5C9B\nINR,Indian Rupee,\u5370\u5EA6\u5362\u6BD4,India,\u5370\u5EA6\nIQD,Iraqi Dinar,\u4F0A\u62C9\u514B\u7B2C\u7EB3\u5C14,Iraq,\u4F0A\u62C9\u514B\nIRR,Iranian Rial,\u4F0A\u6717\u91CC\u4E9A\u5C14,Iran,\u4F0A\u6717\nISK,Icelandic Kr\u00F3na,\u51B0\u5C9B\u514B\u6717,Iceland,\u51B0\u5C9B\nJEP,Jersey Pound,\u6CFD\u897F\u5C9B\u9551,Jersey,\u6CFD\u897F\u5C9B\nJMD,Jamaican Dollar,\u7259\u4E70\u52A0\u5143,Jamaica,\u7259\u4E70\u52A0\nJOD,Jordanian Dinar,\u7EA6\u65E6\u7B2C\u7EB3\u5C14,Jordan,\u7EA6\u65E6\nJPY,Japanese Yen,\u65E5\u5143,Japan,\u65E5\u672C\nKES,Kenyan Shilling,\u80AF\u5C3C\u4E9A\u5148\u4EE4,Kenya,\u80AF\u5C3C\u4E9A\nKGS,Kyrgyzstani Som,\u5409\u5C14\u5409\u65AF\u65AF\u5766\u7D22\u59C6,Kyrgyzstan,\u5409\u5C14\u5409\u65AF\u65AF\u5766\nKHR,Cambodian Riel,\u67EC\u57D4\u5BE8\u745E\u5C14,Cambodia,\u67EC\u57D4\u5BE8\nKID,Kiribati Dollar,\u57FA\u91CC\u5DF4\u65AF\u5143,Kiribati,\u57FA\u91CC\u5DF4\u65AF\nKMF,Comorian Franc,\u79D1\u6469\u7F57\u6CD5\u90CE,Comoros,\u79D1\u6469\u7F57\nKRW,South Korean Won,\u97E9\u5143,South Korea,\u97E9\u56FD\nKWD,Kuwaiti Dinar,\u79D1\u5A01\u7279\u7B2C\u7EB3\u5C14,Kuwait,\u79D1\u5A01\u7279\nKYD,Cayman Islands Dollar,\u5F00\u66FC\u7FA4\u5C9B\u5143,Cayman Islands,\u5F00\u66FC\u7FA4\u5C9B\nKZT,Kazakhstani Tenge,\u54C8\u8428\u514B\u65AF\u5766\u575A\u6208,Kazakhstan,\u54C8\u8428\u514B\u65AF\u5766\nLAK,Lao Kip,\u8001\u631D\u57FA\u666E,Laos,\u8001\u631D\nLBP,Lebanese Pound,\u9ECE\u5DF4\u5AE9\u9551,Lebanon,\u9ECE\u5DF4\u5AE9\nLKR,Sri Lanka Rupee,\u65AF\u91CC\u5170\u5361\u5362\u6BD4,Sri Lanka,\u65AF\u91CC\u5170\u5361\nLRD,Liberian Dollar,\u5229\u6BD4\u91CC\u4E9A\u5143,Liberia,\u5229\u6BD4\u91CC\u4E9A\nLSL,Lesotho Loti,\u83B1\u7D22\u6258\u6D1B\u8482,Lesotho,\u83B1\u7D22\u6258\nLYD,Libyan Dinar,\u5229\u6BD4\u4E9A\u7B2C\u7EB3\u5C14,Libya,\u5229\u6BD4\u4E9A\nMAD,Moroccan Dirham,\u6469\u6D1B\u54E5\u8FEA\u62C9\u59C6,Morocco,\u6469\u6D1B\u54E5\nMDL,Moldovan Leu,\u6469\u5C14\u591A\u74E6\u5217\u4F0A,Moldova,\u6469\u5C14\u591A\u74E6\nMGA,Malagasy Ariary,\u9A6C\u8FBE\u52A0\u65AF\u52A0\u963F\u91CC\u4E9A\u91CC,Madagascar,\u9A6C\u8FBE\u52A0\u65AF\u52A0\nMKD,Macedonian Denar,\u5317\u9A6C\u5176\u987F\u7B2C\u7EB3\u5C14,North Macedonia,\u5317\u9A6C\u5176\u987F\nMMK,Burmese Kyat,\u7F05\u7538\u5143,Myanmar,\u7F05\u7538\nMNT,Mongolian T\u00F6gr\u00F6g,\u8499\u53E4\u56FE\u683C\u91CC\u514B,Mongolia,\u8499\u53E4\nMOP,Macanese Pataca,\u6FB3\u95E8\u5143,Macau,\u4E2D\u56FD\u6FB3\u95E8\nMRU,Mauritanian Ouguiya,\u6BDB\u91CC\u5854\u5C3C\u4E9A\u4E4C\u5409\u4E9A,Mauritania,\u6BDB\u91CC\u5854\u5C3C\u4E9A\nMUR,Mauritian Rupee,\u6BDB\u91CC\u6C42\u65AF\u5362\u6BD4,Mauritius,\u6BDB\u91CC\u6C42\u65AF\nMVR,Maldivian Rufiyaa,\u9A6C\u5C14\u4EE3\u592B\u62C9\u83F2\u4E9A,Maldives,\u9A6C\u5C14\u4EE3\u592B\nMWK,Malawian Kwacha,\u9A6C\u62C9\u7EF4\u514B\u74E6\u67E5,Malawi,\u9A6C\u62C9\u7EF4\nMXN,Mexican Peso,\u58A8\u897F\u54E5\u6BD4\u7D22,Mexico,\u58A8\u897F\u54E5\nMYR,Malaysian Ringgit,\u9A6C\u6765\u897F\u4E9A\u6797\u5409\u7279,Malaysia,\u9A6C\u6765\u897F\u4E9A\nMZN,Mozambican Metical,\u83AB\u6851\u6BD4\u514B\u6885\u8482\u5361\u5C14,Mozambique,\u83AB\u6851\u6BD4\u514B\nNAD,Namibian Dollar,\u7EB3\u7C73\u6BD4\u4E9A\u5143,Namibia,\u7EB3\u7C73\u6BD4\u4E9A\nNGN,Nigerian Naira,\u5C3C\u65E5\u5229\u4E9A\u5948\u62C9,Nigeria,\u5C3C\u65E5\u5229\u4E9A\nNIO,Nicaraguan C\u00F3rdoba,\u5C3C\u52A0\u62C9\u74DC\u79D1\u591A\u5DF4,Nicaragua,\u5C3C\u52A0\u62C9\u74DC\nNOK,Norwegian Krone,\u632A\u5A01\u514B\u6717,Norway,\u632A\u5A01\nNPR,Nepalese Rupee,\u5C3C\u6CCA\u5C14\u5362\u6BD4,Nepal,\u5C3C\u6CCA\u5C14\nNZD,New Zealand Dollar,\u65B0\u897F\u5170\u5143,New Zealand,\u65B0\u897F\u5170\nOMR,Omani Rial,\u963F\u66FC\u91CC\u4E9A\u5C14,Oman,\u963F\u66FC\nPAB,Panamanian Balboa,\u5DF4\u62FF\u9A6C\u5DF4\u6CE2\u4E9A,Panama,\u5DF4\u62FF\u9A6C\nPEN,Peruvian Sol,\u79D8\u9C81\u7D22\u5C14,Peru,\u79D8\u9C81\nPGK,Papua New Guinean Kina,\u5DF4\u5E03\u4E9A\u65B0\u51E0\u5185\u4E9A\u57FA\u90A3,Papua New Guinea,\u5DF4\u5E03\u4E9A\u65B0\u51E0\u5185\u4E9A\nPHP,Philippine Peso,\u83F2\u5F8B\u5BBE\u6BD4\u7D22,Philippines,\u83F2\u5F8B\u5BBE\nPKR,Pakistani Rupee,\u5DF4\u57FA\u65AF\u5766\u5362\u6BD4,Pakistan,\u5DF4\u57FA\u65AF\u5766\nPLN,Polish Z\u0142oty,\u6CE2\u5170\u5179\u7F57\u63D0,Poland,\u6CE2\u5170\nPYG,Paraguayan Guaran\u00ED,\u5DF4\u62C9\u572D\u74DC\u62C9\u5C3C,Paraguay,\u5DF4\u62C9\u572D\nQAR,Qatari Riyal,\u5361\u5854\u5C14\u91CC\u4E9A\u5C14,Qatar,\u5361\u5854\u5C14\nRON,Romanian Leu,\u7F57\u9A6C\u5C3C\u4E9A\u5217\u4F0A,Romania,\u7F57\u9A6C\u5C3C\u4E9A\nRSD,Serbian Dinar,\u585E\u5C14\u7EF4\u4E9A\u7B2C\u7EB3\u5C14,Serbia,\u585E\u5C14\u7EF4\u4E9A\nRUB,Russian Ruble,\u4FC4\u7F57\u65AF\u5362\u5E03,Russia,\u4FC4\u7F57\u65AF\nRWF,Rwandan Franc,\u5362\u65FA\u8FBE\u6CD5\u90CE,Rwanda,\u5362\u65FA\u8FBE\nSAR,Saudi Riyal,\u6C99\u7279\u91CC\u4E9A\u5C14,Saudi Arabia,\u6C99\u7279\u963F\u62C9\u4F2F\nSBD,Solomon Islands Dollar,\u6240\u7F57\u95E8\u7FA4\u5C9B\u5143,Solomon Islands,\u6240\u7F57\u95E8\u7FA4\u5C9B\nSCR,Seychellois Rupee,\u585E\u820C\u5C14\u5362\u6BD4,Seychelles,\u585E\u820C\u5C14\nSDG,Sudanese Pound,\u82CF\u4E39\u9551,Sudan,\u82CF\u4E39\nSEK,Swedish Krona,\u745E\u5178\u514B\u6717,Sweden,\u745E\u5178\nSGD,Singapore Dollar,\u65B0\u52A0\u5761\u5143,Singapore,\u65B0\u52A0\u5761\nSHP,Saint Helena Pound,\u5723\u8D6B\u52D2\u62FF\u9551,Saint Helena,\u5723\u8D6B\u52D2\u62FF\nSLE,Sierra Leonean Leone,\u585E\u62C9\u5229\u6602\u5229\u6602,Sierra Leone,\u585E\u62C9\u5229\u6602\nSLL,Sierra Leonean Leone,\u585E\u62C9\u5229\u6602\u5229\u6602(\u65E7),Sierra Leone,\u585E\u62C9\u5229\u6602\nSOS,Somali Shilling,\u7D22\u9A6C\u91CC\u5148\u4EE4,Somalia,\u7D22\u9A6C\u91CC\nSRD,Surinamese Dollar,\u82CF\u91CC\u5357\u5143,Suriname,\u82CF\u91CC\u5357\nSSP,South Sudanese Pound,\u5357\u82CF\u4E39\u9551,South Sudan,\u5357\u82CF\u4E39\nSTN,S\u00E3o Tom\u00E9 and Pr\u00EDncipe Dobra,\u5723\u591A\u7F8E\u591A\u5E03\u62C9,S\u00E3o Tom\u00E9 and Pr\u00EDncipe,\u5723\u591A\u7F8E\u548C\u666E\u6797\u897F\u6BD4\nSYP,Syrian Pound,\u53D9\u5229\u4E9A\u9551,Syria,\u53D9\u5229\u4E9A\nSZL,Eswatini Lilangeni,\u65AF\u5A01\u58EB\u5170\u91CC\u5170\u5409\u5C3C,Eswatini,\u65AF\u5A01\u58EB\u5170\nTHB,Thai Baht,\u6CF0\u94E2,Thailand,\u6CF0\u56FD\nTJS,Tajikistani Somoni,\u5854\u5409\u514B\u65AF\u5766\u7D22\u83AB\u5C3C,Tajikistan,\u5854\u5409\u514B\u65AF\u5766\nTMT,Turkmenistan Manat,\u571F\u5E93\u66FC\u65AF\u5766\u9A6C\u7EB3\u7279,Turkmenistan,\u571F\u5E93\u66FC\u65AF\u5766\nTND,Tunisian Dinar,\u7A81\u5C3C\u65AF\u7B2C\u7EB3\u5C14,Tunisia,\u7A81\u5C3C\u65AF\nTOP,Tongan Pa\u02BBanga,\u6C64\u52A0\u6F58\u52A0,Tonga,\u6C64\u52A0\nTRY,Turkish Lira,\u571F\u8033\u5176\u91CC\u62C9,Turkey,\u571F\u8033\u5176\nTTD,Trinidad and Tobago Dollar,\u7279\u7ACB\u5C3C\u8FBE\u548C\u591A\u5DF4\u54E5\u5143,Trinidad and Tobago,\u7279\u7ACB\u5C3C\u8FBE\u548C\u591A\u5DF4\u54E5\nTVD,Tuvaluan Dollar,\u56FE\u74E6\u5362\u5143,Tuvalu,\u56FE\u74E6\u5362\nTWD,New Taiwan Dollar,\u65B0\u53F0\u5E01,Taiwan,\u4E2D\u56FD\u53F0\u6E7E\nTZS,Tanzanian Shilling,\u5766\u6851\u5C3C\u4E9A\u5148\u4EE4,Tanzania,\u5766\u6851\u5C3C\u4E9A\nUAH,Ukrainian Hryvnia,\u4E4C\u514B\u5170\u683C\u91CC\u592B\u7EB3,Ukraine,\u4E4C\u514B\u5170\nUGX,Ugandan Shilling,\u4E4C\u5E72\u8FBE\u5148\u4EE4,Uganda,\u4E4C\u5E72\u8FBE\nUSD,United States Dollar,\u7F8E\u5143,United States,\u7F8E\u56FD\nUYU,Uruguayan Peso,\u4E4C\u62C9\u572D\u6BD4\u7D22,Uruguay,\u4E4C\u62C9\u572D\nUZS,Uzbekistani So'm,\u4E4C\u5179\u522B\u514B\u65AF\u5766\u82CF\u59C6,Uzbekistan,\u4E4C\u5179\u522B\u514B\u65AF\u5766\nVES,Venezuelan Bol\u00EDvar Soberano,\u59D4\u5185\u745E\u62C9\u73BB\u5229\u74E6\u5C14,Venezuela,\u59D4\u5185\u745E\u62C9\nVND,Vietnamese \u0110\u1ED3ng,\u8D8A\u5357\u76FE,Vietnam,\u8D8A\u5357\nVUV,Vanuatu Vatu,\u74E6\u52AA\u963F\u56FE\u74E6\u56FE,Vanuatu,\u74E6\u52AA\u963F\u56FE\nWST,Samoan T\u0101l\u0101,\u8428\u6469\u4E9A\u5854\u62C9,Samoa,\u8428\u6469\u4E9A\nXAF,Central African CFA Franc,\u4E2D\u975E\u6CD5\u90CE,Central African States,\u4E2D\u975E\u56FD\u5BB6\nXCD,East Caribbean Dollar,\u4E1C\u52A0\u52D2\u6BD4\u5143,East Caribbean States,\u4E1C\u52A0\u52D2\u6BD4\u56FD\u5BB6\nXCG,Caribbean Guilder,\u52A0\u52D2\u6BD4\u76FE,Caribbean,\u52A0\u52D2\u6BD4\u5730\u533A\nXDR,Special Drawing Rights,\u7279\u522B\u63D0\u6B3E\u6743,International Monetary Fund,\u56FD\u9645\u8D27\u5E01\u57FA\u91D1\u7EC4\u7EC7\nXOF,West African CFA franc,\u897F\u975E\u6CD5\u90CE,West African States,\u897F\u975E\u56FD\u5BB6\nXPF,CFP Franc,\u592A\u5E73\u6D0B\u6CD5\u90CE,French Pacific Territories,\u6CD5\u5C5E\u592A\u5E73\u6D0B\u9886\u5730\nYER,Yemeni Rial,\u4E5F\u95E8\u91CC\u4E9A\u5C14,Yemen,\u4E5F\u95E8\nZAR,South African Rand,\u5357\u975E\u5170\u7279,South Africa,\u5357\u975E\nZMW,Zambian Kwacha,\u8D5E\u6BD4\u4E9A\u514B\u74E6\u67E5,Zambia,\u8D5E\u6BD4\u4E9A\nZWG,Zimbabwean Dollar,\u6D25\u5DF4\u5E03\u97E6\u5143(\u65B0),Zimbabwe,\u6D25\u5DF4\u5E03\u97E6\nZWL,Zimbabwean Dollar,\u6D25\u5DF4\u5E03\u97E6\u5143,Zimbabwe,\u6D25\u5DF4\u5E03\u97E6\n";
@@ -0,0 +1,9 @@
1
+ import type { ErrorCode, SDKError } from './types';
2
+ /**
3
+ * 创建 SDK 错误
4
+ */
5
+ export declare function createError(code: ErrorCode, message: string, details?: unknown): SDKError;
6
+ /**
7
+ * 检查是否为 SDK 错误
8
+ */
9
+ export declare function isSDKError(error: unknown): error is SDKError;
@@ -0,0 +1 @@
1
+ "use strict";const a="exchange_rate_sdk_";function n(){return"undefined"!=typeof window&&void 0!==window.localStorage}class e{constructor(a){this.memoryCache=new Map,this.ttl=a}get(e){const i=a+e,r=this.memoryCache.get(i);if(r){if(Date.now()<r.expiresAt)return r.data;this.memoryCache.delete(i)}if(n())try{const a=localStorage.getItem(i);if(a){const n=JSON.parse(a);if(Date.now()<n.expiresAt)return this.memoryCache.set(i,n),n.data;localStorage.removeItem(i)}}catch{}return null}set(e,i){const r=a+e,t={data:i,expiresAt:Date.now()+this.ttl};if(this.memoryCache.set(r,t),n())try{localStorage.setItem(r,JSON.stringify(t))}catch{}}delete(e){const i=a+e;if(this.memoryCache.delete(i),n())try{localStorage.removeItem(i)}catch{}}clear(){if(this.memoryCache.clear(),n())try{const n=[];for(let e=0;e<localStorage.length;e++){const i=localStorage.key(e);i&&i.startsWith(a)&&n.push(i)}n.forEach(a=>localStorage.removeItem(a))}catch{}}setTTL(a){this.ttl=a}}function i(a,n,e){const i=new Error(n);return i.code=a,i.name="ExchangeRateSDKError",void 0!==e&&(i.details=e),i}function r(a){return new Promise(n=>setTimeout(n,a))}async function t(a,n){const e=new AbortController,i=setTimeout(()=>e.abort(),n);try{return await fetch(a,{signal:e.signal,headers:{"User-Agent":"ExchangeRateSDK/1.0.0"}})}finally{clearTimeout(i)}}function o(a,n){if(a instanceof Error){if("AbortError"===a.name)return!0;if(a.message.includes("network"))return!0;if(a.message.includes("timeout"))return!0}return!!(n&&n>=500&&n<600)||429===n}exports.ExchangeRateClient=class{constructor(a={}){this.cacheTTL=a.cacheTTL??864e5,this.timeout=a.timeout??1e4,this.baseUrl=a.baseUrl??"https://api.exchangerate-api.com/v4/latest",this.maxRetries=a.maxRetries??3,this.retryDelay=a.retryDelay??1e3,this.cache=new e(this.cacheTTL),this.currencies=function(){const a="code,name,name_cn,country,country_cn\nAED,UAE Dirham,阿联酋迪拉姆,United Arab Emirates,阿联酋\nAFN,Afghan Afghani,阿富汗尼,Afghanistan,阿富汗\nALL,Albanian Lek,阿尔巴尼亚列克,Albania,阿尔巴尼亚\nAMD,Armenian Dram,亚美尼亚德拉姆,Armenia,亚美尼亚\nANG,Netherlands Antillian Guilder,荷属安的列斯盾,Netherlands Antilles,荷属安的列斯\nAOA,Angolan Kwanza,安哥拉宽扎,Angola,安哥拉\nARS,Argentine Peso,阿根廷比索,Argentina,阿根廷\nAUD,Australian Dollar,澳大利亚元,Australia,澳大利亚\nAWG,Aruban Florin,阿鲁巴弗罗林,Aruba,阿鲁巴\nAZN,Azerbaijani Manat,阿塞拜疆马纳特,Azerbaijan,阿塞拜疆\nBAM,Bosnia and Herzegovina Convertible Mark,波黑可兑换马克,Bosnia and Herzegovina,波斯尼亚和黑塞哥维那\nBBD,Barbados Dollar,巴巴多斯元,Barbados,巴巴多斯\nBDT,Bangladeshi Taka,孟加拉塔卡,Bangladesh,孟加拉国\nBGN,Bulgarian Lev,保加利亚列弗,Bulgaria,保加利亚\nBHD,Bahraini Dinar,巴林第纳尔,Bahrain,巴林\nBIF,Burundian Franc,布隆迪法郎,Burundi,布隆迪\nBMD,Bermudian Dollar,百慕大元,Bermuda,百慕大\nBND,Brunei Dollar,文莱元,Brunei,文莱\nBOB,Bolivian Boliviano,玻利维亚诺,Bolivia,玻利维亚\nBRL,Brazilian Real,巴西雷亚尔,Brazil,巴西\nBSD,Bahamian Dollar,巴哈马元,Bahamas,巴哈马\nBTN,Bhutanese Ngultrum,不丹努尔特鲁姆,Bhutan,不丹\nBWP,Botswana Pula,博茨瓦纳普拉,Botswana,博茨瓦纳\nBYN,Belarusian Ruble,白俄罗斯卢布,Belarus,白俄罗斯\nBZD,Belize Dollar,伯利兹元,Belize,伯利兹\nCAD,Canadian Dollar,加拿大元,Canada,加拿大\nCDF,Congolese Franc,刚果法郎,Democratic Republic of the Congo,刚果民主共和国\nCHF,Swiss Franc,瑞士法郎,Switzerland,瑞士\nCLF,Chilean Unidad de Fomento,智利发展单位,Chile,智利\nCLP,Chilean Peso,智利比索,Chile,智利\nCNH,Offshore Chinese Renminbi,离岸人民币,China,中国\nCNY,Chinese Renminbi,人民币,China,中国\nCOP,Colombian Peso,哥伦比亚比索,Colombia,哥伦比亚\nCRC,Costa Rican Colon,哥斯达黎加科朗,Costa Rica,哥斯达黎加\nCUP,Cuban Peso,古巴比索,Cuba,古巴\nCVE,Cape Verdean Escudo,佛得角埃斯库多,Cape Verde,佛得角\nCZK,Czech Koruna,捷克克朗,Czech Republic,捷克\nDJF,Djiboutian Franc,吉布提法郎,Djibouti,吉布提\nDKK,Danish Krone,丹麦克朗,Denmark,丹麦\nDOP,Dominican Peso,多米尼加比索,Dominican Republic,多米尼加\nDZD,Algerian Dinar,阿尔及利亚第纳尔,Algeria,阿尔及利亚\nEGP,Egyptian Pound,埃及镑,Egypt,埃及\nERN,Eritrean Nakfa,厄立特里亚纳克法,Eritrea,厄立特里亚\nETB,Ethiopian Birr,埃塞俄比亚比尔,Ethiopia,埃塞俄比亚\nEUR,Euro,欧元,European Union,欧盟\nFJD,Fiji Dollar,斐济元,Fiji,斐济\nFKP,Falkland Islands Pound,福克兰群岛镑,Falkland Islands,福克兰群岛\nFOK,Faroese Króna,法罗克朗,Faroe Islands,法罗群岛\nGBP,Pound Sterling,英镑,United Kingdom,英国\nGEL,Georgian Lari,格鲁吉亚拉里,Georgia,格鲁吉亚\nGGP,Guernsey Pound,根西岛镑,Guernsey,根西岛\nGHS,Ghanaian Cedi,加纳塞地,Ghana,加纳\nGIP,Gibraltar Pound,直布罗陀镑,Gibraltar,直布罗陀\nGMD,Gambian Dalasi,冈比亚达拉西,Gambia,冈比亚\nGNF,Guinean Franc,几内亚法郎,Guinea,几内亚\nGTQ,Guatemalan Quetzal,危地马拉格查尔,Guatemala,危地马拉\nGYD,Guyanese Dollar,圭亚那元,Guyana,圭亚那\nHKD,Hong Kong Dollar,港元,Hong Kong,中国香港\nHNL,Honduran Lempira,洪都拉斯伦皮拉,Honduras,洪都拉斯\nHRK,Croatian Kuna,克罗地亚库纳,Croatia,克罗地亚\nHTG,Haitian Gourde,海地古德,Haiti,海地\nHUF,Hungarian Forint,匈牙利福林,Hungary,匈牙利\nIDR,Indonesian Rupiah,印尼盾,Indonesia,印度尼西亚\nILS,Israeli New Shekel,以色列新谢克尔,Israel,以色列\nIMP,Manx Pound,马恩岛镑,Isle of Man,马恩岛\nINR,Indian Rupee,印度卢比,India,印度\nIQD,Iraqi Dinar,伊拉克第纳尔,Iraq,伊拉克\nIRR,Iranian Rial,伊朗里亚尔,Iran,伊朗\nISK,Icelandic Króna,冰岛克朗,Iceland,冰岛\nJEP,Jersey Pound,泽西岛镑,Jersey,泽西岛\nJMD,Jamaican Dollar,牙买加元,Jamaica,牙买加\nJOD,Jordanian Dinar,约旦第纳尔,Jordan,约旦\nJPY,Japanese Yen,日元,Japan,日本\nKES,Kenyan Shilling,肯尼亚先令,Kenya,肯尼亚\nKGS,Kyrgyzstani Som,吉尔吉斯斯坦索姆,Kyrgyzstan,吉尔吉斯斯坦\nKHR,Cambodian Riel,柬埔寨瑞尔,Cambodia,柬埔寨\nKID,Kiribati Dollar,基里巴斯元,Kiribati,基里巴斯\nKMF,Comorian Franc,科摩罗法郎,Comoros,科摩罗\nKRW,South Korean Won,韩元,South Korea,韩国\nKWD,Kuwaiti Dinar,科威特第纳尔,Kuwait,科威特\nKYD,Cayman Islands Dollar,开曼群岛元,Cayman Islands,开曼群岛\nKZT,Kazakhstani Tenge,哈萨克斯坦坚戈,Kazakhstan,哈萨克斯坦\nLAK,Lao Kip,老挝基普,Laos,老挝\nLBP,Lebanese Pound,黎巴嫩镑,Lebanon,黎巴嫩\nLKR,Sri Lanka Rupee,斯里兰卡卢比,Sri Lanka,斯里兰卡\nLRD,Liberian Dollar,利比里亚元,Liberia,利比里亚\nLSL,Lesotho Loti,莱索托洛蒂,Lesotho,莱索托\nLYD,Libyan Dinar,利比亚第纳尔,Libya,利比亚\nMAD,Moroccan Dirham,摩洛哥迪拉姆,Morocco,摩洛哥\nMDL,Moldovan Leu,摩尔多瓦列伊,Moldova,摩尔多瓦\nMGA,Malagasy Ariary,马达加斯加阿里亚里,Madagascar,马达加斯加\nMKD,Macedonian Denar,北马其顿第纳尔,North Macedonia,北马其顿\nMMK,Burmese Kyat,缅甸元,Myanmar,缅甸\nMNT,Mongolian Tögrög,蒙古图格里克,Mongolia,蒙古\nMOP,Macanese Pataca,澳门元,Macau,中国澳门\nMRU,Mauritanian Ouguiya,毛里塔尼亚乌吉亚,Mauritania,毛里塔尼亚\nMUR,Mauritian Rupee,毛里求斯卢比,Mauritius,毛里求斯\nMVR,Maldivian Rufiyaa,马尔代夫拉菲亚,Maldives,马尔代夫\nMWK,Malawian Kwacha,马拉维克瓦查,Malawi,马拉维\nMXN,Mexican Peso,墨西哥比索,Mexico,墨西哥\nMYR,Malaysian Ringgit,马来西亚林吉特,Malaysia,马来西亚\nMZN,Mozambican Metical,莫桑比克梅蒂卡尔,Mozambique,莫桑比克\nNAD,Namibian Dollar,纳米比亚元,Namibia,纳米比亚\nNGN,Nigerian Naira,尼日利亚奈拉,Nigeria,尼日利亚\nNIO,Nicaraguan Córdoba,尼加拉瓜科多巴,Nicaragua,尼加拉瓜\nNOK,Norwegian Krone,挪威克朗,Norway,挪威\nNPR,Nepalese Rupee,尼泊尔卢比,Nepal,尼泊尔\nNZD,New Zealand Dollar,新西兰元,New Zealand,新西兰\nOMR,Omani Rial,阿曼里亚尔,Oman,阿曼\nPAB,Panamanian Balboa,巴拿马巴波亚,Panama,巴拿马\nPEN,Peruvian Sol,秘鲁索尔,Peru,秘鲁\nPGK,Papua New Guinean Kina,巴布亚新几内亚基那,Papua New Guinea,巴布亚新几内亚\nPHP,Philippine Peso,菲律宾比索,Philippines,菲律宾\nPKR,Pakistani Rupee,巴基斯坦卢比,Pakistan,巴基斯坦\nPLN,Polish Złoty,波兰兹罗提,Poland,波兰\nPYG,Paraguayan Guaraní,巴拉圭瓜拉尼,Paraguay,巴拉圭\nQAR,Qatari Riyal,卡塔尔里亚尔,Qatar,卡塔尔\nRON,Romanian Leu,罗马尼亚列伊,Romania,罗马尼亚\nRSD,Serbian Dinar,塞尔维亚第纳尔,Serbia,塞尔维亚\nRUB,Russian Ruble,俄罗斯卢布,Russia,俄罗斯\nRWF,Rwandan Franc,卢旺达法郎,Rwanda,卢旺达\nSAR,Saudi Riyal,沙特里亚尔,Saudi Arabia,沙特阿拉伯\nSBD,Solomon Islands Dollar,所罗门群岛元,Solomon Islands,所罗门群岛\nSCR,Seychellois Rupee,塞舌尔卢比,Seychelles,塞舌尔\nSDG,Sudanese Pound,苏丹镑,Sudan,苏丹\nSEK,Swedish Krona,瑞典克朗,Sweden,瑞典\nSGD,Singapore Dollar,新加坡元,Singapore,新加坡\nSHP,Saint Helena Pound,圣赫勒拿镑,Saint Helena,圣赫勒拿\nSLE,Sierra Leonean Leone,塞拉利昂利昂,Sierra Leone,塞拉利昂\nSLL,Sierra Leonean Leone,塞拉利昂利昂(旧),Sierra Leone,塞拉利昂\nSOS,Somali Shilling,索马里先令,Somalia,索马里\nSRD,Surinamese Dollar,苏里南元,Suriname,苏里南\nSSP,South Sudanese Pound,南苏丹镑,South Sudan,南苏丹\nSTN,São Tomé and Príncipe Dobra,圣多美多布拉,São Tomé and Príncipe,圣多美和普林西比\nSYP,Syrian Pound,叙利亚镑,Syria,叙利亚\nSZL,Eswatini Lilangeni,斯威士兰里兰吉尼,Eswatini,斯威士兰\nTHB,Thai Baht,泰铢,Thailand,泰国\nTJS,Tajikistani Somoni,塔吉克斯坦索莫尼,Tajikistan,塔吉克斯坦\nTMT,Turkmenistan Manat,土库曼斯坦马纳特,Turkmenistan,土库曼斯坦\nTND,Tunisian Dinar,突尼斯第纳尔,Tunisia,突尼斯\nTOP,Tongan Paʻanga,汤加潘加,Tonga,汤加\nTRY,Turkish Lira,土耳其里拉,Turkey,土耳其\nTTD,Trinidad and Tobago Dollar,特立尼达和多巴哥元,Trinidad and Tobago,特立尼达和多巴哥\nTVD,Tuvaluan Dollar,图瓦卢元,Tuvalu,图瓦卢\nTWD,New Taiwan Dollar,新台币,Taiwan,中国台湾\nTZS,Tanzanian Shilling,坦桑尼亚先令,Tanzania,坦桑尼亚\nUAH,Ukrainian Hryvnia,乌克兰格里夫纳,Ukraine,乌克兰\nUGX,Ugandan Shilling,乌干达先令,Uganda,乌干达\nUSD,United States Dollar,美元,United States,美国\nUYU,Uruguayan Peso,乌拉圭比索,Uruguay,乌拉圭\nUZS,Uzbekistani So'm,乌兹别克斯坦苏姆,Uzbekistan,乌兹别克斯坦\nVES,Venezuelan Bolívar Soberano,委内瑞拉玻利瓦尔,Venezuela,委内瑞拉\nVND,Vietnamese Đồng,越南盾,Vietnam,越南\nVUV,Vanuatu Vatu,瓦努阿图瓦图,Vanuatu,瓦努阿图\nWST,Samoan Tālā,萨摩亚塔拉,Samoa,萨摩亚\nXAF,Central African CFA Franc,中非法郎,Central African States,中非国家\nXCD,East Caribbean Dollar,东加勒比元,East Caribbean States,东加勒比国家\nXCG,Caribbean Guilder,加勒比盾,Caribbean,加勒比地区\nXDR,Special Drawing Rights,特别提款权,International Monetary Fund,国际货币基金组织\nXOF,West African CFA franc,西非法郎,West African States,西非国家\nXPF,CFP Franc,太平洋法郎,French Pacific Territories,法属太平洋领地\nYER,Yemeni Rial,也门里亚尔,Yemen,也门\nZAR,South African Rand,南非兰特,South Africa,南非\nZMW,Zambian Kwacha,赞比亚克瓦查,Zambia,赞比亚\nZWG,Zimbabwean Dollar,津巴布韦元(新),Zimbabwe,津巴布韦\nZWL,Zimbabwean Dollar,津巴布韦元,Zimbabwe,津巴布韦\n".split(/\r?\n/),n=[];for(let e=0;e<a.length;e++){const i=a[e].trim();if(!i)continue;if(0===e&&i.toLowerCase().startsWith("code,"))continue;const r=i.split(",");r.length>=5&&n.push({code:r[0].trim(),name:r[1].trim(),name_cn:r[2].trim(),country:r[3].trim(),country_cn:r[4].trim()})}return n}(),this.currencyCodeSet=new Set(this.currencies.map(a=>a.code))}validateCurrencyCode(a){const n=a.toUpperCase();if(!this.currencyCodeSet.has(n))throw i("INVALID_CURRENCY_CODE",`Invalid currency code: ${a}. The currency code is not in the supported list.`,{code:a})}async getRates(a){const n=a.toUpperCase();this.validateCurrencyCode(n);const e=`rates_${n}`,s=this.cache.get(e);if(s)return s;const l=`${this.baseUrl}/${encodeURIComponent(n)}`,c=await async function(a,n){let e,s;for(let l=0;l<=n.maxRetries;l++)try{const e=await t(a,n.timeout);if(s=e.status,!e.ok){if(o(null,e.status)&&l<n.maxRetries){const a=n.retryDelay*Math.pow(2,l);await r(a);continue}throw i("API_ERROR",`API request failed with status ${e.status}`,{status:e.status})}return await e.json()}catch(a){if(e=a,a instanceof Error&&"ExchangeRateSDKError"===a.name&&!o(null,s))throw a;if(a instanceof Error&&"AbortError"===a.name&&(e=i("TIMEOUT_ERROR","Request timeout")),o(a,s)&&l<n.maxRetries){const a=n.retryDelay*Math.pow(2,l);await r(a);continue}if(a instanceof Error&&"ExchangeRateSDKError"===a.name)throw a;throw i("NETWORK_ERROR",a instanceof Error?a.message:"Network request failed",a)}if(e instanceof Error&&"ExchangeRateSDKError"===e.name)throw e;throw i("NETWORK_ERROR","All retry attempts failed",e)}(l,{timeout:this.timeout,maxRetries:this.maxRetries,retryDelay:this.retryDelay});if(!c||!c.rates||c.base!==n)throw i("API_ERROR","Invalid API response format",{response:c});return this.cache.set(e,c),c}async getRate(a,n){const e=a.toUpperCase(),r=n.toUpperCase();if(this.validateCurrencyCode(e),this.validateCurrencyCode(r),e===r)return 1;const t=(await this.getRates(e)).rates[r];if(void 0===t)throw i("API_ERROR",`Exchange rate not found for ${e} to ${r}`,{from:e,to:r});return t}async convert(a,n,e){const i=await this.getRate(n,e);return{amount:a*i,from:n.toUpperCase(),to:e.toUpperCase(),rate:i}}getCurrency(a){const n=a.toUpperCase();return this.validateCurrencyCode(n),this.currencies.find(a=>a.code===n)}getCurrencies(){return[...this.currencies]}searchCurrency(a){const n=a.toLowerCase();return this.currencies.filter(e=>e.code.toLowerCase().includes(n)||e.name.toLowerCase().includes(n)||e.name_cn.includes(a)||e.country.toLowerCase().includes(n)||e.country_cn.includes(a))}clearCache(){this.cache.clear()}setCacheTTL(a){this.cacheTTL=a,this.cache.setTTL(a)}},exports.createError=i,exports.isSDKError=function(a){return a instanceof Error&&"code"in a&&"ExchangeRateSDKError"===a.name};
@@ -0,0 +1,3 @@
1
+ export { ExchangeRateClient } from './client';
2
+ export { createError, isSDKError } from './error';
3
+ export type { ExchangeRateClientOptions, Currency, RatesResponse, ConvertResult, CacheEntry, ErrorCode, SDKError, } from './types';
@@ -0,0 +1 @@
1
+ const a="exchange_rate_sdk_";function n(){return"undefined"!=typeof window&&void 0!==window.localStorage}class e{constructor(a){this.memoryCache=new Map,this.ttl=a}get(e){const i=a+e,r=this.memoryCache.get(i);if(r){if(Date.now()<r.expiresAt)return r.data;this.memoryCache.delete(i)}if(n())try{const a=localStorage.getItem(i);if(a){const n=JSON.parse(a);if(Date.now()<n.expiresAt)return this.memoryCache.set(i,n),n.data;localStorage.removeItem(i)}}catch{}return null}set(e,i){const r=a+e,t={data:i,expiresAt:Date.now()+this.ttl};if(this.memoryCache.set(r,t),n())try{localStorage.setItem(r,JSON.stringify(t))}catch{}}delete(e){const i=a+e;if(this.memoryCache.delete(i),n())try{localStorage.removeItem(i)}catch{}}clear(){if(this.memoryCache.clear(),n())try{const n=[];for(let e=0;e<localStorage.length;e++){const i=localStorage.key(e);i&&i.startsWith(a)&&n.push(i)}n.forEach(a=>localStorage.removeItem(a))}catch{}}setTTL(a){this.ttl=a}}function i(a,n,e){const i=new Error(n);return i.code=a,i.name="ExchangeRateSDKError",void 0!==e&&(i.details=e),i}function r(a){return a instanceof Error&&"code"in a&&"ExchangeRateSDKError"===a.name}function t(a){return new Promise(n=>setTimeout(n,a))}async function o(a,n){const e=new AbortController,i=setTimeout(()=>e.abort(),n);try{return await fetch(a,{signal:e.signal,headers:{"User-Agent":"ExchangeRateSDK/1.0.0"}})}finally{clearTimeout(i)}}function s(a,n){if(a instanceof Error){if("AbortError"===a.name)return!0;if(a.message.includes("network"))return!0;if(a.message.includes("timeout"))return!0}return!!(n&&n>=500&&n<600)||429===n}class l{constructor(a={}){this.cacheTTL=a.cacheTTL??864e5,this.timeout=a.timeout??1e4,this.baseUrl=a.baseUrl??"https://api.exchangerate-api.com/v4/latest",this.maxRetries=a.maxRetries??3,this.retryDelay=a.retryDelay??1e3,this.cache=new e(this.cacheTTL),this.currencies=function(){const a="code,name,name_cn,country,country_cn\nAED,UAE Dirham,阿联酋迪拉姆,United Arab Emirates,阿联酋\nAFN,Afghan Afghani,阿富汗尼,Afghanistan,阿富汗\nALL,Albanian Lek,阿尔巴尼亚列克,Albania,阿尔巴尼亚\nAMD,Armenian Dram,亚美尼亚德拉姆,Armenia,亚美尼亚\nANG,Netherlands Antillian Guilder,荷属安的列斯盾,Netherlands Antilles,荷属安的列斯\nAOA,Angolan Kwanza,安哥拉宽扎,Angola,安哥拉\nARS,Argentine Peso,阿根廷比索,Argentina,阿根廷\nAUD,Australian Dollar,澳大利亚元,Australia,澳大利亚\nAWG,Aruban Florin,阿鲁巴弗罗林,Aruba,阿鲁巴\nAZN,Azerbaijani Manat,阿塞拜疆马纳特,Azerbaijan,阿塞拜疆\nBAM,Bosnia and Herzegovina Convertible Mark,波黑可兑换马克,Bosnia and Herzegovina,波斯尼亚和黑塞哥维那\nBBD,Barbados Dollar,巴巴多斯元,Barbados,巴巴多斯\nBDT,Bangladeshi Taka,孟加拉塔卡,Bangladesh,孟加拉国\nBGN,Bulgarian Lev,保加利亚列弗,Bulgaria,保加利亚\nBHD,Bahraini Dinar,巴林第纳尔,Bahrain,巴林\nBIF,Burundian Franc,布隆迪法郎,Burundi,布隆迪\nBMD,Bermudian Dollar,百慕大元,Bermuda,百慕大\nBND,Brunei Dollar,文莱元,Brunei,文莱\nBOB,Bolivian Boliviano,玻利维亚诺,Bolivia,玻利维亚\nBRL,Brazilian Real,巴西雷亚尔,Brazil,巴西\nBSD,Bahamian Dollar,巴哈马元,Bahamas,巴哈马\nBTN,Bhutanese Ngultrum,不丹努尔特鲁姆,Bhutan,不丹\nBWP,Botswana Pula,博茨瓦纳普拉,Botswana,博茨瓦纳\nBYN,Belarusian Ruble,白俄罗斯卢布,Belarus,白俄罗斯\nBZD,Belize Dollar,伯利兹元,Belize,伯利兹\nCAD,Canadian Dollar,加拿大元,Canada,加拿大\nCDF,Congolese Franc,刚果法郎,Democratic Republic of the Congo,刚果民主共和国\nCHF,Swiss Franc,瑞士法郎,Switzerland,瑞士\nCLF,Chilean Unidad de Fomento,智利发展单位,Chile,智利\nCLP,Chilean Peso,智利比索,Chile,智利\nCNH,Offshore Chinese Renminbi,离岸人民币,China,中国\nCNY,Chinese Renminbi,人民币,China,中国\nCOP,Colombian Peso,哥伦比亚比索,Colombia,哥伦比亚\nCRC,Costa Rican Colon,哥斯达黎加科朗,Costa Rica,哥斯达黎加\nCUP,Cuban Peso,古巴比索,Cuba,古巴\nCVE,Cape Verdean Escudo,佛得角埃斯库多,Cape Verde,佛得角\nCZK,Czech Koruna,捷克克朗,Czech Republic,捷克\nDJF,Djiboutian Franc,吉布提法郎,Djibouti,吉布提\nDKK,Danish Krone,丹麦克朗,Denmark,丹麦\nDOP,Dominican Peso,多米尼加比索,Dominican Republic,多米尼加\nDZD,Algerian Dinar,阿尔及利亚第纳尔,Algeria,阿尔及利亚\nEGP,Egyptian Pound,埃及镑,Egypt,埃及\nERN,Eritrean Nakfa,厄立特里亚纳克法,Eritrea,厄立特里亚\nETB,Ethiopian Birr,埃塞俄比亚比尔,Ethiopia,埃塞俄比亚\nEUR,Euro,欧元,European Union,欧盟\nFJD,Fiji Dollar,斐济元,Fiji,斐济\nFKP,Falkland Islands Pound,福克兰群岛镑,Falkland Islands,福克兰群岛\nFOK,Faroese Króna,法罗克朗,Faroe Islands,法罗群岛\nGBP,Pound Sterling,英镑,United Kingdom,英国\nGEL,Georgian Lari,格鲁吉亚拉里,Georgia,格鲁吉亚\nGGP,Guernsey Pound,根西岛镑,Guernsey,根西岛\nGHS,Ghanaian Cedi,加纳塞地,Ghana,加纳\nGIP,Gibraltar Pound,直布罗陀镑,Gibraltar,直布罗陀\nGMD,Gambian Dalasi,冈比亚达拉西,Gambia,冈比亚\nGNF,Guinean Franc,几内亚法郎,Guinea,几内亚\nGTQ,Guatemalan Quetzal,危地马拉格查尔,Guatemala,危地马拉\nGYD,Guyanese Dollar,圭亚那元,Guyana,圭亚那\nHKD,Hong Kong Dollar,港元,Hong Kong,中国香港\nHNL,Honduran Lempira,洪都拉斯伦皮拉,Honduras,洪都拉斯\nHRK,Croatian Kuna,克罗地亚库纳,Croatia,克罗地亚\nHTG,Haitian Gourde,海地古德,Haiti,海地\nHUF,Hungarian Forint,匈牙利福林,Hungary,匈牙利\nIDR,Indonesian Rupiah,印尼盾,Indonesia,印度尼西亚\nILS,Israeli New Shekel,以色列新谢克尔,Israel,以色列\nIMP,Manx Pound,马恩岛镑,Isle of Man,马恩岛\nINR,Indian Rupee,印度卢比,India,印度\nIQD,Iraqi Dinar,伊拉克第纳尔,Iraq,伊拉克\nIRR,Iranian Rial,伊朗里亚尔,Iran,伊朗\nISK,Icelandic Króna,冰岛克朗,Iceland,冰岛\nJEP,Jersey Pound,泽西岛镑,Jersey,泽西岛\nJMD,Jamaican Dollar,牙买加元,Jamaica,牙买加\nJOD,Jordanian Dinar,约旦第纳尔,Jordan,约旦\nJPY,Japanese Yen,日元,Japan,日本\nKES,Kenyan Shilling,肯尼亚先令,Kenya,肯尼亚\nKGS,Kyrgyzstani Som,吉尔吉斯斯坦索姆,Kyrgyzstan,吉尔吉斯斯坦\nKHR,Cambodian Riel,柬埔寨瑞尔,Cambodia,柬埔寨\nKID,Kiribati Dollar,基里巴斯元,Kiribati,基里巴斯\nKMF,Comorian Franc,科摩罗法郎,Comoros,科摩罗\nKRW,South Korean Won,韩元,South Korea,韩国\nKWD,Kuwaiti Dinar,科威特第纳尔,Kuwait,科威特\nKYD,Cayman Islands Dollar,开曼群岛元,Cayman Islands,开曼群岛\nKZT,Kazakhstani Tenge,哈萨克斯坦坚戈,Kazakhstan,哈萨克斯坦\nLAK,Lao Kip,老挝基普,Laos,老挝\nLBP,Lebanese Pound,黎巴嫩镑,Lebanon,黎巴嫩\nLKR,Sri Lanka Rupee,斯里兰卡卢比,Sri Lanka,斯里兰卡\nLRD,Liberian Dollar,利比里亚元,Liberia,利比里亚\nLSL,Lesotho Loti,莱索托洛蒂,Lesotho,莱索托\nLYD,Libyan Dinar,利比亚第纳尔,Libya,利比亚\nMAD,Moroccan Dirham,摩洛哥迪拉姆,Morocco,摩洛哥\nMDL,Moldovan Leu,摩尔多瓦列伊,Moldova,摩尔多瓦\nMGA,Malagasy Ariary,马达加斯加阿里亚里,Madagascar,马达加斯加\nMKD,Macedonian Denar,北马其顿第纳尔,North Macedonia,北马其顿\nMMK,Burmese Kyat,缅甸元,Myanmar,缅甸\nMNT,Mongolian Tögrög,蒙古图格里克,Mongolia,蒙古\nMOP,Macanese Pataca,澳门元,Macau,中国澳门\nMRU,Mauritanian Ouguiya,毛里塔尼亚乌吉亚,Mauritania,毛里塔尼亚\nMUR,Mauritian Rupee,毛里求斯卢比,Mauritius,毛里求斯\nMVR,Maldivian Rufiyaa,马尔代夫拉菲亚,Maldives,马尔代夫\nMWK,Malawian Kwacha,马拉维克瓦查,Malawi,马拉维\nMXN,Mexican Peso,墨西哥比索,Mexico,墨西哥\nMYR,Malaysian Ringgit,马来西亚林吉特,Malaysia,马来西亚\nMZN,Mozambican Metical,莫桑比克梅蒂卡尔,Mozambique,莫桑比克\nNAD,Namibian Dollar,纳米比亚元,Namibia,纳米比亚\nNGN,Nigerian Naira,尼日利亚奈拉,Nigeria,尼日利亚\nNIO,Nicaraguan Córdoba,尼加拉瓜科多巴,Nicaragua,尼加拉瓜\nNOK,Norwegian Krone,挪威克朗,Norway,挪威\nNPR,Nepalese Rupee,尼泊尔卢比,Nepal,尼泊尔\nNZD,New Zealand Dollar,新西兰元,New Zealand,新西兰\nOMR,Omani Rial,阿曼里亚尔,Oman,阿曼\nPAB,Panamanian Balboa,巴拿马巴波亚,Panama,巴拿马\nPEN,Peruvian Sol,秘鲁索尔,Peru,秘鲁\nPGK,Papua New Guinean Kina,巴布亚新几内亚基那,Papua New Guinea,巴布亚新几内亚\nPHP,Philippine Peso,菲律宾比索,Philippines,菲律宾\nPKR,Pakistani Rupee,巴基斯坦卢比,Pakistan,巴基斯坦\nPLN,Polish Złoty,波兰兹罗提,Poland,波兰\nPYG,Paraguayan Guaraní,巴拉圭瓜拉尼,Paraguay,巴拉圭\nQAR,Qatari Riyal,卡塔尔里亚尔,Qatar,卡塔尔\nRON,Romanian Leu,罗马尼亚列伊,Romania,罗马尼亚\nRSD,Serbian Dinar,塞尔维亚第纳尔,Serbia,塞尔维亚\nRUB,Russian Ruble,俄罗斯卢布,Russia,俄罗斯\nRWF,Rwandan Franc,卢旺达法郎,Rwanda,卢旺达\nSAR,Saudi Riyal,沙特里亚尔,Saudi Arabia,沙特阿拉伯\nSBD,Solomon Islands Dollar,所罗门群岛元,Solomon Islands,所罗门群岛\nSCR,Seychellois Rupee,塞舌尔卢比,Seychelles,塞舌尔\nSDG,Sudanese Pound,苏丹镑,Sudan,苏丹\nSEK,Swedish Krona,瑞典克朗,Sweden,瑞典\nSGD,Singapore Dollar,新加坡元,Singapore,新加坡\nSHP,Saint Helena Pound,圣赫勒拿镑,Saint Helena,圣赫勒拿\nSLE,Sierra Leonean Leone,塞拉利昂利昂,Sierra Leone,塞拉利昂\nSLL,Sierra Leonean Leone,塞拉利昂利昂(旧),Sierra Leone,塞拉利昂\nSOS,Somali Shilling,索马里先令,Somalia,索马里\nSRD,Surinamese Dollar,苏里南元,Suriname,苏里南\nSSP,South Sudanese Pound,南苏丹镑,South Sudan,南苏丹\nSTN,São Tomé and Príncipe Dobra,圣多美多布拉,São Tomé and Príncipe,圣多美和普林西比\nSYP,Syrian Pound,叙利亚镑,Syria,叙利亚\nSZL,Eswatini Lilangeni,斯威士兰里兰吉尼,Eswatini,斯威士兰\nTHB,Thai Baht,泰铢,Thailand,泰国\nTJS,Tajikistani Somoni,塔吉克斯坦索莫尼,Tajikistan,塔吉克斯坦\nTMT,Turkmenistan Manat,土库曼斯坦马纳特,Turkmenistan,土库曼斯坦\nTND,Tunisian Dinar,突尼斯第纳尔,Tunisia,突尼斯\nTOP,Tongan Paʻanga,汤加潘加,Tonga,汤加\nTRY,Turkish Lira,土耳其里拉,Turkey,土耳其\nTTD,Trinidad and Tobago Dollar,特立尼达和多巴哥元,Trinidad and Tobago,特立尼达和多巴哥\nTVD,Tuvaluan Dollar,图瓦卢元,Tuvalu,图瓦卢\nTWD,New Taiwan Dollar,新台币,Taiwan,中国台湾\nTZS,Tanzanian Shilling,坦桑尼亚先令,Tanzania,坦桑尼亚\nUAH,Ukrainian Hryvnia,乌克兰格里夫纳,Ukraine,乌克兰\nUGX,Ugandan Shilling,乌干达先令,Uganda,乌干达\nUSD,United States Dollar,美元,United States,美国\nUYU,Uruguayan Peso,乌拉圭比索,Uruguay,乌拉圭\nUZS,Uzbekistani So'm,乌兹别克斯坦苏姆,Uzbekistan,乌兹别克斯坦\nVES,Venezuelan Bolívar Soberano,委内瑞拉玻利瓦尔,Venezuela,委内瑞拉\nVND,Vietnamese Đồng,越南盾,Vietnam,越南\nVUV,Vanuatu Vatu,瓦努阿图瓦图,Vanuatu,瓦努阿图\nWST,Samoan Tālā,萨摩亚塔拉,Samoa,萨摩亚\nXAF,Central African CFA Franc,中非法郎,Central African States,中非国家\nXCD,East Caribbean Dollar,东加勒比元,East Caribbean States,东加勒比国家\nXCG,Caribbean Guilder,加勒比盾,Caribbean,加勒比地区\nXDR,Special Drawing Rights,特别提款权,International Monetary Fund,国际货币基金组织\nXOF,West African CFA franc,西非法郎,West African States,西非国家\nXPF,CFP Franc,太平洋法郎,French Pacific Territories,法属太平洋领地\nYER,Yemeni Rial,也门里亚尔,Yemen,也门\nZAR,South African Rand,南非兰特,South Africa,南非\nZMW,Zambian Kwacha,赞比亚克瓦查,Zambia,赞比亚\nZWG,Zimbabwean Dollar,津巴布韦元(新),Zimbabwe,津巴布韦\nZWL,Zimbabwean Dollar,津巴布韦元,Zimbabwe,津巴布韦\n".split(/\r?\n/),n=[];for(let e=0;e<a.length;e++){const i=a[e].trim();if(!i)continue;if(0===e&&i.toLowerCase().startsWith("code,"))continue;const r=i.split(",");r.length>=5&&n.push({code:r[0].trim(),name:r[1].trim(),name_cn:r[2].trim(),country:r[3].trim(),country_cn:r[4].trim()})}return n}(),this.currencyCodeSet=new Set(this.currencies.map(a=>a.code))}validateCurrencyCode(a){const n=a.toUpperCase();if(!this.currencyCodeSet.has(n))throw i("INVALID_CURRENCY_CODE",`Invalid currency code: ${a}. The currency code is not in the supported list.`,{code:a})}async getRates(a){const n=a.toUpperCase();this.validateCurrencyCode(n);const e=`rates_${n}`,r=this.cache.get(e);if(r)return r;const l=`${this.baseUrl}/${encodeURIComponent(n)}`,c=await async function(a,n){let e,r;for(let l=0;l<=n.maxRetries;l++)try{const e=await o(a,n.timeout);if(r=e.status,!e.ok){if(s(null,e.status)&&l<n.maxRetries){const a=n.retryDelay*Math.pow(2,l);await t(a);continue}throw i("API_ERROR",`API request failed with status ${e.status}`,{status:e.status})}return await e.json()}catch(a){if(e=a,a instanceof Error&&"ExchangeRateSDKError"===a.name&&!s(null,r))throw a;if(a instanceof Error&&"AbortError"===a.name&&(e=i("TIMEOUT_ERROR","Request timeout")),s(a,r)&&l<n.maxRetries){const a=n.retryDelay*Math.pow(2,l);await t(a);continue}if(a instanceof Error&&"ExchangeRateSDKError"===a.name)throw a;throw i("NETWORK_ERROR",a instanceof Error?a.message:"Network request failed",a)}if(e instanceof Error&&"ExchangeRateSDKError"===e.name)throw e;throw i("NETWORK_ERROR","All retry attempts failed",e)}(l,{timeout:this.timeout,maxRetries:this.maxRetries,retryDelay:this.retryDelay});if(!c||!c.rates||c.base!==n)throw i("API_ERROR","Invalid API response format",{response:c});return this.cache.set(e,c),c}async getRate(a,n){const e=a.toUpperCase(),r=n.toUpperCase();if(this.validateCurrencyCode(e),this.validateCurrencyCode(r),e===r)return 1;const t=(await this.getRates(e)).rates[r];if(void 0===t)throw i("API_ERROR",`Exchange rate not found for ${e} to ${r}`,{from:e,to:r});return t}async convert(a,n,e){const i=await this.getRate(n,e);return{amount:a*i,from:n.toUpperCase(),to:e.toUpperCase(),rate:i}}getCurrency(a){const n=a.toUpperCase();return this.validateCurrencyCode(n),this.currencies.find(a=>a.code===n)}getCurrencies(){return[...this.currencies]}searchCurrency(a){const n=a.toLowerCase();return this.currencies.filter(e=>e.code.toLowerCase().includes(n)||e.name.toLowerCase().includes(n)||e.name_cn.includes(a)||e.country.toLowerCase().includes(n)||e.country_cn.includes(a))}clearCache(){this.cache.clear()}setCacheTTL(a){this.cacheTTL=a,this.cache.setTTL(a)}}export{l as ExchangeRateClient,i as createError,r as isSDKError};
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 带重试的请求函数
3
+ */
4
+ export declare function requestWithRetry<T>(url: string, options: {
5
+ timeout: number;
6
+ maxRetries: number;
7
+ retryDelay: number;
8
+ }): Promise<T>;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * SDK 配置选项
3
+ */
4
+ export interface ExchangeRateClientOptions {
5
+ /** 缓存过期时间(毫秒),默认 24 小时 */
6
+ cacheTTL?: number;
7
+ /** 请求超时时间(毫秒),默认 10 秒 */
8
+ timeout?: number;
9
+ /** API 基础 URL */
10
+ baseUrl?: string;
11
+ /** 最大重试次数,默认 3 */
12
+ maxRetries?: number;
13
+ /** 重试延迟基数(毫秒),默认 1000 */
14
+ retryDelay?: number;
15
+ }
16
+ /**
17
+ * 货币信息
18
+ */
19
+ export interface Currency {
20
+ /** 货币代码 e.g. 'USD' */
21
+ code: string;
22
+ /** 英文名称 */
23
+ name: string;
24
+ /** 中文名称 */
25
+ name_cn: string;
26
+ /** 国家/地区英文名 */
27
+ country: string;
28
+ /** 国家/地区中文名 */
29
+ country_cn: string;
30
+ }
31
+ /**
32
+ * 汇率响应
33
+ */
34
+ export interface RatesResponse {
35
+ /** 基准货币 */
36
+ base: string;
37
+ /** 汇率日期 */
38
+ date: string;
39
+ /** 汇率映射 */
40
+ rates: Record<string, number>;
41
+ }
42
+ /**
43
+ * 货币转换结果
44
+ */
45
+ export interface ConvertResult {
46
+ /** 转换后金额 */
47
+ amount: number;
48
+ /** 源货币 */
49
+ from: string;
50
+ /** 目标货币 */
51
+ to: string;
52
+ /** 使用的汇率 */
53
+ rate: number;
54
+ }
55
+ /**
56
+ * 缓存数据结构
57
+ */
58
+ export interface CacheEntry<T> {
59
+ /** 缓存数据 */
60
+ data: T;
61
+ /** 过期时间戳 */
62
+ expiresAt: number;
63
+ }
64
+ /**
65
+ * SDK 错误类型
66
+ */
67
+ export type ErrorCode = 'INVALID_CURRENCY_CODE' | 'NETWORK_ERROR' | 'TIMEOUT_ERROR' | 'API_ERROR' | 'PARSE_ERROR' | 'UNKNOWN_ERROR';
68
+ /**
69
+ * SDK 错误响应
70
+ */
71
+ export interface SDKError extends Error {
72
+ code: ErrorCode;
73
+ details?: unknown;
74
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "exchange-rate-sdk",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "A lightweight, cross-platform exchange rate JavaScript SDK for browser and Node.js",
6
+ "main": "./dist/index.cjs.js",
7
+ "module": "./dist/index.esm.js",
8
+ "browser": "./dist/index.esm.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.esm.js",
13
+ "require": "./dist/index.cjs.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "engines": {
21
+ "node": ">=14.0.0"
22
+ },
23
+ "sideEffects": false,
24
+ "scripts": {
25
+ "build": "rollup -c",
26
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
27
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
28
+ "prepublishOnly": "yarn build && yarn test"
29
+ },
30
+ "keywords": [
31
+ "exchange-rate",
32
+ "currency",
33
+ "forex",
34
+ "conversion",
35
+ "currency-converter",
36
+ "finance",
37
+ "iso-4217"
38
+ ],
39
+ "author": "chengzuopeng",
40
+ "license": "ISC",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/chengzuopeng/exchange-rate-sdk.git"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/chengzuopeng/exchange-rate-sdk/issues"
47
+ },
48
+ "homepage": "https://github.com/chengzuopeng/exchange-rate-sdk#readme",
49
+ "devDependencies": {
50
+ "@rollup/plugin-node-resolve": "^15.2.3",
51
+ "@rollup/plugin-terser": "^0.4.4",
52
+ "@rollup/plugin-typescript": "^11.1.6",
53
+ "@types/jest": "^29.5.14",
54
+ "jest": "^29.7.0",
55
+ "rollup": "^4.28.1",
56
+ "ts-jest": "^29.2.5",
57
+ "tslib": "^2.8.1",
58
+ "typescript": "^5.7.2"
59
+ }
60
+ }