@entitlehub/sdk 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to `@entitlehub/sdk`. Adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## 0.3.2 (2026-09-21)
6
+
7
+ ### Fixed
8
+ - **The SDK reported the wrong version of itself.** 0.3.1 shipped with `SDK_VERSION = "0.3.0"`,
9
+ so every request's `X-EntitleHub-Client` header attributed 0.3.1 traffic to 0.3.0. Harmless to
10
+ your app, wrong for the dashboard's "which SDK is this project on" reporting, which exists to
11
+ warn you when you are running a build with a known bug.
12
+ - The constant is now generated from `package.json` at build time instead of being hand-maintained
13
+ next to a comment asking whoever cuts the release to remember. A test asserts the built bundle
14
+ carries the published version, so it fails rather than drifting silently.
15
+
5
16
  ## 0.3.1 (2026-09-20)
6
17
 
7
18
  ### Added
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var I=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var D=(r,t)=>{for(var e in t)I(r,e,{get:t[e],enumerable:!0})},q=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of U(t))!A.call(r,s)&&s!==e&&I(r,s,{get:()=>t[s],enumerable:!(n=H(t,s))||n.enumerable});return r};var N=r=>q(I({},"__esModule",{value:!0}),r);var L={};D(L,{CustomerInfo:()=>c,EntitleHub:()=>y,EntitleHubError:()=>a,EntitleHubServer:()=>b,EntitlementsApi:()=>l,OfferingsApi:()=>m,ProductsApi:()=>g,isReceiptRevoked:()=>x});module.exports=N(L);var c=class{constructor(t){this.appUserId=t.app_user_id,this.entitlements=t.active_entitlements??[];let e={};for(let n of this.entitlements)e[n.entitlement]=n;this.active=e}isActive(t){return!!this.active[t]}get activeEntitlementIds(){return Object.keys(this.active)}expirationDate(t){let e=this.active[t];if(e)return e.expires_at?new Date(e.expires_at):null}};var S="0.3.0";var a=class extends Error{constructor(t,e,n="error",s){super(t),this.name="EntitleHubError",this.status=e,this.code=n,this.body=s,this.apiCode=typeof s?.code=="string"?s.code:void 0}};function x(r){if(!r||typeof r!="object")return!1;let t=r;return t.apiCode==="receipt_revoked"||t.body?.code==="receipt_revoked"}var K=r=>new Promise(t=>setTimeout(t,r));async function i(r,t,e,n){let s=r.fetchImpl??globalThis.fetch;if(!s)throw new a("No fetch implementation available. On Node <18, pass fetchImpl.",0,"no_fetch");let C=`${r.baseUrl.replace(/\/$/,"")}${e}`,E=t==="GET"?r.retries??2:0,_;for(let f=0;f<=E;f++){let w=new AbortController,T=r.timeoutMs?setTimeout(()=>w.abort(),r.timeoutMs):void 0;try{let u=await s(C,{method:t,headers:{Authorization:`Bearer ${r.apiKey}`,"X-EntitleHub-Client":r.client??`${"js"}/${S}`,...n?{"Content-Type":"application/json"}:{}},body:n?JSON.stringify(n):void 0,signal:w.signal}),v=await u.text(),h=v?j(v):{};if(!u.ok){let O=`HTTP ${u.status}`,P=h&&typeof h=="object"?h:void 0;throw P&&"error"in P&&(O=String(P.error)),new a(O,u.status,u.status===401||u.status===403?"auth":"http",P)}return h}catch(u){if(_=u,u instanceof a)throw u;f<E&&await K(250*(f+1))}finally{T&&clearTimeout(T)}}throw new a(`Network request failed: ${String(_?.message??_)}`,0,"network")}function j(r){try{return JSON.parse(r)}catch{return{}}}var y=class{constructor(t){this.listeners=new Set;if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.appUserId)throw new a("appUserId is required.",0,"config");if(t.apiKey.startsWith("sk_"))throw new a("Never use a secret (sk_) key in the client SDK. Use your publishable (pk_) key.",0,"config");this.appUserId=t.appUserId,this.cacheTtlMs=t.cacheTtlMs??5*6e4,this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3,client:t.client}}get currentAppUserId(){return this.appUserId}async logIn(t){return this.appUserId=t,this.cached=void 0,this.getCustomerInfo({fetchPolicy:"network-only"})}logOut(){this.cached=void 0}async getCustomerInfo(t={}){if((t.fetchPolicy??"cache-first")==="cache-first"&&this.cached&&Date.now()-this.cached.at<this.cacheTtlMs)return this.cached.info;let n=await i(this.http,"GET",`/subscribers/${encodeURIComponent(this.appUserId)}`),s=new c(n);this.cached={info:s,at:Date.now()};for(let C of this.listeners)try{C(s)}catch{}return s}async isEntitled(t){return(await this.getCustomerInfo()).isActive(t)}async checkEntitlement(t,e={}){return i(this.http,"POST","/check",{app_user_id:this.appUserId,entitlement:t,sandbox:!!e.sandbox})}async getOfferings(){return i(this.http,"GET","/offerings")}async reportPurchase(t){let e=await i(this.http,"POST",`/subscribers/${encodeURIComponent(this.appUserId)}/purchases`,{store:t.store??"",store_product_id:t.storeProductId??"",is_sandbox:!!t.isSandbox,purchase_token:t.purchaseToken??"",is_subscription:!!t.isSubscription,signed_transaction:t.signedTransaction??"",stripe_subscription_id:t.stripeSubscriptionId??""}),n=new c(e);this.cached={info:n,at:Date.now()};for(let s of this.listeners)try{s(n)}catch{}return n}addCustomerInfoUpdateListener(t){return this.listeners.add(t),()=>this.listeners.delete(t)}};var o=encodeURIComponent;function p(r){return typeof r=="string"?r:"id"in r?{id:r.id}:{store:r.store,store_product_id:r.storeProductId}}function d(r){return typeof r=="string"?{seg:o(r),qs:""}:"id"in r?{seg:o(r.id),qs:""}:{seg:o(r.storeProductId),qs:`?store=${o(r.store)}`}}var k=r=>r?.includeArchived?"include_archived=true":"";async function $(r,t){try{return await r()}catch(e){if(e instanceof a&&e.apiCode===t&&e.body?.existing)return e.body.existing;throw e}}var l=class{constructor(t){this.http=t}async list(t){let e=k(t);return(await i(this.http,"GET",`/entitlements${e?`?${e}`:""}`)).entitlements}get(t){return i(this.http,"GET",`/entitlements/${o(t)}`)}create(t){return i(this.http,"POST","/entitlements",{key:t.key,name:t.name,description:t.description,products:t.products?.map(p)})}ensure(t){return $(()=>this.create(t),"entitlement_exists")}update(t,e){return i(this.http,"PATCH",`/entitlements/${o(t)}`,{name:e.name,description:e.description,products:e.products?.map(p)})}delete(t){return i(this.http,"DELETE",`/entitlements/${o(t)}`)}async products(t,e){let n=k(e);return(await i(this.http,"GET",`/entitlements/${o(t)}/products${n?`?${n}`:""}`)).products}attachProducts(t,e){return i(this.http,"POST",`/entitlements/${o(t)}/attach_products`,{products:e.map(p)})}detachProducts(t,e){return i(this.http,"POST",`/entitlements/${o(t)}/detach_products`,{products:e.map(p)})}archive(t){return i(this.http,"POST",`/entitlements/${o(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/entitlements/${o(t)}/unarchive`)}},g=class{constructor(t){this.http=t}async list(t){let e=new URLSearchParams;t?.store&&e.set("store",t.store),t?.entitlement&&e.set("entitlement",t.entitlement),t?.includeArchived&&e.set("include_archived","true");let n=e.toString();return(await i(this.http,"GET",`/products${n?`?${n}`:""}`)).products}get(t){let{seg:e,qs:n}=d(t);return i(this.http,"GET",`/products/${e}${n}`)}create(t){return i(this.http,"POST","/products",{store:t.store,store_product_id:t.storeProductId,type:t.type,duration:t.duration,display_name:t.displayName,price_micros:t.priceMicros,currency:t.currency,entitlements:t.entitlements})}ensure(t){return $(()=>this.create(t),"product_exists")}update(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"PATCH",`/products/${n}${s}`,{display_name:e.displayName,price_micros:e.priceMicros,currency:e.currency,entitlements:e.entitlements})}delete(t){let{seg:e,qs:n}=d(t);return i(this.http,"DELETE",`/products/${e}${n}`)}attachEntitlements(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"POST",`/products/${n}/attach_entitlements${s}`,{entitlements:e})}detachEntitlements(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"POST",`/products/${n}/detach_entitlements${s}`,{entitlements:e})}archive(t){let{seg:e,qs:n}=d(t);return i(this.http,"POST",`/products/${e}/archive${n}`)}unarchive(t){let{seg:e,qs:n}=d(t);return i(this.http,"POST",`/products/${e}/unarchive${n}`)}},m=class{constructor(t){this.http=t}async list(t){let e=k(t);return(await i(this.http,"GET",`/offerings/all${e?`?${e}`:""}`)).offerings}get(t){return i(this.http,"GET",`/offerings/${o(t)}`)}create(t){return i(this.http,"POST","/offerings",{identifier:t.identifier,display_name:t.displayName,is_current:t.isCurrent,metadata:t.metadata,packages:t.packages?.map(R)})}update(t,e){return i(this.http,"PATCH",`/offerings/${o(t)}`,{display_name:e.displayName,is_current:e.isCurrent,metadata:e.metadata})}delete(t){return i(this.http,"DELETE",`/offerings/${o(t)}`)}archive(t){return i(this.http,"POST",`/offerings/${o(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/offerings/${o(t)}/unarchive`)}async packages(t){return(await i(this.http,"GET",`/offerings/${o(t)}/packages`)).packages}addPackage(t,e){return i(this.http,"POST",`/offerings/${o(t)}/packages`,R(e))}updatePackage(t,e,n){return i(this.http,"PATCH",`/offerings/${o(t)}/packages/${o(e)}`,{display_name:n.displayName,position:n.position,product:n.product===void 0?void 0:p(n.product)})}deletePackage(t,e){return i(this.http,"DELETE",`/offerings/${o(t)}/packages/${o(e)}`)}};function R(r){return{identifier:r.identifier,product:p(r.product),position:r.position,display_name:r.displayName}}var b=class{constructor(t){if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.apiKey.startsWith("sk_"))throw new a("EntitleHubServer needs a secret (sk_) key. For client reads, use the EntitleHub class with a pk_ key.",0,"config");this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3},this.entitlements=new l(this.http),this.products=new g(this.http),this.offerings=new m(this.http)}async reportPurchase(t,e){let n=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/purchases`,{store:e.store,store_product_id:e.storeProductId,is_sandbox:!!e.isSandbox,transaction_id:e.transactionId??"",purchase_token:e.purchaseToken??"",is_subscription:!!e.isSubscription,signed_transaction:e.signedTransaction??"",stripe_subscription_id:e.stripeSubscriptionId??""});return new c(n)}async grantEntitlement(t,e,n={}){let s=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/grant`,{entitlement:e,duration_days:n.durationDays??0,is_sandbox:!!n.isSandbox});return new c(s)}async getCustomerInfo(t){let e=await i(this.http,"GET",`/subscribers/${encodeURIComponent(t)}`);return new c(e)}async check(t,e,n={}){return i(this.http,"POST","/check",{app_user_id:t,entitlement:e,sandbox:!!n.sandbox})}};0&&(module.exports={CustomerInfo,EntitleHub,EntitleHubError,EntitleHubServer,EntitlementsApi,OfferingsApi,ProductsApi,isReceiptRevoked});
1
+ "use strict";var I=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var D=(r,t)=>{for(var e in t)I(r,e,{get:t[e],enumerable:!0})},q=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of U(t))!A.call(r,s)&&s!==e&&I(r,s,{get:()=>t[s],enumerable:!(n=H(t,s))||n.enumerable});return r};var N=r=>q(I({},"__esModule",{value:!0}),r);var L={};D(L,{CustomerInfo:()=>c,EntitleHub:()=>y,EntitleHubError:()=>a,EntitleHubServer:()=>b,EntitlementsApi:()=>l,OfferingsApi:()=>m,ProductsApi:()=>g,isReceiptRevoked:()=>x});module.exports=N(L);var c=class{constructor(t){this.appUserId=t.app_user_id,this.entitlements=t.active_entitlements??[];let e={};for(let n of this.entitlements)e[n.entitlement]=n;this.active=e}isActive(t){return!!this.active[t]}get activeEntitlementIds(){return Object.keys(this.active)}expirationDate(t){let e=this.active[t];if(e)return e.expires_at?new Date(e.expires_at):null}};var S="0.3.2";var a=class extends Error{constructor(t,e,n="error",s){super(t),this.name="EntitleHubError",this.status=e,this.code=n,this.body=s,this.apiCode=typeof s?.code=="string"?s.code:void 0}};function x(r){if(!r||typeof r!="object")return!1;let t=r;return t.apiCode==="receipt_revoked"||t.body?.code==="receipt_revoked"}var K=r=>new Promise(t=>setTimeout(t,r));async function i(r,t,e,n){let s=r.fetchImpl??globalThis.fetch;if(!s)throw new a("No fetch implementation available. On Node <18, pass fetchImpl.",0,"no_fetch");let C=`${r.baseUrl.replace(/\/$/,"")}${e}`,E=t==="GET"?r.retries??2:0,_;for(let f=0;f<=E;f++){let w=new AbortController,T=r.timeoutMs?setTimeout(()=>w.abort(),r.timeoutMs):void 0;try{let u=await s(C,{method:t,headers:{Authorization:`Bearer ${r.apiKey}`,"X-EntitleHub-Client":r.client??`${"js"}/${S}`,...n?{"Content-Type":"application/json"}:{}},body:n?JSON.stringify(n):void 0,signal:w.signal}),v=await u.text(),h=v?j(v):{};if(!u.ok){let O=`HTTP ${u.status}`,P=h&&typeof h=="object"?h:void 0;throw P&&"error"in P&&(O=String(P.error)),new a(O,u.status,u.status===401||u.status===403?"auth":"http",P)}return h}catch(u){if(_=u,u instanceof a)throw u;f<E&&await K(250*(f+1))}finally{T&&clearTimeout(T)}}throw new a(`Network request failed: ${String(_?.message??_)}`,0,"network")}function j(r){try{return JSON.parse(r)}catch{return{}}}var y=class{constructor(t){this.listeners=new Set;if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.appUserId)throw new a("appUserId is required.",0,"config");if(t.apiKey.startsWith("sk_"))throw new a("Never use a secret (sk_) key in the client SDK. Use your publishable (pk_) key.",0,"config");this.appUserId=t.appUserId,this.cacheTtlMs=t.cacheTtlMs??5*6e4,this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3,client:t.client}}get currentAppUserId(){return this.appUserId}async logIn(t){return this.appUserId=t,this.cached=void 0,this.getCustomerInfo({fetchPolicy:"network-only"})}logOut(){this.cached=void 0}async getCustomerInfo(t={}){if((t.fetchPolicy??"cache-first")==="cache-first"&&this.cached&&Date.now()-this.cached.at<this.cacheTtlMs)return this.cached.info;let n=await i(this.http,"GET",`/subscribers/${encodeURIComponent(this.appUserId)}`),s=new c(n);this.cached={info:s,at:Date.now()};for(let C of this.listeners)try{C(s)}catch{}return s}async isEntitled(t){return(await this.getCustomerInfo()).isActive(t)}async checkEntitlement(t,e={}){return i(this.http,"POST","/check",{app_user_id:this.appUserId,entitlement:t,sandbox:!!e.sandbox})}async getOfferings(){return i(this.http,"GET","/offerings")}async reportPurchase(t){let e=await i(this.http,"POST",`/subscribers/${encodeURIComponent(this.appUserId)}/purchases`,{store:t.store??"",store_product_id:t.storeProductId??"",is_sandbox:!!t.isSandbox,purchase_token:t.purchaseToken??"",is_subscription:!!t.isSubscription,signed_transaction:t.signedTransaction??"",stripe_subscription_id:t.stripeSubscriptionId??""}),n=new c(e);this.cached={info:n,at:Date.now()};for(let s of this.listeners)try{s(n)}catch{}return n}addCustomerInfoUpdateListener(t){return this.listeners.add(t),()=>this.listeners.delete(t)}};var o=encodeURIComponent;function p(r){return typeof r=="string"?r:"id"in r?{id:r.id}:{store:r.store,store_product_id:r.storeProductId}}function d(r){return typeof r=="string"?{seg:o(r),qs:""}:"id"in r?{seg:o(r.id),qs:""}:{seg:o(r.storeProductId),qs:`?store=${o(r.store)}`}}var k=r=>r?.includeArchived?"include_archived=true":"";async function $(r,t){try{return await r()}catch(e){if(e instanceof a&&e.apiCode===t&&e.body?.existing)return e.body.existing;throw e}}var l=class{constructor(t){this.http=t}async list(t){let e=k(t);return(await i(this.http,"GET",`/entitlements${e?`?${e}`:""}`)).entitlements}get(t){return i(this.http,"GET",`/entitlements/${o(t)}`)}create(t){return i(this.http,"POST","/entitlements",{key:t.key,name:t.name,description:t.description,products:t.products?.map(p)})}ensure(t){return $(()=>this.create(t),"entitlement_exists")}update(t,e){return i(this.http,"PATCH",`/entitlements/${o(t)}`,{name:e.name,description:e.description,products:e.products?.map(p)})}delete(t){return i(this.http,"DELETE",`/entitlements/${o(t)}`)}async products(t,e){let n=k(e);return(await i(this.http,"GET",`/entitlements/${o(t)}/products${n?`?${n}`:""}`)).products}attachProducts(t,e){return i(this.http,"POST",`/entitlements/${o(t)}/attach_products`,{products:e.map(p)})}detachProducts(t,e){return i(this.http,"POST",`/entitlements/${o(t)}/detach_products`,{products:e.map(p)})}archive(t){return i(this.http,"POST",`/entitlements/${o(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/entitlements/${o(t)}/unarchive`)}},g=class{constructor(t){this.http=t}async list(t){let e=new URLSearchParams;t?.store&&e.set("store",t.store),t?.entitlement&&e.set("entitlement",t.entitlement),t?.includeArchived&&e.set("include_archived","true");let n=e.toString();return(await i(this.http,"GET",`/products${n?`?${n}`:""}`)).products}get(t){let{seg:e,qs:n}=d(t);return i(this.http,"GET",`/products/${e}${n}`)}create(t){return i(this.http,"POST","/products",{store:t.store,store_product_id:t.storeProductId,type:t.type,duration:t.duration,display_name:t.displayName,price_micros:t.priceMicros,currency:t.currency,entitlements:t.entitlements})}ensure(t){return $(()=>this.create(t),"product_exists")}update(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"PATCH",`/products/${n}${s}`,{display_name:e.displayName,price_micros:e.priceMicros,currency:e.currency,entitlements:e.entitlements})}delete(t){let{seg:e,qs:n}=d(t);return i(this.http,"DELETE",`/products/${e}${n}`)}attachEntitlements(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"POST",`/products/${n}/attach_entitlements${s}`,{entitlements:e})}detachEntitlements(t,e){let{seg:n,qs:s}=d(t);return i(this.http,"POST",`/products/${n}/detach_entitlements${s}`,{entitlements:e})}archive(t){let{seg:e,qs:n}=d(t);return i(this.http,"POST",`/products/${e}/archive${n}`)}unarchive(t){let{seg:e,qs:n}=d(t);return i(this.http,"POST",`/products/${e}/unarchive${n}`)}},m=class{constructor(t){this.http=t}async list(t){let e=k(t);return(await i(this.http,"GET",`/offerings/all${e?`?${e}`:""}`)).offerings}get(t){return i(this.http,"GET",`/offerings/${o(t)}`)}create(t){return i(this.http,"POST","/offerings",{identifier:t.identifier,display_name:t.displayName,is_current:t.isCurrent,metadata:t.metadata,packages:t.packages?.map(R)})}update(t,e){return i(this.http,"PATCH",`/offerings/${o(t)}`,{display_name:e.displayName,is_current:e.isCurrent,metadata:e.metadata})}delete(t){return i(this.http,"DELETE",`/offerings/${o(t)}`)}archive(t){return i(this.http,"POST",`/offerings/${o(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/offerings/${o(t)}/unarchive`)}async packages(t){return(await i(this.http,"GET",`/offerings/${o(t)}/packages`)).packages}addPackage(t,e){return i(this.http,"POST",`/offerings/${o(t)}/packages`,R(e))}updatePackage(t,e,n){return i(this.http,"PATCH",`/offerings/${o(t)}/packages/${o(e)}`,{display_name:n.displayName,position:n.position,product:n.product===void 0?void 0:p(n.product)})}deletePackage(t,e){return i(this.http,"DELETE",`/offerings/${o(t)}/packages/${o(e)}`)}};function R(r){return{identifier:r.identifier,product:p(r.product),position:r.position,display_name:r.displayName}}var b=class{constructor(t){if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.apiKey.startsWith("sk_"))throw new a("EntitleHubServer needs a secret (sk_) key. For client reads, use the EntitleHub class with a pk_ key.",0,"config");this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3},this.entitlements=new l(this.http),this.products=new g(this.http),this.offerings=new m(this.http)}async reportPurchase(t,e){let n=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/purchases`,{store:e.store,store_product_id:e.storeProductId,is_sandbox:!!e.isSandbox,transaction_id:e.transactionId??"",purchase_token:e.purchaseToken??"",is_subscription:!!e.isSubscription,signed_transaction:e.signedTransaction??"",stripe_subscription_id:e.stripeSubscriptionId??""});return new c(n)}async grantEntitlement(t,e,n={}){let s=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/grant`,{entitlement:e,duration_days:n.durationDays??0,is_sandbox:!!n.isSandbox});return new c(s)}async getCustomerInfo(t){let e=await i(this.http,"GET",`/subscribers/${encodeURIComponent(t)}`);return new c(e)}async check(t,e,n={}){return i(this.http,"POST","/check",{app_user_id:t,entitlement:e,sandbox:!!n.sandbox})}};0&&(module.exports={CustomerInfo,EntitleHub,EntitleHubError,EntitleHubServer,EntitlementsApi,OfferingsApi,ProductsApi,isReceiptRevoked});
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- var u=class{constructor(t){this.appUserId=t.app_user_id,this.entitlements=t.active_entitlements??[];let e={};for(let r of this.entitlements)e[r.entitlement]=r;this.active=e}isActive(t){return!!this.active[t]}get activeEntitlementIds(){return Object.keys(this.active)}expirationDate(t){let e=this.active[t];if(e)return e.expires_at?new Date(e.expires_at):null}};var O="0.3.0";var a=class extends Error{constructor(t,e,r="error",o){super(t),this.name="EntitleHubError",this.status=e,this.code=r,this.body=o,this.apiCode=typeof o?.code=="string"?o.code:void 0}};function $(n){if(!n||typeof n!="object")return!1;let t=n;return t.apiCode==="receipt_revoked"||t.body?.code==="receipt_revoked"}var H=n=>new Promise(t=>setTimeout(t,n));async function i(n,t,e,r){let o=n.fetchImpl??globalThis.fetch;if(!o)throw new a("No fetch implementation available. On Node <18, pass fetchImpl.",0,"no_fetch");let y=`${n.baseUrl.replace(/\/$/,"")}${e}`,k=t==="GET"?n.retries??2:0,b;for(let f=0;f<=k;f++){let E=new AbortController,w=n.timeoutMs?setTimeout(()=>E.abort(),n.timeoutMs):void 0;try{let c=await o(y,{method:t,headers:{Authorization:`Bearer ${n.apiKey}`,"X-EntitleHub-Client":n.client??`${"js"}/${O}`,...r?{"Content-Type":"application/json"}:{}},body:r?JSON.stringify(r):void 0,signal:E.signal}),T=await c.text(),h=T?U(T):{};if(!c.ok){let v=`HTTP ${c.status}`,P=h&&typeof h=="object"?h:void 0;throw P&&"error"in P&&(v=String(P.error)),new a(v,c.status,c.status===401||c.status===403?"auth":"http",P)}return h}catch(c){if(b=c,c instanceof a)throw c;f<k&&await H(250*(f+1))}finally{w&&clearTimeout(w)}}throw new a(`Network request failed: ${String(b?.message??b)}`,0,"network")}function U(n){try{return JSON.parse(n)}catch{return{}}}var C=class{constructor(t){this.listeners=new Set;if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.appUserId)throw new a("appUserId is required.",0,"config");if(t.apiKey.startsWith("sk_"))throw new a("Never use a secret (sk_) key in the client SDK. Use your publishable (pk_) key.",0,"config");this.appUserId=t.appUserId,this.cacheTtlMs=t.cacheTtlMs??5*6e4,this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3,client:t.client}}get currentAppUserId(){return this.appUserId}async logIn(t){return this.appUserId=t,this.cached=void 0,this.getCustomerInfo({fetchPolicy:"network-only"})}logOut(){this.cached=void 0}async getCustomerInfo(t={}){if((t.fetchPolicy??"cache-first")==="cache-first"&&this.cached&&Date.now()-this.cached.at<this.cacheTtlMs)return this.cached.info;let r=await i(this.http,"GET",`/subscribers/${encodeURIComponent(this.appUserId)}`),o=new u(r);this.cached={info:o,at:Date.now()};for(let y of this.listeners)try{y(o)}catch{}return o}async isEntitled(t){return(await this.getCustomerInfo()).isActive(t)}async checkEntitlement(t,e={}){return i(this.http,"POST","/check",{app_user_id:this.appUserId,entitlement:t,sandbox:!!e.sandbox})}async getOfferings(){return i(this.http,"GET","/offerings")}async reportPurchase(t){let e=await i(this.http,"POST",`/subscribers/${encodeURIComponent(this.appUserId)}/purchases`,{store:t.store??"",store_product_id:t.storeProductId??"",is_sandbox:!!t.isSandbox,purchase_token:t.purchaseToken??"",is_subscription:!!t.isSubscription,signed_transaction:t.signedTransaction??"",stripe_subscription_id:t.stripeSubscriptionId??""}),r=new u(e);this.cached={info:r,at:Date.now()};for(let o of this.listeners)try{o(r)}catch{}return r}addCustomerInfoUpdateListener(t){return this.listeners.add(t),()=>this.listeners.delete(t)}};var s=encodeURIComponent;function p(n){return typeof n=="string"?n:"id"in n?{id:n.id}:{store:n.store,store_product_id:n.storeProductId}}function d(n){return typeof n=="string"?{seg:s(n),qs:""}:"id"in n?{seg:s(n.id),qs:""}:{seg:s(n.storeProductId),qs:`?store=${s(n.store)}`}}var _=n=>n?.includeArchived?"include_archived=true":"";async function x(n,t){try{return await n()}catch(e){if(e instanceof a&&e.apiCode===t&&e.body?.existing)return e.body.existing;throw e}}var l=class{constructor(t){this.http=t}async list(t){let e=_(t);return(await i(this.http,"GET",`/entitlements${e?`?${e}`:""}`)).entitlements}get(t){return i(this.http,"GET",`/entitlements/${s(t)}`)}create(t){return i(this.http,"POST","/entitlements",{key:t.key,name:t.name,description:t.description,products:t.products?.map(p)})}ensure(t){return x(()=>this.create(t),"entitlement_exists")}update(t,e){return i(this.http,"PATCH",`/entitlements/${s(t)}`,{name:e.name,description:e.description,products:e.products?.map(p)})}delete(t){return i(this.http,"DELETE",`/entitlements/${s(t)}`)}async products(t,e){let r=_(e);return(await i(this.http,"GET",`/entitlements/${s(t)}/products${r?`?${r}`:""}`)).products}attachProducts(t,e){return i(this.http,"POST",`/entitlements/${s(t)}/attach_products`,{products:e.map(p)})}detachProducts(t,e){return i(this.http,"POST",`/entitlements/${s(t)}/detach_products`,{products:e.map(p)})}archive(t){return i(this.http,"POST",`/entitlements/${s(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/entitlements/${s(t)}/unarchive`)}},g=class{constructor(t){this.http=t}async list(t){let e=new URLSearchParams;t?.store&&e.set("store",t.store),t?.entitlement&&e.set("entitlement",t.entitlement),t?.includeArchived&&e.set("include_archived","true");let r=e.toString();return(await i(this.http,"GET",`/products${r?`?${r}`:""}`)).products}get(t){let{seg:e,qs:r}=d(t);return i(this.http,"GET",`/products/${e}${r}`)}create(t){return i(this.http,"POST","/products",{store:t.store,store_product_id:t.storeProductId,type:t.type,duration:t.duration,display_name:t.displayName,price_micros:t.priceMicros,currency:t.currency,entitlements:t.entitlements})}ensure(t){return x(()=>this.create(t),"product_exists")}update(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"PATCH",`/products/${r}${o}`,{display_name:e.displayName,price_micros:e.priceMicros,currency:e.currency,entitlements:e.entitlements})}delete(t){let{seg:e,qs:r}=d(t);return i(this.http,"DELETE",`/products/${e}${r}`)}attachEntitlements(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"POST",`/products/${r}/attach_entitlements${o}`,{entitlements:e})}detachEntitlements(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"POST",`/products/${r}/detach_entitlements${o}`,{entitlements:e})}archive(t){let{seg:e,qs:r}=d(t);return i(this.http,"POST",`/products/${e}/archive${r}`)}unarchive(t){let{seg:e,qs:r}=d(t);return i(this.http,"POST",`/products/${e}/unarchive${r}`)}},m=class{constructor(t){this.http=t}async list(t){let e=_(t);return(await i(this.http,"GET",`/offerings/all${e?`?${e}`:""}`)).offerings}get(t){return i(this.http,"GET",`/offerings/${s(t)}`)}create(t){return i(this.http,"POST","/offerings",{identifier:t.identifier,display_name:t.displayName,is_current:t.isCurrent,metadata:t.metadata,packages:t.packages?.map(S)})}update(t,e){return i(this.http,"PATCH",`/offerings/${s(t)}`,{display_name:e.displayName,is_current:e.isCurrent,metadata:e.metadata})}delete(t){return i(this.http,"DELETE",`/offerings/${s(t)}`)}archive(t){return i(this.http,"POST",`/offerings/${s(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/offerings/${s(t)}/unarchive`)}async packages(t){return(await i(this.http,"GET",`/offerings/${s(t)}/packages`)).packages}addPackage(t,e){return i(this.http,"POST",`/offerings/${s(t)}/packages`,S(e))}updatePackage(t,e,r){return i(this.http,"PATCH",`/offerings/${s(t)}/packages/${s(e)}`,{display_name:r.displayName,position:r.position,product:r.product===void 0?void 0:p(r.product)})}deletePackage(t,e){return i(this.http,"DELETE",`/offerings/${s(t)}/packages/${s(e)}`)}};function S(n){return{identifier:n.identifier,product:p(n.product),position:n.position,display_name:n.displayName}}var I=class{constructor(t){if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.apiKey.startsWith("sk_"))throw new a("EntitleHubServer needs a secret (sk_) key. For client reads, use the EntitleHub class with a pk_ key.",0,"config");this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3},this.entitlements=new l(this.http),this.products=new g(this.http),this.offerings=new m(this.http)}async reportPurchase(t,e){let r=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/purchases`,{store:e.store,store_product_id:e.storeProductId,is_sandbox:!!e.isSandbox,transaction_id:e.transactionId??"",purchase_token:e.purchaseToken??"",is_subscription:!!e.isSubscription,signed_transaction:e.signedTransaction??"",stripe_subscription_id:e.stripeSubscriptionId??""});return new u(r)}async grantEntitlement(t,e,r={}){let o=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/grant`,{entitlement:e,duration_days:r.durationDays??0,is_sandbox:!!r.isSandbox});return new u(o)}async getCustomerInfo(t){let e=await i(this.http,"GET",`/subscribers/${encodeURIComponent(t)}`);return new u(e)}async check(t,e,r={}){return i(this.http,"POST","/check",{app_user_id:t,entitlement:e,sandbox:!!r.sandbox})}};export{u as CustomerInfo,C as EntitleHub,a as EntitleHubError,I as EntitleHubServer,l as EntitlementsApi,m as OfferingsApi,g as ProductsApi,$ as isReceiptRevoked};
1
+ var u=class{constructor(t){this.appUserId=t.app_user_id,this.entitlements=t.active_entitlements??[];let e={};for(let r of this.entitlements)e[r.entitlement]=r;this.active=e}isActive(t){return!!this.active[t]}get activeEntitlementIds(){return Object.keys(this.active)}expirationDate(t){let e=this.active[t];if(e)return e.expires_at?new Date(e.expires_at):null}};var O="0.3.2";var a=class extends Error{constructor(t,e,r="error",o){super(t),this.name="EntitleHubError",this.status=e,this.code=r,this.body=o,this.apiCode=typeof o?.code=="string"?o.code:void 0}};function $(n){if(!n||typeof n!="object")return!1;let t=n;return t.apiCode==="receipt_revoked"||t.body?.code==="receipt_revoked"}var H=n=>new Promise(t=>setTimeout(t,n));async function i(n,t,e,r){let o=n.fetchImpl??globalThis.fetch;if(!o)throw new a("No fetch implementation available. On Node <18, pass fetchImpl.",0,"no_fetch");let y=`${n.baseUrl.replace(/\/$/,"")}${e}`,k=t==="GET"?n.retries??2:0,b;for(let f=0;f<=k;f++){let E=new AbortController,w=n.timeoutMs?setTimeout(()=>E.abort(),n.timeoutMs):void 0;try{let c=await o(y,{method:t,headers:{Authorization:`Bearer ${n.apiKey}`,"X-EntitleHub-Client":n.client??`${"js"}/${O}`,...r?{"Content-Type":"application/json"}:{}},body:r?JSON.stringify(r):void 0,signal:E.signal}),T=await c.text(),h=T?U(T):{};if(!c.ok){let v=`HTTP ${c.status}`,P=h&&typeof h=="object"?h:void 0;throw P&&"error"in P&&(v=String(P.error)),new a(v,c.status,c.status===401||c.status===403?"auth":"http",P)}return h}catch(c){if(b=c,c instanceof a)throw c;f<k&&await H(250*(f+1))}finally{w&&clearTimeout(w)}}throw new a(`Network request failed: ${String(b?.message??b)}`,0,"network")}function U(n){try{return JSON.parse(n)}catch{return{}}}var C=class{constructor(t){this.listeners=new Set;if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.appUserId)throw new a("appUserId is required.",0,"config");if(t.apiKey.startsWith("sk_"))throw new a("Never use a secret (sk_) key in the client SDK. Use your publishable (pk_) key.",0,"config");this.appUserId=t.appUserId,this.cacheTtlMs=t.cacheTtlMs??5*6e4,this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3,client:t.client}}get currentAppUserId(){return this.appUserId}async logIn(t){return this.appUserId=t,this.cached=void 0,this.getCustomerInfo({fetchPolicy:"network-only"})}logOut(){this.cached=void 0}async getCustomerInfo(t={}){if((t.fetchPolicy??"cache-first")==="cache-first"&&this.cached&&Date.now()-this.cached.at<this.cacheTtlMs)return this.cached.info;let r=await i(this.http,"GET",`/subscribers/${encodeURIComponent(this.appUserId)}`),o=new u(r);this.cached={info:o,at:Date.now()};for(let y of this.listeners)try{y(o)}catch{}return o}async isEntitled(t){return(await this.getCustomerInfo()).isActive(t)}async checkEntitlement(t,e={}){return i(this.http,"POST","/check",{app_user_id:this.appUserId,entitlement:t,sandbox:!!e.sandbox})}async getOfferings(){return i(this.http,"GET","/offerings")}async reportPurchase(t){let e=await i(this.http,"POST",`/subscribers/${encodeURIComponent(this.appUserId)}/purchases`,{store:t.store??"",store_product_id:t.storeProductId??"",is_sandbox:!!t.isSandbox,purchase_token:t.purchaseToken??"",is_subscription:!!t.isSubscription,signed_transaction:t.signedTransaction??"",stripe_subscription_id:t.stripeSubscriptionId??""}),r=new u(e);this.cached={info:r,at:Date.now()};for(let o of this.listeners)try{o(r)}catch{}return r}addCustomerInfoUpdateListener(t){return this.listeners.add(t),()=>this.listeners.delete(t)}};var s=encodeURIComponent;function p(n){return typeof n=="string"?n:"id"in n?{id:n.id}:{store:n.store,store_product_id:n.storeProductId}}function d(n){return typeof n=="string"?{seg:s(n),qs:""}:"id"in n?{seg:s(n.id),qs:""}:{seg:s(n.storeProductId),qs:`?store=${s(n.store)}`}}var _=n=>n?.includeArchived?"include_archived=true":"";async function x(n,t){try{return await n()}catch(e){if(e instanceof a&&e.apiCode===t&&e.body?.existing)return e.body.existing;throw e}}var l=class{constructor(t){this.http=t}async list(t){let e=_(t);return(await i(this.http,"GET",`/entitlements${e?`?${e}`:""}`)).entitlements}get(t){return i(this.http,"GET",`/entitlements/${s(t)}`)}create(t){return i(this.http,"POST","/entitlements",{key:t.key,name:t.name,description:t.description,products:t.products?.map(p)})}ensure(t){return x(()=>this.create(t),"entitlement_exists")}update(t,e){return i(this.http,"PATCH",`/entitlements/${s(t)}`,{name:e.name,description:e.description,products:e.products?.map(p)})}delete(t){return i(this.http,"DELETE",`/entitlements/${s(t)}`)}async products(t,e){let r=_(e);return(await i(this.http,"GET",`/entitlements/${s(t)}/products${r?`?${r}`:""}`)).products}attachProducts(t,e){return i(this.http,"POST",`/entitlements/${s(t)}/attach_products`,{products:e.map(p)})}detachProducts(t,e){return i(this.http,"POST",`/entitlements/${s(t)}/detach_products`,{products:e.map(p)})}archive(t){return i(this.http,"POST",`/entitlements/${s(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/entitlements/${s(t)}/unarchive`)}},g=class{constructor(t){this.http=t}async list(t){let e=new URLSearchParams;t?.store&&e.set("store",t.store),t?.entitlement&&e.set("entitlement",t.entitlement),t?.includeArchived&&e.set("include_archived","true");let r=e.toString();return(await i(this.http,"GET",`/products${r?`?${r}`:""}`)).products}get(t){let{seg:e,qs:r}=d(t);return i(this.http,"GET",`/products/${e}${r}`)}create(t){return i(this.http,"POST","/products",{store:t.store,store_product_id:t.storeProductId,type:t.type,duration:t.duration,display_name:t.displayName,price_micros:t.priceMicros,currency:t.currency,entitlements:t.entitlements})}ensure(t){return x(()=>this.create(t),"product_exists")}update(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"PATCH",`/products/${r}${o}`,{display_name:e.displayName,price_micros:e.priceMicros,currency:e.currency,entitlements:e.entitlements})}delete(t){let{seg:e,qs:r}=d(t);return i(this.http,"DELETE",`/products/${e}${r}`)}attachEntitlements(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"POST",`/products/${r}/attach_entitlements${o}`,{entitlements:e})}detachEntitlements(t,e){let{seg:r,qs:o}=d(t);return i(this.http,"POST",`/products/${r}/detach_entitlements${o}`,{entitlements:e})}archive(t){let{seg:e,qs:r}=d(t);return i(this.http,"POST",`/products/${e}/archive${r}`)}unarchive(t){let{seg:e,qs:r}=d(t);return i(this.http,"POST",`/products/${e}/unarchive${r}`)}},m=class{constructor(t){this.http=t}async list(t){let e=_(t);return(await i(this.http,"GET",`/offerings/all${e?`?${e}`:""}`)).offerings}get(t){return i(this.http,"GET",`/offerings/${s(t)}`)}create(t){return i(this.http,"POST","/offerings",{identifier:t.identifier,display_name:t.displayName,is_current:t.isCurrent,metadata:t.metadata,packages:t.packages?.map(S)})}update(t,e){return i(this.http,"PATCH",`/offerings/${s(t)}`,{display_name:e.displayName,is_current:e.isCurrent,metadata:e.metadata})}delete(t){return i(this.http,"DELETE",`/offerings/${s(t)}`)}archive(t){return i(this.http,"POST",`/offerings/${s(t)}/archive`)}unarchive(t){return i(this.http,"POST",`/offerings/${s(t)}/unarchive`)}async packages(t){return(await i(this.http,"GET",`/offerings/${s(t)}/packages`)).packages}addPackage(t,e){return i(this.http,"POST",`/offerings/${s(t)}/packages`,S(e))}updatePackage(t,e,r){return i(this.http,"PATCH",`/offerings/${s(t)}/packages/${s(e)}`,{display_name:r.displayName,position:r.position,product:r.product===void 0?void 0:p(r.product)})}deletePackage(t,e){return i(this.http,"DELETE",`/offerings/${s(t)}/packages/${s(e)}`)}};function S(n){return{identifier:n.identifier,product:p(n.product),position:n.position,display_name:n.displayName}}var I=class{constructor(t){if(!t.apiKey)throw new a("apiKey is required.",0,"config");if(!t.apiKey.startsWith("sk_"))throw new a("EntitleHubServer needs a secret (sk_) key. For client reads, use the EntitleHub class with a pk_ key.",0,"config");this.http={baseUrl:t.baseUrl??"https://entitlehub.com/v1",apiKey:t.apiKey,fetchImpl:t.fetchImpl,timeoutMs:15e3},this.entitlements=new l(this.http),this.products=new g(this.http),this.offerings=new m(this.http)}async reportPurchase(t,e){let r=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/purchases`,{store:e.store,store_product_id:e.storeProductId,is_sandbox:!!e.isSandbox,transaction_id:e.transactionId??"",purchase_token:e.purchaseToken??"",is_subscription:!!e.isSubscription,signed_transaction:e.signedTransaction??"",stripe_subscription_id:e.stripeSubscriptionId??""});return new u(r)}async grantEntitlement(t,e,r={}){let o=await i(this.http,"POST",`/subscribers/${encodeURIComponent(t)}/grant`,{entitlement:e,duration_days:r.durationDays??0,is_sandbox:!!r.isSandbox});return new u(o)}async getCustomerInfo(t){let e=await i(this.http,"GET",`/subscribers/${encodeURIComponent(t)}`);return new u(e)}async check(t,e,r={}){return i(this.http,"POST","/check",{app_user_id:t,entitlement:e,sandbox:!!r.sandbox})}};export{u as CustomerInfo,C as EntitleHub,a as EntitleHubError,I as EntitleHubServer,l as EntitlementsApi,m as OfferingsApi,g as ProductsApi,$ as isReceiptRevoked};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@entitlehub/sdk",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "EntitleHub SDK: one entitlement API across App Store, Google Play, Stripe, and web. Works in browsers, React Native, Expo, and Node.",
5
5
  "keywords": [
6
6
  "entitlehub",
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  "sideEffects": false,
44
44
  "scripts": {
45
- "build": "tsup src/index.ts --format esm,cjs --dts --clean --minify",
45
+ "build": "node scripts/gen-version.mjs && tsup src/index.ts --format esm,cjs --dts --clean --minify",
46
46
  "typecheck": "tsc --noEmit",
47
47
  "test": "node --test \"test/*.test.mjs\"",
48
48
  "prepublishOnly": "npm run build"