@ozura/elements 0.1.0-beta.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +717 -0
  3. package/dist/frame/element-frame.html +22 -0
  4. package/dist/frame/element-frame.js +731 -0
  5. package/dist/frame/element-frame.js.map +1 -0
  6. package/dist/frame/tokenizer-frame.html +11 -0
  7. package/dist/frame/tokenizer-frame.js +328 -0
  8. package/dist/frame/tokenizer-frame.js.map +1 -0
  9. package/dist/oz-elements.esm.js +1190 -0
  10. package/dist/oz-elements.esm.js.map +1 -0
  11. package/dist/oz-elements.umd.js +1202 -0
  12. package/dist/oz-elements.umd.js.map +1 -0
  13. package/dist/react/frame/elementFrame.d.ts +8 -0
  14. package/dist/react/frame/tokenizerFrame.d.ts +13 -0
  15. package/dist/react/index.cjs.js +1407 -0
  16. package/dist/react/index.cjs.js.map +1 -0
  17. package/dist/react/index.esm.js +1400 -0
  18. package/dist/react/index.esm.js.map +1 -0
  19. package/dist/react/react/index.d.ts +214 -0
  20. package/dist/react/sdk/OzElement.d.ts +65 -0
  21. package/dist/react/sdk/OzVault.d.ts +106 -0
  22. package/dist/react/sdk/errors.d.ts +55 -0
  23. package/dist/react/sdk/index.d.ts +5 -0
  24. package/dist/react/server/index.d.ts +140 -0
  25. package/dist/react/types/index.d.ts +432 -0
  26. package/dist/react/utils/appearance.d.ts +13 -0
  27. package/dist/react/utils/billingUtils.d.ts +60 -0
  28. package/dist/react/utils/cardUtils.d.ts +37 -0
  29. package/dist/server/frame/elementFrame.d.ts +8 -0
  30. package/dist/server/frame/tokenizerFrame.d.ts +13 -0
  31. package/dist/server/index.cjs.js +294 -0
  32. package/dist/server/index.cjs.js.map +1 -0
  33. package/dist/server/index.esm.js +290 -0
  34. package/dist/server/index.esm.js.map +1 -0
  35. package/dist/server/sdk/OzElement.d.ts +65 -0
  36. package/dist/server/sdk/OzVault.d.ts +106 -0
  37. package/dist/server/sdk/errors.d.ts +55 -0
  38. package/dist/server/sdk/index.d.ts +5 -0
  39. package/dist/server/server/index.d.ts +140 -0
  40. package/dist/server/types/index.d.ts +432 -0
  41. package/dist/server/utils/appearance.d.ts +13 -0
  42. package/dist/server/utils/billingUtils.d.ts +60 -0
  43. package/dist/server/utils/cardUtils.d.ts +37 -0
  44. package/dist/types/frame/elementFrame.d.ts +8 -0
  45. package/dist/types/frame/tokenizerFrame.d.ts +13 -0
  46. package/dist/types/sdk/OzElement.d.ts +65 -0
  47. package/dist/types/sdk/OzVault.d.ts +106 -0
  48. package/dist/types/sdk/errors.d.ts +55 -0
  49. package/dist/types/sdk/index.d.ts +5 -0
  50. package/dist/types/server/index.d.ts +140 -0
  51. package/dist/types/types/index.d.ts +432 -0
  52. package/dist/types/utils/appearance.d.ts +13 -0
  53. package/dist/types/utils/billingUtils.d.ts +60 -0
  54. package/dist/types/utils/cardUtils.d.ts +37 -0
  55. package/package.json +97 -0
@@ -0,0 +1,13 @@
1
+ /**
2
+ * tokenizerFrame.ts — runs inside a hidden <iframe> served from Ozura's domain.
3
+ *
4
+ * Collects raw card field values sent by element frames (same-origin),
5
+ * assembles the vault tokenization payload, and POSTs it directly to the
6
+ * vault API. The merchant page never sees raw card data.
7
+ */
8
+ /**
9
+ * Returns true when the given URL's origin is in the compile-time allowlist.
10
+ * For localhost entries, any port is accepted (dev-server port varies).
11
+ * Exported for unit testing only — not part of the public SDK API.
12
+ */
13
+ export declare function isAllowedVaultOrigin(apiUrl: string): boolean;
@@ -0,0 +1,294 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @ozura/server — Server-side SDK for the Ozura Pay API.
5
+ *
6
+ * Wraps cardSale and transaction query endpoints with typed methods,
7
+ * automatic field mapping, retry logic, and error handling.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { Ozura } from 'oz-elements/server';
12
+ *
13
+ * const ozura = new Ozura({
14
+ * merchantId: process.env.MERCHANT_ID!,
15
+ * apiKey: process.env.MERCHANT_API_KEY!,
16
+ * vaultKey: process.env.VAULT_API_KEY!,
17
+ * });
18
+ *
19
+ * const result = await ozura.cardSale({
20
+ * token: tokenResponse.token,
21
+ * cvcSession: tokenResponse.cvcSession,
22
+ * amount: '49.00',
23
+ * currency: 'USD',
24
+ * billing: tokenResponse.billing,
25
+ * clientIpAddress: req.ip,
26
+ * });
27
+ *
28
+ * console.log(result.transactionId);
29
+ * ```
30
+ */
31
+ // ─── Configuration ───────────────────────────────────────────────────────────
32
+ const DEFAULT_API_URL = "https://ozurapay-pay-api-v2-staging-c8abbdfhfbd3c5em.eastus-01.azurewebsites.net";
33
+ const DEFAULT_TIMEOUT = 30000;
34
+ // ─── Error ───────────────────────────────────────────────────────────────────
35
+ class OzuraError extends Error {
36
+ constructor(message, statusCode, raw, retryAfter) {
37
+ super(message);
38
+ this.name = 'OzuraError';
39
+ this.statusCode = statusCode;
40
+ this.raw = raw !== null && raw !== void 0 ? raw : message;
41
+ this.retryAfter = retryAfter;
42
+ }
43
+ }
44
+ // ─── Retry helper ─────────────────────────────────────────────────────────────
45
+ const DEFAULT_RETRIES = 2;
46
+ function isRetryable(status) {
47
+ return status >= 500 && status < 600;
48
+ }
49
+ async function sleep(ms) {
50
+ return new Promise(resolve => setTimeout(resolve, ms));
51
+ }
52
+ // ─── Main class ──────────────────────────────────────────────────────────────
53
+ class Ozura {
54
+ constructor(config) {
55
+ var _a, _b;
56
+ if (!config.merchantId)
57
+ throw new OzuraError('merchantId is required', 0);
58
+ if (!config.apiKey)
59
+ throw new OzuraError('apiKey is required', 0);
60
+ if (!config.vaultKey)
61
+ throw new OzuraError('vaultKey is required', 0);
62
+ this.merchantId = config.merchantId;
63
+ this.apiKey = config.apiKey;
64
+ this.vaultKey = config.vaultKey;
65
+ this.apiUrl = config.apiUrl || DEFAULT_API_URL;
66
+ this.timeoutMs = (_a = config.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT;
67
+ this.retries = (_b = config.retries) !== null && _b !== void 0 ? _b : DEFAULT_RETRIES;
68
+ }
69
+ /**
70
+ * Charge a tokenized card. Maps the friendly `CardSaleInput` shape to the
71
+ * Pay API's flat field format and handles headers, defaults, and errors.
72
+ *
73
+ * Rate limit: 100 requests/minute per merchant.
74
+ */
75
+ async cardSale(input) {
76
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
77
+ const billing = input.billing;
78
+ const body = {
79
+ merchantId: this.merchantId,
80
+ amount: input.amount,
81
+ currency: input.currency || 'USD',
82
+ ozuraCardToken: input.token,
83
+ ozuraCvcSession: input.cvcSession,
84
+ billingFirstName: billing.firstName,
85
+ billingLastName: billing.lastName,
86
+ billingEmail: billing.email || '',
87
+ billingPhone: billing.phone || '',
88
+ billingAddress1: ((_a = billing.address) === null || _a === void 0 ? void 0 : _a.line1) || '',
89
+ billingCity: ((_b = billing.address) === null || _b === void 0 ? void 0 : _b.city) || '',
90
+ billingState: ((_c = billing.address) === null || _c === void 0 ? void 0 : _c.state) || '',
91
+ billingZipcode: ((_d = billing.address) === null || _d === void 0 ? void 0 : _d.zip) || '',
92
+ billingCountry: ((_e = billing.address) === null || _e === void 0 ? void 0 : _e.country) || 'US',
93
+ clientIpAddress: input.clientIpAddress,
94
+ salesTaxExempt: (_f = input.salesTaxExempt) !== null && _f !== void 0 ? _f : false,
95
+ surchargePercent: (_g = input.surchargePercent) !== null && _g !== void 0 ? _g : '0.00',
96
+ tipAmount: (_h = input.tipAmount) !== null && _h !== void 0 ? _h : '0.00',
97
+ };
98
+ if ((_j = billing.address) === null || _j === void 0 ? void 0 : _j.line2) {
99
+ body.billingAddress2 = billing.address.line2;
100
+ }
101
+ if (input.processor) {
102
+ body.processor = input.processor;
103
+ }
104
+ return this.post('/api/v1/cardSale', body, true);
105
+ }
106
+ /**
107
+ * Retrieve a single transaction by ID.
108
+ *
109
+ * **Known issue:** The Pay API requires the API key as a query parameter
110
+ * (`access_token`), which means it can appear in server logs, CDN caches,
111
+ * and HTTP Referer headers. This is a Pay API design issue — the SDK will
112
+ * switch to header-based auth once the backend supports it.
113
+ *
114
+ * Rate limit: 100 requests/minute per merchant.
115
+ */
116
+ async getTransaction(transactionId) {
117
+ const qs = new URLSearchParams({ access_token: this.apiKey });
118
+ return this.get(`/api/v1/transactions/${encodeURIComponent(transactionId)}?${qs}`);
119
+ }
120
+ /**
121
+ * List transactions by date range with pagination.
122
+ *
123
+ * Rate limit: 200 requests/minute per merchant.
124
+ */
125
+ async listTransactions(input = {}) {
126
+ const params = { merchantId: this.merchantId };
127
+ if (input.dateFrom)
128
+ params.dateFrom = input.dateFrom;
129
+ if (input.dateTo)
130
+ params.dateTo = input.dateTo;
131
+ if (input.transactionType)
132
+ params.transactionType = input.transactionType;
133
+ if (input.page)
134
+ params.page = String(input.page);
135
+ if (input.limit)
136
+ params.limit = String(input.limit);
137
+ if (input.fields)
138
+ params.fields = input.fields;
139
+ if (input.sortBy)
140
+ params.sortBy = input.sortBy;
141
+ if (input.sortOrder)
142
+ params.sortOrder = input.sortOrder;
143
+ const qs = new URLSearchParams(params);
144
+ const raw = await this.getRaw(`/api/v1/transQuery?${qs}`);
145
+ return { transactions: raw.data, pagination: raw.pagination };
146
+ }
147
+ // ─── HTTP helpers ────────────────────────────────────────────────────────
148
+ /**
149
+ * Execute a fetch with retry on 5xx / network errors.
150
+ * 4xx errors (including 429) are never retried — they require caller action.
151
+ */
152
+ async fetchWithRetry(url, init) {
153
+ let lastError;
154
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
155
+ try {
156
+ const res = await fetch(url, Object.assign(Object.assign({}, init), { signal: AbortSignal.timeout(this.timeoutMs) }));
157
+ if (isRetryable(res.status) && attempt < this.retries) {
158
+ // Consume/cancel body so the connection is released (undici holds socket until body is drained)
159
+ if (res.body) {
160
+ try {
161
+ await res.body.cancel();
162
+ }
163
+ catch (_a) {
164
+ /* ignore */
165
+ }
166
+ }
167
+ const backoff = Math.min(1000 * 2 ** attempt, 8000);
168
+ await sleep(backoff);
169
+ continue;
170
+ }
171
+ return res;
172
+ }
173
+ catch (err) {
174
+ lastError = err;
175
+ if (attempt < this.retries) {
176
+ const backoff = Math.min(1000 * 2 ** attempt, 8000);
177
+ await sleep(backoff);
178
+ continue;
179
+ }
180
+ }
181
+ }
182
+ // All attempts exhausted — wrap the raw error in OzuraError
183
+ if (lastError instanceof Error) {
184
+ if (lastError.name === 'TimeoutError' || lastError.name === 'AbortError') {
185
+ throw new OzuraError(`Request timed out after ${this.timeoutMs}ms`, 0, lastError.message);
186
+ }
187
+ throw new OzuraError(`Network error: ${lastError.message}`, 0, lastError.message);
188
+ }
189
+ throw new OzuraError('Network error', 0);
190
+ }
191
+ async post(path, body, includeVaultKey) {
192
+ const headers = {
193
+ 'Content-Type': 'application/json',
194
+ 'x-api-key': this.apiKey,
195
+ };
196
+ if (includeVaultKey) {
197
+ headers['vault-api-key'] = this.vaultKey;
198
+ }
199
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
200
+ method: 'POST',
201
+ headers,
202
+ body: JSON.stringify(body),
203
+ });
204
+ return this.handleResponse(res);
205
+ }
206
+ async get(path) {
207
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
208
+ method: 'GET',
209
+ headers: { 'x-api-key': this.apiKey },
210
+ });
211
+ return this.handleResponse(res);
212
+ }
213
+ async getRaw(path) {
214
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
215
+ method: 'GET',
216
+ headers: { 'x-api-key': this.apiKey },
217
+ });
218
+ const json = await res.json().catch(() => ({ error: res.statusText }));
219
+ if (!res.ok) {
220
+ const retryAfter = res.status === 429
221
+ ? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
222
+ : undefined;
223
+ throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
224
+ }
225
+ if (json.success === false) {
226
+ throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
227
+ }
228
+ return json;
229
+ }
230
+ async handleResponse(res) {
231
+ var _a;
232
+ const json = await res.json().catch(() => ({ error: res.statusText }));
233
+ if (!res.ok) {
234
+ const retryAfter = res.status === 429
235
+ ? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
236
+ : undefined;
237
+ throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
238
+ }
239
+ if (json.success === false) {
240
+ throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
241
+ }
242
+ return ((_a = json.data) !== null && _a !== void 0 ? _a : json);
243
+ }
244
+ }
245
+ // ─── Utilities ────────────────────────────────────────────────────────────────
246
+ /**
247
+ * Extract the client IP address from a server request object.
248
+ * Works with Express (`req.ip`), Fastify (`request.ip`), Next.js App Router
249
+ * (`req.headers.get('x-forwarded-for')`), and raw Node.js `IncomingMessage`.
250
+ *
251
+ * @example
252
+ * // Express / Fastify
253
+ * clientIpAddress: getClientIp(req)
254
+ *
255
+ * // Next.js App Router
256
+ * clientIpAddress: getClientIp(req)
257
+ */
258
+ function getClientIp(req) {
259
+ // Express / Fastify: req.ip
260
+ if (typeof req.ip === 'string' && req.ip)
261
+ return req.ip;
262
+ // Next.js App Router: req.headers.get('x-forwarded-for')
263
+ const headers = req.headers;
264
+ if (headers && typeof headers.get === 'function') {
265
+ const xff = headers.get('x-forwarded-for');
266
+ if (xff)
267
+ return xff.split(',')[0].trim();
268
+ const realIp = headers.get('x-real-ip');
269
+ if (realIp)
270
+ return realIp;
271
+ }
272
+ // Node.js IncomingMessage: req.headers['x-forwarded-for']
273
+ if (headers && typeof headers === 'object') {
274
+ const h = headers;
275
+ const xff = h['x-forwarded-for'];
276
+ if (typeof xff === 'string' && xff)
277
+ return xff.split(',')[0].trim();
278
+ if (Array.isArray(xff) && xff[0])
279
+ return xff[0].split(',')[0].trim();
280
+ const realIp = h['x-real-ip'];
281
+ if (typeof realIp === 'string' && realIp)
282
+ return realIp;
283
+ }
284
+ // Raw Node.js socket
285
+ const socket = req.socket;
286
+ if (socket === null || socket === void 0 ? void 0 : socket.remoteAddress)
287
+ return socket.remoteAddress;
288
+ return '0.0.0.0';
289
+ }
290
+
291
+ exports.Ozura = Ozura;
292
+ exports.OzuraError = OzuraError;
293
+ exports.getClientIp = getClientIp;
294
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../../src/server/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,290 @@
1
+ /**
2
+ * @ozura/server — Server-side SDK for the Ozura Pay API.
3
+ *
4
+ * Wraps cardSale and transaction query endpoints with typed methods,
5
+ * automatic field mapping, retry logic, and error handling.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Ozura } from 'oz-elements/server';
10
+ *
11
+ * const ozura = new Ozura({
12
+ * merchantId: process.env.MERCHANT_ID!,
13
+ * apiKey: process.env.MERCHANT_API_KEY!,
14
+ * vaultKey: process.env.VAULT_API_KEY!,
15
+ * });
16
+ *
17
+ * const result = await ozura.cardSale({
18
+ * token: tokenResponse.token,
19
+ * cvcSession: tokenResponse.cvcSession,
20
+ * amount: '49.00',
21
+ * currency: 'USD',
22
+ * billing: tokenResponse.billing,
23
+ * clientIpAddress: req.ip,
24
+ * });
25
+ *
26
+ * console.log(result.transactionId);
27
+ * ```
28
+ */
29
+ // ─── Configuration ───────────────────────────────────────────────────────────
30
+ const DEFAULT_API_URL = "https://ozurapay-pay-api-v2-staging-c8abbdfhfbd3c5em.eastus-01.azurewebsites.net";
31
+ const DEFAULT_TIMEOUT = 30000;
32
+ // ─── Error ───────────────────────────────────────────────────────────────────
33
+ class OzuraError extends Error {
34
+ constructor(message, statusCode, raw, retryAfter) {
35
+ super(message);
36
+ this.name = 'OzuraError';
37
+ this.statusCode = statusCode;
38
+ this.raw = raw !== null && raw !== void 0 ? raw : message;
39
+ this.retryAfter = retryAfter;
40
+ }
41
+ }
42
+ // ─── Retry helper ─────────────────────────────────────────────────────────────
43
+ const DEFAULT_RETRIES = 2;
44
+ function isRetryable(status) {
45
+ return status >= 500 && status < 600;
46
+ }
47
+ async function sleep(ms) {
48
+ return new Promise(resolve => setTimeout(resolve, ms));
49
+ }
50
+ // ─── Main class ──────────────────────────────────────────────────────────────
51
+ class Ozura {
52
+ constructor(config) {
53
+ var _a, _b;
54
+ if (!config.merchantId)
55
+ throw new OzuraError('merchantId is required', 0);
56
+ if (!config.apiKey)
57
+ throw new OzuraError('apiKey is required', 0);
58
+ if (!config.vaultKey)
59
+ throw new OzuraError('vaultKey is required', 0);
60
+ this.merchantId = config.merchantId;
61
+ this.apiKey = config.apiKey;
62
+ this.vaultKey = config.vaultKey;
63
+ this.apiUrl = config.apiUrl || DEFAULT_API_URL;
64
+ this.timeoutMs = (_a = config.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT;
65
+ this.retries = (_b = config.retries) !== null && _b !== void 0 ? _b : DEFAULT_RETRIES;
66
+ }
67
+ /**
68
+ * Charge a tokenized card. Maps the friendly `CardSaleInput` shape to the
69
+ * Pay API's flat field format and handles headers, defaults, and errors.
70
+ *
71
+ * Rate limit: 100 requests/minute per merchant.
72
+ */
73
+ async cardSale(input) {
74
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
75
+ const billing = input.billing;
76
+ const body = {
77
+ merchantId: this.merchantId,
78
+ amount: input.amount,
79
+ currency: input.currency || 'USD',
80
+ ozuraCardToken: input.token,
81
+ ozuraCvcSession: input.cvcSession,
82
+ billingFirstName: billing.firstName,
83
+ billingLastName: billing.lastName,
84
+ billingEmail: billing.email || '',
85
+ billingPhone: billing.phone || '',
86
+ billingAddress1: ((_a = billing.address) === null || _a === void 0 ? void 0 : _a.line1) || '',
87
+ billingCity: ((_b = billing.address) === null || _b === void 0 ? void 0 : _b.city) || '',
88
+ billingState: ((_c = billing.address) === null || _c === void 0 ? void 0 : _c.state) || '',
89
+ billingZipcode: ((_d = billing.address) === null || _d === void 0 ? void 0 : _d.zip) || '',
90
+ billingCountry: ((_e = billing.address) === null || _e === void 0 ? void 0 : _e.country) || 'US',
91
+ clientIpAddress: input.clientIpAddress,
92
+ salesTaxExempt: (_f = input.salesTaxExempt) !== null && _f !== void 0 ? _f : false,
93
+ surchargePercent: (_g = input.surchargePercent) !== null && _g !== void 0 ? _g : '0.00',
94
+ tipAmount: (_h = input.tipAmount) !== null && _h !== void 0 ? _h : '0.00',
95
+ };
96
+ if ((_j = billing.address) === null || _j === void 0 ? void 0 : _j.line2) {
97
+ body.billingAddress2 = billing.address.line2;
98
+ }
99
+ if (input.processor) {
100
+ body.processor = input.processor;
101
+ }
102
+ return this.post('/api/v1/cardSale', body, true);
103
+ }
104
+ /**
105
+ * Retrieve a single transaction by ID.
106
+ *
107
+ * **Known issue:** The Pay API requires the API key as a query parameter
108
+ * (`access_token`), which means it can appear in server logs, CDN caches,
109
+ * and HTTP Referer headers. This is a Pay API design issue — the SDK will
110
+ * switch to header-based auth once the backend supports it.
111
+ *
112
+ * Rate limit: 100 requests/minute per merchant.
113
+ */
114
+ async getTransaction(transactionId) {
115
+ const qs = new URLSearchParams({ access_token: this.apiKey });
116
+ return this.get(`/api/v1/transactions/${encodeURIComponent(transactionId)}?${qs}`);
117
+ }
118
+ /**
119
+ * List transactions by date range with pagination.
120
+ *
121
+ * Rate limit: 200 requests/minute per merchant.
122
+ */
123
+ async listTransactions(input = {}) {
124
+ const params = { merchantId: this.merchantId };
125
+ if (input.dateFrom)
126
+ params.dateFrom = input.dateFrom;
127
+ if (input.dateTo)
128
+ params.dateTo = input.dateTo;
129
+ if (input.transactionType)
130
+ params.transactionType = input.transactionType;
131
+ if (input.page)
132
+ params.page = String(input.page);
133
+ if (input.limit)
134
+ params.limit = String(input.limit);
135
+ if (input.fields)
136
+ params.fields = input.fields;
137
+ if (input.sortBy)
138
+ params.sortBy = input.sortBy;
139
+ if (input.sortOrder)
140
+ params.sortOrder = input.sortOrder;
141
+ const qs = new URLSearchParams(params);
142
+ const raw = await this.getRaw(`/api/v1/transQuery?${qs}`);
143
+ return { transactions: raw.data, pagination: raw.pagination };
144
+ }
145
+ // ─── HTTP helpers ────────────────────────────────────────────────────────
146
+ /**
147
+ * Execute a fetch with retry on 5xx / network errors.
148
+ * 4xx errors (including 429) are never retried — they require caller action.
149
+ */
150
+ async fetchWithRetry(url, init) {
151
+ let lastError;
152
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
153
+ try {
154
+ const res = await fetch(url, Object.assign(Object.assign({}, init), { signal: AbortSignal.timeout(this.timeoutMs) }));
155
+ if (isRetryable(res.status) && attempt < this.retries) {
156
+ // Consume/cancel body so the connection is released (undici holds socket until body is drained)
157
+ if (res.body) {
158
+ try {
159
+ await res.body.cancel();
160
+ }
161
+ catch (_a) {
162
+ /* ignore */
163
+ }
164
+ }
165
+ const backoff = Math.min(1000 * 2 ** attempt, 8000);
166
+ await sleep(backoff);
167
+ continue;
168
+ }
169
+ return res;
170
+ }
171
+ catch (err) {
172
+ lastError = err;
173
+ if (attempt < this.retries) {
174
+ const backoff = Math.min(1000 * 2 ** attempt, 8000);
175
+ await sleep(backoff);
176
+ continue;
177
+ }
178
+ }
179
+ }
180
+ // All attempts exhausted — wrap the raw error in OzuraError
181
+ if (lastError instanceof Error) {
182
+ if (lastError.name === 'TimeoutError' || lastError.name === 'AbortError') {
183
+ throw new OzuraError(`Request timed out after ${this.timeoutMs}ms`, 0, lastError.message);
184
+ }
185
+ throw new OzuraError(`Network error: ${lastError.message}`, 0, lastError.message);
186
+ }
187
+ throw new OzuraError('Network error', 0);
188
+ }
189
+ async post(path, body, includeVaultKey) {
190
+ const headers = {
191
+ 'Content-Type': 'application/json',
192
+ 'x-api-key': this.apiKey,
193
+ };
194
+ if (includeVaultKey) {
195
+ headers['vault-api-key'] = this.vaultKey;
196
+ }
197
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
198
+ method: 'POST',
199
+ headers,
200
+ body: JSON.stringify(body),
201
+ });
202
+ return this.handleResponse(res);
203
+ }
204
+ async get(path) {
205
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
206
+ method: 'GET',
207
+ headers: { 'x-api-key': this.apiKey },
208
+ });
209
+ return this.handleResponse(res);
210
+ }
211
+ async getRaw(path) {
212
+ const res = await this.fetchWithRetry(`${this.apiUrl}${path}`, {
213
+ method: 'GET',
214
+ headers: { 'x-api-key': this.apiKey },
215
+ });
216
+ const json = await res.json().catch(() => ({ error: res.statusText }));
217
+ if (!res.ok) {
218
+ const retryAfter = res.status === 429
219
+ ? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
220
+ : undefined;
221
+ throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
222
+ }
223
+ if (json.success === false) {
224
+ throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
225
+ }
226
+ return json;
227
+ }
228
+ async handleResponse(res) {
229
+ var _a;
230
+ const json = await res.json().catch(() => ({ error: res.statusText }));
231
+ if (!res.ok) {
232
+ const retryAfter = res.status === 429
233
+ ? Number(res.headers.get('retry-after') || json.retryAfter) || undefined
234
+ : undefined;
235
+ throw new OzuraError(json.error || `HTTP ${res.status}`, res.status, json.error, retryAfter);
236
+ }
237
+ if (json.success === false) {
238
+ throw new OzuraError(json.error || 'Request was not successful', res.status, json.error);
239
+ }
240
+ return ((_a = json.data) !== null && _a !== void 0 ? _a : json);
241
+ }
242
+ }
243
+ // ─── Utilities ────────────────────────────────────────────────────────────────
244
+ /**
245
+ * Extract the client IP address from a server request object.
246
+ * Works with Express (`req.ip`), Fastify (`request.ip`), Next.js App Router
247
+ * (`req.headers.get('x-forwarded-for')`), and raw Node.js `IncomingMessage`.
248
+ *
249
+ * @example
250
+ * // Express / Fastify
251
+ * clientIpAddress: getClientIp(req)
252
+ *
253
+ * // Next.js App Router
254
+ * clientIpAddress: getClientIp(req)
255
+ */
256
+ function getClientIp(req) {
257
+ // Express / Fastify: req.ip
258
+ if (typeof req.ip === 'string' && req.ip)
259
+ return req.ip;
260
+ // Next.js App Router: req.headers.get('x-forwarded-for')
261
+ const headers = req.headers;
262
+ if (headers && typeof headers.get === 'function') {
263
+ const xff = headers.get('x-forwarded-for');
264
+ if (xff)
265
+ return xff.split(',')[0].trim();
266
+ const realIp = headers.get('x-real-ip');
267
+ if (realIp)
268
+ return realIp;
269
+ }
270
+ // Node.js IncomingMessage: req.headers['x-forwarded-for']
271
+ if (headers && typeof headers === 'object') {
272
+ const h = headers;
273
+ const xff = h['x-forwarded-for'];
274
+ if (typeof xff === 'string' && xff)
275
+ return xff.split(',')[0].trim();
276
+ if (Array.isArray(xff) && xff[0])
277
+ return xff[0].split(',')[0].trim();
278
+ const realIp = h['x-real-ip'];
279
+ if (typeof realIp === 'string' && realIp)
280
+ return realIp;
281
+ }
282
+ // Raw Node.js socket
283
+ const socket = req.socket;
284
+ if (socket === null || socket === void 0 ? void 0 : socket.remoteAddress)
285
+ return socket.remoteAddress;
286
+ return '0.0.0.0';
287
+ }
288
+
289
+ export { Ozura, OzuraError, getClientIp };
290
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../../src/server/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}