@kelviq/react-sdk 2.0.2-beta → 2.1.0

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