@ordius/adonisjs-currencyx 1.4.9
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.md +9 -0
- package/README.md +508 -0
- package/build/configure.d.ts +2 -0
- package/build/configure.js +50 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +13 -0
- package/build/providers/currency_provider.d.ts +34 -0
- package/build/providers/currency_provider.js +46 -0
- package/build/services/main.d.ts +19 -0
- package/build/services/main.js +29 -0
- package/build/src/define_config.d.ts +31 -0
- package/build/src/define_config.js +56 -0
- package/build/src/exchanges/database.d.ts +54 -0
- package/build/src/exchanges/database.js +361 -0
- package/build/src/symbols.d.ts +5 -0
- package/build/src/symbols.js +5 -0
- package/build/src/types.d.ts +111 -0
- package/build/src/types.js +1 -0
- package/build/stubs/config/currency.stub +97 -0
- package/build/stubs/main.d.ts +5 -0
- package/build/stubs/main.js +7 -0
- package/build/stubs/migrations/create_currencies_table.stub +41 -0
- package/build/stubs/models/currency.stub +111 -0
- package/package.json +146 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
# AdonisJS CurrencyX
|
|
2
|
+
|
|
3
|
+
> AdonisJS integration for CurrencyX with database provider and cache support. Seamlessly integrate currency conversion into your AdonisJS applications.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/@mixxtor%2Fcurrencyx-adonisjs)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://adonisjs.com/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
|
|
12
|
+
- 🚀 **AdonisJS Integration** - Seamless integration with AdonisJS v6 framework
|
|
13
|
+
- 💾 **Database Exchange** - Store exchange rates in your database using Lucid ORM
|
|
14
|
+
- 🔄 **Multiple Exchanges** - Google Finance, Fixer.io, and database exchanges
|
|
15
|
+
- 📦 **Cache Support** - Built-in caching with AdonisJS Cache
|
|
16
|
+
- 🎯 **Type Safety** - Full TypeScript support with intelligent inference
|
|
17
|
+
- 🔧 **Easy Setup** - Simple configuration and installation
|
|
18
|
+
- 🌐 **Service Container** - Registered as AdonisJS service for dependency injection
|
|
19
|
+
- 🏗️ **Repository Pattern** - Clean architecture following AdonisJS patterns
|
|
20
|
+
|
|
21
|
+
## 📦 Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @ordius/adonisjs-currencyx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 🚀 Setup
|
|
28
|
+
|
|
29
|
+
### 1. Configure the package
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
node ace configure @ordius/adonisjs-currencyx
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This will:
|
|
36
|
+
|
|
37
|
+
- Create `config/currency.ts` configuration file
|
|
38
|
+
- Create Currency model and migration stubs
|
|
39
|
+
- Register the service provider
|
|
40
|
+
|
|
41
|
+
### 2. Configure providers
|
|
42
|
+
|
|
43
|
+
Edit `config/currency.ts`:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import env from '#start/env'
|
|
47
|
+
import { defineConfig, exchanges } from '@ordius/adonisjs-currencyx'
|
|
48
|
+
|
|
49
|
+
export default defineConfig({
|
|
50
|
+
/*
|
|
51
|
+
|--------------------------------------------------------------------------
|
|
52
|
+
| Default Exchange
|
|
53
|
+
|--------------------------------------------------------------------------
|
|
54
|
+
*/
|
|
55
|
+
default: env.get('CURRENCY_PROVIDER', 'database') as 'database' | 'google' | 'fixer',
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
|--------------------------------------------------------------------------
|
|
59
|
+
| Exchange Configurations
|
|
60
|
+
|--------------------------------------------------------------------------
|
|
61
|
+
*/
|
|
62
|
+
exchanges: {
|
|
63
|
+
/*
|
|
64
|
+
|--------------------------------------------------------------------------
|
|
65
|
+
| Database Exchange
|
|
66
|
+
|--------------------------------------------------------------------------
|
|
67
|
+
| Uses your local database to store and retrieve exchange rates.
|
|
68
|
+
*/
|
|
69
|
+
database: exchanges.database({
|
|
70
|
+
model: () => import('#models/currency'),
|
|
71
|
+
base: 'USD',
|
|
72
|
+
columns: {
|
|
73
|
+
code: 'code',
|
|
74
|
+
rate: 'exchange_rate',
|
|
75
|
+
},
|
|
76
|
+
// Cache configuration (optional)
|
|
77
|
+
// cache: {
|
|
78
|
+
// service: () => import('@adonisjs/cache/services/main'),
|
|
79
|
+
// ttl: '1h', // Cache TTL (human readable or milliseconds)
|
|
80
|
+
// keyPrefix: 'currency' // Cache key prefix
|
|
81
|
+
// }
|
|
82
|
+
}),
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
|--------------------------------------------------------------------------
|
|
86
|
+
| Google Finance Exchange
|
|
87
|
+
|--------------------------------------------------------------------------
|
|
88
|
+
| Free exchange using Google Finance API. No API key required.
|
|
89
|
+
*/
|
|
90
|
+
google: exchanges.google({
|
|
91
|
+
base: env.get('CURRENCY_BASE', 'USD'),
|
|
92
|
+
timeout: 5000,
|
|
93
|
+
}),
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
|--------------------------------------------------------------------------
|
|
97
|
+
| Fixer.io Exchange
|
|
98
|
+
|--------------------------------------------------------------------------
|
|
99
|
+
| Requires API key from fixer.io.
|
|
100
|
+
*/
|
|
101
|
+
// fixer: exchanges.fixer({
|
|
102
|
+
// accessKey: env.get('FIXER_API_KEY'),
|
|
103
|
+
// base: env.get('CURRENCY_BASE', 'USD'),
|
|
104
|
+
// timeout: 10000
|
|
105
|
+
// })
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Create Currency model
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
node ace make:model Currency
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// app/models/currency.ts
|
|
118
|
+
import { DateTime } from 'luxon'
|
|
119
|
+
import { BaseModel, column } from '@adonisjs/lucid/orm'
|
|
120
|
+
|
|
121
|
+
export default class Currency extends BaseModel {
|
|
122
|
+
@column({ isPrimary: true })
|
|
123
|
+
declare id: number
|
|
124
|
+
|
|
125
|
+
@column()
|
|
126
|
+
declare code: string
|
|
127
|
+
|
|
128
|
+
@column()
|
|
129
|
+
declare name: string
|
|
130
|
+
|
|
131
|
+
@column()
|
|
132
|
+
declare exchange_rate: number
|
|
133
|
+
|
|
134
|
+
@column.dateTime({ autoCreate: true })
|
|
135
|
+
declare createdAt: DateTime
|
|
136
|
+
|
|
137
|
+
@column.dateTime({ autoCreate: true, autoUpdate: true })
|
|
138
|
+
declare updatedAt: DateTime
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 4. Create migration
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
node ace make:migration create_currencies_table
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// database/migrations/xxx_create_currencies_table.ts
|
|
150
|
+
import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
151
|
+
|
|
152
|
+
export default class extends BaseSchema {
|
|
153
|
+
protected tableName = 'currencies'
|
|
154
|
+
|
|
155
|
+
async up() {
|
|
156
|
+
this.schema.createTable(this.tableName, (table) => {
|
|
157
|
+
table.increments('id')
|
|
158
|
+
table.string('code', 3).notNullable().unique()
|
|
159
|
+
table.string('name').notNullable()
|
|
160
|
+
table.decimal('exchange_rate', 15, 8).notNullable()
|
|
161
|
+
table.timestamp('created_at')
|
|
162
|
+
table.timestamp('updated_at')
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async down() {
|
|
167
|
+
this.schema.dropTable(this.tableName)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 5. Run migration
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
node ace migration:run
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 💡 Usage
|
|
179
|
+
|
|
180
|
+
### Basic Usage in Controllers
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// app/controllers/exchange_controller.ts
|
|
184
|
+
import { inject } from '@adonisjs/core'
|
|
185
|
+
import type { HttpContext } from '@adonisjs/core/http'
|
|
186
|
+
import CurrencyService from '@ordius/adonisjs-currencyx/services/main'
|
|
187
|
+
|
|
188
|
+
@inject()
|
|
189
|
+
export default class ExchangeController {
|
|
190
|
+
constructor(private currency: CurrencyService) {}
|
|
191
|
+
|
|
192
|
+
async convert({ request, response }: HttpContext) {
|
|
193
|
+
const { amount, from, to } = request.only(['amount', 'from', 'to'])
|
|
194
|
+
|
|
195
|
+
const result = await this.currency.convert({
|
|
196
|
+
amount: Number(amount),
|
|
197
|
+
from,
|
|
198
|
+
to,
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
if (result.success) {
|
|
202
|
+
return response.json({
|
|
203
|
+
success: true,
|
|
204
|
+
data: {
|
|
205
|
+
amount,
|
|
206
|
+
from,
|
|
207
|
+
to,
|
|
208
|
+
result: result.result,
|
|
209
|
+
rate: result.info.rate,
|
|
210
|
+
timestamp: result.info.timestamp,
|
|
211
|
+
},
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return response.status(400).json({
|
|
216
|
+
success: false,
|
|
217
|
+
error: result.error?.info,
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async getRates({ request, response }: HttpContext) {
|
|
222
|
+
const { base, codes } = request.only(['base', 'codes'])
|
|
223
|
+
|
|
224
|
+
const result = await this.currency.getExchangeRates({
|
|
225
|
+
base,
|
|
226
|
+
codes: codes.split(','),
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
if (result.success) {
|
|
230
|
+
return response.json({
|
|
231
|
+
success: true,
|
|
232
|
+
data: result,
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return response.status(400).json({
|
|
237
|
+
success: false,
|
|
238
|
+
error: result.error?.info,
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Exchange Switching
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
// Switch to different exchange at runtime
|
|
248
|
+
await this.currency.use('google')
|
|
249
|
+
const googleResult = await this.currency.convert({ amount: 100, from: 'USD', to: 'EUR' })
|
|
250
|
+
|
|
251
|
+
await this.currency.use('fixer')
|
|
252
|
+
const fixerResult = await this.currency.convert({ amount: 100, from: 'USD', to: 'EUR' })
|
|
253
|
+
|
|
254
|
+
await this.currency.use('database')
|
|
255
|
+
const dbResult = await this.currency.convert({ amount: 100, from: 'USD', to: 'EUR' })
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Database Exchange Usage
|
|
259
|
+
|
|
260
|
+
Seed your database with exchange rates:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// database/seeders/currency_seeder.ts
|
|
264
|
+
import { BaseSeeder } from '@adonisjs/lucid/seeders'
|
|
265
|
+
import Currency from '#models/currency'
|
|
266
|
+
|
|
267
|
+
export default class extends BaseSeeder {
|
|
268
|
+
async run() {
|
|
269
|
+
const rates = [
|
|
270
|
+
{ code: 'USD', name: 'US Dollar', exchange_rate: 1.0 },
|
|
271
|
+
{ code: 'EUR', name: 'Euro', exchange_rate: 0.85 },
|
|
272
|
+
{ code: 'GBP', name: 'British Pound', exchange_rate: 0.73 },
|
|
273
|
+
{ code: 'JPY', name: 'Japanese Yen', exchange_rate: 110.0 },
|
|
274
|
+
{ code: 'CAD', name: 'Canadian Dollar', exchange_rate: 1.25 },
|
|
275
|
+
{ code: 'AUD', name: 'Australian Dollar', exchange_rate: 1.35 },
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
for (const rate of rates) {
|
|
279
|
+
await Currency.updateOrCreate({ code: rate.code }, rate)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Run the seeder:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
node ace db:seed
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Caching
|
|
292
|
+
|
|
293
|
+
Enable caching for better performance:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// config/currency.ts
|
|
297
|
+
database: exchanges.database({
|
|
298
|
+
model: () => import('#models/currency'),
|
|
299
|
+
base: 'USD',
|
|
300
|
+
columns: {
|
|
301
|
+
code: 'code',
|
|
302
|
+
rate: 'exchange_rate',
|
|
303
|
+
},
|
|
304
|
+
cache: {
|
|
305
|
+
service: () => import('@adonisjs/cache/services/main'), // AdonisJS cache service
|
|
306
|
+
ttl: '1h', // Cache TTL (human readable or milliseconds)
|
|
307
|
+
keyPrefix: 'currency', // Cache key prefix
|
|
308
|
+
},
|
|
309
|
+
})
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## 📚 API Reference
|
|
313
|
+
|
|
314
|
+
The AdonisJS integration provides the same API as the core CurrencyX package:
|
|
315
|
+
|
|
316
|
+
### Core Methods
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// Convert currency
|
|
320
|
+
const result = await currency.convert({
|
|
321
|
+
amount: 100,
|
|
322
|
+
from: 'USD',
|
|
323
|
+
to: 'EUR',
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
// Get exchange rates
|
|
327
|
+
const rates = await currency.getExchangeRates({
|
|
328
|
+
base: 'USD',
|
|
329
|
+
codes: ['EUR', 'GBP', 'JPY'],
|
|
330
|
+
})
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Convenience Methods
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
// Shorthand for getting rates
|
|
337
|
+
const rates = await currency.latestRates({ base: 'USD', codes: ['EUR', 'GBP'] })
|
|
338
|
+
|
|
339
|
+
// Get exchange rates with same API as core library
|
|
340
|
+
const rates = await currency.getExchangeRates({ base: 'USD', codes: ['EUR', 'GBP'] })
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Exchange Management
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
// Switch exchanges
|
|
347
|
+
currency.use('google')
|
|
348
|
+
|
|
349
|
+
// Get current exchange
|
|
350
|
+
const current = currency.getCurrentExchange()
|
|
351
|
+
|
|
352
|
+
// List available exchanges
|
|
353
|
+
const exchanges = currency.getAvailableExchanges()
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Utility Methods
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// Format currency (object parameters)
|
|
360
|
+
const formatted = currency.formatCurrency({ amount: 1234.56, code: 'USD', locale: 'en-US' })
|
|
361
|
+
|
|
362
|
+
// Round values
|
|
363
|
+
const rounded = currency.round(123.456789, { precision: 2, direction: 'up' })
|
|
364
|
+
|
|
365
|
+
// Get supported currencies
|
|
366
|
+
const currencies = await currency.getSupportedCurrencies()
|
|
367
|
+
|
|
368
|
+
// Currency information utilities
|
|
369
|
+
const allCurrencies = currency.getList()
|
|
370
|
+
const usdInfo = currency.getByCode('USD')
|
|
371
|
+
const dollarCurrencies = currency.getBySymbol('$')
|
|
372
|
+
const usCurrency = currency.getByCountry('US')
|
|
373
|
+
const euroCurrencies = currency.filterByName('Euro')
|
|
374
|
+
const usCurrencies = currency.filterByCountry('US')
|
|
375
|
+
|
|
376
|
+
// Round money according to currency rules
|
|
377
|
+
const rounded = currency.roundMoney(123.456, 'USD')
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## ⚙️ Configuration
|
|
381
|
+
|
|
382
|
+
### Environment Variables
|
|
383
|
+
|
|
384
|
+
Add these to your `.env` file:
|
|
385
|
+
|
|
386
|
+
```env
|
|
387
|
+
# Default exchange
|
|
388
|
+
CURRENCY_PROVIDER=database
|
|
389
|
+
|
|
390
|
+
# Base currency
|
|
391
|
+
CURRENCY_BASE=USD
|
|
392
|
+
|
|
393
|
+
# Fixer.io API key (if using fixer exchange)
|
|
394
|
+
FIXER_API_KEY=your_api_key_here
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Exchange Configuration
|
|
398
|
+
|
|
399
|
+
#### Database Exchange
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
database: exchanges.database({
|
|
403
|
+
model: () => import('#models/currency'), // Your Currency model
|
|
404
|
+
base: 'USD', // Base currency
|
|
405
|
+
columns: {
|
|
406
|
+
code: 'code', // Currency code column
|
|
407
|
+
rate: 'exchange_rate', // Exchange rate column
|
|
408
|
+
},
|
|
409
|
+
cache: {
|
|
410
|
+
// Optional caching
|
|
411
|
+
service: () => import('@adonisjs/cache/services/main'), // AdonisJS cache service
|
|
412
|
+
ttl: '1h', // Cache TTL (human readable or milliseconds)
|
|
413
|
+
keyPrefix: 'currency', // Cache key prefix
|
|
414
|
+
},
|
|
415
|
+
})
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### Google Finance Exchange
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
google: exchanges.google({
|
|
422
|
+
base: 'USD', // Base currency
|
|
423
|
+
timeout: 5000, // Request timeout (optional)
|
|
424
|
+
})
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
#### Fixer.io Exchange
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
fixer: exchanges.fixer({
|
|
431
|
+
accessKey: 'your-api-key', // Required
|
|
432
|
+
base: 'USD', // Base currency (default: 'USD' for this library)
|
|
433
|
+
timeout: 10000, // Request timeout (optional)
|
|
434
|
+
})
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## 🛡️ Error Handling
|
|
438
|
+
|
|
439
|
+
All methods return result objects with success indicators:
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
const result = await currency.convert({
|
|
443
|
+
amount: 100,
|
|
444
|
+
from: 'USD',
|
|
445
|
+
to: 'EUR',
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
if (result.success) {
|
|
449
|
+
// Handle success
|
|
450
|
+
console.log(`Converted: ${result.result}`)
|
|
451
|
+
console.log(`Rate: ${result.info.rate}`)
|
|
452
|
+
console.log(`Timestamp: ${result.info.timestamp}`)
|
|
453
|
+
} else {
|
|
454
|
+
// Handle error
|
|
455
|
+
console.error(`Error: ${result.error?.info}`)
|
|
456
|
+
console.error(`Type: ${result.error?.type}`)
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## 🧪 Testing
|
|
461
|
+
|
|
462
|
+
The package includes comprehensive tests. Run them with:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npm test
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
For development testing:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
npm run quick:test
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
For test coverage:
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
npm run test
|
|
478
|
+
# Coverage report will be generated in ./coverage/
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## 📋 Requirements
|
|
482
|
+
|
|
483
|
+
- **Node.js** >= 20.6.0
|
|
484
|
+
- **AdonisJS** >= 6.19.0
|
|
485
|
+
- **@adonisjs/lucid** >= 21.7.0 (for database provider)
|
|
486
|
+
- **@adonisjs/cache** >= 1.3.0 (optional, for caching)
|
|
487
|
+
|
|
488
|
+
## 🤝 Contributing
|
|
489
|
+
|
|
490
|
+
Contributions are welcome! Please read the contributing guidelines before submitting PRs.
|
|
491
|
+
|
|
492
|
+
## 📄 License
|
|
493
|
+
|
|
494
|
+
MIT License - see [LICENSE.md](./LICENSE.md) file for details.
|
|
495
|
+
|
|
496
|
+
## 📦 Related Packages
|
|
497
|
+
|
|
498
|
+
- [@mixxtor/currencyx-js](https://www.npmjs.com/package/@mixxtor/currencyx-js) - Core currency conversion library
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
<div align="center">
|
|
503
|
+
|
|
504
|
+
**[Documentation](https://github.com/mixxtor/currencyx-adonisjs#readme)** • **[Issues](https://github.com/mixxtor/currencyx-adonisjs/issues)** • **[Contributing](./CONTRIBUTING.md)**
|
|
505
|
+
|
|
506
|
+
Made with ❤️ by [Mixxtor](https://github.com/mixxtor)
|
|
507
|
+
|
|
508
|
+
</div>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|--------------------------------------------------------------------------
|
|
3
|
+
| Configure hook
|
|
4
|
+
|--------------------------------------------------------------------------
|
|
5
|
+
|
|
|
6
|
+
| The configure hook is called when someone runs "node ace configure <package>"
|
|
7
|
+
| command. You are free to perform any operations inside this function to
|
|
8
|
+
| configure the package.
|
|
9
|
+
|
|
|
10
|
+
| To make things easier, you have access to the underlying "ConfigureCommand"
|
|
11
|
+
| instance and you can use codemods to modify the source files.
|
|
12
|
+
|
|
|
13
|
+
*/
|
|
14
|
+
import { stubsRoot } from './stubs/main.js';
|
|
15
|
+
export async function configure(command) {
|
|
16
|
+
const codemods = await command.createCodemods();
|
|
17
|
+
/**
|
|
18
|
+
* Publish config file
|
|
19
|
+
*/
|
|
20
|
+
await codemods.makeUsingStub(stubsRoot, 'config/currency.stub', {});
|
|
21
|
+
/**
|
|
22
|
+
* Register provider
|
|
23
|
+
*/
|
|
24
|
+
await codemods.updateRcFile((rcFile) => {
|
|
25
|
+
rcFile.addProvider('@ordius/adonisjs-currencyx/currency_provider');
|
|
26
|
+
});
|
|
27
|
+
/**
|
|
28
|
+
* Create currency model if it doesn't exist
|
|
29
|
+
*/
|
|
30
|
+
const project = await codemods.getTsMorphProject();
|
|
31
|
+
const modelExists = project?.getSourceFile('app/models/currency.ts');
|
|
32
|
+
if (!modelExists) {
|
|
33
|
+
await codemods.makeUsingStub(stubsRoot, 'models/currency.stub', {});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create migration if it doesn't exist
|
|
37
|
+
*/
|
|
38
|
+
const migrationPattern = 'database/migrations/*_create_currencies_table.ts';
|
|
39
|
+
const migrationFiles = project?.getSourceFiles(migrationPattern) || [];
|
|
40
|
+
const migrationExists = migrationFiles.length > 0;
|
|
41
|
+
if (!migrationExists) {
|
|
42
|
+
const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..+/, '');
|
|
43
|
+
await codemods.makeUsingStub(stubsRoot, 'migrations/create_currencies_table.stub', {
|
|
44
|
+
migration: {
|
|
45
|
+
className: 'CreateCurrenciesTable',
|
|
46
|
+
fileName: `${timestamp}_create_currencies_table.ts`,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { configure } from './configure.js';
|
|
2
|
+
export { stubsRoot } from './stubs/main.js';
|
|
3
|
+
export { defineConfig, exchanges } from './src/define_config.js';
|
|
4
|
+
export type { CurrencyCode, DatabaseConfig, CacheConfig, CurrencyConfig, CurrencyRecord, CurrencyExchanges, InferExchanges, } from './src/types.js';
|
|
5
|
+
export { DatabaseExchange } from './src/exchanges/database.js';
|
package/build/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|--------------------------------------------------------------------------
|
|
3
|
+
| Package entrypoint
|
|
4
|
+
|--------------------------------------------------------------------------
|
|
5
|
+
|
|
|
6
|
+
| Export values from the package entrypoint as you see fit.
|
|
7
|
+
|
|
|
8
|
+
*/
|
|
9
|
+
export { configure } from './configure.js';
|
|
10
|
+
export { stubsRoot } from './stubs/main.js';
|
|
11
|
+
export { defineConfig, exchanges } from './src/define_config.js';
|
|
12
|
+
// Database Provider
|
|
13
|
+
export { DatabaseExchange } from './src/exchanges/database.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ordius/adonisjs-currencyx
|
|
3
|
+
*
|
|
4
|
+
* (c) Mixxtor
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
10
|
+
import type CurrencyService from '@mixxtor/currencyx-js';
|
|
11
|
+
/**
|
|
12
|
+
* Extend AdonisJS container bindings with currency service
|
|
13
|
+
*/
|
|
14
|
+
declare module '@adonisjs/core/types' {
|
|
15
|
+
interface ContainerBindings {
|
|
16
|
+
'currency.manager': CurrencyService;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default class CurrencyProvider {
|
|
20
|
+
protected app: ApplicationService;
|
|
21
|
+
constructor(app: ApplicationService);
|
|
22
|
+
/**
|
|
23
|
+
* Register currency service
|
|
24
|
+
*/
|
|
25
|
+
register(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Boot the provider
|
|
28
|
+
*/
|
|
29
|
+
boot(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Shutdown the provider
|
|
32
|
+
*/
|
|
33
|
+
shutdown(): Promise<void>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ordius/adonisjs-currencyx
|
|
3
|
+
*
|
|
4
|
+
* (c) Mixxtor
|
|
5
|
+
*
|
|
6
|
+
* For the full copyright and license information, please view the LICENSE
|
|
7
|
+
* file that was distributed with this source code.
|
|
8
|
+
*/
|
|
9
|
+
import { createCurrency } from '@mixxtor/currencyx-js';
|
|
10
|
+
import { configProvider } from '@adonisjs/core';
|
|
11
|
+
import { RuntimeException } from '@adonisjs/core/exceptions';
|
|
12
|
+
export default class CurrencyProvider {
|
|
13
|
+
app;
|
|
14
|
+
constructor(app) {
|
|
15
|
+
this.app = app;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Register currency service
|
|
19
|
+
*/
|
|
20
|
+
async register() {
|
|
21
|
+
this.app.container.singleton('currency.manager', async () => {
|
|
22
|
+
const currencyConfigProvider = this.app.config.get('currency');
|
|
23
|
+
if (!currencyConfigProvider) {
|
|
24
|
+
throw new RuntimeException('Currency configuration not found. Make sure you have a "config/currency.ts" file with "defineConfig" export');
|
|
25
|
+
}
|
|
26
|
+
const config = await configProvider.resolve(this.app, currencyConfigProvider);
|
|
27
|
+
if (!config) {
|
|
28
|
+
throw new RuntimeException('Invalid "config/currency.ts" file. Make sure you are using the "defineConfig" method');
|
|
29
|
+
}
|
|
30
|
+
// Create currency service with all providers
|
|
31
|
+
return createCurrency(config);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Boot the provider
|
|
36
|
+
*/
|
|
37
|
+
async boot() {
|
|
38
|
+
// Nothing to boot
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Shutdown the provider
|
|
42
|
+
*/
|
|
43
|
+
async shutdown() {
|
|
44
|
+
// Nothing to shutdown
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type CurrencyService from '@mixxtor/currencyx-js';
|
|
2
|
+
import type { CurrencyExchanges } from '../src/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Currency service with full type inference
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```ts
|
|
8
|
+
* import currency from '@ordius/adonisjs-currencyx/services/currency'
|
|
9
|
+
*
|
|
10
|
+
* // Direct usage - no type casting needed
|
|
11
|
+
* const rates = await currency.latestRates()
|
|
12
|
+
*
|
|
13
|
+
* // Provider switching with type inference
|
|
14
|
+
* const googleProvider = currency.use('google') // Only configured providers
|
|
15
|
+
* const rates = await googleProvider.latestRates()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
declare let currency: CurrencyService<Record<keyof CurrencyExchanges, CurrencyExchanges[keyof CurrencyExchanges]>>;
|
|
19
|
+
export { currency as default };
|