@unirate/next 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UniRate API
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # @unirate/next
2
+
3
+ Next.js App Router integration for the [UniRate API](https://unirateapi.com) — free currency exchange rates, conversion, historical data, and VAT rates.
4
+
5
+ **Zero runtime dependencies.** Works with Next.js 14+ App Router and React 18/19.
6
+
7
+ ## Features
8
+
9
+ - **Async RSC components** — `<Price />` and `<ExchangeRate />` render exchange data server-side with zero client JS
10
+ - **Server helpers** — `getRate()`, `convert()`, `listCurrencies()` with React `cache()` deduplication
11
+ - **Currency middleware** — auto-detect visitor currency from geo/locale and set it via header + cookie
12
+ - **Route handler** — proxy UniRate API calls through your app to keep the API key server-side
13
+ - **Next.js Data Cache** — pass `revalidate` to control ISR caching out of the box
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @unirate/next
19
+ ```
20
+
21
+ Set your API key (get one free at [unirateapi.com](https://unirateapi.com)):
22
+
23
+ ```bash
24
+ # .env.local
25
+ UNIRATE_API_KEY=your_api_key_here
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ ### Server Components
31
+
32
+ ```tsx
33
+ // app/page.tsx
34
+ import { Price, ExchangeRate, getRate, convert } from '@unirate/next';
35
+
36
+ export default async function Page() {
37
+ // Use components — they fetch at render time, zero client JS
38
+ return (
39
+ <div>
40
+ <p>Price: <Price amount={99.99} from="USD" to="EUR" /></p>
41
+ <p>Rate: <ExchangeRate from="USD" to="EUR" /></p>
42
+ </div>
43
+ );
44
+ }
45
+ ```
46
+
47
+ ### Server-side data fetching
48
+
49
+ ```tsx
50
+ import { getRate, convert, listCurrencies, createUniRate } from '@unirate/next';
51
+
52
+ // Top-level functions use UNIRATE_API_KEY from env
53
+ const rate = await getRate('USD', 'EUR'); // 0.92
54
+ const result = await convert('USD', 'EUR', 100); // 92.50
55
+ const currencies = await listCurrencies(); // ['USD', 'EUR', ...]
56
+
57
+ // Or create a configured instance with custom options
58
+ const unirate = createUniRate({
59
+ apiKey: 'custom-key', // override env var
60
+ revalidate: 3600, // ISR: revalidate every hour
61
+ });
62
+ const rate2 = await unirate.getRate('GBP', 'JPY');
63
+ ```
64
+
65
+ ### Currency middleware
66
+
67
+ Auto-detect visitor currency from Vercel/Cloudflare geo headers or `Accept-Language`:
68
+
69
+ ```ts
70
+ // middleware.ts
71
+ import { createCurrencyMiddleware } from '@unirate/next/middleware';
72
+
73
+ export const middleware = createCurrencyMiddleware({
74
+ defaultCurrency: 'USD',
75
+ });
76
+
77
+ export const config = {
78
+ matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
79
+ };
80
+ ```
81
+
82
+ Then read the detected currency in any Server Component:
83
+
84
+ ```tsx
85
+ import { headers } from 'next/headers';
86
+
87
+ export default async function Page() {
88
+ const h = await headers();
89
+ const currency = h.get('x-unirate-currency') ?? 'USD';
90
+ return <Price amount={49.99} from="USD" to={currency} />;
91
+ }
92
+ ```
93
+
94
+ ### Route handler (API proxy)
95
+
96
+ Keep your API key server-side by proxying through a Route Handler:
97
+
98
+ ```ts
99
+ // app/api/unirate/route.ts
100
+ import { createUniRateHandler } from '@unirate/next/route';
101
+
102
+ const handler = createUniRateHandler();
103
+ export { handler as GET };
104
+ ```
105
+
106
+ Then call from client components:
107
+
108
+ ```ts
109
+ // Client-side fetch (no API key exposed)
110
+ const res = await fetch('/api/unirate?path=/api/rates&from=USD&to=EUR');
111
+ const { rate } = await res.json();
112
+ ```
113
+
114
+ ## Components
115
+
116
+ ### `<Price />`
117
+
118
+ Async Server Component that converts an amount and renders it formatted.
119
+
120
+ | Prop | Type | Default | Description |
121
+ |------|------|---------|-------------|
122
+ | `amount` | `number` | — | Amount to convert |
123
+ | `from` | `string` | `"USD"` | Source currency |
124
+ | `to` | `string` | — | Target currency |
125
+ | `decimals` | `number` | `2` | Fraction digits |
126
+ | `locale` | `string` | runtime | BCP-47 locale for formatting |
127
+
128
+ ### `<ExchangeRate />`
129
+
130
+ Async Server Component that renders a bare exchange rate.
131
+
132
+ | Prop | Type | Default | Description |
133
+ |------|------|---------|-------------|
134
+ | `from` | `string` | — | Base currency |
135
+ | `to` | `string` | — | Quote currency |
136
+ | `decimals` | `number` | `4` | Fraction digits |
137
+ | `locale` | `string` | runtime | BCP-47 locale for formatting |
138
+
139
+ ## Error handling
140
+
141
+ All methods throw typed errors inheriting from `UniRateError`:
142
+
143
+ | Error | HTTP | Meaning |
144
+ |-------|------|---------|
145
+ | `AuthenticationError` | 401 | Missing or invalid API key |
146
+ | `ProRequiredError` | 403 | Endpoint requires Pro subscription |
147
+ | `InvalidCurrencyError` | 404 | Currency not found |
148
+ | `InvalidRequestError` | 400 | Bad parameters |
149
+ | `RateLimitError` | 429 | Rate limit exceeded |
150
+
151
+ ## Rate limits
152
+
153
+ The free tier allows 1,000 requests/month. Historical and time-series endpoints require a [Pro subscription](https://unirateapi.com). See the [API docs](https://unirateapi.com/docs) for details.
154
+
155
+ ## Related packages
156
+
157
+ | Package | Description |
158
+ |---------|-------------|
159
+ | [`@unirate/react`](https://github.com/UniRate-API/react-unirate) | React hooks + client components |
160
+ | [`@unirate/nestjs`](https://github.com/UniRate-API/nestjs-unirate) | NestJS module |
161
+ | [`@unirate/astro`](https://github.com/UniRate-API/astro-unirate) | Astro integration |
162
+ | [`@unirate/eleventy`](https://github.com/UniRate-API/eleventy-unirate) | Eleventy plugin |
163
+ | [`trpc-unirate`](https://github.com/UniRate-API/trpc-unirate) | tRPC v11 router |
164
+ | [`unirate-api`](https://github.com/UniRate-API/unirate-api-nodejs) | Standalone Node.js client |
165
+
166
+ ## License
167
+
168
+ MIT
@@ -0,0 +1,65 @@
1
+ export declare class UniRateError extends Error {
2
+ readonly status?: number;
3
+ readonly body?: unknown;
4
+ constructor(message: string, status?: number, body?: unknown);
5
+ }
6
+ export declare class AuthenticationError extends UniRateError {
7
+ constructor(message?: string, body?: unknown);
8
+ }
9
+ export declare class RateLimitError extends UniRateError {
10
+ constructor(message?: string, body?: unknown);
11
+ }
12
+ export declare class InvalidCurrencyError extends UniRateError {
13
+ constructor(message?: string, body?: unknown);
14
+ }
15
+ export declare class InvalidRequestError extends UniRateError {
16
+ constructor(message?: string, body?: unknown);
17
+ }
18
+ export declare class ProRequiredError extends UniRateError {
19
+ constructor(message?: string, body?: unknown);
20
+ }
21
+ export interface UniRateClientOptions {
22
+ apiKey: string;
23
+ baseUrl?: string;
24
+ fetch?: typeof fetch;
25
+ timeoutMs?: number;
26
+ userAgent?: string;
27
+ revalidate?: number | false;
28
+ }
29
+ export interface VATEntry {
30
+ country_code: string;
31
+ country_name: string;
32
+ vat_rate: number;
33
+ }
34
+ export interface VATRatesAll {
35
+ total_countries: number;
36
+ date: string;
37
+ vat_rates: Record<string, VATEntry>;
38
+ }
39
+ export interface VATRateOne {
40
+ country: string;
41
+ vat_data: VATEntry;
42
+ }
43
+ export interface HistoricalLimitsResponse {
44
+ total_currencies: number;
45
+ data_source: string;
46
+ currencies: Record<string, {
47
+ earliest_date: string;
48
+ latest_date: string;
49
+ total_days: number;
50
+ description: string;
51
+ }>;
52
+ }
53
+ export declare class UniRateClient {
54
+ #private;
55
+ constructor(opts: UniRateClientOptions);
56
+ getRate(from: string, to?: string): Promise<number | Record<string, number>>;
57
+ convert(to: string, amount: number, from: string): Promise<number>;
58
+ listCurrencies(): Promise<string[]>;
59
+ getHistoricalRate(date: string, amount: number, from: string, to?: string): Promise<number | Record<string, number>>;
60
+ getVatRates(): Promise<VATRatesAll>;
61
+ getVatRates(country: string): Promise<VATRateOne>;
62
+ getTimeSeries(startDate: string, endDate: string, amount?: number, base?: string, currencies?: string[]): Promise<Record<string, Record<string, number>>>;
63
+ getHistoricalLimits(): Promise<HistoricalLimitsResponse>;
64
+ }
65
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;CAM7D;AAED,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,SAA+B,EAAE,IAAI,CAAC,EAAE,OAAO;CAInE;AAED,qBAAa,cAAe,SAAQ,YAAY;gBAClC,OAAO,SAAwB,EAAE,IAAI,CAAC,EAAE,OAAO;CAI5D;AAED,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,OAAO,SAA4C,EAAE,IAAI,CAAC,EAAE,OAAO;CAIhF;AAED,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,SAA+B,EAAE,IAAI,CAAC,EAAE,OAAO;CAInE;AAED,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,SAAyC,EAAE,IAAI,CAAC,EAAE,OAAO;CAI7E;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B;AAoBD,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAChB,MAAM,EACN;QACE,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CACF,CAAC;CACH;AAED,qBAAa,aAAa;;gBAQZ,IAAI,EAAE,oBAAoB;IA8FhC,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,EAAE,CAAC,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAerC,OAAO,CACX,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC;IAeZ,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQnC,iBAAiB,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,EAAE,CAAC,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA4BrC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IACnC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAOjD,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,SAAI,EACV,IAAI,SAAQ,EACZ,UAAU,CAAC,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAiB5C,mBAAmB,IAAI,OAAO,CAAC,wBAAwB,CAAC;CAG/D"}
package/dist/client.js ADDED
@@ -0,0 +1,217 @@
1
+ export class UniRateError extends Error {
2
+ status;
3
+ body;
4
+ constructor(message, status, body) {
5
+ super(message);
6
+ this.name = "UniRateError";
7
+ this.status = status;
8
+ this.body = body;
9
+ }
10
+ }
11
+ export class AuthenticationError extends UniRateError {
12
+ constructor(message = "Missing or invalid API key", body) {
13
+ super(message, 401, body);
14
+ this.name = "AuthenticationError";
15
+ }
16
+ }
17
+ export class RateLimitError extends UniRateError {
18
+ constructor(message = "Rate limit exceeded", body) {
19
+ super(message, 429, body);
20
+ this.name = "RateLimitError";
21
+ }
22
+ }
23
+ export class InvalidCurrencyError extends UniRateError {
24
+ constructor(message = "Currency not found or no data available", body) {
25
+ super(message, 404, body);
26
+ this.name = "InvalidCurrencyError";
27
+ }
28
+ }
29
+ export class InvalidRequestError extends UniRateError {
30
+ constructor(message = "Invalid request parameters", body) {
31
+ super(message, 400, body);
32
+ this.name = "InvalidRequestError";
33
+ }
34
+ }
35
+ export class ProRequiredError extends UniRateError {
36
+ constructor(message = "Endpoint requires a Pro subscription", body) {
37
+ super(message, 403, body);
38
+ this.name = "ProRequiredError";
39
+ }
40
+ }
41
+ const DEFAULT_BASE_URL = "https://api.unirateapi.com";
42
+ const DEFAULT_TIMEOUT_MS = 30_000;
43
+ const DEFAULT_USER_AGENT = "@unirate/next/0.1.0";
44
+ const toNum = (v) => {
45
+ const n = typeof v === "string" ? Number.parseFloat(v) : v;
46
+ if (!Number.isFinite(n)) {
47
+ throw new UniRateError(`Non-numeric value: ${String(v)}`);
48
+ }
49
+ return n;
50
+ };
51
+ const toRates = (raw) => {
52
+ const out = {};
53
+ for (const [k, v] of Object.entries(raw))
54
+ out[k] = toNum(v);
55
+ return out;
56
+ };
57
+ export class UniRateClient {
58
+ #apiKey;
59
+ #baseUrl;
60
+ #fetch;
61
+ #timeoutMs;
62
+ #userAgent;
63
+ #revalidate;
64
+ constructor(opts) {
65
+ if (!opts.apiKey)
66
+ throw new UniRateError("apiKey is required");
67
+ this.#apiKey = opts.apiKey;
68
+ this.#baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
69
+ this.#fetch = opts.fetch ?? globalThis.fetch;
70
+ this.#timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
71
+ this.#userAgent = opts.userAgent ?? DEFAULT_USER_AGENT;
72
+ this.#revalidate = opts.revalidate;
73
+ if (typeof this.#fetch !== "function") {
74
+ throw new UniRateError("global fetch is unavailable; pass `fetch` explicitly");
75
+ }
76
+ }
77
+ async #get(path, params) {
78
+ const url = new URL(this.#baseUrl + path);
79
+ url.searchParams.set("api_key", this.#apiKey);
80
+ for (const [k, v] of Object.entries(params)) {
81
+ if (v !== undefined)
82
+ url.searchParams.set(k, String(v));
83
+ }
84
+ const ctrl = new AbortController();
85
+ const timer = setTimeout(() => ctrl.abort(), this.#timeoutMs);
86
+ const fetchOpts = {
87
+ headers: {
88
+ Accept: "application/json",
89
+ "User-Agent": this.#userAgent,
90
+ },
91
+ signal: ctrl.signal,
92
+ };
93
+ if (this.#revalidate !== undefined) {
94
+ fetchOpts.next = { revalidate: this.#revalidate };
95
+ }
96
+ let res;
97
+ try {
98
+ res = await this.#fetch(url.toString(), fetchOpts);
99
+ }
100
+ catch (err) {
101
+ clearTimeout(timer);
102
+ const msg = err instanceof Error ? err.message : String(err);
103
+ throw new UniRateError(`Request to ${path} failed: ${msg}`);
104
+ }
105
+ clearTimeout(timer);
106
+ const text = await res.text();
107
+ let body = null;
108
+ if (text) {
109
+ try {
110
+ body = JSON.parse(text);
111
+ }
112
+ catch {
113
+ if (!res.ok) {
114
+ throw new UniRateError(`HTTP ${res.status} from ${path}`, res.status, text);
115
+ }
116
+ throw new UniRateError(`Non-JSON response from ${path}`, res.status, text);
117
+ }
118
+ }
119
+ if (!res.ok) {
120
+ const detail = body && typeof body === "object" && "error" in body && typeof body.error === "string"
121
+ ? body.error
122
+ : undefined;
123
+ switch (res.status) {
124
+ case 400:
125
+ throw new InvalidRequestError(detail ?? "Invalid request parameters", body);
126
+ case 401:
127
+ throw new AuthenticationError(detail ?? "Missing or invalid API key", body);
128
+ case 403:
129
+ throw new ProRequiredError(detail ?? "Endpoint requires a Pro subscription", body);
130
+ case 404:
131
+ throw new InvalidCurrencyError(detail ?? "Currency not found or no data available", body);
132
+ case 429:
133
+ throw new RateLimitError(detail ?? "Rate limit exceeded", body);
134
+ default:
135
+ throw new UniRateError(detail ?? `HTTP ${res.status} from ${path}`, res.status, body);
136
+ }
137
+ }
138
+ return body;
139
+ }
140
+ async getRate(from, to) {
141
+ const params = { from: from.toUpperCase() };
142
+ if (to)
143
+ params.to = to.toUpperCase();
144
+ const raw = await this.#get("/api/rates", params);
145
+ if (to) {
146
+ if (raw.rate === undefined)
147
+ throw new UniRateError("Malformed /api/rates response", undefined, raw);
148
+ return toNum(raw.rate);
149
+ }
150
+ if (!raw.rates)
151
+ throw new UniRateError("Malformed /api/rates response", undefined, raw);
152
+ return toRates(raw.rates);
153
+ }
154
+ async convert(to, amount, from) {
155
+ const raw = await this.#get("/api/convert", {
156
+ from: from.toUpperCase(),
157
+ to: to.toUpperCase(),
158
+ amount,
159
+ });
160
+ if (raw.result === undefined) {
161
+ throw new UniRateError("Malformed /api/convert response", undefined, raw);
162
+ }
163
+ return toNum(raw.result);
164
+ }
165
+ async listCurrencies() {
166
+ const raw = await this.#get("/api/currencies", {});
167
+ if (!Array.isArray(raw.currencies)) {
168
+ throw new UniRateError("Malformed /api/currencies response", undefined, raw);
169
+ }
170
+ return raw.currencies;
171
+ }
172
+ async getHistoricalRate(date, amount, from, to) {
173
+ const params = {
174
+ date,
175
+ amount,
176
+ from: from.toUpperCase(),
177
+ };
178
+ if (to)
179
+ params.to = to.toUpperCase();
180
+ const raw = await this.#get("/api/historical/rates", params);
181
+ if (to) {
182
+ const v = amount === 1 ? raw.rate : raw.result;
183
+ if (v === undefined) {
184
+ throw new UniRateError("Malformed /api/historical/rates response", undefined, raw);
185
+ }
186
+ return toNum(v);
187
+ }
188
+ const map = amount === 1 ? raw.rates : raw.results;
189
+ if (!map) {
190
+ throw new UniRateError("Malformed /api/historical/rates response", undefined, raw);
191
+ }
192
+ return toRates(map);
193
+ }
194
+ async getVatRates(country) {
195
+ const params = {};
196
+ if (country)
197
+ params.country = country.toUpperCase();
198
+ return this.#get("/api/vat/rates", params);
199
+ }
200
+ async getTimeSeries(startDate, endDate, amount = 1, base = "USD", currencies) {
201
+ const params = {
202
+ start_date: startDate,
203
+ end_date: endDate,
204
+ amount,
205
+ base: base.toUpperCase(),
206
+ };
207
+ if (currencies?.length) {
208
+ params.currencies = currencies.map((c) => c.toUpperCase()).join(",");
209
+ }
210
+ const raw = await this.#get("/api/historical/timeseries", params);
211
+ return raw.data;
212
+ }
213
+ async getHistoricalLimits() {
214
+ return this.#get("/api/historical/limits", {});
215
+ }
216
+ }
217
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface PriceProps {
2
+ amount: number;
3
+ from?: string;
4
+ to: string;
5
+ decimals?: number;
6
+ locale?: string;
7
+ }
8
+ export declare function Price({ amount, from, to, decimals, locale, }: PriceProps): Promise<import("react/jsx-runtime").JSX.Element>;
9
+ export interface ExchangeRateProps {
10
+ from: string;
11
+ to: string;
12
+ decimals?: number;
13
+ locale?: string;
14
+ }
15
+ export declare function ExchangeRate({ from, to, decimals, locale, }: ExchangeRateProps): Promise<import("react/jsx-runtime").JSX.Element>;
16
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgBD,wBAAsB,KAAK,CAAC,EAC1B,MAAM,EACN,IAAY,EACZ,EAAE,EACF,QAAY,EACZ,MAAM,GACP,EAAE,UAAU,oDAGZ;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,EACjC,IAAI,EACJ,EAAE,EACF,QAAY,EACZ,MAAM,GACP,EAAE,iBAAiB,oDAUnB"}
@@ -0,0 +1,22 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { getRate, convert } from "./server.js";
3
+ function formatMoney(amount, currency, decimals, locale) {
4
+ return new Intl.NumberFormat(locale, {
5
+ style: "currency",
6
+ currency,
7
+ minimumFractionDigits: decimals,
8
+ maximumFractionDigits: decimals,
9
+ }).format(amount);
10
+ }
11
+ export async function Price({ amount, from = "USD", to, decimals = 2, locale, }) {
12
+ const result = await convert(from, to, amount);
13
+ return _jsx(_Fragment, { children: formatMoney(result, to, decimals, locale) });
14
+ }
15
+ export async function ExchangeRate({ from, to, decimals = 4, locale, }) {
16
+ const rate = (await getRate(from, to));
17
+ return (_jsx(_Fragment, { children: new Intl.NumberFormat(locale, {
18
+ minimumFractionDigits: decimals,
19
+ maximumFractionDigits: decimals,
20
+ }).format(rate) }));
21
+ }
22
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAU/C,SAAS,WAAW,CAClB,MAAc,EACd,QAAgB,EAChB,QAAgB,EAChB,MAAe;IAEf,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;QACnC,KAAK,EAAE,UAAU;QACjB,QAAQ;QACR,qBAAqB,EAAE,QAAQ;QAC/B,qBAAqB,EAAE,QAAQ;KAChC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,EAC1B,MAAM,EACN,IAAI,GAAG,KAAK,EACZ,EAAE,EACF,QAAQ,GAAG,CAAC,EACZ,MAAM,GACK;IACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/C,OAAO,4BAAG,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAI,CAAC;AAC1D,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,IAAI,EACJ,EAAE,EACF,QAAQ,GAAG,CAAC,EACZ,MAAM,GACY;IAClB,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAW,CAAC;IACjD,OAAO,CACL,4BACG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;YAC7B,qBAAqB,EAAE,QAAQ;YAC/B,qBAAqB,EAAE,QAAQ;SAChC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GACd,CACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { AuthenticationError, InvalidCurrencyError, InvalidRequestError, ProRequiredError, RateLimitError, UniRateClient, UniRateError, type HistoricalLimitsResponse, type UniRateClientOptions, type VATEntry, type VATRateOne, type VATRatesAll, } from "./client.js";
2
+ export { createUniRate, getRate, convert, listCurrencies, getHistoricalRate, getVatRates, getTimeSeries, getHistoricalLimits, type UniRateNextOptions, } from "./server.js";
3
+ export { Price, ExchangeRate, type PriceProps, type ExchangeRateProps } from "./components.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,OAAO,EACP,OAAO,EACP,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { AuthenticationError, InvalidCurrencyError, InvalidRequestError, ProRequiredError, RateLimitError, UniRateClient, UniRateError, } from "./client.js";
2
+ export { createUniRate, getRate, convert, listCurrencies, getHistoricalRate, getVatRates, getTimeSeries, getHistoricalLimits, } from "./server.js";
3
+ export { Price, ExchangeRate } from "./components.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,GAMb,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,OAAO,EACP,OAAO,EACP,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,mBAAmB,GAEpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,EAAE,YAAY,EAA2C,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { NextRequest } from "next/server";
2
+ import { NextResponse } from "next/server";
3
+ export declare const UNIRATE_CURRENCY_HEADER = "x-unirate-currency";
4
+ export declare const UNIRATE_CURRENCY_COOKIE = "unirate_currency";
5
+ export interface CurrencyMiddlewareOptions {
6
+ defaultCurrency?: string;
7
+ cookieName?: string;
8
+ headerName?: string;
9
+ cookieMaxAge?: number;
10
+ localeCurrencyMap?: Record<string, string>;
11
+ }
12
+ export declare function createCurrencyMiddleware(opts?: CurrencyMiddlewareOptions): (request: NextRequest) => NextResponse;
13
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgC3C,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAC5D,eAAO,MAAM,uBAAuB,qBAAqB,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAkCD,wBAAgB,wBAAwB,CAAC,IAAI,GAAE,yBAA8B,IAKxC,SAAS,WAAW,KAAG,YAAY,CAqBvE"}
@@ -0,0 +1,83 @@
1
+ import { NextResponse } from "next/server";
2
+ const LOCALE_CURRENCY = {
3
+ US: "USD", GB: "GBP", AU: "AUD", CA: "CAD", NZ: "NZD",
4
+ JP: "JPY", CN: "CNY", HK: "HKD", SG: "SGD", TW: "TWD",
5
+ KR: "KRW", IN: "INR", PH: "PHP", TH: "THB", MY: "MYR",
6
+ ID: "IDR", VN: "VND",
7
+ CH: "CHF", NO: "NOK", SE: "SEK", DK: "DKK", PL: "PLN",
8
+ CZ: "CZK", HU: "HUF", RO: "RON", BG: "BGN", HR: "EUR",
9
+ AT: "EUR", BE: "EUR", CY: "EUR", EE: "EUR", FI: "EUR",
10
+ FR: "EUR", DE: "EUR", GR: "EUR", IE: "EUR", IT: "EUR",
11
+ LV: "EUR", LT: "EUR", LU: "EUR", MT: "EUR", NL: "EUR",
12
+ PT: "EUR", SK: "EUR", SI: "EUR", ES: "EUR",
13
+ BR: "BRL", MX: "MXN", AR: "ARS", CL: "CLP", CO: "COP",
14
+ PE: "PEN", UY: "UYU",
15
+ ZA: "ZAR", NG: "NGN", KE: "KES", GH: "GHS", EG: "EGP",
16
+ MA: "MAD", TN: "TND",
17
+ AE: "AED", SA: "SAR", QA: "QAR", KW: "KWD", BH: "BHD",
18
+ OM: "OMR", JO: "JOD", IL: "ILS", TR: "TRY",
19
+ RU: "RUB", UA: "UAH", KZ: "KZT",
20
+ PK: "PKR", BD: "BDT", LK: "LKR",
21
+ };
22
+ const LANG_CURRENCY = {
23
+ en: "USD", ja: "JPY", zh: "CNY", ko: "KRW", de: "EUR",
24
+ fr: "EUR", es: "EUR", it: "EUR", pt: "BRL", nl: "EUR",
25
+ sv: "SEK", no: "NOK", da: "DKK", fi: "EUR", pl: "PLN",
26
+ cs: "CZK", hu: "HUF", ro: "RON", bg: "BGN", hr: "EUR",
27
+ tr: "TRY", ar: "SAR", he: "ILS", hi: "INR", th: "THB",
28
+ vi: "VND", ms: "MYR", id: "IDR", ru: "RUB", uk: "UAH",
29
+ };
30
+ export const UNIRATE_CURRENCY_HEADER = "x-unirate-currency";
31
+ export const UNIRATE_CURRENCY_COOKIE = "unirate_currency";
32
+ function detectCurrency(request, opts) {
33
+ const cookie = request.cookies.get(opts.cookieName ?? UNIRATE_CURRENCY_COOKIE);
34
+ if (cookie?.value)
35
+ return cookie.value.toUpperCase();
36
+ const geo = request.geo;
37
+ if (geo?.country) {
38
+ const map = opts.localeCurrencyMap ?? LOCALE_CURRENCY;
39
+ const match = map[geo.country.toUpperCase()];
40
+ if (match)
41
+ return match;
42
+ }
43
+ const accept = request.headers.get("accept-language");
44
+ if (accept) {
45
+ const parts = accept.split(",");
46
+ for (const part of parts) {
47
+ const tag = part.split(";")[0].trim();
48
+ const region = tag.split("-")[1]?.toUpperCase();
49
+ if (region) {
50
+ const map = opts.localeCurrencyMap ?? LOCALE_CURRENCY;
51
+ if (map[region])
52
+ return map[region];
53
+ }
54
+ const lang = tag.split("-")[0].toLowerCase();
55
+ if (LANG_CURRENCY[lang])
56
+ return LANG_CURRENCY[lang];
57
+ }
58
+ }
59
+ return (opts.defaultCurrency ?? "USD").toUpperCase();
60
+ }
61
+ export function createCurrencyMiddleware(opts = {}) {
62
+ const headerName = opts.headerName ?? UNIRATE_CURRENCY_HEADER;
63
+ const cookieName = opts.cookieName ?? UNIRATE_CURRENCY_COOKIE;
64
+ const maxAge = opts.cookieMaxAge ?? 365 * 24 * 60 * 60;
65
+ return function currencyMiddleware(request) {
66
+ const currency = detectCurrency(request, opts);
67
+ const requestHeaders = new Headers(request.headers);
68
+ requestHeaders.set(headerName, currency);
69
+ const response = NextResponse.next({
70
+ request: { headers: requestHeaders },
71
+ });
72
+ if (!request.cookies.get(cookieName)) {
73
+ response.cookies.set(cookieName, currency, {
74
+ maxAge,
75
+ path: "/",
76
+ sameSite: "lax",
77
+ httpOnly: false,
78
+ });
79
+ }
80
+ return response;
81
+ };
82
+ }
83
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface UniRateHandlerOptions {
2
+ apiKey?: string;
3
+ baseUrl?: string;
4
+ timeoutMs?: number;
5
+ allowedPaths?: string[];
6
+ }
7
+ export declare function createUniRateHandler(opts?: UniRateHandlerOptions): (request: Request) => Promise<Response>;
8
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,qBAA0B,IAWzC,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAuD/D"}
package/dist/route.js ADDED
@@ -0,0 +1,61 @@
1
+ const DEFAULT_ALLOWED = [
2
+ "/api/rates",
3
+ "/api/convert",
4
+ "/api/currencies",
5
+ "/api/vat/rates",
6
+ "/api/historical/rates",
7
+ "/api/historical/timeseries",
8
+ "/api/historical/limits",
9
+ ];
10
+ export function createUniRateHandler(opts = {}) {
11
+ const apiKey = opts.apiKey ?? process.env.UNIRATE_API_KEY;
12
+ if (!apiKey) {
13
+ throw new Error("UniRate API key not found. Set UNIRATE_API_KEY env var or pass apiKey to createUniRateHandler().");
14
+ }
15
+ const baseUrl = (opts.baseUrl ?? "https://api.unirateapi.com").replace(/\/+$/, "");
16
+ const allowed = new Set(opts.allowedPaths ?? DEFAULT_ALLOWED);
17
+ const timeoutMs = opts.timeoutMs ?? 30_000;
18
+ return async function GET(request) {
19
+ const url = new URL(request.url);
20
+ const path = url.searchParams.get("path");
21
+ if (!path) {
22
+ return Response.json({ error: "Missing 'path' query parameter" }, { status: 400 });
23
+ }
24
+ const apiPath = path.startsWith("/") ? path : `/${path}`;
25
+ if (!allowed.has(apiPath)) {
26
+ return Response.json({ error: `Path not allowed: ${apiPath}` }, { status: 403 });
27
+ }
28
+ const target = new URL(baseUrl + apiPath);
29
+ target.searchParams.set("api_key", apiKey);
30
+ for (const [k, v] of url.searchParams.entries()) {
31
+ if (k !== "path")
32
+ target.searchParams.set(k, v);
33
+ }
34
+ const ctrl = new AbortController();
35
+ const timer = setTimeout(() => ctrl.abort(), timeoutMs);
36
+ try {
37
+ const upstream = await fetch(target.toString(), {
38
+ headers: {
39
+ Accept: "application/json",
40
+ "User-Agent": "@unirate/next/0.1.0",
41
+ },
42
+ signal: ctrl.signal,
43
+ });
44
+ clearTimeout(timer);
45
+ const body = await upstream.text();
46
+ return new Response(body, {
47
+ status: upstream.status,
48
+ headers: {
49
+ "Content-Type": upstream.headers.get("Content-Type") ?? "application/json",
50
+ "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
51
+ },
52
+ });
53
+ }
54
+ catch (err) {
55
+ clearTimeout(timer);
56
+ const message = err instanceof Error ? err.message : String(err);
57
+ return Response.json({ error: `Upstream request failed: ${message}` }, { status: 502 });
58
+ }
59
+ };
60
+ }
61
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { UniRateClient, type VATRatesAll, type VATRateOne, type HistoricalLimitsResponse } from "./client.js";
2
+ export interface UniRateNextOptions {
3
+ apiKey?: string;
4
+ baseUrl?: string;
5
+ revalidate?: number | false;
6
+ timeoutMs?: number;
7
+ }
8
+ export declare function createUniRate(opts?: UniRateNextOptions): {
9
+ client: UniRateClient;
10
+ getRate: (from: string, to?: string) => Promise<number | Record<string, number>>;
11
+ convert: (from: string, to: string, amount: number) => Promise<number>;
12
+ listCurrencies: () => Promise<string[]>;
13
+ getHistoricalRate: (date: string, from: string, to?: string, amount?: number) => Promise<number | Record<string, number>>;
14
+ getVatRates: (country?: string) => Promise<VATRatesAll | VATRateOne>;
15
+ getTimeSeries: (startDate: string, endDate: string, base?: string, currencies?: string[], amount?: number) => Promise<Record<string, Record<string, number>>>;
16
+ getHistoricalLimits: () => Promise<HistoricalLimitsResponse>;
17
+ };
18
+ export declare const getRate: ReturnType<typeof createUniRate>["getRate"];
19
+ export declare const convert: ReturnType<typeof createUniRate>["convert"];
20
+ export declare const listCurrencies: ReturnType<typeof createUniRate>["listCurrencies"];
21
+ export declare const getHistoricalRate: ReturnType<typeof createUniRate>["getHistoricalRate"];
22
+ export declare const getVatRates: ReturnType<typeof createUniRate>["getVatRates"];
23
+ export declare const getTimeSeries: ReturnType<typeof createUniRate>["getTimeSeries"];
24
+ export declare const getHistoricalLimits: ReturnType<typeof createUniRate>["getHistoricalLimits"];
25
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EAEb,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,kBAAkB;;oBAYtC,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAK9D,MAAM,MAAM,MAAM,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;0BAI5B,OAAO,CAAC,MAAM,EAAE,CAAC;8BAI9C,MAAM,QACN,MAAM,OACP,MAAM,WACF,MAAM,KACd,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;4BAK1B,MAAM,KAAG,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC;+BAM9C,MAAM,WACR,MAAM,SACR,MAAM,eACA,MAAM,EAAE,WACZ,MAAM,KACd,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;+BAKxC,OAAO,CAAC,wBAAwB,CAAC;EAa9C;AAUD,eAAO,MAAM,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,SAAS,CAC5B,CAAC;AAErC,eAAO,MAAM,OAAO,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,SAAS,CAC5B,CAAC;AAErC,eAAO,MAAM,cAAc,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,gBAAgB,CACnC,CAAC;AAE5C,eAAO,MAAM,iBAAiB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,mBAAmB,CACtC,CAAC;AAE/C,eAAO,MAAM,WAAW,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,aAAa,CAChC,CAAC;AAEzC,eAAO,MAAM,aAAa,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,eAAe,CAClC,CAAC;AAE3C,eAAO,MAAM,mBAAmB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,qBAAqB,CAErC,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,52 @@
1
+ import { cache } from "react";
2
+ import { UniRateClient, } from "./client.js";
3
+ function resolveApiKey(opts) {
4
+ const key = opts?.apiKey ?? process.env.UNIRATE_API_KEY;
5
+ if (!key) {
6
+ throw new Error("UniRate API key not found. Set UNIRATE_API_KEY env var or pass apiKey to createUniRate().");
7
+ }
8
+ return key;
9
+ }
10
+ export function createUniRate(opts) {
11
+ const clientOpts = {
12
+ apiKey: resolveApiKey(opts),
13
+ baseUrl: opts?.baseUrl,
14
+ revalidate: opts?.revalidate,
15
+ timeoutMs: opts?.timeoutMs,
16
+ userAgent: "@unirate/next/0.1.0",
17
+ };
18
+ const client = new UniRateClient(clientOpts);
19
+ const getRate = cache(async (from, to) => client.getRate(from, to));
20
+ const convert = cache(async (from, to, amount) => client.convert(to, amount, from));
21
+ const listCurrencies = cache(async () => client.listCurrencies());
22
+ const getHistoricalRate = cache(async (date, from, to, amount) => client.getHistoricalRate(date, amount ?? 1, from, to));
23
+ const getVatRates = cache(async (country) => country ? client.getVatRates(country) : client.getVatRates());
24
+ const getTimeSeries = cache(async (startDate, endDate, base, currencies, amount) => client.getTimeSeries(startDate, endDate, amount, base, currencies));
25
+ const getHistoricalLimits = cache(async () => client.getHistoricalLimits());
26
+ return {
27
+ client,
28
+ getRate,
29
+ convert,
30
+ listCurrencies,
31
+ getHistoricalRate,
32
+ getVatRates,
33
+ getTimeSeries,
34
+ getHistoricalLimits,
35
+ };
36
+ }
37
+ const defaultInstance = /* @__PURE__ */ (() => {
38
+ let instance;
39
+ return () => {
40
+ if (!instance)
41
+ instance = createUniRate();
42
+ return instance;
43
+ };
44
+ })();
45
+ export const getRate = (...args) => defaultInstance().getRate(...args);
46
+ export const convert = (...args) => defaultInstance().convert(...args);
47
+ export const listCurrencies = (...args) => defaultInstance().listCurrencies(...args);
48
+ export const getHistoricalRate = (...args) => defaultInstance().getHistoricalRate(...args);
49
+ export const getVatRates = (...args) => defaultInstance().getVatRates(...args);
50
+ export const getTimeSeries = (...args) => defaultInstance().getTimeSeries(...args);
51
+ export const getHistoricalLimits = (...args) => defaultInstance().getHistoricalLimits(...args);
52
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EACL,aAAa,GAKd,MAAM,aAAa,CAAC;AASrB,SAAS,aAAa,CAAC,IAAyB;IAC9C,MAAM,GAAG,GAAG,IAAI,EAAE,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAyB;IACrD,MAAM,UAAU,GAAyB;QACvC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,OAAO;QACtB,UAAU,EAAE,IAAI,EAAE,UAAU;QAC5B,SAAS,EAAE,IAAI,EAAE,SAAS;QAC1B,SAAS,EAAE,qBAAqB;KACjC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAG,KAAK,CACnB,KAAK,EAAE,IAAY,EAAE,EAAW,EAA4C,EAAE,CAC5E,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAC3B,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CACnB,KAAK,EAAE,IAAY,EAAE,EAAU,EAAE,MAAc,EAAmB,EAAE,CAClE,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CACnC,CAAC;IAEF,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,IAAuB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAErF,MAAM,iBAAiB,GAAG,KAAK,CAC7B,KAAK,EACH,IAAY,EACZ,IAAY,EACZ,EAAW,EACX,MAAe,EAC2B,EAAE,CAC5C,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CACxD,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,CACvB,KAAK,EAAE,OAAgB,EAAqC,EAAE,CAC5D,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAC/D,CAAC;IAEF,MAAM,aAAa,GAAG,KAAK,CACzB,KAAK,EACH,SAAiB,EACjB,OAAe,EACf,IAAa,EACb,UAAqB,EACrB,MAAe,EACkC,EAAE,CACnD,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CACrE,CAAC;IAEF,MAAM,mBAAmB,GAAG,KAAK,CAC/B,KAAK,IAAuC,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAC5E,CAAC;IAEF,OAAO;QACL,MAAM;QACN,OAAO;QACP,OAAO;QACP,cAAc;QACd,iBAAiB;QACjB,WAAW;QACX,aAAa;QACb,mBAAmB;KACpB,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,GAAG,EAAE;IAC5C,IAAI,QAAsD,CAAC;IAC3D,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,QAAQ;YAAE,QAAQ,GAAG,aAAa,EAAE,CAAC;QAC1C,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,CAAC,MAAM,OAAO,GAAgD,CAAC,GAAG,IAAI,EAAE,EAAE,CAC9E,eAAe,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,OAAO,GAAgD,CAAC,GAAG,IAAI,EAAE,EAAE,CAC9E,eAAe,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,cAAc,GAAuD,CAAC,GAAG,IAAI,EAAE,EAAE,CAC5F,eAAe,EAAE,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,CAAC;AAE5C,MAAM,CAAC,MAAM,iBAAiB,GAA0D,CAAC,GAAG,IAAI,EAAE,EAAE,CAClG,eAAe,EAAE,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,CAAC;AAE/C,MAAM,CAAC,MAAM,WAAW,GAAoD,CAAC,GAAG,IAAI,EAAE,EAAE,CACtF,eAAe,EAAE,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC;AAEzC,MAAM,CAAC,MAAM,aAAa,GAAsD,CAAC,GAAG,IAAI,EAAE,EAAE,CAC1F,eAAe,EAAE,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,mBAAmB,GAA4D,CAC1F,GAAG,IAAI,EACP,EAAE,CAAC,eAAe,EAAE,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@unirate/next",
3
+ "version": "0.1.0",
4
+ "description": "Next.js App Router integration for the UniRate currency-exchange API. Async RSC <Price/> and <ExchangeRate/> components, server-side getRate/convert helpers with React cache() dedup, geo-based currency middleware, and a route handler proxy that keeps your API key server-side. Zero runtime deps.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "UniRate (https://unirateapi.com)",
8
+ "homepage": "https://github.com/UniRate-API/next-unirate#readme",
9
+ "bugs": "https://github.com/UniRate-API/next-unirate/issues",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/UniRate-API/next-unirate.git"
13
+ },
14
+ "keywords": [
15
+ "nextjs",
16
+ "next",
17
+ "react-server-components",
18
+ "rsc",
19
+ "app-router",
20
+ "unirate",
21
+ "currency",
22
+ "currency-converter",
23
+ "exchange-rates",
24
+ "forex",
25
+ "fx",
26
+ "money",
27
+ "fintech",
28
+ "middleware"
29
+ ],
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "main": "./dist/index.js",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "import": "./dist/index.js"
40
+ },
41
+ "./server": {
42
+ "types": "./dist/server.d.ts",
43
+ "import": "./dist/server.js"
44
+ },
45
+ "./middleware": {
46
+ "types": "./dist/middleware.d.ts",
47
+ "import": "./dist/middleware.js"
48
+ },
49
+ "./route": {
50
+ "types": "./dist/route.d.ts",
51
+ "import": "./dist/route.js"
52
+ },
53
+ "./client": {
54
+ "types": "./dist/client.d.ts",
55
+ "import": "./dist/client.js"
56
+ },
57
+ "./package.json": "./package.json"
58
+ },
59
+ "scripts": {
60
+ "build": "tsc -p tsconfig.build.json",
61
+ "test": "vitest run",
62
+ "test:watch": "vitest",
63
+ "typecheck": "tsc --noEmit",
64
+ "prepublishOnly": "npm run build"
65
+ },
66
+ "peerDependencies": {
67
+ "next": ">=14.0.0",
68
+ "react": "^18.0.0 || ^19.0.0"
69
+ },
70
+ "devDependencies": {
71
+ "@types/node": "^20.11.0",
72
+ "@types/react": "^19.0.0",
73
+ "react": "^19.0.0",
74
+ "typescript": "^5.4.0",
75
+ "vitest": "^4.1.7"
76
+ },
77
+ "engines": {
78
+ "node": ">=20.12.0"
79
+ },
80
+ "publishConfig": {
81
+ "access": "public",
82
+ "provenance": true
83
+ }
84
+ }