@kelviq/js-sdk 2.0.0-beta → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export interface RawEntitlement {
11
11
  remaining?: number | null;
12
12
  }
13
13
  export interface RawEntitlementsApiResponse {
14
- customer_id: string;
14
+ customerId: string;
15
15
  entitlements: RawEntitlement[];
16
16
  }
17
17
  export interface Entitlement {
@@ -1 +1 @@
1
- var kelviqSDK=function(){"use strict";var I=Object.defineProperty;var _=(y,d,q)=>d in y?I(y,d,{enumerable:!0,configurable:!0,writable:!0,value:q}):y[d]=q;var E=(y,d,q)=>_(y,typeof d!="symbol"?d+"":d,q);function y(a){const e={};if(!a||!Array.isArray(a.entitlements))return console.warn("[Kelviq SDK] transformApiEntitlements: Invalid or empty entitlements array in API response.",a),e;const i={};a.entitlements.forEach(t=>{if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("[Kelviq SDK] transformApiEntitlements: Skipping invalid raw entitlement object:",t);return}i[t.featureId]||(i[t.featureId]=[]),i[t.featureId].push(t)});for(const t of Object.keys(i)){const c=i[t],u=c[0].featureType;let A=0,r=null,f=null,l=!1,m=!1;if(u==="METER"){let n=!0;for(const s of c)A+=typeof s.currentUsage=="number"?s.currentUsage:0,typeof s.usageLimit=="number"&&(r=(r??0)+s.usageLimit,n=!1);n&&(r=null),f=r!==null?r-A:null,l=c.some(s=>s.hardLimit===!0),m=f===null||f>0}else if(u==="CUSTOMIZABLE"){const n=c[0];r=typeof n.usageLimit=="number"?n.usageLimit:null,A=typeof n.currentUsage=="number"?n.currentUsage:0,f=typeof n.remaining=="number"?n.remaining:null,l=n.hardLimit===!0,m=c.some(s=>s.hasAccess)}else if(u==="BOOLEAN")m=c.some(n=>n.hasAccess);else{console.warn(`[Kelviq SDK] transformApiEntitlements: Encountered unknown featureType: '${u}' for feature '${t}'. This entitlement will be ignored.`);continue}const R={featureId:t,featureType:u,hasAccess:m,hardLimit:l,currentUsage:A,usageLimit:r,remaining:f,items:c};e[t]=R}return e}const d="GET",q=5e3,K=3,P=1e3;function C(a){const{method:e=d,headers:i={},body:t,timeout:c=q,maxRetries:u=K,backoffBaseDelay:A=P,queryParams:r,accessToken:f}=a;let l=a.url,m=0;return new Promise((R,n)=>{if(r){const h=new URLSearchParams;for(const g in r)r[g]!==void 0&&h.append(g,String(r[g]));h.toString()&&(l=l+(l.includes("?")?"&":"?")+h.toString())}function s(){const h=new XMLHttpRequest;h.open(e,l,!0),h.timeout=c;const g={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...i};e!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(g["Content-Type"]||(g["Content-Type"]="application/json")),f&&(g.Authorization=`Bearer ${f}`);for(const[o,p]of Object.entries(g))h.setRequestHeader(o,p);h.onload=function(){const{status:o,statusText:p,responseText:F}=h;if(o>=200&&o<300)try{const v=F?JSON.parse(F):{};R({status:o,statusText:p,data:v})}catch(v){const w=v instanceof Error?v:new Error(String(v));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${l}. Error: ${w.message}. Response: ${F}`),n(new Error(`Invalid JSON response: ${w.message}`))}else S(`Request to ${l} failed with status ${o} ${p}. Response: ${F}`)},h.onerror=()=>S(`Network error for URL ${l}. The request could not be completed.`),h.ontimeout=()=>S(`Request to ${l} timed out.`);function S(o){if(m<u){m++;const p=Math.min(A*Math.pow(2,m-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${l}. Attempt ${m}/${u}. Error: ${o}. Retrying in ${p}ms.`),setTimeout(s,p)}else n(new Error(`${o} (Max retries ${u} reached)`))}try{let o=t;t&&typeof t=="object"&&!(t instanceof FormData)&&g["Content-Type"]==="application/json"&&(o=JSON.stringify(t)),h.send(o)}catch(o){const p=o instanceof Error?o:new Error(String(o));console.error(`Kelviq SDK (apiRequest): Error sending request to ${l}.`,p),n(new Error(`Failed to send request: ${p.message}`))}}s()})}const L="https://edge.api.kelviq.com/api/v1/",D="https://edge.sandboxapi.kelviq.com/api/v1/",T="entitlements/";class ${constructor(e,i){E(this,"options");E(this,"entitlementsCache",null);E(this,"rawApiResponse",null);E(this,"isFetching",!1);E(this,"inFlightPromise",null);E(this,"readyPromise",null);E(this,"lastFetchError",null);E(this,"apiRequestService");if(!e||!e.customerId)throw new Error("[Kelviq SDK] KelviqClient: CustomerId is required in options.");this.options={...e,apiConfig:e.apiConfig||{},entitlementsPath:e.entitlementsPath||T},this.apiRequestService=i||C}async fetchAllEntitlements(e=!1){if(this.inFlightPromise&&!e)return this.inFlightPromise;if(this.entitlementsCache&&!e)return Promise.resolve(this.entitlementsCache);this.isFetching=!0,this.lastFetchError=null;const{apiUrl:i=this.options.environment==="sandbox"?D:L,entitlementsPath:t,customerId:c,accessToken:u,apiConfig:A,onError:r}=this.options,f=i.replace(/\/$/,""),l=t.replace(/^\//,""),m=`${f}/${l}`,R={customer_id:c};return this.inFlightPromise=this.apiRequestService({url:m,method:"GET",queryParams:R,accessToken:u,...A||{}}).then(n=>{if(n&&n.data&&Array.isArray(n.data.entitlements))return this.rawApiResponse=n.data,this.entitlementsCache=y(n.data),this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache;{const s=new Error("[Kelviq SDK] Received empty, malformed, or invalid data structure from entitlements API.");throw this.lastFetchError=s,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(s),s}}).catch(n=>{const s=n instanceof Error?n:new Error(String(n));throw this.lastFetchError=s,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(s),s}),this.inFlightPromise}getEntitlement(e){return this.entitlementsCache?this.entitlementsCache[e]??null:(console.warn(`[Kelviq SDK] getEntitlement: Entitlements not fetched or cache is empty for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getEntitlements(){return this.entitlementsCache}getRawEntitlement(e){return this.rawApiResponse?this.rawApiResponse.entitlements.filter(i=>i.featureId===e):(console.warn(`[Kelviq SDK] getRawEntitlement: Entitlements not fetched for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getRawEntitlements(){return this.rawApiResponse}hasAccess(e){if(!this.entitlementsCache)return console.warn(`[Kelviq SDK] hasAccess: Entitlements not fetched yet for featureId '${e}'. Call fetchAllEntitlements() first. Returning false.`),!1;const i=this.entitlementsCache[e];return i?i.hasAccess:!1}isLoading(){return this.isFetching}getLastError(){return this.lastFetchError}ready(){return this.readyPromise??Promise.resolve()}_setReadyPromise(e){this.readyPromise=e}clearCache(){this.entitlementsCache=null,this.rawApiResponse=null,this.isFetching=!1,this.lastFetchError=null,console.log("[Kelviq SDK] Entitlement cache cleared.")}}function U(a,e){const i={...a,initializeAndFetch:a.initializeAndFetch??!0,apiConfig:a.apiConfig||{},environment:a.environment||"production",entitlementsPath:a.entitlementsPath||T},t=new $(i,e);if(i.initializeAndFetch===!0){const c=t.fetchAllEntitlements().catch(u=>{console.error("[Kelviq SDK] Initial fetch on client creation failed:",u.message)});t._setReadyPromise(c.then(()=>{}))}return t}return U}();
1
+ var kelviqSDK=function(){"use strict";var U=Object.defineProperty;var _=(y,p,q)=>p in y?U(y,p,{enumerable:!0,configurable:!0,writable:!0,value:q}):y[p]=q;var E=(y,p,q)=>_(y,typeof p!="symbol"?p+"":p,q);function y(a){const e={};if(!a||!Array.isArray(a.entitlements))return console.warn("[Kelviq SDK] transformApiEntitlements: Invalid or empty entitlements array in API response.",a),e;const s={};a.entitlements.forEach(t=>{if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("[Kelviq SDK] transformApiEntitlements: Skipping invalid raw entitlement object:",t);return}s[t.featureId]||(s[t.featureId]=[]),s[t.featureId].push(t)});for(const t of Object.keys(s)){const c=s[t],u=c[0].featureType;let A=0,r=null,f=null,l=!1,h=!1;if(u==="METER"){let n=!0;for(const i of c)A+=typeof i.currentUsage=="number"?i.currentUsage:0,typeof i.usageLimit=="number"&&(r=(r??0)+i.usageLimit,n=!1);n&&(r=null),f=r!==null?r-A:null,l=c.some(i=>i.hardLimit===!0),h=f===null||f>0}else if(u==="CUSTOMIZABLE"){const n=c[0];r=typeof n.usageLimit=="number"?n.usageLimit:null,A=typeof n.currentUsage=="number"?n.currentUsage:0,f=typeof n.remaining=="number"?n.remaining:null,l=n.hardLimit===!0,h=c.some(i=>i.hasAccess)}else if(u==="BOOLEAN")h=c.some(n=>n.hasAccess);else{console.warn(`[Kelviq SDK] transformApiEntitlements: Encountered unknown featureType: '${u}' for feature '${t}'. This entitlement will be ignored.`);continue}const R={featureId:t,featureType:u,hasAccess:h,hardLimit:l,currentUsage:A,usageLimit:r,remaining:f,items:c};e[t]=R}return e}const p="GET",q=5e3,K=3,P=1e3;function C(a){const{method:e=p,headers:s={},body:t,timeout:c=q,maxRetries:u=K,backoffBaseDelay:A=P,queryParams:r,accessToken:f}=a;let l=a.url,h=0;return new Promise((R,n)=>{if(r){const m=new URLSearchParams;for(const g in r)r[g]!==void 0&&m.append(g,String(r[g]));m.toString()&&(l=l+(l.includes("?")?"&":"?")+m.toString())}function i(){const m=new XMLHttpRequest;m.open(e,l,!0),m.timeout=c;const g={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...s};e!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(g["Content-Type"]||(g["Content-Type"]="application/json")),f&&(g.Authorization=`Bearer ${f}`);for(const[o,d]of Object.entries(g))m.setRequestHeader(o,d);m.onload=function(){const{status:o,statusText:d,responseText:F}=m;if(o>=200&&o<300)try{const v=F?JSON.parse(F):{};R({status:o,statusText:d,data:v})}catch(v){const w=v instanceof Error?v:new Error(String(v));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${l}. Error: ${w.message}. Response: ${F}`),n(new Error(`Invalid JSON response: ${w.message}`))}else S(`Request to ${l} failed with status ${o} ${d}. Response: ${F}`)},m.onerror=()=>S(`Network error for URL ${l}. The request could not be completed.`),m.ontimeout=()=>S(`Request to ${l} timed out.`);function S(o){if(h<u){h++;const d=Math.min(A*Math.pow(2,h-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${l}. Attempt ${h}/${u}. Error: ${o}. Retrying in ${d}ms.`),setTimeout(i,d)}else n(new Error(`${o} (Max retries ${u} reached)`))}try{let o=t;t&&typeof t=="object"&&!(t instanceof FormData)&&g["Content-Type"]==="application/json"&&(o=JSON.stringify(t)),m.send(o)}catch(o){const d=o instanceof Error?o:new Error(String(o));console.error(`Kelviq SDK (apiRequest): Error sending request to ${l}.`,d),n(new Error(`Failed to send request: ${d.message}`))}}i()})}const L="https://edge.api.kelviq.com/api/v1/",D="https://edge.sandboxapi.kelviq.com/api/v1/",T="entitlements/";class ${constructor(e,s){E(this,"options");E(this,"entitlementsCache",null);E(this,"rawApiResponse",null);E(this,"isFetching",!1);E(this,"inFlightPromise",null);E(this,"readyPromise",null);E(this,"lastFetchError",null);E(this,"apiRequestService");if(!e||!e.customerId)throw new Error("[Kelviq SDK] KelviqClient: CustomerId is required in options.");this.options={...e,apiConfig:e.apiConfig||{},entitlementsPath:e.entitlementsPath||T},this.apiRequestService=s||C}async fetchAllEntitlements(e=!1){if(this.inFlightPromise&&!e)return this.inFlightPromise;if(this.entitlementsCache&&!e)return Promise.resolve(this.entitlementsCache);this.isFetching=!0,this.lastFetchError=null;const{apiUrl:s=this.options.environment==="sandbox"?D:L,entitlementsPath:t,customerId:c,accessToken:u,apiConfig:A,onError:r}=this.options,f=s.replace(/\/$/,""),l=t.replace(/^\//,""),h=`${f}/${l}`,R={customer_id:c};return this.inFlightPromise=this.apiRequestService({url:h,method:"GET",queryParams:R,accessToken:u,...A||{}}).then(n=>{if(n&&n.data&&Array.isArray(n.data.entitlements)){const i=n.data;return this.rawApiResponse={customerId:i.customer_id??i.customerId,entitlements:i.entitlements},this.entitlementsCache=y(n.data),this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache}else{const i=new Error("[Kelviq SDK] Received empty, malformed, or invalid data structure from entitlements API.");throw this.lastFetchError=i,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(i),i}}).catch(n=>{const i=n instanceof Error?n:new Error(String(n));throw this.lastFetchError=i,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(i),i}),this.inFlightPromise}getEntitlement(e){return this.entitlementsCache?this.entitlementsCache[e]??null:(console.warn(`[Kelviq SDK] getEntitlement: Entitlements not fetched or cache is empty for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getEntitlements(){return this.entitlementsCache}getRawEntitlement(e){return this.rawApiResponse?this.rawApiResponse.entitlements.filter(s=>s.featureId===e):(console.warn(`[Kelviq SDK] getRawEntitlement: Entitlements not fetched for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getRawEntitlements(){return this.rawApiResponse}hasAccess(e){if(!this.entitlementsCache)return console.warn(`[Kelviq SDK] hasAccess: Entitlements not fetched yet for featureId '${e}'. Call fetchAllEntitlements() first. Returning false.`),!1;const s=this.entitlementsCache[e];return s?s.hasAccess:!1}isLoading(){return this.isFetching}getLastError(){return this.lastFetchError}ready(){return this.readyPromise??Promise.resolve()}_setReadyPromise(e){this.readyPromise=e}clearCache(){this.entitlementsCache=null,this.rawApiResponse=null,this.isFetching=!1,this.lastFetchError=null,console.log("[Kelviq SDK] Entitlement cache cleared.")}}function I(a,e){const s={...a,initializeAndFetch:a.initializeAndFetch??!0,apiConfig:a.apiConfig||{},environment:a.environment||"production",entitlementsPath:a.entitlementsPath||T},t=new $(s,e);if(s.initializeAndFetch===!0){const c=t.fetchAllEntitlements().catch(u=>{console.error("[Kelviq SDK] Initial fetch on client creation failed:",u.message)});t._setReadyPromise(c.then(()=>{}))}return t}return I}();
@@ -1,15 +1,15 @@
1
1
  var S = Object.defineProperty;
2
- var T = (s, e, i) => e in s ? S(s, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : s[e] = i;
3
- var g = (s, e, i) => T(s, typeof e != "symbol" ? e + "" : e, i);
4
- function w(s) {
2
+ var T = (r, e, i) => e in r ? S(r, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : r[e] = i;
3
+ var g = (r, e, i) => T(r, typeof e != "symbol" ? e + "" : e, i);
4
+ function w(r) {
5
5
  const e = {};
6
- if (!s || !Array.isArray(s.entitlements))
6
+ if (!r || !Array.isArray(r.entitlements))
7
7
  return console.warn(
8
8
  "[Kelviq SDK] transformApiEntitlements: Invalid or empty entitlements array in API response.",
9
- s
9
+ r
10
10
  ), e;
11
11
  const i = {};
12
- s.entitlements.forEach((t) => {
12
+ r.entitlements.forEach((t) => {
13
13
  if (!t || typeof t.featureId != "string" || typeof t.featureType != "string") {
14
14
  console.warn(
15
15
  "[Kelviq SDK] transformApiEntitlements: Skipping invalid raw entitlement object:",
@@ -21,17 +21,17 @@ function w(s) {
21
21
  });
22
22
  for (const t of Object.keys(i)) {
23
23
  const c = i[t], u = c[0].featureType;
24
- let E = 0, l = null, f = null, o = !1, m = !1;
24
+ let E = 0, l = null, f = null, o = !1, h = !1;
25
25
  if (u === "METER") {
26
26
  let n = !0;
27
- for (const r of c)
28
- E += typeof r.currentUsage == "number" ? r.currentUsage : 0, typeof r.usageLimit == "number" && (l = (l ?? 0) + r.usageLimit, n = !1);
29
- n && (l = null), f = l !== null ? l - E : null, o = c.some((r) => r.hardLimit === !0), m = f === null || f > 0;
27
+ for (const s of c)
28
+ E += typeof s.currentUsage == "number" ? s.currentUsage : 0, typeof s.usageLimit == "number" && (l = (l ?? 0) + s.usageLimit, n = !1);
29
+ n && (l = null), f = l !== null ? l - E : null, o = c.some((s) => s.hardLimit === !0), h = f === null || f > 0;
30
30
  } else if (u === "CUSTOMIZABLE") {
31
31
  const n = c[0];
32
- l = typeof n.usageLimit == "number" ? n.usageLimit : null, E = typeof n.currentUsage == "number" ? n.currentUsage : 0, f = typeof n.remaining == "number" ? n.remaining : null, o = n.hardLimit === !0, m = c.some((r) => r.hasAccess);
32
+ l = typeof n.usageLimit == "number" ? n.usageLimit : null, E = typeof n.currentUsage == "number" ? n.currentUsage : 0, f = typeof n.remaining == "number" ? n.remaining : null, o = n.hardLimit === !0, h = c.some((s) => s.hasAccess);
33
33
  } else if (u === "BOOLEAN")
34
- m = c.some((n) => n.hasAccess);
34
+ h = c.some((n) => n.hasAccess);
35
35
  else {
36
36
  console.warn(
37
37
  `[Kelviq SDK] transformApiEntitlements: Encountered unknown featureType: '${u}' for feature '${t}'. This entitlement will be ignored.`
@@ -41,7 +41,7 @@ function w(s) {
41
41
  const A = {
42
42
  featureId: t,
43
43
  featureType: u,
44
- hasAccess: m,
44
+ hasAccess: h,
45
45
  hardLimit: o,
46
46
  currentUsage: E,
47
47
  usageLimit: l,
@@ -53,7 +53,7 @@ function w(s) {
53
53
  return e;
54
54
  }
55
55
  const P = "GET", C = 5e3, K = 3, L = 1e3;
56
- function $(s) {
56
+ function $(r) {
57
57
  const {
58
58
  method: e = P,
59
59
  headers: i = {},
@@ -65,33 +65,33 @@ function $(s) {
65
65
  queryParams: l,
66
66
  accessToken: f
67
67
  // Use the direct accessToken
68
- } = s;
69
- let o = s.url, m = 0;
68
+ } = r;
69
+ let o = r.url, h = 0;
70
70
  return new Promise((A, n) => {
71
71
  if (l) {
72
- const h = new URLSearchParams();
73
- for (const d in l)
74
- l[d] !== void 0 && h.append(d, String(l[d]));
75
- h.toString() && (o = o + (o.includes("?") ? "&" : "?") + h.toString());
72
+ const m = new URLSearchParams();
73
+ for (const p in l)
74
+ l[p] !== void 0 && m.append(p, String(l[p]));
75
+ m.toString() && (o = o + (o.includes("?") ? "&" : "?") + m.toString());
76
76
  }
77
- function r() {
78
- const h = new XMLHttpRequest();
79
- h.open(e, o, !0), h.timeout = c;
80
- const d = {
77
+ function s() {
78
+ const m = new XMLHttpRequest();
79
+ m.open(e, o, !0), m.timeout = c;
80
+ const p = {
81
81
  Accept: "application/json",
82
82
  "X-Requested-With": "XMLHttpRequest",
83
83
  ...i
84
84
  // Apply custom headers, allowing them to override defaults
85
85
  };
86
- e !== "GET" && t && typeof t == "object" && !(t instanceof FormData) && (d["Content-Type"] || (d["Content-Type"] = "application/json")), f && (d.Authorization = `Bearer ${f}`);
87
- for (const [a, p] of Object.entries(d))
88
- h.setRequestHeader(a, p);
89
- h.onload = function() {
90
- const { status: a, statusText: p, responseText: R } = h;
86
+ e !== "GET" && t && typeof t == "object" && !(t instanceof FormData) && (p["Content-Type"] || (p["Content-Type"] = "application/json")), f && (p.Authorization = `Bearer ${f}`);
87
+ for (const [a, d] of Object.entries(p))
88
+ m.setRequestHeader(a, d);
89
+ m.onload = function() {
90
+ const { status: a, statusText: d, responseText: R } = m;
91
91
  if (a >= 200 && a < 300)
92
92
  try {
93
93
  const y = R ? JSON.parse(R) : {};
94
- A({ status: a, statusText: p, data: y });
94
+ A({ status: a, statusText: d, data: y });
95
95
  } catch (y) {
96
96
  const v = y instanceof Error ? y : new Error(String(y));
97
97
  console.error(
@@ -100,22 +100,22 @@ function $(s) {
100
100
  }
101
101
  else
102
102
  q(
103
- `Request to ${o} failed with status ${a} ${p}. Response: ${R}`
103
+ `Request to ${o} failed with status ${a} ${d}. Response: ${R}`
104
104
  );
105
- }, h.onerror = () => q(
105
+ }, m.onerror = () => q(
106
106
  `Network error for URL ${o}. The request could not be completed.`
107
- ), h.ontimeout = () => q(`Request to ${o} timed out.`);
107
+ ), m.ontimeout = () => q(`Request to ${o} timed out.`);
108
108
  function q(a) {
109
- if (m < u) {
110
- m++;
111
- const p = Math.min(
112
- E * Math.pow(2, m - 1),
109
+ if (h < u) {
110
+ h++;
111
+ const d = Math.min(
112
+ E * Math.pow(2, h - 1),
113
113
  3e4
114
114
  // Cap retry delay at 30 seconds
115
115
  );
116
116
  console.warn(
117
- `Kelviq SDK (apiRequest): Retrying request to ${o}. Attempt ${m}/${u}. Error: ${a}. Retrying in ${p}ms.`
118
- ), setTimeout(r, p);
117
+ `Kelviq SDK (apiRequest): Retrying request to ${o}. Attempt ${h}/${u}. Error: ${a}. Retrying in ${d}ms.`
118
+ ), setTimeout(s, d);
119
119
  } else
120
120
  n(
121
121
  new Error(`${a} (Max retries ${u} reached)`)
@@ -123,20 +123,20 @@ function $(s) {
123
123
  }
124
124
  try {
125
125
  let a = t;
126
- t && typeof t == "object" && !(t instanceof FormData) && d["Content-Type"] === "application/json" && (a = JSON.stringify(t)), h.send(a);
126
+ t && typeof t == "object" && !(t instanceof FormData) && p["Content-Type"] === "application/json" && (a = JSON.stringify(t)), m.send(a);
127
127
  } catch (a) {
128
- const p = a instanceof Error ? a : new Error(String(a));
128
+ const d = a instanceof Error ? a : new Error(String(a));
129
129
  console.error(
130
130
  `Kelviq SDK (apiRequest): Error sending request to ${o}.`,
131
- p
132
- ), n(new Error(`Failed to send request: ${p.message}`));
131
+ d
132
+ ), n(new Error(`Failed to send request: ${d.message}`));
133
133
  }
134
134
  }
135
- r();
135
+ s();
136
136
  });
137
137
  }
138
- const D = "https://edge.api.kelviq.com/api/v1/", U = "https://edge.sandboxapi.kelviq.com/api/v1/", F = "entitlements/";
139
- class I {
138
+ const D = "https://edge.api.kelviq.com/api/v1/", I = "https://edge.sandboxapi.kelviq.com/api/v1/", F = "entitlements/";
139
+ class U {
140
140
  /**
141
141
  * Creates an instance of KelviqClient.
142
142
  * Prefer using the `kelviqSDK` factory function for instantiation.
@@ -179,33 +179,37 @@ class I {
179
179
  return Promise.resolve(this.entitlementsCache);
180
180
  this.isFetching = !0, this.lastFetchError = null;
181
181
  const {
182
- apiUrl: i = this.options.environment === "sandbox" ? U : D,
182
+ apiUrl: i = this.options.environment === "sandbox" ? I : D,
183
183
  entitlementsPath: t,
184
184
  customerId: c,
185
185
  accessToken: u,
186
186
  apiConfig: E,
187
187
  onError: l
188
- } = this.options, f = i.replace(/\/$/, ""), o = t.replace(/^\//, ""), m = `${f}/${o}`, A = {
188
+ } = this.options, f = i.replace(/\/$/, ""), o = t.replace(/^\//, ""), h = `${f}/${o}`, A = {
189
189
  customer_id: c
190
190
  };
191
191
  return this.inFlightPromise = this.apiRequestService({
192
- url: m,
192
+ url: h,
193
193
  method: "GET",
194
194
  queryParams: A,
195
195
  accessToken: u,
196
196
  ...E || {}
197
197
  }).then((n) => {
198
- if (n && n.data && Array.isArray(n.data.entitlements))
199
- return this.rawApiResponse = n.data, this.entitlementsCache = w(n.data), this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache;
200
- {
201
- const r = new Error(
198
+ if (n && n.data && Array.isArray(n.data.entitlements)) {
199
+ const s = n.data;
200
+ return this.rawApiResponse = {
201
+ customerId: s.customer_id ?? s.customerId,
202
+ entitlements: s.entitlements
203
+ }, this.entitlementsCache = w(n.data), this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache;
204
+ } else {
205
+ const s = new Error(
202
206
  "[Kelviq SDK] Received empty, malformed, or invalid data structure from entitlements API."
203
207
  );
204
- throw this.lastFetchError = r, this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache = null, this.rawApiResponse = null, l && l(r), r;
208
+ throw this.lastFetchError = s, this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache = null, this.rawApiResponse = null, l && l(s), s;
205
209
  }
206
210
  }).catch((n) => {
207
- const r = n instanceof Error ? n : new Error(String(n));
208
- throw this.lastFetchError = r, this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache = null, this.rawApiResponse = null, l && l(r), r;
211
+ const s = n instanceof Error ? n : new Error(String(n));
212
+ throw this.lastFetchError = s, this.isFetching = !1, this.inFlightPromise = null, this.entitlementsCache = null, this.rawApiResponse = null, l && l(s), s;
209
213
  }), this.inFlightPromise;
210
214
  }
211
215
  /**
@@ -296,14 +300,14 @@ class I {
296
300
  this.entitlementsCache = null, this.rawApiResponse = null, this.isFetching = !1, this.lastFetchError = null, console.log("[Kelviq SDK] Entitlement cache cleared.");
297
301
  }
298
302
  }
299
- function b(s, e) {
303
+ function b(r, e) {
300
304
  const i = {
301
- ...s,
302
- initializeAndFetch: s.initializeAndFetch ?? !0,
303
- apiConfig: s.apiConfig || {},
304
- environment: s.environment || "production",
305
- entitlementsPath: s.entitlementsPath || F
306
- }, t = new I(i, e);
305
+ ...r,
306
+ initializeAndFetch: r.initializeAndFetch ?? !0,
307
+ apiConfig: r.apiConfig || {},
308
+ environment: r.environment || "production",
309
+ entitlementsPath: r.entitlementsPath || F
310
+ }, t = new U(i, e);
307
311
  if (i.initializeAndFetch === !0) {
308
312
  const c = t.fetchAllEntitlements().catch((u) => {
309
313
  console.error(
@@ -1 +1 @@
1
- (function(f,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(f=typeof globalThis<"u"?globalThis:f||self,f.kelviqSDK=c())})(this,function(){"use strict";var I=Object.defineProperty;var b=(f,c,q)=>c in f?I(f,c,{enumerable:!0,configurable:!0,writable:!0,value:q}):f[c]=q;var A=(f,c,q)=>b(f,typeof c!="symbol"?c+"":c,q);function f(a){const e={};if(!a||!Array.isArray(a.entitlements))return console.warn("[Kelviq SDK] transformApiEntitlements: Invalid or empty entitlements array in API response.",a),e;const i={};a.entitlements.forEach(t=>{if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("[Kelviq SDK] transformApiEntitlements: Skipping invalid raw entitlement object:",t);return}i[t.featureId]||(i[t.featureId]=[]),i[t.featureId].push(t)});for(const t of Object.keys(i)){const u=i[t],h=u[0].featureType;let y=0,r=null,p=null,o=!1,d=!1;if(h==="METER"){let n=!0;for(const s of u)y+=typeof s.currentUsage=="number"?s.currentUsage:0,typeof s.usageLimit=="number"&&(r=(r??0)+s.usageLimit,n=!1);n&&(r=null),p=r!==null?r-y:null,o=u.some(s=>s.hardLimit===!0),d=p===null||p>0}else if(h==="CUSTOMIZABLE"){const n=u[0];r=typeof n.usageLimit=="number"?n.usageLimit:null,y=typeof n.currentUsage=="number"?n.currentUsage:0,p=typeof n.remaining=="number"?n.remaining:null,o=n.hardLimit===!0,d=u.some(s=>s.hasAccess)}else if(h==="BOOLEAN")d=u.some(n=>n.hasAccess);else{console.warn(`[Kelviq SDK] transformApiEntitlements: Encountered unknown featureType: '${h}' for feature '${t}'. This entitlement will be ignored.`);continue}const R={featureId:t,featureType:h,hasAccess:d,hardLimit:o,currentUsage:y,usageLimit:r,remaining:p,items:u};e[t]=R}return e}const c="GET",q=5e3,K=3,P=1e3;function C(a){const{method:e=c,headers:i={},body:t,timeout:u=q,maxRetries:h=K,backoffBaseDelay:y=P,queryParams:r,accessToken:p}=a;let o=a.url,d=0;return new Promise((R,n)=>{if(r){const m=new URLSearchParams;for(const E in r)r[E]!==void 0&&m.append(E,String(r[E]));m.toString()&&(o=o+(o.includes("?")?"&":"?")+m.toString())}function s(){const m=new XMLHttpRequest;m.open(e,o,!0),m.timeout=u;const E={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...i};e!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(E["Content-Type"]||(E["Content-Type"]="application/json")),p&&(E.Authorization=`Bearer ${p}`);for(const[l,g]of Object.entries(E))m.setRequestHeader(l,g);m.onload=function(){const{status:l,statusText:g,responseText:T}=m;if(l>=200&&l<300)try{const v=T?JSON.parse(T):{};R({status:l,statusText:g,data:v})}catch(v){const w=v instanceof Error?v:new Error(String(v));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${o}. Error: ${w.message}. Response: ${T}`),n(new Error(`Invalid JSON response: ${w.message}`))}else F(`Request to ${o} failed with status ${l} ${g}. Response: ${T}`)},m.onerror=()=>F(`Network error for URL ${o}. The request could not be completed.`),m.ontimeout=()=>F(`Request to ${o} timed out.`);function F(l){if(d<h){d++;const g=Math.min(y*Math.pow(2,d-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${o}. Attempt ${d}/${h}. Error: ${l}. Retrying in ${g}ms.`),setTimeout(s,g)}else n(new Error(`${l} (Max retries ${h} reached)`))}try{let l=t;t&&typeof t=="object"&&!(t instanceof FormData)&&E["Content-Type"]==="application/json"&&(l=JSON.stringify(t)),m.send(l)}catch(l){const g=l instanceof Error?l:new Error(String(l));console.error(`Kelviq SDK (apiRequest): Error sending request to ${o}.`,g),n(new Error(`Failed to send request: ${g.message}`))}}s()})}const L="https://edge.api.kelviq.com/api/v1/",D="https://edge.sandboxapi.kelviq.com/api/v1/",S="entitlements/";class ${constructor(e,i){A(this,"options");A(this,"entitlementsCache",null);A(this,"rawApiResponse",null);A(this,"isFetching",!1);A(this,"inFlightPromise",null);A(this,"readyPromise",null);A(this,"lastFetchError",null);A(this,"apiRequestService");if(!e||!e.customerId)throw new Error("[Kelviq SDK] KelviqClient: CustomerId is required in options.");this.options={...e,apiConfig:e.apiConfig||{},entitlementsPath:e.entitlementsPath||S},this.apiRequestService=i||C}async fetchAllEntitlements(e=!1){if(this.inFlightPromise&&!e)return this.inFlightPromise;if(this.entitlementsCache&&!e)return Promise.resolve(this.entitlementsCache);this.isFetching=!0,this.lastFetchError=null;const{apiUrl:i=this.options.environment==="sandbox"?D:L,entitlementsPath:t,customerId:u,accessToken:h,apiConfig:y,onError:r}=this.options,p=i.replace(/\/$/,""),o=t.replace(/^\//,""),d=`${p}/${o}`,R={customer_id:u};return this.inFlightPromise=this.apiRequestService({url:d,method:"GET",queryParams:R,accessToken:h,...y||{}}).then(n=>{if(n&&n.data&&Array.isArray(n.data.entitlements))return this.rawApiResponse=n.data,this.entitlementsCache=f(n.data),this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache;{const s=new Error("[Kelviq SDK] Received empty, malformed, or invalid data structure from entitlements API.");throw this.lastFetchError=s,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(s),s}}).catch(n=>{const s=n instanceof Error?n:new Error(String(n));throw this.lastFetchError=s,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(s),s}),this.inFlightPromise}getEntitlement(e){return this.entitlementsCache?this.entitlementsCache[e]??null:(console.warn(`[Kelviq SDK] getEntitlement: Entitlements not fetched or cache is empty for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getEntitlements(){return this.entitlementsCache}getRawEntitlement(e){return this.rawApiResponse?this.rawApiResponse.entitlements.filter(i=>i.featureId===e):(console.warn(`[Kelviq SDK] getRawEntitlement: Entitlements not fetched for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getRawEntitlements(){return this.rawApiResponse}hasAccess(e){if(!this.entitlementsCache)return console.warn(`[Kelviq SDK] hasAccess: Entitlements not fetched yet for featureId '${e}'. Call fetchAllEntitlements() first. Returning false.`),!1;const i=this.entitlementsCache[e];return i?i.hasAccess:!1}isLoading(){return this.isFetching}getLastError(){return this.lastFetchError}ready(){return this.readyPromise??Promise.resolve()}_setReadyPromise(e){this.readyPromise=e}clearCache(){this.entitlementsCache=null,this.rawApiResponse=null,this.isFetching=!1,this.lastFetchError=null,console.log("[Kelviq SDK] Entitlement cache cleared.")}}function U(a,e){const i={...a,initializeAndFetch:a.initializeAndFetch??!0,apiConfig:a.apiConfig||{},environment:a.environment||"production",entitlementsPath:a.entitlementsPath||S},t=new $(i,e);if(i.initializeAndFetch===!0){const u=t.fetchAllEntitlements().catch(h=>{console.error("[Kelviq SDK] Initial fetch on client creation failed:",h.message)});t._setReadyPromise(u.then(()=>{}))}return t}return U});
1
+ (function(f,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(f=typeof globalThis<"u"?globalThis:f||self,f.kelviqSDK=c())})(this,function(){"use strict";var U=Object.defineProperty;var _=(f,c,q)=>c in f?U(f,c,{enumerable:!0,configurable:!0,writable:!0,value:q}):f[c]=q;var A=(f,c,q)=>_(f,typeof c!="symbol"?c+"":c,q);function f(a){const e={};if(!a||!Array.isArray(a.entitlements))return console.warn("[Kelviq SDK] transformApiEntitlements: Invalid or empty entitlements array in API response.",a),e;const s={};a.entitlements.forEach(t=>{if(!t||typeof t.featureId!="string"||typeof t.featureType!="string"){console.warn("[Kelviq SDK] transformApiEntitlements: Skipping invalid raw entitlement object:",t);return}s[t.featureId]||(s[t.featureId]=[]),s[t.featureId].push(t)});for(const t of Object.keys(s)){const u=s[t],m=u[0].featureType;let y=0,r=null,p=null,o=!1,d=!1;if(m==="METER"){let n=!0;for(const i of u)y+=typeof i.currentUsage=="number"?i.currentUsage:0,typeof i.usageLimit=="number"&&(r=(r??0)+i.usageLimit,n=!1);n&&(r=null),p=r!==null?r-y:null,o=u.some(i=>i.hardLimit===!0),d=p===null||p>0}else if(m==="CUSTOMIZABLE"){const n=u[0];r=typeof n.usageLimit=="number"?n.usageLimit:null,y=typeof n.currentUsage=="number"?n.currentUsage:0,p=typeof n.remaining=="number"?n.remaining:null,o=n.hardLimit===!0,d=u.some(i=>i.hasAccess)}else if(m==="BOOLEAN")d=u.some(n=>n.hasAccess);else{console.warn(`[Kelviq SDK] transformApiEntitlements: Encountered unknown featureType: '${m}' for feature '${t}'. This entitlement will be ignored.`);continue}const R={featureId:t,featureType:m,hasAccess:d,hardLimit:o,currentUsage:y,usageLimit:r,remaining:p,items:u};e[t]=R}return e}const c="GET",q=5e3,K=3,P=1e3;function C(a){const{method:e=c,headers:s={},body:t,timeout:u=q,maxRetries:m=K,backoffBaseDelay:y=P,queryParams:r,accessToken:p}=a;let o=a.url,d=0;return new Promise((R,n)=>{if(r){const h=new URLSearchParams;for(const E in r)r[E]!==void 0&&h.append(E,String(r[E]));h.toString()&&(o=o+(o.includes("?")?"&":"?")+h.toString())}function i(){const h=new XMLHttpRequest;h.open(e,o,!0),h.timeout=u;const E={Accept:"application/json","X-Requested-With":"XMLHttpRequest",...s};e!=="GET"&&t&&typeof t=="object"&&!(t instanceof FormData)&&(E["Content-Type"]||(E["Content-Type"]="application/json")),p&&(E.Authorization=`Bearer ${p}`);for(const[l,g]of Object.entries(E))h.setRequestHeader(l,g);h.onload=function(){const{status:l,statusText:g,responseText:T}=h;if(l>=200&&l<300)try{const v=T?JSON.parse(T):{};R({status:l,statusText:g,data:v})}catch(v){const w=v instanceof Error?v:new Error(String(v));console.error(`Kelviq SDK (apiRequest): Invalid JSON response for URL ${o}. Error: ${w.message}. Response: ${T}`),n(new Error(`Invalid JSON response: ${w.message}`))}else F(`Request to ${o} failed with status ${l} ${g}. Response: ${T}`)},h.onerror=()=>F(`Network error for URL ${o}. The request could not be completed.`),h.ontimeout=()=>F(`Request to ${o} timed out.`);function F(l){if(d<m){d++;const g=Math.min(y*Math.pow(2,d-1),3e4);console.warn(`Kelviq SDK (apiRequest): Retrying request to ${o}. Attempt ${d}/${m}. Error: ${l}. Retrying in ${g}ms.`),setTimeout(i,g)}else n(new Error(`${l} (Max retries ${m} reached)`))}try{let l=t;t&&typeof t=="object"&&!(t instanceof FormData)&&E["Content-Type"]==="application/json"&&(l=JSON.stringify(t)),h.send(l)}catch(l){const g=l instanceof Error?l:new Error(String(l));console.error(`Kelviq SDK (apiRequest): Error sending request to ${o}.`,g),n(new Error(`Failed to send request: ${g.message}`))}}i()})}const L="https://edge.api.kelviq.com/api/v1/",D="https://edge.sandboxapi.kelviq.com/api/v1/",S="entitlements/";class ${constructor(e,s){A(this,"options");A(this,"entitlementsCache",null);A(this,"rawApiResponse",null);A(this,"isFetching",!1);A(this,"inFlightPromise",null);A(this,"readyPromise",null);A(this,"lastFetchError",null);A(this,"apiRequestService");if(!e||!e.customerId)throw new Error("[Kelviq SDK] KelviqClient: CustomerId is required in options.");this.options={...e,apiConfig:e.apiConfig||{},entitlementsPath:e.entitlementsPath||S},this.apiRequestService=s||C}async fetchAllEntitlements(e=!1){if(this.inFlightPromise&&!e)return this.inFlightPromise;if(this.entitlementsCache&&!e)return Promise.resolve(this.entitlementsCache);this.isFetching=!0,this.lastFetchError=null;const{apiUrl:s=this.options.environment==="sandbox"?D:L,entitlementsPath:t,customerId:u,accessToken:m,apiConfig:y,onError:r}=this.options,p=s.replace(/\/$/,""),o=t.replace(/^\//,""),d=`${p}/${o}`,R={customer_id:u};return this.inFlightPromise=this.apiRequestService({url:d,method:"GET",queryParams:R,accessToken:m,...y||{}}).then(n=>{if(n&&n.data&&Array.isArray(n.data.entitlements)){const i=n.data;return this.rawApiResponse={customerId:i.customer_id??i.customerId,entitlements:i.entitlements},this.entitlementsCache=f(n.data),this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache}else{const i=new Error("[Kelviq SDK] Received empty, malformed, or invalid data structure from entitlements API.");throw this.lastFetchError=i,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(i),i}}).catch(n=>{const i=n instanceof Error?n:new Error(String(n));throw this.lastFetchError=i,this.isFetching=!1,this.inFlightPromise=null,this.entitlementsCache=null,this.rawApiResponse=null,r&&r(i),i}),this.inFlightPromise}getEntitlement(e){return this.entitlementsCache?this.entitlementsCache[e]??null:(console.warn(`[Kelviq SDK] getEntitlement: Entitlements not fetched or cache is empty for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getEntitlements(){return this.entitlementsCache}getRawEntitlement(e){return this.rawApiResponse?this.rawApiResponse.entitlements.filter(s=>s.featureId===e):(console.warn(`[Kelviq SDK] getRawEntitlement: Entitlements not fetched for featureId '${e}'. Call fetchAllEntitlements() first.`),null)}getRawEntitlements(){return this.rawApiResponse}hasAccess(e){if(!this.entitlementsCache)return console.warn(`[Kelviq SDK] hasAccess: Entitlements not fetched yet for featureId '${e}'. Call fetchAllEntitlements() first. Returning false.`),!1;const s=this.entitlementsCache[e];return s?s.hasAccess:!1}isLoading(){return this.isFetching}getLastError(){return this.lastFetchError}ready(){return this.readyPromise??Promise.resolve()}_setReadyPromise(e){this.readyPromise=e}clearCache(){this.entitlementsCache=null,this.rawApiResponse=null,this.isFetching=!1,this.lastFetchError=null,console.log("[Kelviq SDK] Entitlement cache cleared.")}}function I(a,e){const s={...a,initializeAndFetch:a.initializeAndFetch??!0,apiConfig:a.apiConfig||{},environment:a.environment||"production",entitlementsPath:a.entitlementsPath||S},t=new $(s,e);if(s.initializeAndFetch===!0){const u=t.fetchAllEntitlements().catch(m=>{console.error("[Kelviq SDK] Initial fetch on client creation failed:",m.message)});t._setReadyPromise(u.then(()=>{}))}return t}return I});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kelviq/js-sdk",
3
- "version": "2.0.0-beta",
3
+ "version": "2.0.0",
4
4
  "module": "./dist/kelviq-js-sdk.js",
5
5
  "type": "module",
6
6
  "files": [