@kelviq/react-sdk 2.1.0 → 2.1.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.
@@ -13,6 +13,8 @@ interface KelviqProviderProps {
13
13
  accessToken: string | null;
14
14
  /** Optional: Product identifier for fetching pricing data. Required when fetchPricingOnMount is true. */
15
15
  productId?: string;
16
+ /** Optional: Comma-separated list of plan identifiers to include in the pricing response. When omitted, all active plans are returned. */
17
+ plansEnabled?: string;
16
18
  /** Optional: Further configuration options for API behavior. */
17
19
  config?: KelviqApiBehaviorOptions;
18
20
  }
@@ -1,131 +1,131 @@
1
1
  import { jsx as L, Fragment as w } from "react/jsx-runtime";
2
- import { createContext as oe, useState as I, useCallback as K, useEffect as se, useMemo as ae, useContext as le } from "react";
3
- const ce = "GET", ue = 5e3, de = 3, fe = 1e3;
2
+ import { createContext as se, useState as I, useCallback as R, useEffect as ae, useMemo as le, useContext as ce } from "react";
3
+ const ue = "GET", de = 5e3, fe = 3, me = 1e3;
4
4
  function x(n) {
5
5
  const {
6
- method: i = ce,
7
- headers: a = {},
6
+ method: i = ue,
7
+ headers: s = {},
8
8
  // Renamed to avoid conflict with internal 'headers' variable
9
- body: r,
10
- timeout: f = ue,
11
- maxRetries: l = de,
12
- backoffBaseDelay: c = fe,
9
+ body: t,
10
+ timeout: m = de,
11
+ maxRetries: u = fe,
12
+ backoffBaseDelay: d = me,
13
13
  queryParams: E,
14
14
  accessToken: o
15
15
  // Use the direct accessToken
16
16
  } = n;
17
- let { url: s } = n, p = 0;
18
- return new Promise((q, U) => {
17
+ let { url: a } = n, g = 0;
18
+ return new Promise((q, P) => {
19
19
  if (E) {
20
20
  const v = new URLSearchParams();
21
21
  for (const S in E)
22
22
  E[S] !== void 0 && v.append(S, String(E[S]));
23
- v.toString() && (s += (s.includes("?") ? "&" : "?") + v.toString());
23
+ v.toString() && (a += (a.includes("?") ? "&" : "?") + v.toString());
24
24
  }
25
25
  function b() {
26
26
  const v = new XMLHttpRequest();
27
- v.open(i, s, !0), v.timeout = f;
27
+ v.open(i, a, !0), v.timeout = m;
28
28
  const S = {
29
29
  Accept: "application/json",
30
30
  "X-Requested-With": "XMLHttpRequest",
31
- ...a
31
+ ...s
32
32
  // Apply custom headers, allowing them to override defaults
33
33
  };
34
- i !== "GET" && r && typeof r == "object" && !(r instanceof FormData) && (S["Content-Type"] || (S["Content-Type"] = "application/json")), o && (S.Authorization = `Bearer ${o}`);
35
- for (const [u, m] of Object.entries(S))
36
- v.setRequestHeader(u, m);
34
+ i !== "GET" && t && typeof t == "object" && !(t instanceof FormData) && (S["Content-Type"] || (S["Content-Type"] = "application/json")), o && (S.Authorization = `Bearer ${o}`);
35
+ for (const [l, p] of Object.entries(S))
36
+ v.setRequestHeader(l, p);
37
37
  v.onload = function() {
38
- const { status: u, statusText: m, responseText: y } = v;
39
- if (u >= 200 && u < 300)
38
+ const { status: l, statusText: p, responseText: y } = v;
39
+ if (l >= 200 && l < 300)
40
40
  try {
41
- const P = y ? JSON.parse(y) : {};
42
- q({ status: u, statusText: m, data: P });
43
- } catch (P) {
44
- const _ = P instanceof Error ? P : new Error(String(P));
41
+ const A = y ? JSON.parse(y) : {};
42
+ q({ status: l, statusText: p, data: A });
43
+ } catch (A) {
44
+ const K = A instanceof Error ? A : new Error(String(A));
45
45
  console.error(
46
- `Kelviq SDK (apiRequest): Invalid JSON response for URL ${s}. Error: ${_.message}. Response: ${y}`
47
- ), U(
46
+ `Kelviq SDK (apiRequest): Invalid JSON response for URL ${a}. Error: ${K.message}. Response: ${y}`
47
+ ), P(
48
48
  new Error(
49
- `Invalid JSON response: ${_.message}`
49
+ `Invalid JSON response: ${K.message}`
50
50
  )
51
51
  );
52
52
  }
53
53
  else
54
- A(
55
- `Request to ${s} failed with status ${u} ${m}. Response: ${y}`
54
+ $(
55
+ `Request to ${a} failed with status ${l} ${p}. Response: ${y}`
56
56
  );
57
- }, v.onerror = () => A(
58
- `Network error for URL ${s}. The request could not be completed.`
59
- ), v.ontimeout = () => A(`Request to ${s} timed out.`);
60
- function A(u) {
61
- if (p < l) {
62
- p++;
63
- const m = Math.min(
64
- c * Math.pow(2, p - 1),
57
+ }, v.onerror = () => $(
58
+ `Network error for URL ${a}. The request could not be completed.`
59
+ ), v.ontimeout = () => $(`Request to ${a} timed out.`);
60
+ function $(l) {
61
+ if (g < u) {
62
+ g++;
63
+ const p = Math.min(
64
+ d * Math.pow(2, g - 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 ${s}. Attempt ${p}/${l}. Error: ${u}. Retrying in ${m}ms.`
70
- ), setTimeout(b, m);
69
+ `Kelviq SDK (apiRequest): Retrying request to ${a}. Attempt ${g}/${u}. Error: ${l}. Retrying in ${p}ms.`
70
+ ), setTimeout(b, p);
71
71
  } else
72
- U(
72
+ P(
73
73
  new Error(
74
- `${u} (Max retries ${l} reached)`
74
+ `${l} (Max retries ${u} reached)`
75
75
  )
76
76
  );
77
77
  }
78
78
  try {
79
- let u = r;
80
- r && typeof r == "object" && !(r instanceof FormData) && S["Content-Type"] === "application/json" && (u = JSON.stringify(r)), v.send(u);
81
- } catch (u) {
82
- const m = u instanceof Error ? u : new Error(String(u));
79
+ let l = t;
80
+ t && typeof t == "object" && !(t instanceof FormData) && S["Content-Type"] === "application/json" && (l = JSON.stringify(t)), v.send(l);
81
+ } catch (l) {
82
+ const p = l instanceof Error ? l : new Error(String(l));
83
83
  console.error(
84
- `Kelviq SDK (apiRequest): Error sending request to ${s}.`,
85
- m
86
- ), U(new Error(`Failed to send request: ${m.message}`));
84
+ `Kelviq SDK (apiRequest): Error sending request to ${a}.`,
85
+ p
86
+ ), P(new Error(`Failed to send request: ${p.message}`));
87
87
  }
88
88
  }
89
89
  b();
90
90
  });
91
91
  }
92
- function me(n, i) {
93
- const a = i[0].featureType;
94
- if (a === "METER") {
95
- let r = 0, f = 0, l = !1;
92
+ function ge(n, i) {
93
+ const s = i[0].featureType;
94
+ if (s === "METER") {
95
+ let t = 0, m = 0, u = !1;
96
96
  for (const E of i) {
97
- const o = E, s = typeof o.usageLimit == "number" ? o.usageLimit : null, p = typeof o.currentUsage == "number" ? o.currentUsage : 0;
98
- s === null && (r = null), r !== null && (r += s), f += p, o.hardLimit && (l = !0);
97
+ const o = E, a = typeof o.usageLimit == "number" ? o.usageLimit : null, g = typeof o.currentUsage == "number" ? o.currentUsage : 0;
98
+ a === null && (t = null), t !== null && (t += a), m += g, o.hardLimit && (u = !0);
99
99
  }
100
- const c = r !== null ? r - f : null;
100
+ const d = t !== null ? t - m : null;
101
101
  return {
102
102
  featureId: n,
103
- featureType: a,
104
- hasAccess: c === null || c > 0,
105
- currentUsage: f,
106
- usageLimit: r,
107
- remaining: c,
108
- hardLimit: l,
103
+ featureType: s,
104
+ hasAccess: d === null || d > 0,
105
+ currentUsage: m,
106
+ usageLimit: t,
107
+ remaining: d,
108
+ hardLimit: u,
109
109
  items: i
110
110
  };
111
111
  }
112
- if (a === "CUSTOMIZABLE") {
113
- const r = i[0];
112
+ if (s === "CUSTOMIZABLE") {
113
+ const t = i[0];
114
114
  return {
115
115
  featureId: n,
116
- featureType: a,
117
- hasAccess: i.some((f) => f.hasAccess),
118
- currentUsage: typeof r.currentUsage == "number" ? r.currentUsage : 0,
119
- usageLimit: typeof r.usageLimit == "number" ? r.usageLimit : null,
120
- remaining: typeof r.remaining == "number" ? r.remaining : null,
121
- hardLimit: r.hardLimit === !0,
116
+ featureType: s,
117
+ hasAccess: i.some((m) => m.hasAccess),
118
+ currentUsage: typeof t.currentUsage == "number" ? t.currentUsage : 0,
119
+ usageLimit: typeof t.usageLimit == "number" ? t.usageLimit : null,
120
+ remaining: typeof t.remaining == "number" ? t.remaining : null,
121
+ hardLimit: t.hardLimit === !0,
122
122
  items: i
123
123
  };
124
124
  }
125
125
  return {
126
126
  featureId: n,
127
- featureType: a,
128
- hasAccess: i.some((r) => r.hasAccess),
127
+ featureType: s,
128
+ hasAccess: i.some((t) => t.hasAccess),
129
129
  currentUsage: 0,
130
130
  usageLimit: null,
131
131
  remaining: null,
@@ -133,28 +133,28 @@ function me(n, i) {
133
133
  items: i
134
134
  };
135
135
  }
136
- function ge(n) {
136
+ function pe(n) {
137
137
  const i = {};
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
142
  ), i;
143
- const a = {};
144
- for (const r of n.entitlements) {
145
- if (!r || typeof r.featureId != "string" || typeof r.featureType != "string") {
143
+ const s = {};
144
+ for (const t of n.entitlements) {
145
+ if (!t || typeof t.featureId != "string" || typeof t.featureType != "string") {
146
146
  console.warn(
147
147
  "Kelviq SDK: Skipping invalid raw entitlement object:",
148
- r
148
+ t
149
149
  );
150
150
  continue;
151
151
  }
152
- a[r.featureId] || (a[r.featureId] = []), a[r.featureId].push(r);
152
+ s[t.featureId] || (s[t.featureId] = []), s[t.featureId].push(t);
153
153
  }
154
- for (const r in a)
155
- i[r] = me(
156
- r,
157
- a[r]
154
+ for (const t in s)
155
+ i[t] = ge(
156
+ t,
157
+ s[t]
158
158
  );
159
159
  return i;
160
160
  }
@@ -207,428 +207,432 @@ const re = {
207
207
  environment: "production",
208
208
  entitlementsPath: "",
209
209
  customerId: ""
210
- }, te = oe(
210
+ }, te = se(
211
211
  re
212
- ), pe = "https://edge.api.kelviq.com/api/v1/", he = "https://edge.sandboxapi.kelviq.com/api/v1/", Ee = "https://api.kelviq.com/api/v1/", Le = "https://sandboxapi.kelviq.com/api/v1/", ve = "entitlements/", Ae = "monetization/product-offering/", qe = ({
212
+ ), he = "https://edge.api.kelviq.com/api/v1/", Ee = "https://edge.sandboxapi.kelviq.com/api/v1/", Le = "https://api.kelviq.com/api/v1/", ve = "https://sandboxapi.kelviq.com/api/v1/", ye = "entitlements/", Ae = "monetization/product-offering/", Se = ({
213
213
  children: n,
214
214
  apiUrl: i,
215
- entitlementsPath: a = ve,
216
- customerId: r,
217
- environment: f = "production",
218
- accessToken: l,
219
- productId: c,
220
- config: E = {}
215
+ entitlementsPath: s = ye,
216
+ customerId: t,
217
+ environment: m = "production",
218
+ accessToken: u,
219
+ productId: d,
220
+ plansEnabled: E,
221
+ config: o = {}
221
222
  }) => {
222
223
  const {
223
- onError: o,
224
- maxRetries: s,
225
- timeout: p,
226
- backoffBaseDelay: q,
227
- fetchEntitlementsOnMount: U = !0,
228
- fetchSubscriptionsOnMount: b = !1,
229
- fetchCustomerOnMount: v = !1,
230
- fetchPricingOnMount: S = !1
231
- } = E, A = i || (f === "sandbox" ? he : pe), u = f === "sandbox" ? Le : Ee, [m, y] = I({
224
+ onError: a,
225
+ maxRetries: g,
226
+ timeout: q,
227
+ backoffBaseDelay: P,
228
+ fetchEntitlementsOnMount: b = !0,
229
+ fetchSubscriptionsOnMount: v = !1,
230
+ fetchCustomerOnMount: S = !1,
231
+ fetchPricingOnMount: $ = !1
232
+ } = o, l = i || (m === "sandbox" ? Ee : he), p = m === "sandbox" ? ve : Le, [y, A] = I({
232
233
  data: null,
233
- isLoading: !!A && U,
234
+ isLoading: !!l && b,
234
235
  error: null
235
- }), [P, _] = I(null), [k, T] = I({
236
+ }), [K, ie] = I(null), [k, M] = I({
236
237
  data: null,
237
- isLoading: !!A && b,
238
+ isLoading: !!l && v,
238
239
  error: null
239
- }), [X, M] = I({
240
+ }), [X, D] = I({
240
241
  data: null,
241
- isLoading: !!A && v,
242
+ isLoading: !!l && S,
242
243
  error: null
243
- }), [z, D] = I({
244
+ }), [z, _] = I({
244
245
  data: null,
245
- isLoading: !!A && S,
246
+ isLoading: !!l && $,
246
247
  error: null
247
- }), [F, $] = I(
248
- !!A && U
249
- ), [W, j] = I(null), h = K(
250
- (d, e, t) => {
251
- const g = new Error(
252
- `Kelviq SDK (${e}): ${d}`
248
+ }), [F, T] = I(
249
+ !!l && b
250
+ ), [W, j] = I(null), h = R(
251
+ (f, e, r) => {
252
+ const c = new Error(
253
+ `Kelviq SDK (${e}): ${f}`
253
254
  );
254
- console.error(g.message, t || ""), j((R) => R || g), o && o(g);
255
+ console.error(c.message, r || ""), j((U) => U || c), a && a(c);
255
256
  },
256
- [o]
257
- ), O = K(() => {
258
- if (!A) {
259
- const t = "API URL not configured. Cannot fetch entitlements.";
260
- return y({
257
+ [a]
258
+ ), O = R(() => {
259
+ if (!l) {
260
+ const r = "API URL not configured. Cannot fetch entitlements.";
261
+ return A({
261
262
  data: null,
262
263
  isLoading: !1,
263
- error: new Error(t)
264
- }), h(t, "fetchAllEntitlements"), $(!1), Promise.reject(new Error(t));
264
+ error: new Error(r)
265
+ }), h(r, "fetchAllEntitlements"), T(!1), Promise.reject(new Error(r));
265
266
  }
266
- if (!r) {
267
- const t = "CustomerId must be provided as props to KelviqProvider.";
268
- return y(() => ({
267
+ if (!t) {
268
+ const r = "CustomerId must be provided as props to KelviqProvider.";
269
+ return A(() => ({
269
270
  data: null,
270
271
  isLoading: !1,
271
- error: new Error(t)
272
- })), h(t, "fetchAllEntitlements"), $(!1), Promise.reject(new Error(t));
272
+ error: new Error(r)
273
+ })), h(r, "fetchAllEntitlements"), T(!1), Promise.reject(new Error(r));
273
274
  }
274
- y((t) => ({
275
- ...t,
275
+ A((r) => ({
276
+ ...r,
276
277
  isLoading: !0,
277
278
  error: null
278
- })), $(!0), j(null);
279
- const d = `${A.replace(/\/$/, "")}/${a.replace(/^\//, "")}`;
279
+ })), T(!0), j(null);
280
+ const f = `${l.replace(/\/$/, "")}/${s.replace(/^\//, "")}`;
280
281
  return x({
281
- url: d,
282
+ url: f,
282
283
  method: "GET",
283
- timeout: p,
284
- maxRetries: s,
285
- backoffBaseDelay: q,
286
- accessToken: l,
284
+ timeout: q,
285
+ maxRetries: g,
286
+ backoffBaseDelay: P,
287
+ accessToken: u,
287
288
  queryParams: {
288
- customer_id: r
289
+ customer_id: t
289
290
  }
290
- }).then((t) => {
291
- if (t && t.data && Array.isArray(t.data.entitlements)) {
292
- _(t.data);
293
- const g = ge(
294
- t.data
291
+ }).then((r) => {
292
+ if (r && r.data && Array.isArray(r.data.entitlements)) {
293
+ ie(r.data);
294
+ const c = pe(
295
+ r.data
295
296
  );
296
- y({
297
- data: g,
297
+ A({
298
+ data: c,
298
299
  isLoading: !1,
299
300
  error: null
300
301
  });
301
302
  } else {
302
- const g = new Error(
303
+ const c = new Error(
303
304
  "Received empty, malformed, or invalid data structure from entitlements API."
304
305
  );
305
- throw y({
306
+ throw A({
306
307
  data: null,
307
308
  isLoading: !1,
308
- error: g
309
+ error: c
309
310
  }), h(
310
- g.message,
311
+ c.message,
311
312
  "fetchAllEntitlements",
312
- t
313
- ), g;
313
+ r
314
+ ), c;
314
315
  }
315
- }).catch((t) => {
316
- const g = t instanceof Error ? t : new Error(String(t));
317
- return y((R) => ({
318
- ...R,
316
+ }).catch((r) => {
317
+ const c = r instanceof Error ? r : new Error(String(r));
318
+ return A((U) => ({
319
+ ...U,
319
320
  isLoading: !1,
320
- error: g
321
- })), h(g.message, "fetchAllEntitlements", t), Promise.reject(g);
321
+ error: c
322
+ })), h(c.message, "fetchAllEntitlements", r), Promise.reject(c);
322
323
  }).finally(() => {
323
- $(!1);
324
+ T(!1);
324
325
  });
325
326
  }, [
326
- A,
327
- r,
328
- a,
329
- p,
327
+ l,
328
+ t,
330
329
  s,
331
330
  q,
332
- l,
331
+ g,
332
+ P,
333
+ u,
333
334
  h
334
- ]), B = K(() => {
335
- if (!u) {
335
+ ]), B = R(() => {
336
+ if (!p) {
336
337
  const e = "Main API URL not configured. Cannot fetch subscriptions.";
337
- return T({
338
+ return M({
338
339
  data: null,
339
340
  isLoading: !1,
340
341
  error: new Error(e)
341
342
  }), h(e, "fetchSubscriptions"), Promise.reject(new Error(e));
342
343
  }
343
- if (!r) {
344
+ if (!t) {
344
345
  const e = "CustomerId must be provided as props to KelviqProvider.";
345
- return T({
346
+ return M({
346
347
  data: null,
347
348
  isLoading: !1,
348
349
  error: new Error(e)
349
350
  }), h(e, "fetchSubscriptions"), Promise.reject(new Error(e));
350
351
  }
351
- T((e) => ({
352
+ M((e) => ({
352
353
  ...e,
353
354
  isLoading: !0,
354
355
  error: null
355
356
  }));
356
- const d = `${u.replace(/\/$/, "")}/subscriptions/`;
357
+ const f = `${p.replace(/\/$/, "")}/subscriptions/`;
357
358
  return x({
358
- url: d,
359
+ url: f,
359
360
  method: "GET",
360
- timeout: p,
361
- maxRetries: s,
362
- backoffBaseDelay: q,
363
- accessToken: l,
364
- queryParams: { customer_id: r }
361
+ timeout: q,
362
+ maxRetries: g,
363
+ backoffBaseDelay: P,
364
+ accessToken: u,
365
+ queryParams: { customer_id: t }
365
366
  }).then((e) => {
366
367
  if (e && e.data && Array.isArray(e.data.results))
367
- T({
368
+ M({
368
369
  data: e.data.results,
369
370
  isLoading: !1,
370
371
  error: null
371
372
  });
372
373
  else {
373
- const t = new Error(
374
+ const r = new Error(
374
375
  "Received empty, malformed, or invalid data structure from subscriptions API."
375
376
  );
376
- throw T({
377
+ throw M({
377
378
  data: null,
378
379
  isLoading: !1,
379
- error: t
380
+ error: r
380
381
  }), h(
381
- t.message,
382
+ r.message,
382
383
  "fetchSubscriptions",
383
384
  e
384
- ), t;
385
+ ), r;
385
386
  }
386
387
  }).catch((e) => {
387
- const t = e instanceof Error ? e : new Error(String(e));
388
- return T((g) => ({
389
- ...g,
388
+ const r = e instanceof Error ? e : new Error(String(e));
389
+ return M((c) => ({
390
+ ...c,
390
391
  isLoading: !1,
391
- error: t
392
+ error: r
392
393
  })), h(
393
- t.message,
394
+ r.message,
394
395
  "fetchSubscriptions",
395
396
  e
396
- ), Promise.reject(t);
397
+ ), Promise.reject(r);
397
398
  });
398
399
  }, [
399
- u,
400
- r,
401
400
  p,
402
- s,
401
+ t,
403
402
  q,
404
- l,
403
+ g,
404
+ P,
405
+ u,
405
406
  h
406
- ]), N = K(() => {
407
- if (!u) {
407
+ ]), N = R(() => {
408
+ if (!p) {
408
409
  const e = "Main API URL not configured. Cannot fetch customer.";
409
- return M({
410
+ return D({
410
411
  data: null,
411
412
  isLoading: !1,
412
413
  error: new Error(e)
413
414
  }), h(e, "fetchCustomer"), Promise.reject(new Error(e));
414
415
  }
415
- if (!r) {
416
+ if (!t) {
416
417
  const e = "CustomerId must be provided as props to KelviqProvider.";
417
- return M({
418
+ return D({
418
419
  data: null,
419
420
  isLoading: !1,
420
421
  error: new Error(e)
421
422
  }), h(e, "fetchCustomer"), Promise.reject(new Error(e));
422
423
  }
423
- M((e) => ({
424
+ D((e) => ({
424
425
  ...e,
425
426
  isLoading: !0,
426
427
  error: null
427
428
  }));
428
- const d = `${u.replace(/\/$/, "")}/customers/${r}/`;
429
+ const f = `${p.replace(/\/$/, "")}/customers/${t}/`;
429
430
  return x({
430
- url: d,
431
+ url: f,
431
432
  method: "GET",
432
- timeout: p,
433
- maxRetries: s,
434
- backoffBaseDelay: q,
435
- accessToken: l
433
+ timeout: q,
434
+ maxRetries: g,
435
+ backoffBaseDelay: P,
436
+ accessToken: u
436
437
  }).then((e) => {
437
438
  if (e && e.data)
438
- M({
439
+ D({
439
440
  data: e.data,
440
441
  isLoading: !1,
441
442
  error: null
442
443
  });
443
444
  else {
444
- const t = new Error(
445
+ const r = new Error(
445
446
  "Received empty or invalid data from customer API."
446
447
  );
447
- throw M({
448
+ throw D({
448
449
  data: null,
449
450
  isLoading: !1,
450
- error: t
451
+ error: r
451
452
  }), h(
452
- t.message,
453
+ r.message,
453
454
  "fetchCustomer",
454
455
  e
455
- ), t;
456
+ ), r;
456
457
  }
457
458
  }).catch((e) => {
458
- const t = e instanceof Error ? e : new Error(String(e));
459
- return M((g) => ({
460
- ...g,
459
+ const r = e instanceof Error ? e : new Error(String(e));
460
+ return D((c) => ({
461
+ ...c,
461
462
  isLoading: !1,
462
- error: t
463
- })), h(t.message, "fetchCustomer", e), Promise.reject(t);
463
+ error: r
464
+ })), h(r.message, "fetchCustomer", e), Promise.reject(r);
464
465
  });
465
466
  }, [
466
- u,
467
- r,
468
467
  p,
469
- s,
468
+ t,
470
469
  q,
471
- l,
470
+ g,
471
+ P,
472
+ u,
472
473
  h
473
- ]), G = K(() => {
474
- if (!u) {
475
- const e = "Main API URL not configured. Cannot fetch pricing.";
476
- return D({
474
+ ]), G = R(() => {
475
+ if (!p) {
476
+ const r = "Main API URL not configured. Cannot fetch pricing.";
477
+ return _({
477
478
  data: null,
478
479
  isLoading: !1,
479
- error: new Error(e)
480
- }), h(e, "fetchPricing"), Promise.reject(new Error(e));
480
+ error: new Error(r)
481
+ }), h(r, "fetchPricing"), Promise.reject(new Error(r));
481
482
  }
482
- if (!c) {
483
- const e = "productId must be provided as a prop to KelviqProvider to fetch pricing.";
484
- return D({
483
+ if (!d) {
484
+ const r = "productId must be provided as a prop to KelviqProvider to fetch pricing.";
485
+ return _({
485
486
  data: null,
486
487
  isLoading: !1,
487
- error: new Error(e)
488
- }), h(e, "fetchPricing"), Promise.reject(new Error(e));
488
+ error: new Error(r)
489
+ }), h(r, "fetchPricing"), Promise.reject(new Error(r));
489
490
  }
490
- D((e) => ({
491
- ...e,
491
+ _((r) => ({
492
+ ...r,
492
493
  isLoading: !0,
493
494
  error: null
494
495
  }));
495
- const d = `${u.replace(/\/$/, "")}/${Ae.replace(/^\//, "")}${c}/`;
496
- return x({
497
- url: d,
496
+ const f = `${p.replace(/\/$/, "")}/${Ae.replace(/^\//, "")}${d}/`, e = {};
497
+ return t && (e.customer_id = t), E && (e.plans_enabled = E), x({
498
+ url: f,
498
499
  method: "GET",
499
- timeout: p,
500
- maxRetries: s,
501
- backoffBaseDelay: q,
502
- accessToken: l
503
- }).then((e) => {
504
- if (e && e.data && Array.isArray(e.data.plans))
505
- D({
506
- data: e.data,
500
+ timeout: q,
501
+ maxRetries: g,
502
+ backoffBaseDelay: P,
503
+ accessToken: u,
504
+ queryParams: e
505
+ }).then((r) => {
506
+ if (r && r.data && Array.isArray(r.data.plans))
507
+ _({
508
+ data: r.data,
507
509
  isLoading: !1,
508
510
  error: null
509
511
  });
510
512
  else {
511
- const t = new Error(
513
+ const c = new Error(
512
514
  "Received empty, malformed, or invalid data structure from pricing API."
513
515
  );
514
- throw D({
516
+ throw _({
515
517
  data: null,
516
518
  isLoading: !1,
517
- error: t
519
+ error: c
518
520
  }), h(
519
- t.message,
521
+ c.message,
520
522
  "fetchPricing",
521
- e
522
- ), t;
523
+ r
524
+ ), c;
523
525
  }
524
- }).catch((e) => {
525
- const t = e instanceof Error ? e : new Error(String(e));
526
- return D((g) => ({
527
- ...g,
526
+ }).catch((r) => {
527
+ const c = r instanceof Error ? r : new Error(String(r));
528
+ return _((U) => ({
529
+ ...U,
528
530
  isLoading: !1,
529
- error: t
530
- })), h(t.message, "fetchPricing", e), Promise.reject(t);
531
+ error: c
532
+ })), h(c.message, "fetchPricing", r), Promise.reject(c);
531
533
  });
532
534
  }, [
533
- u,
534
- c,
535
535
  p,
536
- s,
536
+ d,
537
+ t,
538
+ E,
537
539
  q,
538
- l,
540
+ g,
541
+ P,
542
+ u,
539
543
  h
540
544
  ]);
541
- se(() => {
542
- let d = !0;
543
- if (!A) {
544
- if (d) {
545
+ ae(() => {
546
+ let f = !0;
547
+ if (!l) {
548
+ if (f) {
545
549
  const e = new Error(
546
550
  "KelviqProvider: `apiBaseUrl` must be provided in config."
547
551
  );
548
- j(e), $(!1), y((t) => ({
549
- ...t,
552
+ j(e), T(!1), A((r) => ({
553
+ ...r,
550
554
  isLoading: !1,
551
555
  error: e
552
- })), E.onError && E.onError(e);
556
+ })), o.onError && o.onError(e);
553
557
  }
554
558
  return;
555
559
  }
556
- return U ? O().catch((e) => {
557
- d && F && $(!1), console.error(
560
+ return b ? O().catch((e) => {
561
+ f && F && T(!1), console.error(
558
562
  "Kelviq SDK: Initial entitlement fetch failed.",
559
563
  e
560
564
  );
561
- }) : d && (y((e) => ({
565
+ }) : f && (A((e) => ({
562
566
  ...e,
563
567
  isLoading: !1,
564
568
  data: null,
565
569
  error: null
566
- })), $(!1)), b && B().catch((e) => {
570
+ })), T(!1)), v && B().catch((e) => {
567
571
  console.error(
568
572
  "Kelviq SDK: Initial subscriptions fetch failed.",
569
573
  e
570
574
  );
571
- }), v && N().catch((e) => {
575
+ }), S && N().catch((e) => {
572
576
  console.error(
573
577
  "Kelviq SDK: Initial customer fetch failed.",
574
578
  e
575
579
  );
576
- }), S && G().catch((e) => {
580
+ }), $ && G().catch((e) => {
577
581
  console.error(
578
582
  "Kelviq SDK: Initial pricing fetch failed.",
579
583
  e
580
584
  );
581
585
  }), () => {
582
- d = !1;
586
+ f = !1;
583
587
  };
584
- }, [A, U, b, v, S]);
585
- const J = K(
586
- () => m.data ? m.data : {},
587
- [m.data]
588
- ), Q = K(
589
- () => P ? {
590
- customerId: P.customerId,
591
- entitlements: P.entitlements
588
+ }, [l, b, v, S, $]);
589
+ const J = R(
590
+ () => y.data ? y.data : {},
591
+ [y.data]
592
+ ), Q = R(
593
+ () => K ? {
594
+ customerId: K.customerId,
595
+ entitlements: K.entitlements
592
596
  } : null,
593
- [P]
594
- ), V = K(
595
- (d) => P ? {
596
- customerId: P.customerId,
597
- entitlements: P.entitlements.filter(
598
- (e) => e.featureId === d
597
+ [K]
598
+ ), V = R(
599
+ (f) => K ? {
600
+ customerId: K.customerId,
601
+ entitlements: K.entitlements.filter(
602
+ (e) => e.featureId === f
599
603
  )
600
604
  } : null,
601
- [P]
602
- ), Y = K(
603
- (d) => m.data ? m.data[d] ?? null : null,
604
- [m.data]
605
- ), Z = K(
606
- (d, e) => {
607
- y((t) => {
608
- if (!t.data) return t;
609
- const g = t.data[d];
610
- if (!g) return t;
611
- const R = { ...g, ...e };
612
- return ("usageLimit" in e || "currentUsage" in e) && (R.remaining = R.usageLimit !== null ? R.usageLimit - R.currentUsage : null), {
613
- ...t,
605
+ [K]
606
+ ), Y = R(
607
+ (f) => y.data ? y.data[f] ?? null : null,
608
+ [y.data]
609
+ ), Z = R(
610
+ (f, e) => {
611
+ A((r) => {
612
+ if (!r.data) return r;
613
+ const c = r.data[f];
614
+ if (!c) return r;
615
+ const U = { ...c, ...e };
616
+ return ("usageLimit" in e || "currentUsage" in e) && (U.remaining = U.usageLimit !== null ? U.usageLimit - U.currentUsage : null), {
617
+ ...r,
614
618
  data: {
615
- ...t.data,
616
- [d]: R
619
+ ...r.data,
620
+ [f]: U
617
621
  }
618
622
  };
619
623
  });
620
624
  },
621
625
  []
622
- ), ee = K(
623
- (d) => {
624
- if (!m.data) return !1;
625
- const e = m.data[d];
626
+ ), ee = R(
627
+ (f) => {
628
+ if (!y.data) return !1;
629
+ const e = y.data[f];
626
630
  return e ? e.hasAccess : !1;
627
631
  },
628
- [m.data]
629
- ), ie = ae(
632
+ [y.data]
633
+ ), oe = le(
630
634
  () => ({
631
- allEntitlements: m,
635
+ allEntitlements: y,
632
636
  refreshAllEntitlements: O,
633
637
  getEntitlements: J,
634
638
  getEntitlement: Y,
@@ -644,13 +648,13 @@ const re = {
644
648
  refreshPricing: G,
645
649
  isLoading: F,
646
650
  error: W,
647
- environment: f,
648
- apiUrl: A,
649
- entitlementsPath: a,
650
- customerId: r
651
+ environment: m,
652
+ apiUrl: l,
653
+ entitlementsPath: s,
654
+ customerId: t
651
655
  }),
652
656
  [
653
- m,
657
+ y,
654
658
  O,
655
659
  J,
656
660
  Y,
@@ -666,15 +670,15 @@ const re = {
666
670
  G,
667
671
  F,
668
672
  W,
669
- f,
670
- A,
671
- a,
672
- r
673
+ m,
674
+ l,
675
+ s,
676
+ t
673
677
  ]
674
678
  );
675
- return /* @__PURE__ */ L(te.Provider, { value: ie, children: n });
679
+ return /* @__PURE__ */ L(te.Provider, { value: oe, children: n });
676
680
  }, C = () => {
677
- const n = le(te);
681
+ const n = ce(te);
678
682
  if (n === void 0 || n === re)
679
683
  throw new Error(
680
684
  "useKelviq must be used within an initialized KelviqProvider."
@@ -683,18 +687,18 @@ const re = {
683
687
  }, H = ({
684
688
  featureId: n,
685
689
  children: i,
686
- fallback: a = null,
687
- loadingComponent: r,
688
- condition: f
690
+ fallback: s = null,
691
+ loadingComponent: t,
692
+ condition: m
689
693
  }) => {
690
694
  const {
691
- getEntitlement: l,
692
- isLoading: c,
695
+ getEntitlement: u,
696
+ isLoading: d,
693
697
  error: E
694
- } = C(), o = l(n);
695
- return c && !o ? /* @__PURE__ */ L(w, { children: r !== void 0 ? r : a }) : E && !o ? /* @__PURE__ */ L(w, { children: a }) : !o || !o.hasAccess || f && !f(o) ? /* @__PURE__ */ L(w, { children: a }) : typeof i == "function" ? /* @__PURE__ */ L(w, { children: i(o) }) : /* @__PURE__ */ L(w, { children: i });
696
- }, Se = (n) => /* @__PURE__ */ L(H, { ...n }), be = (n) => {
697
- const i = (a) => a.hasAccess && (a.remaining === null || a.remaining > 0);
698
+ } = C(), o = u(n);
699
+ return d && !o ? /* @__PURE__ */ L(w, { children: t !== void 0 ? t : s }) : E && !o ? /* @__PURE__ */ L(w, { children: s }) : !o || !o.hasAccess || m && !m(o) ? /* @__PURE__ */ L(w, { children: s }) : typeof i == "function" ? /* @__PURE__ */ L(w, { children: i(o) }) : /* @__PURE__ */ L(w, { children: i });
700
+ }, be = (n) => /* @__PURE__ */ L(H, { ...n }), Ke = (n) => {
701
+ const i = (s) => s.hasAccess && (s.remaining === null || s.remaining > 0);
698
702
  return /* @__PURE__ */ L(
699
703
  H,
700
704
  {
@@ -702,119 +706,119 @@ const re = {
702
706
  condition: n.condition || i
703
707
  }
704
708
  );
705
- }, Ke = (n) => /* @__PURE__ */ L(H, { ...n }), Ue = () => {
709
+ }, Ue = (n) => /* @__PURE__ */ L(H, { ...n }), Re = () => {
706
710
  const { allEntitlements: n } = C();
707
711
  return n;
708
- }, Re = (n) => {
709
- const { getEntitlement: i } = C();
710
- return i(n);
711
712
  }, Ce = (n) => {
712
713
  const { getEntitlement: i } = C();
713
714
  return i(n);
714
715
  }, $e = (n) => {
715
716
  const { getEntitlement: i } = C();
716
717
  return i(n);
718
+ }, Te = (n) => {
719
+ const { getEntitlement: i } = C();
720
+ return i(n);
717
721
  }, Ie = () => {
718
722
  const { subscriptions: n } = C();
719
723
  return n;
720
- }, Te = () => {
724
+ }, Me = () => {
721
725
  const { customer: n } = C();
722
726
  return n;
723
727
  }, ne = () => {
724
728
  const { pricing: n } = C();
725
729
  return n;
726
- }, ye = (n, i, a = {}) => {
730
+ }, Pe = (n, i, s = {}) => {
727
731
  if (typeof n != "number")
728
732
  return "";
729
733
  const {
730
- compact: r = !1,
731
- locale: f = a.pricingLocale || "en-US",
732
- includeCurrencySymbol: l = !0
733
- } = a;
734
+ compact: t = !1,
735
+ locale: m = s.pricingLocale || "en-US",
736
+ includeCurrencySymbol: u = !0
737
+ } = s;
734
738
  try {
735
- const c = {
736
- notation: r ? "compact" : "standard",
739
+ const d = {
740
+ notation: t ? "compact" : "standard",
737
741
  compactDisplay: "short"
738
- }, o = new Intl.NumberFormat(f, c).format(n);
739
- return l ? `${i}${o}` : o;
742
+ }, o = new Intl.NumberFormat(m, d).format(n);
743
+ return u ? `${i}${o}` : o;
740
744
  } catch {
741
- const c = n.toString();
742
- return l ? `${i}${c}` : c;
745
+ const d = n.toString();
746
+ return u ? `${i}${d}` : d;
743
747
  }
744
- }, Me = ({
748
+ }, De = ({
745
749
  planIdentifier: n,
746
750
  billingPeriod: i,
747
- children: a,
748
- formatOptions: r,
749
- loadingComponent: f = null,
750
- fallback: l = null
751
+ children: s,
752
+ formatOptions: t,
753
+ loadingComponent: m = null,
754
+ fallback: u = null
751
755
  }) => {
752
- const { data: c, isLoading: E } = ne();
756
+ const { data: d, isLoading: E } = ne();
753
757
  if (E)
754
- return /* @__PURE__ */ L(w, { children: f });
755
- if (!c || !Array.isArray(c.plans))
756
- return /* @__PURE__ */ L(w, { children: l });
757
- const o = c.plans.find(
758
+ return /* @__PURE__ */ L(w, { children: m });
759
+ if (!d || !Array.isArray(d.plans))
760
+ return /* @__PURE__ */ L(w, { children: u });
761
+ const o = d.plans.find(
758
762
  (b) => b.identifier === n && b.enabled
759
763
  );
760
764
  if (!o)
761
- return /* @__PURE__ */ L(w, { children: l });
762
- const s = o.price.charges.find(
765
+ return /* @__PURE__ */ L(w, { children: u });
766
+ const a = o.price.charges.find(
763
767
  (b) => b.chargePeriod === i
764
- ) ?? null, p = s ? s.priceData.amount : 0, q = o.price.priceType === "FREE", U = q ? "Free" : ye(p, c.currencySymbol, {
765
- ...r,
766
- pricingLocale: c.pricingLocale
768
+ ) ?? null, g = a ? a.priceData.amount : 0, q = o.price.priceType === "FREE", P = q ? "Free" : Pe(g, d.currencySymbol, {
769
+ ...t,
770
+ pricingLocale: d.pricingLocale
767
771
  });
768
- return /* @__PURE__ */ L(w, { children: a({
772
+ return /* @__PURE__ */ L(w, { children: s({
769
773
  plan: o,
770
- charge: s,
771
- amount: p,
772
- formattedPrice: U,
773
- currencySymbol: c.currencySymbol,
774
- currencyCode: c.currencyCode,
775
- pricingLocale: c.pricingLocale,
774
+ charge: a,
775
+ amount: g,
776
+ formattedPrice: P,
777
+ currencySymbol: d.currencySymbol,
778
+ currencyCode: d.currencyCode,
779
+ pricingLocale: d.pricingLocale,
776
780
  isFree: q,
777
781
  hasFreeTrial: o.price.freeTrial,
778
782
  trialPeriod: o.price.trialPeriod
779
783
  }) });
780
- }, De = ({
784
+ }, _e = ({
781
785
  planIdentifier: n,
782
786
  children: i,
783
- loadingComponent: a = null,
784
- fallback: r = null,
785
- featureType: f
787
+ loadingComponent: s = null,
788
+ fallback: t = null,
789
+ featureType: m
786
790
  }) => {
787
- const { data: l, isLoading: c } = ne();
788
- if (c)
789
- return /* @__PURE__ */ L(w, { children: a });
790
- if (!l || !Array.isArray(l.plans))
791
- return /* @__PURE__ */ L(w, { children: r });
792
- const E = l.plans.find(
793
- (s) => s.identifier === n && s.enabled
791
+ const { data: u, isLoading: d } = ne();
792
+ if (d)
793
+ return /* @__PURE__ */ L(w, { children: s });
794
+ if (!u || !Array.isArray(u.plans))
795
+ return /* @__PURE__ */ L(w, { children: t });
796
+ const E = u.plans.find(
797
+ (a) => a.identifier === n && a.enabled
794
798
  );
795
799
  if (!E)
796
- return /* @__PURE__ */ L(w, { children: r });
797
- let o = E.features.filter((s) => s.enabled);
798
- return f && (o = o.filter((s) => s.featureType === f)), o.length === 0 ? /* @__PURE__ */ L(w, { children: r }) : /* @__PURE__ */ L(w, { children: o.map(
799
- (s, p) => i({ feature: s, plan: E, index: p })
800
+ return /* @__PURE__ */ L(w, { children: t });
801
+ let o = E.features.filter((a) => a.enabled);
802
+ return m && (o = o.filter((a) => a.featureType === m)), o.length === 0 ? /* @__PURE__ */ L(w, { children: t }) : /* @__PURE__ */ L(w, { children: o.map(
803
+ (a, g) => i({ feature: a, plan: E, index: g })
800
804
  ) });
801
805
  };
802
806
  export {
803
- De as KQFeatureList,
804
- Me as KQPrice,
807
+ _e as KQFeatureList,
808
+ De as KQPrice,
805
809
  te as KelviqContext,
806
- qe as KelviqProvider,
807
- Ke as ShowWhenBooleanEntitled,
808
- Se as ShowWhenCustomizableEntitled,
809
- be as ShowWhenMeteredEntitled,
810
+ Se as KelviqProvider,
811
+ Ue as ShowWhenBooleanEntitled,
812
+ be as ShowWhenCustomizableEntitled,
813
+ Ke as ShowWhenMeteredEntitled,
810
814
  re as defaultKelviqContextValue,
811
- ye as kqFormatPrice,
812
- Ue as useAllEntitlements,
813
- Re as useBooleanEntitlement,
814
- Te as useCustomer,
815
- Ce as useCustomizableEntitlement,
815
+ Pe as kqFormatPrice,
816
+ Re as useAllEntitlements,
817
+ Ce as useBooleanEntitlement,
818
+ Me as useCustomer,
819
+ $e as useCustomizableEntitlement,
816
820
  C as useKelviq,
817
- $e as useMeteredEntitlement,
821
+ Te as useMeteredEntitlement,
818
822
  ne as usePricing,
819
823
  Ie as useSubscriptions
820
824
  };
@@ -1 +1 @@
1
- (function(f,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],i):(f=typeof globalThis<"u"?globalThis:f||self,i(f.KelviqReactSDK={},f.jsxRuntime,f.React))})(this,function(f,i,g){"use strict";const ie="GET";function D(n){const{method:o=ie,headers:l={},body:r,timeout:E=5e3,maxRetries:c=3,backoffBaseDelay:u=1e3,queryParams:A,accessToken:s}=n;let{url:a}=n,L=0;return new Promise((q,K)=>{if(A){const y=new URLSearchParams;for(const b in A)A[b]!==void 0&&y.append(b,String(A[b]));y.toString()&&(a+=(a.includes("?")?"&":"?")+y.toString())}function C(){const y=new XMLHttpRequest;y.open(o,a,!0),y.timeout=E;const b={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...l};o!=="GET"&&r&&typeof r=="object"&&!(r instanceof FormData)&&(b["Content-Type"]||(b["Content-Type"]="application/json")),s&&(b.Authorization=`Bearer ${s}`);for(const[d,h]of Object.entries(b))y.setRequestHeader(d,h);y.onload=function(){const{status:d,statusText:h,responseText:w}=y;if(d>=200&&d<300)try{const S=w?JSON.parse(w):{};q({status:d,statusText:h,data:S})}catch(S){const _=S instanceof Error?S:new Error(String(S));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${a}. Error: ${_.message}. Response: ${w}`),K(new Error(`Invalid JSON response: ${_.message}`))}else P(`Request to ${a} failed with status ${d} ${h}. Response: ${w}`)},y.onerror=()=>P(`Network error for URL ${a}. The request could not be completed.`),y.ontimeout=()=>P(`Request to ${a} timed out.`);function P(d){if(L<c){L++;const h=Math.min(u*Math.pow(2,L-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${a}. Attempt ${L}/${c}. Error: ${d}. Retrying in ${h}ms.`),setTimeout(C,h)}else K(new Error(`${d} (Max retries ${c} reached)`))}try{let d=r;r&&typeof r=="object"&&!(r instanceof FormData)&&b["Content-Type"]==="application/json"&&(d=JSON.stringify(r)),y.send(d)}catch(d){const h=d instanceof Error?d:new Error(String(d));console.error(`Kelviq SDK (apiRequest): Error sending request to ${a}.`,h),K(new Error(`Failed to send request: ${h.message}`))}}C()})}function oe(n,o){const l=o[0].featureType;if(l==="METER"){let r=0,E=0,c=!1;for(const A of o){const s=A,a=typeof s.usageLimit=="number"?s.usageLimit:null,L=typeof s.currentUsage=="number"?s.currentUsage:0;a===null&&(r=null),r!==null&&(r+=a),E+=L,s.hardLimit&&(c=!0)}const u=r!==null?r-E:null;return{featureId:n,featureType:l,hasAccess:u===null||u>0,currentUsage:E,usageLimit:r,remaining:u,hardLimit:c,items:o}}if(l==="CUSTOMIZABLE"){const r=o[0];return{featureId:n,featureType:l,hasAccess:o.some(E=>E.hasAccess),currentUsage:typeof r.currentUsage=="number"?r.currentUsage:0,usageLimit:typeof r.usageLimit=="number"?r.usageLimit:null,remaining:typeof r.remaining=="number"?r.remaining:null,hardLimit:r.hardLimit===!0,items:o}}return{featureId:n,featureType:l,hasAccess:o.some(r=>r.hasAccess),currentUsage:0,usageLimit:null,remaining:null,hardLimit:!1,items:o}}function se(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 l={};for(const r of n.entitlements){if(!r||typeof r.featureId!="string"||typeof r.featureType!="string"){console.warn("Kelviq SDK: Skipping invalid raw entitlement object:",r);continue}l[r.featureId]||(l[r.featureId]=[]),l[r.featureId].push(r)}for(const r in l)o[r]=oe(r,l[r]);return o}const O={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()),pricing:{data:null,isLoading:!1,error:null},refreshPricing:()=>(console.warn("refreshPricing called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),isLoading:!0,error:null,apiUrl:"",environment:"production",entitlementsPath:"",customerId:""},k=g.createContext(O),ae="https://edge.api.kelviq.com/api/v1/",le="https://edge.sandboxapi.kelviq.com/api/v1/",ce="https://api.kelviq.com/api/v1/",ue="https://sandboxapi.kelviq.com/api/v1/",de="entitlements/",fe="monetization/product-offering/",me=({children:n,apiUrl:o,entitlementsPath:l=de,customerId:r,environment:E="production",accessToken:c,productId:u,config:A={}})=>{const{onError:s,maxRetries:a,timeout:L,backoffBaseDelay:q,fetchEntitlementsOnMount:K=!0,fetchSubscriptionsOnMount:C=!1,fetchCustomerOnMount:y=!1,fetchPricingOnMount:b=!1}=A,P=o||(E==="sandbox"?le:ae),d=E==="sandbox"?ue:ce,[h,w]=g.useState({data:null,isLoading:!!P&&K,error:null}),[S,_]=g.useState(null),[J,I]=g.useState({data:null,isLoading:!!P&&C,error:null}),[Q,M]=g.useState({data:null,isLoading:!!P&&y,error:null}),[V,$]=g.useState({data:null,isLoading:!!P&&b,error:null}),[N,F]=g.useState(!!P&&K),[Y,j]=g.useState(null),v=g.useCallback((m,e,t)=>{const p=new Error(`Kelviq SDK (${e}): ${m}`);console.error(p.message,t||""),j(T=>T||p),s&&s(p)},[s]),G=g.useCallback(()=>{if(!P){const t="API URL not configured. Cannot fetch entitlements.";return w({data:null,isLoading:!1,error:new Error(t)}),v(t,"fetchAllEntitlements"),F(!1),Promise.reject(new Error(t))}if(!r){const t="CustomerId must be provided as props to KelviqProvider.";return w(()=>({data:null,isLoading:!1,error:new Error(t)})),v(t,"fetchAllEntitlements"),F(!1),Promise.reject(new Error(t))}w(t=>({...t,isLoading:!0,error:null})),F(!0),j(null);const m=`${P.replace(/\/$/,"")}/${l.replace(/^\//,"")}`;return D({url:m,method:"GET",timeout:L,maxRetries:a,backoffBaseDelay:q,accessToken:c,queryParams:{customer_id:r}}).then(t=>{if(t&&t.data&&Array.isArray(t.data.entitlements)){_(t.data);const p=se(t.data);w({data:p,isLoading:!1,error:null})}else{const p=new Error("Received empty, malformed, or invalid data structure from entitlements API.");throw w({data:null,isLoading:!1,error:p}),v(p.message,"fetchAllEntitlements",t),p}}).catch(t=>{const p=t instanceof Error?t:new Error(String(t));return w(T=>({...T,isLoading:!1,error:p})),v(p.message,"fetchAllEntitlements",t),Promise.reject(p)}).finally(()=>{F(!1)})},[P,r,l,L,a,q,c,v]),H=g.useCallback(()=>{if(!d){const e="Main API URL not configured. Cannot fetch subscriptions.";return I({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchSubscriptions"),Promise.reject(new Error(e))}if(!r){const e="CustomerId must be provided as props to KelviqProvider.";return I({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchSubscriptions"),Promise.reject(new Error(e))}I(e=>({...e,isLoading:!0,error:null}));const m=`${d.replace(/\/$/,"")}/subscriptions/`;return D({url:m,method:"GET",timeout:L,maxRetries:a,backoffBaseDelay:q,accessToken:c,queryParams:{customer_id:r}}).then(e=>{if(e&&e.data&&Array.isArray(e.data.results))I({data:e.data.results,isLoading:!1,error:null});else{const t=new Error("Received empty, malformed, or invalid data structure from subscriptions API.");throw I({data:null,isLoading:!1,error:t}),v(t.message,"fetchSubscriptions",e),t}}).catch(e=>{const t=e instanceof Error?e:new Error(String(e));return I(p=>({...p,isLoading:!1,error:t})),v(t.message,"fetchSubscriptions",e),Promise.reject(t)})},[d,r,L,a,q,c,v]),W=g.useCallback(()=>{if(!d){const e="Main API URL not configured. Cannot fetch customer.";return M({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchCustomer"),Promise.reject(new Error(e))}if(!r){const e="CustomerId must be provided as props to KelviqProvider.";return M({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchCustomer"),Promise.reject(new Error(e))}M(e=>({...e,isLoading:!0,error:null}));const m=`${d.replace(/\/$/,"")}/customers/${r}/`;return D({url:m,method:"GET",timeout:L,maxRetries:a,backoffBaseDelay:q,accessToken:c}).then(e=>{if(e&&e.data)M({data:e.data,isLoading:!1,error:null});else{const t=new Error("Received empty or invalid data from customer API.");throw M({data:null,isLoading:!1,error:t}),v(t.message,"fetchCustomer",e),t}}).catch(e=>{const t=e instanceof Error?e:new Error(String(e));return M(p=>({...p,isLoading:!1,error:t})),v(t.message,"fetchCustomer",e),Promise.reject(t)})},[d,r,L,a,q,c,v]),z=g.useCallback(()=>{if(!d){const e="Main API URL not configured. Cannot fetch pricing.";return $({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchPricing"),Promise.reject(new Error(e))}if(!u){const e="productId must be provided as a prop to KelviqProvider to fetch pricing.";return $({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchPricing"),Promise.reject(new Error(e))}$(e=>({...e,isLoading:!0,error:null}));const m=`${d.replace(/\/$/,"")}/${fe.replace(/^\//,"")}${u}/`;return D({url:m,method:"GET",timeout:L,maxRetries:a,backoffBaseDelay:q,accessToken:c}).then(e=>{if(e&&e.data&&Array.isArray(e.data.plans))$({data:e.data,isLoading:!1,error:null});else{const t=new Error("Received empty, malformed, or invalid data structure from pricing API.");throw $({data:null,isLoading:!1,error:t}),v(t.message,"fetchPricing",e),t}}).catch(e=>{const t=e instanceof Error?e:new Error(String(e));return $(p=>({...p,isLoading:!1,error:t})),v(t.message,"fetchPricing",e),Promise.reject(t)})},[d,u,L,a,q,c,v]);g.useEffect(()=>{let m=!0;if(!P){if(m){const e=new Error("KelviqProvider: `apiBaseUrl` must be provided in config.");j(e),F(!1),w(t=>({...t,isLoading:!1,error:e})),A.onError&&A.onError(e)}return}return K?G().catch(e=>{m&&N&&F(!1),console.error("Kelviq SDK: Initial entitlement fetch failed.",e)}):m&&(w(e=>({...e,isLoading:!1,data:null,error:null})),F(!1)),C&&H().catch(e=>{console.error("Kelviq SDK: Initial subscriptions fetch failed.",e)}),y&&W().catch(e=>{console.error("Kelviq SDK: Initial customer fetch failed.",e)}),b&&z().catch(e=>{console.error("Kelviq SDK: Initial pricing fetch failed.",e)}),()=>{m=!1}},[P,K,C,y,b]);const Z=g.useCallback(()=>h.data?h.data:{},[h.data]),x=g.useCallback(()=>S?{customerId:S.customerId,entitlements:S.entitlements}:null,[S]),ee=g.useCallback(m=>S?{customerId:S.customerId,entitlements:S.entitlements.filter(e=>e.featureId===m)}:null,[S]),re=g.useCallback(m=>h.data?h.data[m]??null:null,[h.data]),te=g.useCallback((m,e)=>{w(t=>{if(!t.data)return t;const p=t.data[m];if(!p)return t;const T={...p,...e};return("usageLimit"in e||"currentUsage"in e)&&(T.remaining=T.usageLimit!==null?T.usageLimit-T.currentUsage:null),{...t,data:{...t.data,[m]:T}}})},[]),ne=g.useCallback(m=>{if(!h.data)return!1;const e=h.data[m];return e?e.hasAccess:!1},[h.data]),qe=g.useMemo(()=>({allEntitlements:h,refreshAllEntitlements:G,getEntitlements:Z,getEntitlement:re,getRawEntitlements:x,getRawEntitlement:ee,hasAccess:ne,updateEntitlement:te,subscriptions:J,refreshSubscriptions:H,customer:Q,refreshCustomer:W,pricing:V,refreshPricing:z,isLoading:N,error:Y,environment:E,apiUrl:P,entitlementsPath:l,customerId:r}),[h,G,Z,re,x,ee,ne,te,J,H,Q,W,V,z,N,Y,E,P,l,r]);return i.jsx(k.Provider,{value:qe,children:n})},U=()=>{const n=g.useContext(k);if(n===void 0||n===O)throw new Error("useKelviq must be used within an initialized KelviqProvider.");return n},B=({featureId:n,children:o,fallback:l=null,loadingComponent:r,condition:E})=>{const{getEntitlement:c,isLoading:u,error:A}=U(),s=c(n);return u&&!s?i.jsx(i.Fragment,{children:r!==void 0?r:l}):A&&!s?i.jsx(i.Fragment,{children:l}):!s||!s.hasAccess||E&&!E(s)?i.jsx(i.Fragment,{children:l}):typeof o=="function"?i.jsx(i.Fragment,{children:o(s)}):i.jsx(i.Fragment,{children:o})},ge=n=>i.jsx(B,{...n}),Ee=n=>{const o=l=>l.hasAccess&&(l.remaining===null||l.remaining>0);return i.jsx(B,{...n,condition:n.condition||o})},he=n=>i.jsx(B,{...n}),pe=()=>{const{allEntitlements:n}=U();return n},Le=n=>{const{getEntitlement:o}=U();return o(n)},ve=n=>{const{getEntitlement:o}=U();return o(n)},Ae=n=>{const{getEntitlement:o}=U();return o(n)},ye=()=>{const{subscriptions:n}=U();return n},Pe=()=>{const{customer:n}=U();return n},R=()=>{const{pricing:n}=U();return n},X=(n,o,l={})=>{if(typeof n!="number")return"";const{compact:r=!1,locale:E=l.pricingLocale||"en-US",includeCurrencySymbol:c=!0}=l;try{const u={notation:r?"compact":"standard",compactDisplay:"short"},s=new Intl.NumberFormat(E,u).format(n);return c?`${o}${s}`:s}catch{const u=n.toString();return c?`${o}${u}`:u}},we=({planIdentifier:n,billingPeriod:o,children:l,formatOptions:r,loadingComponent:E=null,fallback:c=null})=>{const{data:u,isLoading:A}=R();if(A)return i.jsx(i.Fragment,{children:E});if(!u||!Array.isArray(u.plans))return i.jsx(i.Fragment,{children:c});const s=u.plans.find(C=>C.identifier===n&&C.enabled);if(!s)return i.jsx(i.Fragment,{children:c});const a=s.price.charges.find(C=>C.chargePeriod===o)??null,L=a?a.priceData.amount:0,q=s.price.priceType==="FREE",K=q?"Free":X(L,u.currencySymbol,{...r,pricingLocale:u.pricingLocale});return i.jsx(i.Fragment,{children:l({plan:s,charge:a,amount:L,formattedPrice:K,currencySymbol:u.currencySymbol,currencyCode:u.currencyCode,pricingLocale:u.pricingLocale,isFree:q,hasFreeTrial:s.price.freeTrial,trialPeriod:s.price.trialPeriod})})},Se=({planIdentifier:n,children:o,loadingComponent:l=null,fallback:r=null,featureType:E})=>{const{data:c,isLoading:u}=R();if(u)return i.jsx(i.Fragment,{children:l});if(!c||!Array.isArray(c.plans))return i.jsx(i.Fragment,{children:r});const A=c.plans.find(a=>a.identifier===n&&a.enabled);if(!A)return i.jsx(i.Fragment,{children:r});let s=A.features.filter(a=>a.enabled);return E&&(s=s.filter(a=>a.featureType===E)),s.length===0?i.jsx(i.Fragment,{children:r}):i.jsx(i.Fragment,{children:s.map((a,L)=>o({feature:a,plan:A,index:L}))})};f.KQFeatureList=Se,f.KQPrice=we,f.KelviqContext=k,f.KelviqProvider=me,f.ShowWhenBooleanEntitled=he,f.ShowWhenCustomizableEntitled=ge,f.ShowWhenMeteredEntitled=Ee,f.defaultKelviqContextValue=O,f.kqFormatPrice=X,f.useAllEntitlements=pe,f.useBooleanEntitlement=Le,f.useCustomer=Pe,f.useCustomizableEntitlement=ve,f.useKelviq=U,f.useMeteredEntitlement=Ae,f.usePricing=R,f.useSubscriptions=ye,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
1
+ (function(m,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],i):(m=typeof globalThis<"u"?globalThis:m||self,i(m.KelviqReactSDK={},m.jsxRuntime,m.React))})(this,function(m,i,E){"use strict";const ie="GET";function _(n){const{method:o=ie,headers:a={},body:t,timeout:h=5e3,maxRetries:d=3,backoffBaseDelay:f=1e3,queryParams:A,accessToken:s}=n;let{url:l}=n,p=0;return new Promise((q,S)=>{if(A){const y=new URLSearchParams;for(const b in A)A[b]!==void 0&&y.append(b,String(A[b]));y.toString()&&(l+=(l.includes("?")?"&":"?")+y.toString())}function C(){const y=new XMLHttpRequest;y.open(o,l,!0),y.timeout=h;const b={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...a};o!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(b["Content-Type"]||(b["Content-Type"]="application/json")),s&&(b.Authorization=`Bearer ${s}`);for(const[c,L]of Object.entries(b))y.setRequestHeader(c,L);y.onload=function(){const{status:c,statusText:L,responseText:P}=y;if(c>=200&&c<300)try{const w=P?JSON.parse(P):{};q({status:c,statusText:L,data:w})}catch(w){const K=w instanceof Error?w:new Error(String(w));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${l}. Error: ${K.message}. Response: ${P}`),S(new Error(`Invalid JSON response: ${K.message}`))}else F(`Request to ${l} failed with status ${c} ${L}. Response: ${P}`)},y.onerror=()=>F(`Network error for URL ${l}. The request could not be completed.`),y.ontimeout=()=>F(`Request to ${l} timed out.`);function F(c){if(p<d){p++;const L=Math.min(f*Math.pow(2,p-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${l}. Attempt ${p}/${d}. Error: ${c}. Retrying in ${L}ms.`),setTimeout(C,L)}else S(new Error(`${c} (Max retries ${d} reached)`))}try{let c=t;t&&typeof t=="object"&&!(t instanceof FormData)&&b["Content-Type"]==="application/json"&&(c=JSON.stringify(t)),y.send(c)}catch(c){const L=c instanceof Error?c:new Error(String(c));console.error(`Kelviq SDK (apiRequest): Error sending request to ${l}.`,L),S(new Error(`Failed to send request: ${L.message}`))}}C()})}function oe(n,o){const a=o[0].featureType;if(a==="METER"){let t=0,h=0,d=!1;for(const A of o){const s=A,l=typeof s.usageLimit=="number"?s.usageLimit:null,p=typeof s.currentUsage=="number"?s.currentUsage:0;l===null&&(t=null),t!==null&&(t+=l),h+=p,s.hardLimit&&(d=!0)}const f=t!==null?t-h:null;return{featureId:n,featureType:a,hasAccess:f===null||f>0,currentUsage:h,usageLimit:t,remaining:f,hardLimit:d,items:o}}if(a==="CUSTOMIZABLE"){const t=o[0];return{featureId:n,featureType:a,hasAccess:o.some(h=>h.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:a,hasAccess:o.some(t=>t.hasAccess),currentUsage:0,usageLimit:null,remaining:null,hardLimit:!1,items:o}}function se(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 a={};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}a[t.featureId]||(a[t.featureId]=[]),a[t.featureId].push(t)}for(const t in a)o[t]=oe(t,a[t]);return o}const O={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()),pricing:{data:null,isLoading:!1,error:null},refreshPricing:()=>(console.warn("refreshPricing called on default KelviqContext. Ensure KelviqProvider is properly set up."),Promise.resolve()),isLoading:!0,error:null,apiUrl:"",environment:"production",entitlementsPath:"",customerId:""},k=E.createContext(O),ae="https://edge.api.kelviq.com/api/v1/",le="https://edge.sandboxapi.kelviq.com/api/v1/",ce="https://api.kelviq.com/api/v1/",ue="https://sandboxapi.kelviq.com/api/v1/",de="entitlements/",fe="monetization/product-offering/",me=({children:n,apiUrl:o,entitlementsPath:a=de,customerId:t,environment:h="production",accessToken:d,productId:f,plansEnabled:A,config:s={}})=>{const{onError:l,maxRetries:p,timeout:q,backoffBaseDelay:S,fetchEntitlementsOnMount:C=!0,fetchSubscriptionsOnMount:y=!1,fetchCustomerOnMount:b=!1,fetchPricingOnMount:F=!1}=s,c=o||(h==="sandbox"?le:ae),L=h==="sandbox"?ue:ce,[P,w]=E.useState({data:null,isLoading:!!c&&C,error:null}),[K,qe]=E.useState(null),[J,$]=E.useState({data:null,isLoading:!!c&&y,error:null}),[Q,D]=E.useState({data:null,isLoading:!!c&&b,error:null}),[V,I]=E.useState({data:null,isLoading:!!c&&F,error:null}),[N,M]=E.useState(!!c&&C),[Y,j]=E.useState(null),v=E.useCallback((g,e,r)=>{const u=new Error(`Kelviq SDK (${e}): ${g}`);console.error(u.message,r||""),j(U=>U||u),l&&l(u)},[l]),G=E.useCallback(()=>{if(!c){const r="API URL not configured. Cannot fetch entitlements.";return w({data:null,isLoading:!1,error:new Error(r)}),v(r,"fetchAllEntitlements"),M(!1),Promise.reject(new Error(r))}if(!t){const r="CustomerId must be provided as props to KelviqProvider.";return w(()=>({data:null,isLoading:!1,error:new Error(r)})),v(r,"fetchAllEntitlements"),M(!1),Promise.reject(new Error(r))}w(r=>({...r,isLoading:!0,error:null})),M(!0),j(null);const g=`${c.replace(/\/$/,"")}/${a.replace(/^\//,"")}`;return _({url:g,method:"GET",timeout:q,maxRetries:p,backoffBaseDelay:S,accessToken:d,queryParams:{customer_id:t}}).then(r=>{if(r&&r.data&&Array.isArray(r.data.entitlements)){qe(r.data);const u=se(r.data);w({data:u,isLoading:!1,error:null})}else{const u=new Error("Received empty, malformed, or invalid data structure from entitlements API.");throw w({data:null,isLoading:!1,error:u}),v(u.message,"fetchAllEntitlements",r),u}}).catch(r=>{const u=r instanceof Error?r:new Error(String(r));return w(U=>({...U,isLoading:!1,error:u})),v(u.message,"fetchAllEntitlements",r),Promise.reject(u)}).finally(()=>{M(!1)})},[c,t,a,q,p,S,d,v]),H=E.useCallback(()=>{if(!L){const e="Main API URL not configured. Cannot fetch subscriptions.";return $({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchSubscriptions"),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)}),v(e,"fetchSubscriptions"),Promise.reject(new Error(e))}$(e=>({...e,isLoading:!0,error:null}));const g=`${L.replace(/\/$/,"")}/subscriptions/`;return _({url:g,method:"GET",timeout:q,maxRetries:p,backoffBaseDelay:S,accessToken:d,queryParams:{customer_id:t}}).then(e=>{if(e&&e.data&&Array.isArray(e.data.results))$({data:e.data.results,isLoading:!1,error:null});else{const r=new Error("Received empty, malformed, or invalid data structure from subscriptions API.");throw $({data:null,isLoading:!1,error:r}),v(r.message,"fetchSubscriptions",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return $(u=>({...u,isLoading:!1,error:r})),v(r.message,"fetchSubscriptions",e),Promise.reject(r)})},[L,t,q,p,S,d,v]),W=E.useCallback(()=>{if(!L){const e="Main API URL not configured. Cannot fetch customer.";return D({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchCustomer"),Promise.reject(new Error(e))}if(!t){const e="CustomerId must be provided as props to KelviqProvider.";return D({data:null,isLoading:!1,error:new Error(e)}),v(e,"fetchCustomer"),Promise.reject(new Error(e))}D(e=>({...e,isLoading:!0,error:null}));const g=`${L.replace(/\/$/,"")}/customers/${t}/`;return _({url:g,method:"GET",timeout:q,maxRetries:p,backoffBaseDelay:S,accessToken:d}).then(e=>{if(e&&e.data)D({data:e.data,isLoading:!1,error:null});else{const r=new Error("Received empty or invalid data from customer API.");throw D({data:null,isLoading:!1,error:r}),v(r.message,"fetchCustomer",e),r}}).catch(e=>{const r=e instanceof Error?e:new Error(String(e));return D(u=>({...u,isLoading:!1,error:r})),v(r.message,"fetchCustomer",e),Promise.reject(r)})},[L,t,q,p,S,d,v]),z=E.useCallback(()=>{if(!L){const r="Main API URL not configured. Cannot fetch pricing.";return I({data:null,isLoading:!1,error:new Error(r)}),v(r,"fetchPricing"),Promise.reject(new Error(r))}if(!f){const r="productId must be provided as a prop to KelviqProvider to fetch pricing.";return I({data:null,isLoading:!1,error:new Error(r)}),v(r,"fetchPricing"),Promise.reject(new Error(r))}I(r=>({...r,isLoading:!0,error:null}));const g=`${L.replace(/\/$/,"")}/${fe.replace(/^\//,"")}${f}/`,e={};return t&&(e.customer_id=t),A&&(e.plans_enabled=A),_({url:g,method:"GET",timeout:q,maxRetries:p,backoffBaseDelay:S,accessToken:d,queryParams:e}).then(r=>{if(r&&r.data&&Array.isArray(r.data.plans))I({data:r.data,isLoading:!1,error:null});else{const u=new Error("Received empty, malformed, or invalid data structure from pricing API.");throw I({data:null,isLoading:!1,error:u}),v(u.message,"fetchPricing",r),u}}).catch(r=>{const u=r instanceof Error?r:new Error(String(r));return I(U=>({...U,isLoading:!1,error:u})),v(u.message,"fetchPricing",r),Promise.reject(u)})},[L,f,t,A,q,p,S,d,v]);E.useEffect(()=>{let g=!0;if(!c){if(g){const e=new Error("KelviqProvider: `apiBaseUrl` must be provided in config.");j(e),M(!1),w(r=>({...r,isLoading:!1,error:e})),s.onError&&s.onError(e)}return}return C?G().catch(e=>{g&&N&&M(!1),console.error("Kelviq SDK: Initial entitlement fetch failed.",e)}):g&&(w(e=>({...e,isLoading:!1,data:null,error:null})),M(!1)),y&&H().catch(e=>{console.error("Kelviq SDK: Initial subscriptions fetch failed.",e)}),b&&W().catch(e=>{console.error("Kelviq SDK: Initial customer fetch failed.",e)}),F&&z().catch(e=>{console.error("Kelviq SDK: Initial pricing fetch failed.",e)}),()=>{g=!1}},[c,C,y,b,F]);const Z=E.useCallback(()=>P.data?P.data:{},[P.data]),x=E.useCallback(()=>K?{customerId:K.customerId,entitlements:K.entitlements}:null,[K]),ee=E.useCallback(g=>K?{customerId:K.customerId,entitlements:K.entitlements.filter(e=>e.featureId===g)}:null,[K]),re=E.useCallback(g=>P.data?P.data[g]??null:null,[P.data]),te=E.useCallback((g,e)=>{w(r=>{if(!r.data)return r;const u=r.data[g];if(!u)return r;const U={...u,...e};return("usageLimit"in e||"currentUsage"in e)&&(U.remaining=U.usageLimit!==null?U.usageLimit-U.currentUsage:null),{...r,data:{...r.data,[g]:U}}})},[]),ne=E.useCallback(g=>{if(!P.data)return!1;const e=P.data[g];return e?e.hasAccess:!1},[P.data]),be=E.useMemo(()=>({allEntitlements:P,refreshAllEntitlements:G,getEntitlements:Z,getEntitlement:re,getRawEntitlements:x,getRawEntitlement:ee,hasAccess:ne,updateEntitlement:te,subscriptions:J,refreshSubscriptions:H,customer:Q,refreshCustomer:W,pricing:V,refreshPricing:z,isLoading:N,error:Y,environment:h,apiUrl:c,entitlementsPath:a,customerId:t}),[P,G,Z,re,x,ee,ne,te,J,H,Q,W,V,z,N,Y,h,c,a,t]);return i.jsx(k.Provider,{value:be,children:n})},T=()=>{const n=E.useContext(k);if(n===void 0||n===O)throw new Error("useKelviq must be used within an initialized KelviqProvider.");return n},B=({featureId:n,children:o,fallback:a=null,loadingComponent:t,condition:h})=>{const{getEntitlement:d,isLoading:f,error:A}=T(),s=d(n);return f&&!s?i.jsx(i.Fragment,{children:t!==void 0?t:a}):A&&!s?i.jsx(i.Fragment,{children:a}):!s||!s.hasAccess||h&&!h(s)?i.jsx(i.Fragment,{children:a}):typeof o=="function"?i.jsx(i.Fragment,{children:o(s)}):i.jsx(i.Fragment,{children:o})},ge=n=>i.jsx(B,{...n}),Ee=n=>{const o=a=>a.hasAccess&&(a.remaining===null||a.remaining>0);return i.jsx(B,{...n,condition:n.condition||o})},he=n=>i.jsx(B,{...n}),pe=()=>{const{allEntitlements:n}=T();return n},Le=n=>{const{getEntitlement:o}=T();return o(n)},ve=n=>{const{getEntitlement:o}=T();return o(n)},Ae=n=>{const{getEntitlement:o}=T();return o(n)},ye=()=>{const{subscriptions:n}=T();return n},Pe=()=>{const{customer:n}=T();return n},R=()=>{const{pricing:n}=T();return n},X=(n,o,a={})=>{if(typeof n!="number")return"";const{compact:t=!1,locale:h=a.pricingLocale||"en-US",includeCurrencySymbol:d=!0}=a;try{const f={notation:t?"compact":"standard",compactDisplay:"short"},s=new Intl.NumberFormat(h,f).format(n);return d?`${o}${s}`:s}catch{const f=n.toString();return d?`${o}${f}`:f}},we=({planIdentifier:n,billingPeriod:o,children:a,formatOptions:t,loadingComponent:h=null,fallback:d=null})=>{const{data:f,isLoading:A}=R();if(A)return i.jsx(i.Fragment,{children:h});if(!f||!Array.isArray(f.plans))return i.jsx(i.Fragment,{children:d});const s=f.plans.find(C=>C.identifier===n&&C.enabled);if(!s)return i.jsx(i.Fragment,{children:d});const l=s.price.charges.find(C=>C.chargePeriod===o)??null,p=l?l.priceData.amount:0,q=s.price.priceType==="FREE",S=q?"Free":X(p,f.currencySymbol,{...t,pricingLocale:f.pricingLocale});return i.jsx(i.Fragment,{children:a({plan:s,charge:l,amount:p,formattedPrice:S,currencySymbol:f.currencySymbol,currencyCode:f.currencyCode,pricingLocale:f.pricingLocale,isFree:q,hasFreeTrial:s.price.freeTrial,trialPeriod:s.price.trialPeriod})})},Se=({planIdentifier:n,children:o,loadingComponent:a=null,fallback:t=null,featureType:h})=>{const{data:d,isLoading:f}=R();if(f)return i.jsx(i.Fragment,{children:a});if(!d||!Array.isArray(d.plans))return i.jsx(i.Fragment,{children:t});const A=d.plans.find(l=>l.identifier===n&&l.enabled);if(!A)return i.jsx(i.Fragment,{children:t});let s=A.features.filter(l=>l.enabled);return h&&(s=s.filter(l=>l.featureType===h)),s.length===0?i.jsx(i.Fragment,{children:t}):i.jsx(i.Fragment,{children:s.map((l,p)=>o({feature:l,plan:A,index:p}))})};m.KQFeatureList=Se,m.KQPrice=we,m.KelviqContext=k,m.KelviqProvider=me,m.ShowWhenBooleanEntitled=he,m.ShowWhenCustomizableEntitled=ge,m.ShowWhenMeteredEntitled=Ee,m.defaultKelviqContextValue=O,m.kqFormatPrice=X,m.useAllEntitlements=pe,m.useBooleanEntitlement=Le,m.useCustomer=Pe,m.useCustomizableEntitlement=ve,m.useKelviq=T,m.useMeteredEntitlement=Ae,m.usePricing=R,m.useSubscriptions=ye,Object.defineProperty(m,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.1.0",
4
+ "version": "2.1.1",
5
5
  "type": "module",
6
6
  "main": "dist/kelviq-react-sdk.js",
7
7
  "types": "dist/index.d.ts",