@kelviq/react-sdk 2.0.1-beta → 2.0.2

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.
@@ -1,146 +1,146 @@
1
1
  import { jsx as S, Fragment as M } from "react/jsx-runtime";
2
- import { createContext as Z, useState as T, useCallback as y, useEffect as Q, useMemo as ee, useContext as te } from "react";
3
- const re = "GET", ne = 5e3, se = 3, oe = 1e3;
2
+ import { createContext as Q, useState as $, useCallback as w, useEffect as ee, useMemo as te, useContext as re } from "react";
3
+ const ne = "GET", se = 5e3, oe = 3, ie = 1e3;
4
4
  function O(n) {
5
5
  const {
6
- method: o = re,
7
- headers: i = {},
6
+ method: s = ne,
7
+ headers: o = {},
8
8
  // Renamed to avoid conflict with internal 'headers' variable
9
9
  body: t,
10
- timeout: g = ne,
11
- maxRetries: m = se,
12
- backoffBaseDelay: L = oe,
13
- queryParams: v,
10
+ timeout: E = se,
11
+ maxRetries: g = oe,
12
+ backoffBaseDelay: v = ie,
13
+ queryParams: A,
14
14
  accessToken: l
15
15
  // Use the direct accessToken
16
16
  } = n;
17
- let { url: f } = n, p = 0;
18
- return new Promise((U, b) => {
19
- if (v) {
20
- const s = new URLSearchParams();
21
- for (const u in v)
22
- v[u] !== void 0 && s.append(u, String(v[u]));
23
- s.toString() && (f += (f.includes("?") ? "&" : "?") + s.toString());
17
+ let { url: d } = n, L = 0;
18
+ return new Promise((R, P) => {
19
+ if (A) {
20
+ const a = new URLSearchParams();
21
+ for (const m in A)
22
+ A[m] !== void 0 && a.append(m, String(A[m]));
23
+ a.toString() && (d += (d.includes("?") ? "&" : "?") + a.toString());
24
24
  }
25
25
  function C() {
26
- const s = new XMLHttpRequest();
27
- s.open(o, f, !0), s.timeout = g;
28
- const u = {
26
+ const a = new XMLHttpRequest();
27
+ a.open(s, d, !0), a.timeout = E;
28
+ const m = {
29
29
  Accept: "application/json",
30
30
  "X-Requested-With": "XMLHttpRequest",
31
- ...i
31
+ ...o
32
32
  // Apply custom headers, allowing them to override defaults
33
33
  };
34
- o !== "GET" && t && typeof t == "object" && !(t instanceof FormData) && (u["Content-Type"] || (u["Content-Type"] = "application/json")), l && (u.Authorization = `Bearer ${l}`);
35
- for (const [a, w] of Object.entries(u))
36
- s.setRequestHeader(a, w);
37
- s.onload = function() {
38
- const { status: a, statusText: w, responseText: P } = s;
39
- if (a >= 200 && a < 300)
34
+ s !== "GET" && t && typeof t == "object" && !(t instanceof FormData) && (m["Content-Type"] || (m["Content-Type"] = "application/json")), l && (m.Authorization = `Bearer ${l}`);
35
+ for (const [i, f] of Object.entries(m))
36
+ a.setRequestHeader(i, f);
37
+ a.onload = function() {
38
+ const { status: i, statusText: f, responseText: T } = a;
39
+ if (i >= 200 && i < 300)
40
40
  try {
41
- const A = P ? JSON.parse(P) : {};
42
- U({ status: a, statusText: w, data: A });
43
- } catch (A) {
44
- const I = A instanceof Error ? A : new Error(String(A));
41
+ const b = T ? JSON.parse(T) : {};
42
+ R({ status: i, statusText: f, data: b });
43
+ } catch (b) {
44
+ const q = b instanceof Error ? b : new Error(String(b));
45
45
  console.error(
46
- `Kelviq SDK (apiRequest): Invalid JSON response for URL ${f}. Error: ${I.message}. Response: ${P}`
47
- ), b(
46
+ `Kelviq SDK (apiRequest): Invalid JSON response for URL ${d}. Error: ${q.message}. Response: ${T}`
47
+ ), P(
48
48
  new Error(
49
- `Invalid JSON response: ${I.message}`
49
+ `Invalid JSON response: ${q.message}`
50
50
  )
51
51
  );
52
52
  }
53
53
  else
54
- h(
55
- `Request to ${f} failed with status ${a} ${w}. Response: ${P}`
54
+ p(
55
+ `Request to ${d} failed with status ${i} ${f}. Response: ${T}`
56
56
  );
57
- }, s.onerror = () => h(
58
- `Network error for URL ${f}. The request could not be completed.`
59
- ), s.ontimeout = () => h(`Request to ${f} timed out.`);
60
- function h(a) {
61
- if (p < m) {
62
- p++;
63
- const w = Math.min(
64
- L * Math.pow(2, p - 1),
57
+ }, a.onerror = () => p(
58
+ `Network error for URL ${d}. The request could not be completed.`
59
+ ), a.ontimeout = () => p(`Request to ${d} timed out.`);
60
+ function p(i) {
61
+ if (L < g) {
62
+ L++;
63
+ const f = Math.min(
64
+ v * Math.pow(2, L - 1),
65
65
  3e4
66
66
  // Cap retry delay at 30 seconds
67
67
  );
68
68
  console.warn(
69
- `Kelviq SDK (apiRequest): Retrying request to ${f}. Attempt ${p}/${m}. Error: ${a}. Retrying in ${w}ms.`
70
- ), setTimeout(C, w);
69
+ `Kelviq SDK (apiRequest): Retrying request to ${d}. Attempt ${L}/${g}. Error: ${i}. Retrying in ${f}ms.`
70
+ ), setTimeout(C, f);
71
71
  } else
72
- b(
72
+ P(
73
73
  new Error(
74
- `${a} (Max retries ${m} reached)`
74
+ `${i} (Max retries ${g} reached)`
75
75
  )
76
76
  );
77
77
  }
78
78
  try {
79
- let a = t;
80
- t && typeof t == "object" && !(t instanceof FormData) && u["Content-Type"] === "application/json" && (a = JSON.stringify(t)), s.send(a);
81
- } catch (a) {
82
- const w = a instanceof Error ? a : new Error(String(a));
79
+ let i = t;
80
+ t && typeof t == "object" && !(t instanceof FormData) && m["Content-Type"] === "application/json" && (i = JSON.stringify(t)), a.send(i);
81
+ } catch (i) {
82
+ const f = i instanceof Error ? i : new Error(String(i));
83
83
  console.error(
84
- `Kelviq SDK (apiRequest): Error sending request to ${f}.`,
85
- w
86
- ), b(new Error(`Failed to send request: ${w.message}`));
84
+ `Kelviq SDK (apiRequest): Error sending request to ${d}.`,
85
+ f
86
+ ), P(new Error(`Failed to send request: ${f.message}`));
87
87
  }
88
88
  }
89
89
  C();
90
90
  });
91
91
  }
92
- function ie(n, o) {
93
- const i = o[0].featureType;
94
- if (i === "METER") {
95
- let t = 0, g = 0, m = !1;
96
- for (const v of o) {
97
- const l = v, f = typeof l.usageLimit == "number" ? l.usageLimit : null, p = typeof l.currentUsage == "number" ? l.currentUsage : 0;
98
- f === null && (t = null), t !== null && (t += f), g += p, l.hardLimit && (m = !0);
92
+ function ae(n, s) {
93
+ const o = s[0].featureType;
94
+ if (o === "METER") {
95
+ let t = 0, E = 0, g = !1;
96
+ for (const A of s) {
97
+ const l = A, d = typeof l.usageLimit == "number" ? l.usageLimit : null, L = typeof l.currentUsage == "number" ? l.currentUsage : 0;
98
+ d === null && (t = null), t !== null && (t += d), E += L, l.hardLimit && (g = !0);
99
99
  }
100
- const L = t !== null ? t - g : null;
100
+ const v = t !== null ? t - E : null;
101
101
  return {
102
102
  featureId: n,
103
- featureType: i,
104
- hasAccess: L === null || L > 0,
105
- currentUsage: g,
103
+ featureType: o,
104
+ hasAccess: v === null || v > 0,
105
+ currentUsage: E,
106
106
  usageLimit: t,
107
- remaining: L,
108
- hardLimit: m,
109
- items: o
107
+ remaining: v,
108
+ hardLimit: g,
109
+ items: s
110
110
  };
111
111
  }
112
- if (i === "CUSTOMIZABLE") {
113
- const t = o[0];
112
+ if (o === "CUSTOMIZABLE") {
113
+ const t = s[0];
114
114
  return {
115
115
  featureId: n,
116
- featureType: i,
117
- hasAccess: o.some((g) => g.hasAccess),
116
+ featureType: o,
117
+ hasAccess: s.some((E) => E.hasAccess),
118
118
  currentUsage: typeof t.currentUsage == "number" ? t.currentUsage : 0,
119
119
  usageLimit: typeof t.usageLimit == "number" ? t.usageLimit : null,
120
120
  remaining: typeof t.remaining == "number" ? t.remaining : null,
121
121
  hardLimit: t.hardLimit === !0,
122
- items: o
122
+ items: s
123
123
  };
124
124
  }
125
125
  return {
126
126
  featureId: n,
127
- featureType: i,
128
- hasAccess: o.some((t) => t.hasAccess),
127
+ featureType: o,
128
+ hasAccess: s.some((t) => t.hasAccess),
129
129
  currentUsage: 0,
130
130
  usageLimit: null,
131
131
  remaining: null,
132
132
  hardLimit: !1,
133
- items: o
133
+ items: s
134
134
  };
135
135
  }
136
- function ae(n) {
137
- const o = {};
136
+ function le(n) {
137
+ const s = {};
138
138
  if (!n || !Array.isArray(n.entitlements))
139
139
  return console.warn(
140
140
  "Kelviq SDK: Invalid or empty entitlements array in API response.",
141
141
  n
142
- ), o;
143
- const i = {};
142
+ ), s;
143
+ const o = {};
144
144
  for (const t of n.entitlements) {
145
145
  if (!t || typeof t.featureId != "string" || typeof t.featureType != "string") {
146
146
  console.warn(
@@ -149,16 +149,16 @@ function ae(n) {
149
149
  );
150
150
  continue;
151
151
  }
152
- i[t.featureId] || (i[t.featureId] = []), i[t.featureId].push(t);
152
+ o[t.featureId] || (o[t.featureId] = []), o[t.featureId].push(t);
153
153
  }
154
- for (const t in i)
155
- o[t] = ie(
154
+ for (const t in o)
155
+ s[t] = ae(
156
156
  t,
157
- i[t]
157
+ o[t]
158
158
  );
159
- return o;
159
+ return s;
160
160
  }
161
- const J = {
161
+ const V = {
162
162
  allEntitlements: {
163
163
  data: null,
164
164
  isLoading: !0,
@@ -199,158 +199,158 @@ const J = {
199
199
  environment: "production",
200
200
  entitlementsPath: "",
201
201
  customerId: ""
202
- }, V = Z(
203
- J
204
- ), le = "https://edge.api.kelviq.com/api/v1/", ue = "https://edge.sandboxapi.kelviq.com/api/v1/", ce = "entitlements/", me = ({
202
+ }, Y = Q(
203
+ V
204
+ ), ue = "https://edge.api.kelviq.com/api/v1/", ce = "https://edge.sandboxapi.kelviq.com/api/v1/", de = "https://api.kelviq.com/api/v1/", fe = "https://sandboxapi.kelviq.com/api/v1/", me = "entitlements/", pe = ({
205
205
  children: n,
206
- apiUrl: o,
207
- entitlementsPath: i = ce,
206
+ apiUrl: s,
207
+ entitlementsPath: o = me,
208
208
  customerId: t,
209
- environment: g = "production",
210
- accessToken: m,
211
- config: L = {}
209
+ environment: E = "production",
210
+ accessToken: g,
211
+ config: v = {}
212
212
  }) => {
213
213
  const {
214
- onError: v,
214
+ onError: A,
215
215
  maxRetries: l,
216
- timeout: f,
217
- backoffBaseDelay: p,
218
- fetchEntitlementsOnMount: U = !0,
219
- fetchSubscriptionsOnMount: b = !1,
216
+ timeout: d,
217
+ backoffBaseDelay: L,
218
+ fetchEntitlementsOnMount: R = !0,
219
+ fetchSubscriptionsOnMount: P = !1,
220
220
  fetchCustomerOnMount: C = !1
221
- } = L, s = o || (g === "sandbox" ? ue : le), [u, h] = T({
221
+ } = v, a = s || (E === "sandbox" ? ce : ue), m = E === "sandbox" ? fe : de, [p, i] = $({
222
222
  data: null,
223
- isLoading: !!s && U,
223
+ isLoading: !!a && R,
224
224
  error: null
225
- }), [a, w] = T(null), [P, A] = T({
225
+ }), [f, T] = $(null), [b, q] = $({
226
226
  data: null,
227
- isLoading: !!s && b,
227
+ isLoading: !!a && P,
228
228
  error: null
229
- }), [I, $] = T({
229
+ }), [N, I] = $({
230
230
  data: null,
231
- isLoading: !!s && C,
231
+ isLoading: !!a && C,
232
232
  error: null
233
- }), [D, K] = T(
234
- !!s && U
235
- ), [k, x] = T(null), E = y(
236
- (c, e, r) => {
237
- const d = new Error(
238
- `Kelviq SDK (${e}): ${c}`
233
+ }), [D, U] = $(
234
+ !!a && R
235
+ ), [k, x] = $(null), h = w(
236
+ (u, e, r) => {
237
+ const c = new Error(
238
+ `Kelviq SDK (${e}): ${u}`
239
239
  );
240
- console.error(d.message, r || ""), x((q) => q || d), v && v(d);
240
+ console.error(c.message, r || ""), x((y) => y || c), A && A(c);
241
241
  },
242
- [v]
243
- ), _ = y(() => {
244
- if (!s) {
242
+ [A]
243
+ ), _ = w(() => {
244
+ if (!a) {
245
245
  const r = "API URL not configured. Cannot fetch entitlements.";
246
- return h({
246
+ return i({
247
247
  data: null,
248
248
  isLoading: !1,
249
249
  error: new Error(r)
250
- }), E(r, "fetchAllEntitlements"), K(!1), Promise.reject(new Error(r));
250
+ }), h(r, "fetchAllEntitlements"), U(!1), Promise.reject(new Error(r));
251
251
  }
252
252
  if (!t) {
253
253
  const r = "CustomerId must be provided as props to KelviqProvider.";
254
- return h(() => ({
254
+ return i(() => ({
255
255
  data: null,
256
256
  isLoading: !1,
257
257
  error: new Error(r)
258
- })), E(r, "fetchAllEntitlements"), K(!1), Promise.reject(new Error(r));
258
+ })), h(r, "fetchAllEntitlements"), U(!1), Promise.reject(new Error(r));
259
259
  }
260
- h((r) => ({
260
+ i((r) => ({
261
261
  ...r,
262
262
  isLoading: !0,
263
263
  error: null
264
- })), K(!0), x(null);
265
- const c = `${s.replace(/\/$/, "")}/${i.replace(/^\//, "")}`;
264
+ })), U(!0), x(null);
265
+ const u = `${a.replace(/\/$/, "")}/${o.replace(/^\//, "")}`;
266
266
  return O({
267
- url: c,
267
+ url: u,
268
268
  method: "GET",
269
- timeout: f,
269
+ timeout: d,
270
270
  maxRetries: l,
271
- backoffBaseDelay: p,
272
- accessToken: m,
271
+ backoffBaseDelay: L,
272
+ accessToken: g,
273
273
  queryParams: {
274
274
  customer_id: t
275
275
  }
276
276
  }).then((r) => {
277
277
  if (r && r.data && Array.isArray(r.data.entitlements)) {
278
- w(r.data);
279
- const d = ae(
278
+ T(r.data);
279
+ const c = le(
280
280
  r.data
281
281
  );
282
- h({
283
- data: d,
282
+ i({
283
+ data: c,
284
284
  isLoading: !1,
285
285
  error: null
286
286
  });
287
287
  } else {
288
- const d = new Error(
288
+ const c = new Error(
289
289
  "Received empty, malformed, or invalid data structure from entitlements API."
290
290
  );
291
- throw h({
291
+ throw i({
292
292
  data: null,
293
293
  isLoading: !1,
294
- error: d
295
- }), E(
296
- d.message,
294
+ error: c
295
+ }), h(
296
+ c.message,
297
297
  "fetchAllEntitlements",
298
298
  r
299
- ), d;
299
+ ), c;
300
300
  }
301
301
  }).catch((r) => {
302
- const d = r instanceof Error ? r : new Error(String(r));
303
- return h((q) => ({
304
- ...q,
302
+ const c = r instanceof Error ? r : new Error(String(r));
303
+ return i((y) => ({
304
+ ...y,
305
305
  isLoading: !1,
306
- error: d
307
- })), E(d.message, "fetchAllEntitlements", r), Promise.reject(d);
306
+ error: c
307
+ })), h(c.message, "fetchAllEntitlements", r), Promise.reject(c);
308
308
  }).finally(() => {
309
- K(!1);
309
+ U(!1);
310
310
  });
311
311
  }, [
312
- s,
312
+ a,
313
313
  t,
314
- i,
315
- f,
314
+ o,
315
+ d,
316
316
  l,
317
- p,
318
- m,
319
- E
320
- ]), j = y(() => {
321
- if (!s) {
322
- const e = "API URL not configured. Cannot fetch subscriptions.";
323
- return A({
317
+ L,
318
+ g,
319
+ h
320
+ ]), j = w(() => {
321
+ if (!m) {
322
+ const e = "Main API URL not configured. Cannot fetch subscriptions.";
323
+ return q({
324
324
  data: null,
325
325
  isLoading: !1,
326
326
  error: new Error(e)
327
- }), E(e, "fetchSubscriptions"), Promise.reject(new Error(e));
327
+ }), h(e, "fetchSubscriptions"), Promise.reject(new Error(e));
328
328
  }
329
329
  if (!t) {
330
330
  const e = "CustomerId must be provided as props to KelviqProvider.";
331
- return A({
331
+ return q({
332
332
  data: null,
333
333
  isLoading: !1,
334
334
  error: new Error(e)
335
- }), E(e, "fetchSubscriptions"), Promise.reject(new Error(e));
335
+ }), h(e, "fetchSubscriptions"), Promise.reject(new Error(e));
336
336
  }
337
- A((e) => ({
337
+ q((e) => ({
338
338
  ...e,
339
339
  isLoading: !0,
340
340
  error: null
341
341
  }));
342
- const c = `${s.replace(/\/$/, "")}/subscriptions/`;
342
+ const u = `${m.replace(/\/$/, "")}/subscriptions/`;
343
343
  return O({
344
- url: c,
344
+ url: u,
345
345
  method: "GET",
346
- timeout: f,
346
+ timeout: d,
347
347
  maxRetries: l,
348
- backoffBaseDelay: p,
349
- accessToken: m,
348
+ backoffBaseDelay: L,
349
+ accessToken: g,
350
350
  queryParams: { customer_id: t }
351
351
  }).then((e) => {
352
352
  if (e && e.data && Array.isArray(e.data.results))
353
- A({
353
+ q({
354
354
  data: e.data.results,
355
355
  isLoading: !1,
356
356
  error: null
@@ -359,11 +359,11 @@ const J = {
359
359
  const r = new Error(
360
360
  "Received empty, malformed, or invalid data structure from subscriptions API."
361
361
  );
362
- throw A({
362
+ throw q({
363
363
  data: null,
364
364
  isLoading: !1,
365
365
  error: r
366
- }), E(
366
+ }), h(
367
367
  r.message,
368
368
  "fetchSubscriptions",
369
369
  e
@@ -371,57 +371,57 @@ const J = {
371
371
  }
372
372
  }).catch((e) => {
373
373
  const r = e instanceof Error ? e : new Error(String(e));
374
- return A((d) => ({
375
- ...d,
374
+ return q((c) => ({
375
+ ...c,
376
376
  isLoading: !1,
377
377
  error: r
378
- })), E(
378
+ })), h(
379
379
  r.message,
380
380
  "fetchSubscriptions",
381
381
  e
382
382
  ), Promise.reject(r);
383
383
  });
384
384
  }, [
385
- s,
385
+ m,
386
386
  t,
387
- f,
387
+ d,
388
388
  l,
389
- p,
390
- m,
391
- E
392
- ]), F = y(() => {
393
- if (!s) {
394
- const e = "API URL not configured. Cannot fetch customer.";
395
- return $({
389
+ L,
390
+ g,
391
+ h
392
+ ]), F = w(() => {
393
+ if (!m) {
394
+ const e = "Main API URL not configured. Cannot fetch customer.";
395
+ return I({
396
396
  data: null,
397
397
  isLoading: !1,
398
398
  error: new Error(e)
399
- }), E(e, "fetchCustomer"), Promise.reject(new Error(e));
399
+ }), h(e, "fetchCustomer"), Promise.reject(new Error(e));
400
400
  }
401
401
  if (!t) {
402
402
  const e = "CustomerId must be provided as props to KelviqProvider.";
403
- return $({
403
+ return I({
404
404
  data: null,
405
405
  isLoading: !1,
406
406
  error: new Error(e)
407
- }), E(e, "fetchCustomer"), Promise.reject(new Error(e));
407
+ }), h(e, "fetchCustomer"), Promise.reject(new Error(e));
408
408
  }
409
- $((e) => ({
409
+ I((e) => ({
410
410
  ...e,
411
411
  isLoading: !0,
412
412
  error: null
413
413
  }));
414
- const c = `${s.replace(/\/$/, "")}/customers/${t}/`;
414
+ const u = `${m.replace(/\/$/, "")}/customers/${t}/`;
415
415
  return O({
416
- url: c,
416
+ url: u,
417
417
  method: "GET",
418
- timeout: f,
418
+ timeout: d,
419
419
  maxRetries: l,
420
- backoffBaseDelay: p,
421
- accessToken: m
420
+ backoffBaseDelay: L,
421
+ accessToken: g
422
422
  }).then((e) => {
423
423
  if (e && e.data)
424
- $({
424
+ I({
425
425
  data: e.data,
426
426
  isLoading: !1,
427
427
  error: null
@@ -430,11 +430,11 @@ const J = {
430
430
  const r = new Error(
431
431
  "Received empty or invalid data from customer API."
432
432
  );
433
- throw $({
433
+ throw I({
434
434
  data: null,
435
435
  isLoading: !1,
436
436
  error: r
437
- }), E(
437
+ }), h(
438
438
  r.message,
439
439
  "fetchCustomer",
440
440
  e
@@ -442,47 +442,47 @@ const J = {
442
442
  }
443
443
  }).catch((e) => {
444
444
  const r = e instanceof Error ? e : new Error(String(e));
445
- return $((d) => ({
446
- ...d,
445
+ return I((c) => ({
446
+ ...c,
447
447
  isLoading: !1,
448
448
  error: r
449
- })), E(r.message, "fetchCustomer", e), Promise.reject(r);
449
+ })), h(r.message, "fetchCustomer", e), Promise.reject(r);
450
450
  });
451
451
  }, [
452
- s,
452
+ m,
453
453
  t,
454
- f,
454
+ d,
455
455
  l,
456
- p,
457
- m,
458
- E
456
+ L,
457
+ g,
458
+ h
459
459
  ]);
460
- Q(() => {
461
- let c = !0;
462
- if (!s) {
463
- if (c) {
460
+ ee(() => {
461
+ let u = !0;
462
+ if (!a) {
463
+ if (u) {
464
464
  const e = new Error(
465
465
  "KelviqProvider: `apiBaseUrl` must be provided in config."
466
466
  );
467
- x(e), K(!1), h((r) => ({
467
+ x(e), U(!1), i((r) => ({
468
468
  ...r,
469
469
  isLoading: !1,
470
470
  error: e
471
- })), L.onError && L.onError(e);
471
+ })), v.onError && v.onError(e);
472
472
  }
473
473
  return;
474
474
  }
475
- return U ? _().catch((e) => {
476
- c && D && K(!1), console.error(
475
+ return R ? _().catch((e) => {
476
+ u && D && U(!1), console.error(
477
477
  "Kelviq SDK: Initial entitlement fetch failed.",
478
478
  e
479
479
  );
480
- }) : c && (h((e) => ({
480
+ }) : u && (i((e) => ({
481
481
  ...e,
482
482
  isLoading: !1,
483
483
  data: null,
484
484
  error: null
485
- })), K(!1)), b && j().catch((e) => {
485
+ })), U(!1)), P && j().catch((e) => {
486
486
  console.error(
487
487
  "Kelviq SDK: Initial subscriptions fetch failed.",
488
488
  e
@@ -493,156 +493,156 @@ const J = {
493
493
  e
494
494
  );
495
495
  }), () => {
496
- c = !1;
496
+ u = !1;
497
497
  };
498
- }, [s, U, b, C, L.onError]);
499
- const N = y(
500
- () => u.data ? u.data : {},
501
- [u.data]
502
- ), G = y(
503
- () => a ? {
504
- customerId: a.customerId,
505
- entitlements: a.entitlements
498
+ }, [a, R, P, C, v.onError]);
499
+ const G = w(
500
+ () => p.data ? p.data : {},
501
+ [p.data]
502
+ ), H = w(
503
+ () => f ? {
504
+ customerId: f.customerId,
505
+ entitlements: f.entitlements
506
506
  } : null,
507
- [a]
508
- ), H = y(
509
- (c) => a ? {
510
- customerId: a.customerId,
511
- entitlements: a.entitlements.filter(
512
- (e) => e.featureId === c
507
+ [f]
508
+ ), X = w(
509
+ (u) => f ? {
510
+ customerId: f.customerId,
511
+ entitlements: f.entitlements.filter(
512
+ (e) => e.featureId === u
513
513
  )
514
514
  } : null,
515
- [a]
516
- ), W = y(
517
- (c) => u.data ? u.data[c] ?? null : null,
518
- [u.data]
519
- ), X = y(
520
- (c, e) => {
521
- h((r) => {
515
+ [f]
516
+ ), W = w(
517
+ (u) => p.data ? p.data[u] ?? null : null,
518
+ [p.data]
519
+ ), z = w(
520
+ (u, e) => {
521
+ i((r) => {
522
522
  if (!r.data) return r;
523
- const d = r.data[c];
524
- if (!d) return r;
525
- const q = { ...d, ...e };
526
- return ("usageLimit" in e || "currentUsage" in e) && (q.remaining = q.usageLimit !== null ? q.usageLimit - q.currentUsage : null), {
523
+ const c = r.data[u];
524
+ if (!c) return r;
525
+ const y = { ...c, ...e };
526
+ return ("usageLimit" in e || "currentUsage" in e) && (y.remaining = y.usageLimit !== null ? y.usageLimit - y.currentUsage : null), {
527
527
  ...r,
528
528
  data: {
529
529
  ...r.data,
530
- [c]: q
530
+ [u]: y
531
531
  }
532
532
  };
533
533
  });
534
534
  },
535
535
  []
536
- ), z = y(
537
- (c) => {
538
- if (!u.data) return !1;
539
- const e = u.data[c];
536
+ ), J = w(
537
+ (u) => {
538
+ if (!p.data) return !1;
539
+ const e = p.data[u];
540
540
  return e ? e.hasAccess : !1;
541
541
  },
542
- [u.data]
543
- ), Y = ee(
542
+ [p.data]
543
+ ), Z = te(
544
544
  () => ({
545
- allEntitlements: u,
545
+ allEntitlements: p,
546
546
  refreshAllEntitlements: _,
547
- getEntitlements: N,
547
+ getEntitlements: G,
548
548
  getEntitlement: W,
549
- getRawEntitlements: G,
550
- getRawEntitlement: H,
551
- hasAccess: z,
552
- updateEntitlement: X,
553
- subscriptions: P,
549
+ getRawEntitlements: H,
550
+ getRawEntitlement: X,
551
+ hasAccess: J,
552
+ updateEntitlement: z,
553
+ subscriptions: b,
554
554
  refreshSubscriptions: j,
555
- customer: I,
555
+ customer: N,
556
556
  refreshCustomer: F,
557
557
  isLoading: D,
558
558
  error: k,
559
- environment: g,
560
- apiUrl: s,
561
- entitlementsPath: i,
559
+ environment: E,
560
+ apiUrl: a,
561
+ entitlementsPath: o,
562
562
  customerId: t
563
563
  }),
564
564
  [
565
- u,
565
+ p,
566
566
  _,
567
- N,
568
- W,
569
567
  G,
568
+ W,
570
569
  H,
571
- z,
572
570
  X,
573
- P,
571
+ J,
572
+ z,
573
+ b,
574
574
  j,
575
- I,
575
+ N,
576
576
  F,
577
577
  D,
578
578
  k,
579
- g,
580
- s,
581
- i,
579
+ E,
580
+ a,
581
+ o,
582
582
  t
583
583
  ]
584
584
  );
585
- return /* @__PURE__ */ S(V.Provider, { value: Y, children: n });
586
- }, R = () => {
587
- const n = te(V);
588
- if (n === void 0 || n === J)
585
+ return /* @__PURE__ */ S(Y.Provider, { value: Z, children: n });
586
+ }, K = () => {
587
+ const n = re(Y);
588
+ if (n === void 0 || n === V)
589
589
  throw new Error(
590
590
  "useKelviq must be used within an initialized KelviqProvider."
591
591
  );
592
592
  return n;
593
593
  }, B = ({
594
594
  featureId: n,
595
- children: o,
596
- fallback: i = null,
595
+ children: s,
596
+ fallback: o = null,
597
597
  loadingComponent: t,
598
- condition: g
598
+ condition: E
599
599
  }) => {
600
600
  const {
601
- getEntitlement: m,
602
- isLoading: L,
603
- error: v
604
- } = R(), l = m(n);
605
- return L && !l ? /* @__PURE__ */ S(M, { children: t !== void 0 ? t : i }) : v && !l ? /* @__PURE__ */ S(M, { children: i }) : !l || !l.hasAccess || g && !g(l) ? /* @__PURE__ */ S(M, { children: i }) : typeof o == "function" ? /* @__PURE__ */ S(M, { children: o(l) }) : /* @__PURE__ */ S(M, { children: o });
606
- }, Ee = (n) => /* @__PURE__ */ S(B, { ...n }), ge = (n) => {
607
- const o = (i) => i.hasAccess && (i.remaining === null || i.remaining > 0);
601
+ getEntitlement: g,
602
+ isLoading: v,
603
+ error: A
604
+ } = K(), l = g(n);
605
+ return v && !l ? /* @__PURE__ */ S(M, { children: t !== void 0 ? t : o }) : A && !l ? /* @__PURE__ */ S(M, { children: o }) : !l || !l.hasAccess || E && !E(l) ? /* @__PURE__ */ S(M, { children: o }) : typeof s == "function" ? /* @__PURE__ */ S(M, { children: s(l) }) : /* @__PURE__ */ S(M, { children: s });
606
+ }, he = (n) => /* @__PURE__ */ S(B, { ...n }), Le = (n) => {
607
+ const s = (o) => o.hasAccess && (o.remaining === null || o.remaining > 0);
608
608
  return /* @__PURE__ */ S(
609
609
  B,
610
610
  {
611
611
  ...n,
612
- condition: n.condition || o
612
+ condition: n.condition || s
613
613
  }
614
614
  );
615
- }, pe = (n) => /* @__PURE__ */ S(B, { ...n }), he = () => {
616
- const { allEntitlements: n } = R();
615
+ }, ve = (n) => /* @__PURE__ */ S(B, { ...n }), Ae = () => {
616
+ const { allEntitlements: n } = K();
617
617
  return n;
618
- }, Le = (n) => {
619
- const { getEntitlement: o } = R();
620
- return o(n);
621
- }, ve = (n) => {
622
- const { getEntitlement: o } = R();
623
- return o(n);
624
618
  }, we = (n) => {
625
- const { getEntitlement: o } = R();
626
- return o(n);
627
- }, Ae = () => {
628
- const { subscriptions: n } = R();
619
+ const { getEntitlement: s } = K();
620
+ return s(n);
621
+ }, qe = (n) => {
622
+ const { getEntitlement: s } = K();
623
+ return s(n);
624
+ }, ye = (n) => {
625
+ const { getEntitlement: s } = K();
626
+ return s(n);
627
+ }, Se = () => {
628
+ const { subscriptions: n } = K();
629
629
  return n;
630
- }, ye = () => {
631
- const { customer: n } = R();
630
+ }, be = () => {
631
+ const { customer: n } = K();
632
632
  return n;
633
633
  };
634
634
  export {
635
- V as KelviqContext,
636
- me as KelviqProvider,
637
- pe as ShowWhenBooleanEntitled,
638
- Ee as ShowWhenCustomizableEntitled,
639
- ge as ShowWhenMeteredEntitled,
640
- J as defaultKelviqContextValue,
641
- he as useAllEntitlements,
642
- Le as useBooleanEntitlement,
643
- ye as useCustomer,
644
- ve as useCustomizableEntitlement,
645
- R as useKelviq,
646
- we as useMeteredEntitlement,
647
- Ae as useSubscriptions
635
+ Y as KelviqContext,
636
+ pe as KelviqProvider,
637
+ ve as ShowWhenBooleanEntitled,
638
+ he as ShowWhenCustomizableEntitled,
639
+ Le as ShowWhenMeteredEntitled,
640
+ V as defaultKelviqContextValue,
641
+ Ae as useAllEntitlements,
642
+ we as useBooleanEntitlement,
643
+ be as useCustomer,
644
+ qe as useCustomizableEntitlement,
645
+ K as useKelviq,
646
+ ye as useMeteredEntitlement,
647
+ Se as useSubscriptions
648
648
  };
@@ -1 +1 @@
1
- (function(d,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],g):(d=typeof globalThis<"u"?globalThis:d||self,g(d.KelviqReactSDK={},d.jsxRuntime,d.React))})(this,function(d,g,f){"use strict";const V="GET";function I(n){const{method:o=V,headers:i={},body:t,timeout:L=5e3,maxRetries:h=3,backoffBaseDelay:w=1e3,queryParams:S,accessToken:a}=n;let{url:E}=n,v=0;return new Promise((T,K)=>{if(S){const s=new URLSearchParams;for(const u in S)S[u]!==void 0&&s.append(u,String(S[u]));s.toString()&&(E+=(E.includes("?")?"&":"?")+s.toString())}function M(){const s=new XMLHttpRequest;s.open(o,E,!0),s.timeout=L;const u={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...i};o!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(u["Content-Type"]||(u["Content-Type"]="application/json")),a&&(u.Authorization=`Bearer ${a}`);for(const[l,q]of Object.entries(u))s.setRequestHeader(l,q);s.onload=function(){const{status:l,statusText:q,responseText:P}=s;if(l>=200&&l<300)try{const y=P?JSON.parse(P):{};T({status:l,statusText:q,data:y})}catch(y){const D=y instanceof Error?y:new Error(String(y));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${E}. Error: ${D.message}. Response: ${P}`),K(new Error(`Invalid JSON response: ${D.message}`))}else A(`Request to ${E} failed with status ${l} ${q}. Response: ${P}`)},s.onerror=()=>A(`Network error for URL ${E}. The request could not be completed.`),s.ontimeout=()=>A(`Request to ${E} timed out.`);function A(l){if(v<h){v++;const q=Math.min(w*Math.pow(2,v-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${E}. Attempt ${v}/${h}. Error: ${l}. Retrying in ${q}ms.`),setTimeout(M,q)}else K(new Error(`${l} (Max retries ${h} reached)`))}try{let l=t;t&&typeof t=="object"&&!(t instanceof FormData)&&u["Content-Type"]==="application/json"&&(l=JSON.stringify(t)),s.send(l)}catch(l){const q=l instanceof Error?l:new Error(String(l));console.error(`Kelviq SDK (apiRequest): Error sending request to ${E}.`,q),K(new Error(`Failed to send request: ${q.message}`))}}M()})}function Y(n,o){const i=o[0].featureType;if(i==="METER"){let t=0,L=0,h=!1;for(const S of o){const a=S,E=typeof a.usageLimit=="number"?a.usageLimit:null,v=typeof a.currentUsage=="number"?a.currentUsage:0;E===null&&(t=null),t!==null&&(t+=E),L+=v,a.hardLimit&&(h=!0)}const w=t!==null?t-L:null;return{featureId:n,featureType:i,hasAccess:w===null||w>0,currentUsage:L,usageLimit:t,remaining:w,hardLimit:h,items:o}}if(i==="CUSTOMIZABLE"){const t=o[0];return{featureId:n,featureType:i,hasAccess:o.some(L=>L.hasAccess),currentUsage:typeof t.currentUsage=="number"?t.currentUsage:0,usageLimit:typeof t.usageLimit=="number"?t.usageLimit:null,remaining:typeof t.remaining=="number"?t.remaining:null,hardLimit:t.hardLimit===!0,items:o}}return{featureId:n,featureType:i,hasAccess:o.some(t=>t.hasAccess),currentUsage:0,usageLimit:null,remaining:null,hardLimit:!1,items:o}}function Z(n){const o={};if(!n||!Array.isArray(n.entitlements))return console.warn("Kelviq SDK: Invalid or empty entitlements array in API response.",n),o;const i={};for(const t of n.entitlements){if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("Kelviq SDK: Skipping invalid raw entitlement object:",t);continue}i[t.featureId]||(i[t.featureId]=[]),i[t.featureId].push(t)}for(const t in i)o[t]=Y(t,i[t]);return o}const R={allEntitlements:{data:null,isLoading:!0,error:null},refreshAllEntitlements:()=>(console.warn("refreshAllEntitlements called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),getEntitlements:()=>({}),getEntitlement:()=>null,getRawEntitlements:()=>null,getRawEntitlement:()=>null,hasAccess:()=>!1,updateEntitlement:()=>{console.warn("updateEntitlement called on default KelviqContext. Ensure KelviqProvider is properly set up.")},subscriptions:{data:null,isLoading:!1,error:null},refreshSubscriptions:()=>(console.warn("refreshSubscriptions called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),customer:{data:null,isLoading:!1,error:null},refreshCustomer:()=>(console.warn("refreshCustomer called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),isLoading:!0,error:null,apiUrl:"",environment:"production",entitlementsPath:"",customerId:""},F=f.createContext(R),Q="https://edge.api.kelviq.com/api/v1/",ee="https://edge.sandboxapi.kelviq.com/api/v1/",te="entitlements/",re=({children:n,apiUrl:o,entitlementsPath:i=te,customerId:t,environment:L="production",accessToken:h,config:w={}})=>{const{onError:S,maxRetries:a,timeout:E,backoffBaseDelay:v,fetchEntitlementsOnMount:T=!0,fetchSubscriptionsOnMount:K=!1,fetchCustomerOnMount:M=!1}=w,s=o||(L==="sandbox"?ee:Q),[u,A]=f.useState({data:null,isLoading:!!s&&T,error:null}),[l,q]=f.useState(null),[P,y]=f.useState({data:null,isLoading:!!s&&K,error:null}),[D,$]=f.useState({data:null,isLoading:!!s&&M,error:null}),[k,U]=f.useState(!!s&&T),[N,O]=f.useState(null),p=f.useCallback((c,e,r)=>{const m=new Error(`Kelviq SDK (${e}): ${c}`);console.error(m.message,r||""),O(b=>b||m),S&&S(m)},[S]),j=f.useCallback(()=>{if(!s){const r="API URL not configured. Cannot fetch entitlements.";return A({data:null,isLoading:!1,error:new Error(r)}),p(r,"fetchAllEntitlements"),U(!1),Promise.reject(new Error(r))}if(!t){const r="CustomerId must be provided as props to KelviqProvider.";return A(()=>({data:null,isLoading:!1,error:new Error(r)})),p(r,"fetchAllEntitlements"),U(!1),Promise.reject(new Error(r))}A(r=>({...r,isLoading:!0,error:null})),U(!0),O(null);const c=`${s.replace(/\/$/,"")}/${i.replace(/^\//,"")}`;return I({url:c,method:"GET",timeout:E,maxRetries:a,backoffBaseDelay:v,accessToken:h,queryParams:{customer_id:t}}).then(r=>{if(r&&r.data&&Array.isArray(r.data.entitlements)){q(r.data);const m=Z(r.data);A({data:m,isLoading:!1,error:null})}else{const m=new Error("Received empty, malformed, or invalid data structure from entitlements API.");throw A({data:null,isLoading:!1,error:m}),p(m.message,"fetchAllEntitlements",r),m}}).catch(r=>{const m=r instanceof Error?r:new Error(String(r));return A(b=>({...b,isLoading:!1,error:m})),p(m.message,"fetchAllEntitlements",r),Promise.reject(m)}).finally(()=>{U(!1)})},[s,t,i,E,a,v,h,p]),B=f.useCallback(()=>{if(!s){const e="API URL not configured. Cannot fetch subscriptions.";return y({data:null,isLoading:!1,error:new Error(e)}),p(e,"fetchSubscriptions"),Promise.reject(new Error(e))}if(!t){const e="CustomerId must be provided as props to KelviqProvider.";return y({data:null,isLoading:!1,error:new Error(e)}),p(e,"fetchSubscriptions"),Promise.reject(new Error(e))}y(e=>({...e,isLoading:!0,error:null}));const c=`${s.replace(/\/$/,"")}/subscriptions/`;return I({url:c,method:"GET",timeout:E,maxRetries:a,backoffBaseDelay:v,accessToken:h,queryParams:{customer_id:t}}).then(e=>{if(e&&e.data&&Array.isArray(e.data.results))y({data:e.data.results,isLoading:!1,error:null});else{const r=new Error("Received empty, malformed, or invalid data structure from subscriptions API.");throw y({data:null,isLoading:!1,error:r}),p(r.message,"fetchSubscriptions",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return y(m=>({...m,isLoading:!1,error:r})),p(r.message,"fetchSubscriptions",e),Promise.reject(r)})},[s,t,E,a,v,h,p]),x=f.useCallback(()=>{if(!s){const e="API URL not configured. Cannot fetch customer.";return $({data:null,isLoading:!1,error:new Error(e)}),p(e,"fetchCustomer"),Promise.reject(new Error(e))}if(!t){const e="CustomerId must be provided as props to KelviqProvider.";return $({data:null,isLoading:!1,error:new Error(e)}),p(e,"fetchCustomer"),Promise.reject(new Error(e))}$(e=>({...e,isLoading:!0,error:null}));const c=`${s.replace(/\/$/,"")}/customers/${t}/`;return I({url:c,method:"GET",timeout:E,maxRetries:a,backoffBaseDelay:v,accessToken:h}).then(e=>{if(e&&e.data)$({data:e.data,isLoading:!1,error:null});else{const r=new Error("Received empty or invalid data from customer API.");throw $({data:null,isLoading:!1,error:r}),p(r.message,"fetchCustomer",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return $(m=>({...m,isLoading:!1,error:r})),p(r.message,"fetchCustomer",e),Promise.reject(r)})},[s,t,E,a,v,h,p]);f.useEffect(()=>{let c=!0;if(!s){if(c){const e=new Error("KelviqProvider: `apiBaseUrl` must be provided in config.");O(e),U(!1),A(r=>({...r,isLoading:!1,error:e})),w.onError&&w.onError(e)}return}return T?j().catch(e=>{c&&k&&U(!1),console.error("Kelviq SDK: Initial entitlement fetch failed.",e)}):c&&(A(e=>({...e,isLoading:!1,data:null,error:null})),U(!1)),K&&B().catch(e=>{console.error("Kelviq SDK: Initial subscriptions fetch failed.",e)}),M&&x().catch(e=>{console.error("Kelviq SDK: Initial customer fetch failed.",e)}),()=>{c=!1}},[s,T,K,M,w.onError]);const W=f.useCallback(()=>u.data?u.data:{},[u.data]),G=f.useCallback(()=>l?{customerId:l.customerId,entitlements:l.entitlements}:null,[l]),H=f.useCallback(c=>l?{customerId:l.customerId,entitlements:l.entitlements.filter(e=>e.featureId===c)}:null,[l]),z=f.useCallback(c=>u.data?u.data[c]??null:null,[u.data]),X=f.useCallback((c,e)=>{A(r=>{if(!r.data)return r;const m=r.data[c];if(!m)return r;const b={...m,...e};return("usageLimit"in e||"currentUsage"in e)&&(b.remaining=b.usageLimit!==null?b.usageLimit-b.currentUsage:null),{...r,data:{...r.data,[c]:b}}})},[]),J=f.useCallback(c=>{if(!u.data)return!1;const e=u.data[c];return e?e.hasAccess:!1},[u.data]),fe=f.useMemo(()=>({allEntitlements:u,refreshAllEntitlements:j,getEntitlements:W,getEntitlement:z,getRawEntitlements:G,getRawEntitlement:H,hasAccess:J,updateEntitlement:X,subscriptions:P,refreshSubscriptions:B,customer:D,refreshCustomer:x,isLoading:k,error:N,environment:L,apiUrl:s,entitlementsPath:i,customerId:t}),[u,j,W,z,G,H,J,X,P,B,D,x,k,N,L,s,i,t]);return g.jsx(F.Provider,{value:fe,children:n})},C=()=>{const n=f.useContext(F);if(n===void 0||n===R)throw new Error("useKelviq must be used within an initialized KelviqProvider.");return n},_=({featureId:n,children:o,fallback:i=null,loadingComponent:t,condition:L})=>{const{getEntitlement:h,isLoading:w,error:S}=C(),a=h(n);return w&&!a?g.jsx(g.Fragment,{children:t!==void 0?t:i}):S&&!a?g.jsx(g.Fragment,{children:i}):!a||!a.hasAccess||L&&!L(a)?g.jsx(g.Fragment,{children:i}):typeof o=="function"?g.jsx(g.Fragment,{children:o(a)}):g.jsx(g.Fragment,{children:o})},ne=n=>g.jsx(_,{...n}),se=n=>{const o=i=>i.hasAccess&&(i.remaining===null||i.remaining>0);return g.jsx(_,{...n,condition:n.condition||o})},oe=n=>g.jsx(_,{...n}),ie=()=>{const{allEntitlements:n}=C();return n},le=n=>{const{getEntitlement:o}=C();return o(n)},ae=n=>{const{getEntitlement:o}=C();return o(n)},ue=n=>{const{getEntitlement:o}=C();return o(n)},ce=()=>{const{subscriptions:n}=C();return n},de=()=>{const{customer:n}=C();return n};d.KelviqContext=F,d.KelviqProvider=re,d.ShowWhenBooleanEntitled=oe,d.ShowWhenCustomizableEntitled=ne,d.ShowWhenMeteredEntitled=se,d.defaultKelviqContextValue=R,d.useAllEntitlements=ie,d.useBooleanEntitlement=le,d.useCustomer=de,d.useCustomizableEntitlement=ae,d.useKelviq=C,d.useMeteredEntitlement=ue,d.useSubscriptions=ce,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1
+ (function(c,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],g):(c=typeof globalThis<"u"?globalThis:c||self,g(c.KelviqReactSDK={},c.jsxRuntime,c.React))})(this,function(c,g,d){"use strict";const Y="GET";function $(n){const{method:s=Y,headers:o={},body:t,timeout:p=5e3,maxRetries:L=3,backoffBaseDelay:q=1e3,queryParams:S,accessToken:a}=n;let{url:m}=n,w=0;return new Promise((T,U)=>{if(S){const l=new URLSearchParams;for(const h in S)S[h]!==void 0&&l.append(h,String(S[h]));l.toString()&&(m+=(m.includes("?")?"&":"?")+l.toString())}function M(){const l=new XMLHttpRequest;l.open(s,m,!0),l.timeout=p;const h={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...o};s!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(h["Content-Type"]||(h["Content-Type"]="application/json")),a&&(h.Authorization=`Bearer ${a}`);for(const[i,E]of Object.entries(h))l.setRequestHeader(i,E);l.onload=function(){const{status:i,statusText:E,responseText:D}=l;if(i>=200&&i<300)try{const K=D?JSON.parse(D):{};T({status:i,statusText:E,data:K})}catch(K){const b=K instanceof Error?K:new Error(String(K));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${m}. Error: ${b.message}. Response: ${D}`),U(new Error(`Invalid JSON response: ${b.message}`))}else v(`Request to ${m} failed with status ${i} ${E}. Response: ${D}`)},l.onerror=()=>v(`Network error for URL ${m}. The request could not be completed.`),l.ontimeout=()=>v(`Request to ${m} timed out.`);function v(i){if(w<L){w++;const E=Math.min(q*Math.pow(2,w-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${m}. Attempt ${w}/${L}. Error: ${i}. Retrying in ${E}ms.`),setTimeout(M,E)}else U(new Error(`${i} (Max retries ${L} reached)`))}try{let i=t;t&&typeof t=="object"&&!(t instanceof FormData)&&h["Content-Type"]==="application/json"&&(i=JSON.stringify(t)),l.send(i)}catch(i){const E=i instanceof Error?i:new Error(String(i));console.error(`Kelviq SDK (apiRequest): Error sending request to ${m}.`,E),U(new Error(`Failed to send request: ${E.message}`))}}M()})}function Z(n,s){const o=s[0].featureType;if(o==="METER"){let t=0,p=0,L=!1;for(const S of s){const a=S,m=typeof a.usageLimit=="number"?a.usageLimit:null,w=typeof a.currentUsage=="number"?a.currentUsage:0;m===null&&(t=null),t!==null&&(t+=m),p+=w,a.hardLimit&&(L=!0)}const q=t!==null?t-p:null;return{featureId:n,featureType:o,hasAccess:q===null||q>0,currentUsage:p,usageLimit:t,remaining:q,hardLimit:L,items:s}}if(o==="CUSTOMIZABLE"){const t=s[0];return{featureId:n,featureType:o,hasAccess:s.some(p=>p.hasAccess),currentUsage:typeof t.currentUsage=="number"?t.currentUsage:0,usageLimit:typeof t.usageLimit=="number"?t.usageLimit:null,remaining:typeof t.remaining=="number"?t.remaining:null,hardLimit:t.hardLimit===!0,items:s}}return{featureId:n,featureType:o,hasAccess:s.some(t=>t.hasAccess),currentUsage:0,usageLimit:null,remaining:null,hardLimit:!1,items:s}}function Q(n){const s={};if(!n||!Array.isArray(n.entitlements))return console.warn("Kelviq SDK: Invalid or empty entitlements array in API response.",n),s;const o={};for(const t of n.entitlements){if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("Kelviq SDK: Skipping invalid raw entitlement object:",t);continue}o[t.featureId]||(o[t.featureId]=[]),o[t.featureId].push(t)}for(const t in o)s[t]=Z(t,o[t]);return s}const R={allEntitlements:{data:null,isLoading:!0,error:null},refreshAllEntitlements:()=>(console.warn("refreshAllEntitlements called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),getEntitlements:()=>({}),getEntitlement:()=>null,getRawEntitlements:()=>null,getRawEntitlement:()=>null,hasAccess:()=>!1,updateEntitlement:()=>{console.warn("updateEntitlement called on default KelviqContext. Ensure KelviqProvider is properly set up.")},subscriptions:{data:null,isLoading:!1,error:null},refreshSubscriptions:()=>(console.warn("refreshSubscriptions called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),customer:{data:null,isLoading:!1,error:null},refreshCustomer:()=>(console.warn("refreshCustomer called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),isLoading:!0,error:null,apiUrl:"",environment:"production",entitlementsPath:"",customerId:""},_=d.createContext(R),ee="https://edge.api.kelviq.com/api/v1/",te="https://edge.sandboxapi.kelviq.com/api/v1/",re="https://api.kelviq.com/api/v1/",ne="https://sandboxapi.kelviq.com/api/v1/",se="entitlements/",oe=({children:n,apiUrl:s,entitlementsPath:o=se,customerId:t,environment:p="production",accessToken:L,config:q={}})=>{const{onError:S,maxRetries:a,timeout:m,backoffBaseDelay:w,fetchEntitlementsOnMount:T=!0,fetchSubscriptionsOnMount:U=!1,fetchCustomerOnMount:M=!1}=q,l=s||(p==="sandbox"?te:ee),h=p==="sandbox"?ne:re,[v,i]=d.useState({data:null,isLoading:!!l&&T,error:null}),[E,D]=d.useState(null),[K,b]=d.useState({data:null,isLoading:!!l&&U,error:null}),[N,I]=d.useState({data:null,isLoading:!!l&&M,error:null}),[k,P]=d.useState(!!l&&T),[W,B]=d.useState(null),A=d.useCallback((u,e,r)=>{const f=new Error(`Kelviq SDK (${e}): ${u}`);console.error(f.message,r||""),B(y=>y||f),S&&S(f)},[S]),O=d.useCallback(()=>{if(!l){const r="API URL not configured. Cannot fetch entitlements.";return i({data:null,isLoading:!1,error:new Error(r)}),A(r,"fetchAllEntitlements"),P(!1),Promise.reject(new Error(r))}if(!t){const r="CustomerId must be provided as props to KelviqProvider.";return i(()=>({data:null,isLoading:!1,error:new Error(r)})),A(r,"fetchAllEntitlements"),P(!1),Promise.reject(new Error(r))}i(r=>({...r,isLoading:!0,error:null})),P(!0),B(null);const u=`${l.replace(/\/$/,"")}/${o.replace(/^\//,"")}`;return $({url:u,method:"GET",timeout:m,maxRetries:a,backoffBaseDelay:w,accessToken:L,queryParams:{customer_id:t}}).then(r=>{if(r&&r.data&&Array.isArray(r.data.entitlements)){D(r.data);const f=Q(r.data);i({data:f,isLoading:!1,error:null})}else{const f=new Error("Received empty, malformed, or invalid data structure from entitlements API.");throw i({data:null,isLoading:!1,error:f}),A(f.message,"fetchAllEntitlements",r),f}}).catch(r=>{const f=r instanceof Error?r:new Error(String(r));return i(y=>({...y,isLoading:!1,error:f})),A(f.message,"fetchAllEntitlements",r),Promise.reject(f)}).finally(()=>{P(!1)})},[l,t,o,m,a,w,L,A]),j=d.useCallback(()=>{if(!h){const e="Main API URL not configured. Cannot fetch subscriptions.";return b({data:null,isLoading:!1,error:new Error(e)}),A(e,"fetchSubscriptions"),Promise.reject(new Error(e))}if(!t){const e="CustomerId must be provided as props to KelviqProvider.";return b({data:null,isLoading:!1,error:new Error(e)}),A(e,"fetchSubscriptions"),Promise.reject(new Error(e))}b(e=>({...e,isLoading:!0,error:null}));const u=`${h.replace(/\/$/,"")}/subscriptions/`;return $({url:u,method:"GET",timeout:m,maxRetries:a,backoffBaseDelay:w,accessToken:L,queryParams:{customer_id:t}}).then(e=>{if(e&&e.data&&Array.isArray(e.data.results))b({data:e.data.results,isLoading:!1,error:null});else{const r=new Error("Received empty, malformed, or invalid data structure from subscriptions API.");throw b({data:null,isLoading:!1,error:r}),A(r.message,"fetchSubscriptions",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return b(f=>({...f,isLoading:!1,error:r})),A(r.message,"fetchSubscriptions",e),Promise.reject(r)})},[h,t,m,a,w,L,A]),x=d.useCallback(()=>{if(!h){const e="Main API URL not configured. Cannot fetch customer.";return I({data:null,isLoading:!1,error:new Error(e)}),A(e,"fetchCustomer"),Promise.reject(new Error(e))}if(!t){const e="CustomerId must be provided as props to KelviqProvider.";return I({data:null,isLoading:!1,error:new Error(e)}),A(e,"fetchCustomer"),Promise.reject(new Error(e))}I(e=>({...e,isLoading:!0,error:null}));const u=`${h.replace(/\/$/,"")}/customers/${t}/`;return $({url:u,method:"GET",timeout:m,maxRetries:a,backoffBaseDelay:w,accessToken:L}).then(e=>{if(e&&e.data)I({data:e.data,isLoading:!1,error:null});else{const r=new Error("Received empty or invalid data from customer API.");throw I({data:null,isLoading:!1,error:r}),A(r.message,"fetchCustomer",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return I(f=>({...f,isLoading:!1,error:r})),A(r.message,"fetchCustomer",e),Promise.reject(r)})},[h,t,m,a,w,L,A]);d.useEffect(()=>{let u=!0;if(!l){if(u){const e=new Error("KelviqProvider: `apiBaseUrl` must be provided in config.");B(e),P(!1),i(r=>({...r,isLoading:!1,error:e})),q.onError&&q.onError(e)}return}return T?O().catch(e=>{u&&k&&P(!1),console.error("Kelviq SDK: Initial entitlement fetch failed.",e)}):u&&(i(e=>({...e,isLoading:!1,data:null,error:null})),P(!1)),U&&j().catch(e=>{console.error("Kelviq SDK: Initial subscriptions fetch failed.",e)}),M&&x().catch(e=>{console.error("Kelviq SDK: Initial customer fetch failed.",e)}),()=>{u=!1}},[l,T,U,M,q.onError]);const G=d.useCallback(()=>v.data?v.data:{},[v.data]),H=d.useCallback(()=>E?{customerId:E.customerId,entitlements:E.entitlements}:null,[E]),X=d.useCallback(u=>E?{customerId:E.customerId,entitlements:E.entitlements.filter(e=>e.featureId===u)}:null,[E]),z=d.useCallback(u=>v.data?v.data[u]??null:null,[v.data]),J=d.useCallback((u,e)=>{i(r=>{if(!r.data)return r;const f=r.data[u];if(!f)return r;const y={...f,...e};return("usageLimit"in e||"currentUsage"in e)&&(y.remaining=y.usageLimit!==null?y.usageLimit-y.currentUsage:null),{...r,data:{...r.data,[u]:y}}})},[]),V=d.useCallback(u=>{if(!v.data)return!1;const e=v.data[u];return e?e.hasAccess:!1},[v.data]),ge=d.useMemo(()=>({allEntitlements:v,refreshAllEntitlements:O,getEntitlements:G,getEntitlement:z,getRawEntitlements:H,getRawEntitlement:X,hasAccess:V,updateEntitlement:J,subscriptions:K,refreshSubscriptions:j,customer:N,refreshCustomer:x,isLoading:k,error:W,environment:p,apiUrl:l,entitlementsPath:o,customerId:t}),[v,O,G,z,H,X,V,J,K,j,N,x,k,W,p,l,o,t]);return g.jsx(_.Provider,{value:ge,children:n})},C=()=>{const n=d.useContext(_);if(n===void 0||n===R)throw new Error("useKelviq must be used within an initialized KelviqProvider.");return n},F=({featureId:n,children:s,fallback:o=null,loadingComponent:t,condition:p})=>{const{getEntitlement:L,isLoading:q,error:S}=C(),a=L(n);return q&&!a?g.jsx(g.Fragment,{children:t!==void 0?t:o}):S&&!a?g.jsx(g.Fragment,{children:o}):!a||!a.hasAccess||p&&!p(a)?g.jsx(g.Fragment,{children:o}):typeof s=="function"?g.jsx(g.Fragment,{children:s(a)}):g.jsx(g.Fragment,{children:s})},ie=n=>g.jsx(F,{...n}),le=n=>{const s=o=>o.hasAccess&&(o.remaining===null||o.remaining>0);return g.jsx(F,{...n,condition:n.condition||s})},ae=n=>g.jsx(F,{...n}),ue=()=>{const{allEntitlements:n}=C();return n},ce=n=>{const{getEntitlement:s}=C();return s(n)},de=n=>{const{getEntitlement:s}=C();return s(n)},fe=n=>{const{getEntitlement:s}=C();return s(n)},me=()=>{const{subscriptions:n}=C();return n},Ee=()=>{const{customer:n}=C();return n};c.KelviqContext=_,c.KelviqProvider=oe,c.ShowWhenBooleanEntitled=ae,c.ShowWhenCustomizableEntitled=ie,c.ShowWhenMeteredEntitled=le,c.defaultKelviqContextValue=R,c.useAllEntitlements=ue,c.useBooleanEntitlement=ce,c.useCustomer=Ee,c.useCustomizableEntitlement=de,c.useKelviq=C,c.useMeteredEntitlement=fe,c.useSubscriptions=me,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kelviq/react-sdk",
3
3
  "private": false,
4
- "version": "2.0.1-beta",
4
+ "version": "2.0.2",
5
5
  "type": "module",
6
6
  "main": "dist/kelviq-react-sdk.js",
7
7
  "types": "dist/index.d.ts",