@mobtechi/sdk-core 1.0.0 → 1.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.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @mobtechi/sdk-core
2
+
3
+ The official, framework-agnostic core logic and API client for the MobTechi platform. This library provides a robust foundation for interacting with MobTechi services, including authentication, subscriptions, analytics, and ads.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @mobtechi/sdk-core
9
+ ```
10
+ or
11
+ ```bash
12
+ yarn add @mobtechi/sdk-core
13
+ ```
14
+
15
+ ## Getting Started
16
+
17
+ The SDK exposes a `MobTechi` class that automatically wires up the underlying API client, analytics tracker, and entitlement engine.
18
+
19
+ ```typescript
20
+ import { MobTechi, MemoryStorageProvider } from '@mobtechi/sdk-core';
21
+
22
+ const mobtechi = new MobTechi({
23
+ baseUrl: 'https://api.mobtechi.com', // Replace with your environment URL
24
+ appId: 'your-app-id',
25
+ orgId: 'your-org-id', // Optional
26
+ storage: new MemoryStorageProvider(), // Replace with localStorage/AsyncStorage provider for persistence
27
+ tokenKey: 'mobtechi_auth_token'
28
+ });
29
+
30
+ // Access components
31
+ const apiClient = mobtechi.api;
32
+ const entitlements = mobtechi.entitlements;
33
+ const analytics = mobtechi.analytics;
34
+ ```
35
+
36
+ ## Core Features & Modules
37
+
38
+ ### 1. Authentication
39
+ Handles user identity, login, OTP verification, and token management automatically. Token is seamlessly injected into subsequent API calls.
40
+
41
+ ```typescript
42
+ // 1. Identify User
43
+ await mobtechi.api.identify({ identifier: 'user@example.com', app_id: '...', org_id: '...' });
44
+
45
+ // 2. Login (Send OTP or Password)
46
+ await mobtechi.login({ identifier: 'user@example.com', app_id: '...', org_id: '...' });
47
+
48
+ // 3. Verify OTP (Automatically sets the access token upon success)
49
+ await mobtechi.verifyOtp({ identifier: 'user@example.com', code: '123456', app_id: '...', org_id: '...' });
50
+
51
+ // 4. Logout (Clears local token and resets entitlements)
52
+ await mobtechi.logout();
53
+ ```
54
+
55
+ ### 2. Entitlements & Subscriptions
56
+ Manage user access to premium features based on their active subscription.
57
+
58
+ ```typescript
59
+ // Sync entitlements from the server
60
+ const payload = await mobtechi.syncEntitlements('your-app-id');
61
+
62
+ // Check feature access synchronously after syncing
63
+ if (mobtechi.entitlements.hasFeature('premium_analytics')) {
64
+ // Grant access
65
+ }
66
+
67
+ // Check premium status
68
+ const isPremium = mobtechi.entitlements.isPremiumUser();
69
+ ```
70
+
71
+ Direct API methods for subscriptions are available on the `api` client:
72
+ - `api.getPlans()`
73
+ - `api.getSubscriptionStatus()`
74
+ - `api.getEntitlements()`
75
+ - `api.createOrder()`
76
+ - `api.createSubscription()`
77
+ - `api.createTopUp()`
78
+
79
+ ### 3. Ads Config
80
+ Fetch user-specific or app-specific ad configurations and claim rewards.
81
+
82
+ ```typescript
83
+ // Get Ad configs
84
+ const adsConfig = await mobtechi.api.getAdsConfig('your-org-id', 'your-app-key');
85
+
86
+ // Claim rewards
87
+ await mobtechi.api.claimReward({ orgId: '...', appKey: '...', rewardType: '...' });
88
+ ```
89
+
90
+ ## Advanced Usage
91
+
92
+ ### Custom Storage Provider
93
+ By default, `@mobtechi/sdk-core` uses a `MemoryStorageProvider` which loses tokens upon app restart or page refresh. To persist sessions (e.g., in React Native or web), implement the `StorageProvider` interface:
94
+
95
+ ```typescript
96
+ import { StorageProvider } from '@mobtechi/sdk-core';
97
+
98
+ class LocalStorageProvider implements StorageProvider {
99
+ async getItem(key: string): Promise<string | null> {
100
+ return localStorage.getItem(key);
101
+ }
102
+ async setItem(key: string, value: string): Promise<void> {
103
+ localStorage.setItem(key, value);
104
+ }
105
+ async removeItem(key: string): Promise<void> {
106
+ localStorage.removeItem(key);
107
+ }
108
+ }
109
+
110
+ // Use it during initialization
111
+ const mobtechi = new MobTechi({
112
+ baseUrl: 'https://api.mobtechi.com',
113
+ appId: 'your-app-id',
114
+ storage: new LocalStorageProvider(),
115
+ });
116
+ ```
117
+
118
+ ### Generic API Requests
119
+ The `api` object provides generic HTTP methods (`get`, `post`, `put`, `patch`, `delete`) that automatically attach the authorization token and required app/org headers.
120
+
121
+ ```typescript
122
+ const response = await mobtechi.api.get('/custom/endpoint');
123
+ console.log(response.data);
124
+ ```
125
+
126
+ ## License
127
+ MIT
package/dist/index.d.mts CHANGED
@@ -251,5 +251,14 @@ declare class MobTechi {
251
251
  */
252
252
  syncEntitlements(appId: string): Promise<any>;
253
253
  }
254
+ /**
255
+ * Global singleton for framework-agnostic checks (e.g. Angular Ads/Subscription modules)
256
+ * Allows checking premium status without prop-drilling or context providers.
257
+ */
258
+ declare const MobTechiSDK: {
259
+ _isPremium: boolean;
260
+ setPremiumUser: (status: boolean) => void;
261
+ isPremiumUser: () => boolean;
262
+ };
254
263
 
255
- export { type AnalyticsEventPayload, AnalyticsTracker, type AuthDto, type AuthState, type Entitlement, EntitlementEngine, MemoryStorageProvider, MobTechi, MobTechiClient, type MobTechiClientOptions, type MobTechiEvent, type MobTechiUser, type PlanComparison, type StorageProvider, type SubscriptionEnvironment, type SubscriptionPlan, type SubscriptionTopup, type VerifyOtpDto };
264
+ export { type AnalyticsEventPayload, AnalyticsTracker, type AuthDto, type AuthState, type Entitlement, EntitlementEngine, MemoryStorageProvider, MobTechi, MobTechiClient, type MobTechiClientOptions, type MobTechiEvent, MobTechiSDK, type MobTechiUser, type PlanComparison, type StorageProvider, type SubscriptionEnvironment, type SubscriptionPlan, type SubscriptionTopup, type VerifyOtpDto };
package/dist/index.d.ts CHANGED
@@ -251,5 +251,14 @@ declare class MobTechi {
251
251
  */
252
252
  syncEntitlements(appId: string): Promise<any>;
253
253
  }
254
+ /**
255
+ * Global singleton for framework-agnostic checks (e.g. Angular Ads/Subscription modules)
256
+ * Allows checking premium status without prop-drilling or context providers.
257
+ */
258
+ declare const MobTechiSDK: {
259
+ _isPremium: boolean;
260
+ setPremiumUser: (status: boolean) => void;
261
+ isPremiumUser: () => boolean;
262
+ };
254
263
 
255
- export { type AnalyticsEventPayload, AnalyticsTracker, type AuthDto, type AuthState, type Entitlement, EntitlementEngine, MemoryStorageProvider, MobTechi, MobTechiClient, type MobTechiClientOptions, type MobTechiEvent, type MobTechiUser, type PlanComparison, type StorageProvider, type SubscriptionEnvironment, type SubscriptionPlan, type SubscriptionTopup, type VerifyOtpDto };
264
+ export { type AnalyticsEventPayload, AnalyticsTracker, type AuthDto, type AuthState, type Entitlement, EntitlementEngine, MemoryStorageProvider, MobTechi, MobTechiClient, type MobTechiClientOptions, type MobTechiEvent, MobTechiSDK, type MobTechiUser, type PlanComparison, type StorageProvider, type SubscriptionEnvironment, type SubscriptionPlan, type SubscriptionTopup, type VerifyOtpDto };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var T=Object.create;var p=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var x=(r,t)=>{for(var e in t)p(r,e,{get:t[e],enumerable:!0})},b=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of v(t))!P.call(r,i)&&i!==e&&p(r,i,{get:()=>t[i],enumerable:!(s=_(t,i))||s.enumerable});return r};var E=(r,t,e)=>(e=r!=null?T(I(r)):{},b(t||!r||!r.__esModule?p(e,"default",{value:r,enumerable:!0}):e,r)),$=r=>b(p({},"__esModule",{value:!0}),r);var A={};x(A,{AnalyticsTracker:()=>l,EntitlementEngine:()=>u,MemoryStorageProvider:()=>o,MobTechi:()=>y,MobTechiClient:()=>c});module.exports=$(A);var o=class{store={};getItem(t){return this.store[t]||null}setItem(t,e){this.store[t]=e}removeItem(t){delete this.store[t]}};var k=E(require("axios"));var c=class{client;baseUrl;storage;tokenKey;currentToken=null;appId;orgId;constructor(t,e,s,i,m){let d,a=e,n=s,g=i,f=m;typeof t=="object"&&t!==null?(d=t.baseUrl,a=t.appId,n=t.orgId,g=t.storage,f=t.tokenKey):d=t,this.baseUrl=d,this.appId=a,this.orgId=n,this.storage=g||new o,this.tokenKey=f||"mobtechi_auth_token",this.client=k.default.create({baseURL:this.baseUrl,headers:{"Content-Type":"application/json",...a&&{"x-app-id":a},...n&&{"x-org-id":n}}}),this.client.interceptors.request.use(async h=>{if(!this.currentToken){let w=await this.storage.getItem(this.tokenKey);w&&(this.currentToken=w)}return this.currentToken&&h.headers&&(h.headers.Authorization=`Bearer ${this.currentToken}`),h})}async setToken(t){this.currentToken=t,t?await this.storage.setItem(this.tokenKey,t):await this.storage.removeItem(this.tokenKey)}async getToken(){return this.currentToken||(this.currentToken=await this.storage.getItem(this.tokenKey)),this.currentToken}async get(t,e){let s=await this.client.get(t,e);return{data:s.data,status:s.status}}async post(t,e,s){let i=await this.client.post(t,e,s);return{data:i.data,status:i.status}}async put(t,e,s){let i=await this.client.put(t,e,s);return{data:i.data,status:i.status}}async patch(t,e,s){let i=await this.client.patch(t,e,s);return{data:i.data,status:i.status}}async delete(t,e){let s=await this.client.delete(t,e);return{data:s.data,status:s.status}}async identify(t){return(await this.client.post("/auth/identify",t)).data}async login(t){let e=await this.client.post("/auth/login",t);return{status:e.status,data:e.data}}async register(t){return(await this.client.post("/auth/register",t)).data}async verifyOtp(t){let e=await this.client.post("/auth/otp_verify",t);return{status:e.status,data:e.data}}async validateToken(t){return(await this.client.get("/auth/validate",{headers:{Authorization:`Bearer ${t}`}})).data}async refreshToken(t){return(await this.client.post("/auth/refresh",{refresh_token:t})).data}async logout(t){await this.client.delete("/auth/logout",{headers:{Authorization:`Bearer ${t}`}})}async updateProfile(t,e){let s=e?{Authorization:`Bearer ${e}`}:{};return(await this.client.put("/user/update-profile",t,{headers:s})).data}async getPlans(t,e){let s=t||this.orgId||"",i=e||this.appId||"";if(t&&!(a=>a?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(a):!1)(t)){i=t;let a=e||"",n=a?`?user_id=${a}`:"";return(await this.client.get(`/${i}/subscriptions/plans${n}`)).data}return(await this.client.get(`/user/subscription/plans?orgId=${s}&appKey=${i}`)).data}async getSubscriptionStatus(t,e){return(await this.client.get(`/user/subscription/status?appId=${t}`)).data}async getEntitlements(t){return(await this.client.get(`/${t}/subscriptions/entitlements`)).data}async createOrder(t,e){return(await this.client.post("/user/subscription/create-order",t)).data}async createSubscription(t,e){return(await this.client.post(`/${t}/subscriptions/create`,e)).data}async createTopUp(t,e){return(await this.client.post(`/${t}/subscriptions/topup`,e)).data}async getAdsConfig(t,e){return(await this.client.get(`/user/ads/config?orgId=${t}&appKey=${e}`)).data}async claimReward(t){return(await this.client.post("/user/rewards/ad-claim",t)).data}};var u=class{entitlements=[];isPremiumFlag=!1;setState(t,e=[]){this.isPremiumFlag=t,this.entitlements=e}checkPremium(){return this.isPremiumFlag?!0:this.entitlements.some(t=>t.active&&t.tier!=="FREE")}hasFeature(t){return this.isPremiumFlag?!0:this.entitlements.some(e=>e.active&&e.granted_features&&e.granted_features.includes(t))}};var l=class{constructor(t,e){this.api=t;this.appId=e}api;appId;sessionEvents=new Set;async shouldDeduplicate(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;return await this.api.storage.getItem(e)==="true"}return t==="paywall_viewed"?this.sessionEvents.has(t):!1}async markTracked(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;await this.api.storage.setItem(e,"true")}else t==="paywall_viewed"&&this.sessionEvents.add(t)}track(t,e){(async()=>{await this.shouldDeduplicate(t)||(await this.markTracked(t),await this.capture({event_name:t,payload:e}))})().catch(s=>{console.warn(`[MobTechi Analytics] failed async track for ${t}`,s)})}trackError(t,e,s){(async()=>{await this.capture({event_name:t,is_error:!0,stack_trace:e.stack,metadata:s})})().catch(i=>{console.warn(`[MobTechi Analytics] failed async trackError for ${t}`,i)})}async capture(t){try{await this.api.post("/analytics/capture",{app_id:this.appId,...t})}catch{console.warn(`[MobTechi Analytics] Failed to track event: ${t.event_name}`)}}};var y=class{api;entitlements;analytics;constructor(t){this.api=new c(t),this.entitlements=new u,this.analytics=new l(this.api,t.appId||"unknown")}async login(t){return await this.api.login(t)}async verifyOtp(t){let e=await this.api.verifyOtp(t);return e.data&&e.data.token&&await this.api.setToken(e.data.token),e}async logout(){let t=await this.api.getToken();if(t)try{await this.api.logout(t)}catch{}await this.api.setToken(null),this.entitlements.setState(!1,[])}async syncEntitlements(t){try{let e=await this.api.getEntitlements(t);if(e){let s=!!e.isPremium,i=e.features||[];this.entitlements.setState(s,i)}return e}catch(e){throw console.error("Failed to sync entitlements",e),e}}};0&&(module.exports={AnalyticsTracker,EntitlementEngine,MemoryStorageProvider,MobTechi,MobTechiClient});
1
+ "use strict";var _=Object.create;var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var E=(r,t)=>{for(var e in t)p(r,e,{get:t[e],enumerable:!0})},T=(r,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of I(t))!x.call(r,i)&&i!==e&&p(r,i,{get:()=>t[i],enumerable:!(s=v(t,i))||s.enumerable});return r};var $=(r,t,e)=>(e=r!=null?_(P(r)):{},T(t||!r||!r.__esModule?p(e,"default",{value:r,enumerable:!0}):e,r)),A=r=>T(p({},"__esModule",{value:!0}),r);var S={};E(S,{AnalyticsTracker:()=>l,EntitlementEngine:()=>u,MemoryStorageProvider:()=>o,MobTechi:()=>y,MobTechiClient:()=>c,MobTechiSDK:()=>g});module.exports=A(S);var o=class{store={};getItem(t){return this.store[t]||null}setItem(t,e){this.store[t]=e}removeItem(t){delete this.store[t]}};var k=$(require("axios"));var c=class{client;baseUrl;storage;tokenKey;currentToken=null;appId;orgId;constructor(t,e,s,i,f){let d,a=e,n=s,h=i,w=f;typeof t=="object"&&t!==null?(d=t.baseUrl,a=t.appId,n=t.orgId,h=t.storage,w=t.tokenKey):d=t,this.baseUrl=d,this.appId=a,this.orgId=n,this.storage=h||new o,this.tokenKey=w||"mobtechi_auth_token",this.client=k.default.create({baseURL:this.baseUrl,headers:{"Content-Type":"application/json",...a&&{"x-app-id":a},...n&&{"x-org-id":n}}}),this.client.interceptors.request.use(async m=>{if(!this.currentToken){let b=await this.storage.getItem(this.tokenKey);b&&(this.currentToken=b)}return this.currentToken&&m.headers&&(m.headers.Authorization=`Bearer ${this.currentToken}`),m})}async setToken(t){this.currentToken=t,t?await this.storage.setItem(this.tokenKey,t):await this.storage.removeItem(this.tokenKey)}async getToken(){return this.currentToken||(this.currentToken=await this.storage.getItem(this.tokenKey)),this.currentToken}async get(t,e){let s=await this.client.get(t,e);return{data:s.data,status:s.status}}async post(t,e,s){let i=await this.client.post(t,e,s);return{data:i.data,status:i.status}}async put(t,e,s){let i=await this.client.put(t,e,s);return{data:i.data,status:i.status}}async patch(t,e,s){let i=await this.client.patch(t,e,s);return{data:i.data,status:i.status}}async delete(t,e){let s=await this.client.delete(t,e);return{data:s.data,status:s.status}}async identify(t){return(await this.client.post("/auth/identify",t)).data}async login(t){let e=await this.client.post("/auth/login",t);return{status:e.status,data:e.data}}async register(t){return(await this.client.post("/auth/register",t)).data}async verifyOtp(t){let e=await this.client.post("/auth/otp_verify",t);return{status:e.status,data:e.data}}async validateToken(t){return(await this.client.get("/auth/validate",{headers:{Authorization:`Bearer ${t}`}})).data}async refreshToken(t){return(await this.client.post("/auth/refresh",{refresh_token:t})).data}async logout(t){await this.client.delete("/auth/logout",{headers:{Authorization:`Bearer ${t}`}})}async updateProfile(t,e){let s=e?{Authorization:`Bearer ${e}`}:{};return(await this.client.put("/user/update-profile",t,{headers:s})).data}async getPlans(t,e){let s=t||this.orgId||"",i=e||this.appId||"";if(t&&!(a=>a?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(a):!1)(t)){i=t;let a=e||"",n=a?`?user_id=${a}`:"";return(await this.client.get(`/${i}/subscriptions/plans${n}`)).data}return(await this.client.get(`/user/subscription/plans?orgId=${s}&appKey=${i}`)).data}async getSubscriptionStatus(t,e){return(await this.client.get(`/user/subscription/status?appId=${t}`)).data}async getEntitlements(t){return(await this.client.get(`/${t}/subscriptions/entitlements`)).data}async createOrder(t,e){return(await this.client.post("/user/subscription/create-order",t)).data}async createSubscription(t,e){return(await this.client.post(`/${t}/subscriptions/create`,e)).data}async createTopUp(t,e){return(await this.client.post(`/${t}/subscriptions/topup`,e)).data}async getAdsConfig(t,e){return(await this.client.get(`/user/ads/config?orgId=${t}&appKey=${e}`)).data}async claimReward(t){return(await this.client.post("/user/rewards/ad-claim",t)).data}};var u=class{entitlements=[];isPremiumFlag=!1;setState(t,e=[]){this.isPremiumFlag=t,this.entitlements=e}checkPremium(){return this.isPremiumFlag?!0:this.entitlements.some(t=>t.active&&t.tier!=="FREE")}hasFeature(t){return this.isPremiumFlag?!0:this.entitlements.some(e=>e.active&&e.granted_features&&e.granted_features.includes(t))}};var l=class{constructor(t,e){this.api=t;this.appId=e}api;appId;sessionEvents=new Set;async shouldDeduplicate(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;return await this.api.storage.getItem(e)==="true"}return t==="paywall_viewed"?this.sessionEvents.has(t):!1}async markTracked(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;await this.api.storage.setItem(e,"true")}else t==="paywall_viewed"&&this.sessionEvents.add(t)}track(t,e){(async()=>{await this.shouldDeduplicate(t)||(await this.markTracked(t),await this.capture({event_name:t,payload:e}))})().catch(s=>{console.warn(`[MobTechi Analytics] failed async track for ${t}`,s)})}trackError(t,e,s){(async()=>{await this.capture({event_name:t,is_error:!0,stack_trace:e.stack,metadata:s})})().catch(i=>{console.warn(`[MobTechi Analytics] failed async trackError for ${t}`,i)})}async capture(t){try{await this.api.post("/analytics/capture",{app_id:this.appId,...t})}catch{console.warn(`[MobTechi Analytics] Failed to track event: ${t.event_name}`)}}};var y=class{api;entitlements;analytics;constructor(t){this.api=new c(t),this.entitlements=new u,this.analytics=new l(this.api,t.appId||"unknown")}async login(t){return await this.api.login(t)}async verifyOtp(t){let e=await this.api.verifyOtp(t);return e.data&&e.data.token&&await this.api.setToken(e.data.token),e}async logout(){let t=await this.api.getToken();if(t)try{await this.api.logout(t)}catch{}await this.api.setToken(null),this.entitlements.setState(!1,[])}async syncEntitlements(t){try{let e=await this.api.getEntitlements(t);if(e){let s=!!e.isPremium,i=e.features||[];this.entitlements.setState(s,i),g.setPremiumUser(s)}return e}catch(e){throw console.error("Failed to sync entitlements",e),e}}},g={_isPremium:!1,setPremiumUser:r=>{g._isPremium=r},isPremiumUser:()=>g._isPremium};0&&(module.exports={AnalyticsTracker,EntitlementEngine,MemoryStorageProvider,MobTechi,MobTechiClient,MobTechiSDK});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var c=class{store={};getItem(t){return this.store[t]||null}setItem(t,e){this.store[t]=e}removeItem(t){delete this.store[t]}};import w from"axios";var u=class{client;baseUrl;storage;tokenKey;currentToken=null;appId;orgId;constructor(t,e,s,i,h){let o,r=e,a=s,p=i,y=h;typeof t=="object"&&t!==null?(o=t.baseUrl,r=t.appId,a=t.orgId,p=t.storage,y=t.tokenKey):o=t,this.baseUrl=o,this.appId=r,this.orgId=a,this.storage=p||new c,this.tokenKey=y||"mobtechi_auth_token",this.client=w.create({baseURL:this.baseUrl,headers:{"Content-Type":"application/json",...r&&{"x-app-id":r},...a&&{"x-org-id":a}}}),this.client.interceptors.request.use(async g=>{if(!this.currentToken){let m=await this.storage.getItem(this.tokenKey);m&&(this.currentToken=m)}return this.currentToken&&g.headers&&(g.headers.Authorization=`Bearer ${this.currentToken}`),g})}async setToken(t){this.currentToken=t,t?await this.storage.setItem(this.tokenKey,t):await this.storage.removeItem(this.tokenKey)}async getToken(){return this.currentToken||(this.currentToken=await this.storage.getItem(this.tokenKey)),this.currentToken}async get(t,e){let s=await this.client.get(t,e);return{data:s.data,status:s.status}}async post(t,e,s){let i=await this.client.post(t,e,s);return{data:i.data,status:i.status}}async put(t,e,s){let i=await this.client.put(t,e,s);return{data:i.data,status:i.status}}async patch(t,e,s){let i=await this.client.patch(t,e,s);return{data:i.data,status:i.status}}async delete(t,e){let s=await this.client.delete(t,e);return{data:s.data,status:s.status}}async identify(t){return(await this.client.post("/auth/identify",t)).data}async login(t){let e=await this.client.post("/auth/login",t);return{status:e.status,data:e.data}}async register(t){return(await this.client.post("/auth/register",t)).data}async verifyOtp(t){let e=await this.client.post("/auth/otp_verify",t);return{status:e.status,data:e.data}}async validateToken(t){return(await this.client.get("/auth/validate",{headers:{Authorization:`Bearer ${t}`}})).data}async refreshToken(t){return(await this.client.post("/auth/refresh",{refresh_token:t})).data}async logout(t){await this.client.delete("/auth/logout",{headers:{Authorization:`Bearer ${t}`}})}async updateProfile(t,e){let s=e?{Authorization:`Bearer ${e}`}:{};return(await this.client.put("/user/update-profile",t,{headers:s})).data}async getPlans(t,e){let s=t||this.orgId||"",i=e||this.appId||"";if(t&&!(r=>r?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r):!1)(t)){i=t;let r=e||"",a=r?`?user_id=${r}`:"";return(await this.client.get(`/${i}/subscriptions/plans${a}`)).data}return(await this.client.get(`/user/subscription/plans?orgId=${s}&appKey=${i}`)).data}async getSubscriptionStatus(t,e){return(await this.client.get(`/user/subscription/status?appId=${t}`)).data}async getEntitlements(t){return(await this.client.get(`/${t}/subscriptions/entitlements`)).data}async createOrder(t,e){return(await this.client.post("/user/subscription/create-order",t)).data}async createSubscription(t,e){return(await this.client.post(`/${t}/subscriptions/create`,e)).data}async createTopUp(t,e){return(await this.client.post(`/${t}/subscriptions/topup`,e)).data}async getAdsConfig(t,e){return(await this.client.get(`/user/ads/config?orgId=${t}&appKey=${e}`)).data}async claimReward(t){return(await this.client.post("/user/rewards/ad-claim",t)).data}};var l=class{entitlements=[];isPremiumFlag=!1;setState(t,e=[]){this.isPremiumFlag=t,this.entitlements=e}checkPremium(){return this.isPremiumFlag?!0:this.entitlements.some(t=>t.active&&t.tier!=="FREE")}hasFeature(t){return this.isPremiumFlag?!0:this.entitlements.some(e=>e.active&&e.granted_features&&e.granted_features.includes(t))}};var d=class{constructor(t,e){this.api=t;this.appId=e}api;appId;sessionEvents=new Set;async shouldDeduplicate(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;return await this.api.storage.getItem(e)==="true"}return t==="paywall_viewed"?this.sessionEvents.has(t):!1}async markTracked(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;await this.api.storage.setItem(e,"true")}else t==="paywall_viewed"&&this.sessionEvents.add(t)}track(t,e){(async()=>{await this.shouldDeduplicate(t)||(await this.markTracked(t),await this.capture({event_name:t,payload:e}))})().catch(s=>{console.warn(`[MobTechi Analytics] failed async track for ${t}`,s)})}trackError(t,e,s){(async()=>{await this.capture({event_name:t,is_error:!0,stack_trace:e.stack,metadata:s})})().catch(i=>{console.warn(`[MobTechi Analytics] failed async trackError for ${t}`,i)})}async capture(t){try{await this.api.post("/analytics/capture",{app_id:this.appId,...t})}catch{console.warn(`[MobTechi Analytics] Failed to track event: ${t.event_name}`)}}};var f=class{api;entitlements;analytics;constructor(t){this.api=new u(t),this.entitlements=new l,this.analytics=new d(this.api,t.appId||"unknown")}async login(t){return await this.api.login(t)}async verifyOtp(t){let e=await this.api.verifyOtp(t);return e.data&&e.data.token&&await this.api.setToken(e.data.token),e}async logout(){let t=await this.api.getToken();if(t)try{await this.api.logout(t)}catch{}await this.api.setToken(null),this.entitlements.setState(!1,[])}async syncEntitlements(t){try{let e=await this.api.getEntitlements(t);if(e){let s=!!e.isPremium,i=e.features||[];this.entitlements.setState(s,i)}return e}catch(e){throw console.error("Failed to sync entitlements",e),e}}};export{d as AnalyticsTracker,l as EntitlementEngine,c as MemoryStorageProvider,f as MobTechi,u as MobTechiClient};
1
+ var c=class{store={};getItem(t){return this.store[t]||null}setItem(t,e){this.store[t]=e}removeItem(t){delete this.store[t]}};import b from"axios";var u=class{client;baseUrl;storage;tokenKey;currentToken=null;appId;orgId;constructor(t,e,s,i,m){let o,r=e,n=s,p=i,y=m;typeof t=="object"&&t!==null?(o=t.baseUrl,r=t.appId,n=t.orgId,p=t.storage,y=t.tokenKey):o=t,this.baseUrl=o,this.appId=r,this.orgId=n,this.storage=p||new c,this.tokenKey=y||"mobtechi_auth_token",this.client=b.create({baseURL:this.baseUrl,headers:{"Content-Type":"application/json",...r&&{"x-app-id":r},...n&&{"x-org-id":n}}}),this.client.interceptors.request.use(async g=>{if(!this.currentToken){let f=await this.storage.getItem(this.tokenKey);f&&(this.currentToken=f)}return this.currentToken&&g.headers&&(g.headers.Authorization=`Bearer ${this.currentToken}`),g})}async setToken(t){this.currentToken=t,t?await this.storage.setItem(this.tokenKey,t):await this.storage.removeItem(this.tokenKey)}async getToken(){return this.currentToken||(this.currentToken=await this.storage.getItem(this.tokenKey)),this.currentToken}async get(t,e){let s=await this.client.get(t,e);return{data:s.data,status:s.status}}async post(t,e,s){let i=await this.client.post(t,e,s);return{data:i.data,status:i.status}}async put(t,e,s){let i=await this.client.put(t,e,s);return{data:i.data,status:i.status}}async patch(t,e,s){let i=await this.client.patch(t,e,s);return{data:i.data,status:i.status}}async delete(t,e){let s=await this.client.delete(t,e);return{data:s.data,status:s.status}}async identify(t){return(await this.client.post("/auth/identify",t)).data}async login(t){let e=await this.client.post("/auth/login",t);return{status:e.status,data:e.data}}async register(t){return(await this.client.post("/auth/register",t)).data}async verifyOtp(t){let e=await this.client.post("/auth/otp_verify",t);return{status:e.status,data:e.data}}async validateToken(t){return(await this.client.get("/auth/validate",{headers:{Authorization:`Bearer ${t}`}})).data}async refreshToken(t){return(await this.client.post("/auth/refresh",{refresh_token:t})).data}async logout(t){await this.client.delete("/auth/logout",{headers:{Authorization:`Bearer ${t}`}})}async updateProfile(t,e){let s=e?{Authorization:`Bearer ${e}`}:{};return(await this.client.put("/user/update-profile",t,{headers:s})).data}async getPlans(t,e){let s=t||this.orgId||"",i=e||this.appId||"";if(t&&!(r=>r?/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r):!1)(t)){i=t;let r=e||"",n=r?`?user_id=${r}`:"";return(await this.client.get(`/${i}/subscriptions/plans${n}`)).data}return(await this.client.get(`/user/subscription/plans?orgId=${s}&appKey=${i}`)).data}async getSubscriptionStatus(t,e){return(await this.client.get(`/user/subscription/status?appId=${t}`)).data}async getEntitlements(t){return(await this.client.get(`/${t}/subscriptions/entitlements`)).data}async createOrder(t,e){return(await this.client.post("/user/subscription/create-order",t)).data}async createSubscription(t,e){return(await this.client.post(`/${t}/subscriptions/create`,e)).data}async createTopUp(t,e){return(await this.client.post(`/${t}/subscriptions/topup`,e)).data}async getAdsConfig(t,e){return(await this.client.get(`/user/ads/config?orgId=${t}&appKey=${e}`)).data}async claimReward(t){return(await this.client.post("/user/rewards/ad-claim",t)).data}};var l=class{entitlements=[];isPremiumFlag=!1;setState(t,e=[]){this.isPremiumFlag=t,this.entitlements=e}checkPremium(){return this.isPremiumFlag?!0:this.entitlements.some(t=>t.active&&t.tier!=="FREE")}hasFeature(t){return this.isPremiumFlag?!0:this.entitlements.some(e=>e.active&&e.granted_features&&e.granted_features.includes(t))}};var d=class{constructor(t,e){this.api=t;this.appId=e}api;appId;sessionEvents=new Set;async shouldDeduplicate(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;return await this.api.storage.getItem(e)==="true"}return t==="paywall_viewed"?this.sessionEvents.has(t):!1}async markTracked(t){if(t==="onboarding_completed"||t==="first_code_execution"){let e=`mt_dedup_${t}`;await this.api.storage.setItem(e,"true")}else t==="paywall_viewed"&&this.sessionEvents.add(t)}track(t,e){(async()=>{await this.shouldDeduplicate(t)||(await this.markTracked(t),await this.capture({event_name:t,payload:e}))})().catch(s=>{console.warn(`[MobTechi Analytics] failed async track for ${t}`,s)})}trackError(t,e,s){(async()=>{await this.capture({event_name:t,is_error:!0,stack_trace:e.stack,metadata:s})})().catch(i=>{console.warn(`[MobTechi Analytics] failed async trackError for ${t}`,i)})}async capture(t){try{await this.api.post("/analytics/capture",{app_id:this.appId,...t})}catch{console.warn(`[MobTechi Analytics] Failed to track event: ${t.event_name}`)}}};var w=class{api;entitlements;analytics;constructor(t){this.api=new u(t),this.entitlements=new l,this.analytics=new d(this.api,t.appId||"unknown")}async login(t){return await this.api.login(t)}async verifyOtp(t){let e=await this.api.verifyOtp(t);return e.data&&e.data.token&&await this.api.setToken(e.data.token),e}async logout(){let t=await this.api.getToken();if(t)try{await this.api.logout(t)}catch{}await this.api.setToken(null),this.entitlements.setState(!1,[])}async syncEntitlements(t){try{let e=await this.api.getEntitlements(t);if(e){let s=!!e.isPremium,i=e.features||[];this.entitlements.setState(s,i),h.setPremiumUser(s)}return e}catch(e){throw console.error("Failed to sync entitlements",e),e}}},h={_isPremium:!1,setPremiumUser:a=>{h._isPremium=a},isPremiumUser:()=>h._isPremium};export{d as AnalyticsTracker,l as EntitlementEngine,c as MemoryStorageProvider,w as MobTechi,u as MobTechiClient,h as MobTechiSDK};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobtechi/sdk-core",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Framework-agnostic core logic and API client for the MobTechi platform",
5
5
  "author": "MobTechi",
6
6
  "license": "MIT",