@codeswayam/api-client 1.3.0 → 1.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/README.md +881 -96
- package/dist/index.d.ts +86 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,176 +1,961 @@
|
|
|
1
1
|
# @codeswayam/api-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> The canonical HTTP client and TypeScript SDK for all CodeSwayam API interactions.
|
|
4
|
+
|
|
5
|
+
[](./package.json)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://axios-http.com/)
|
|
8
|
+
[](./LICENSE)
|
|
9
|
+
|
|
10
|
+
`@codeswayam/api-client` is the low-level HTTP SDK that powers every CodeSwayam application. It wraps the CodeSwayam REST API with typed functions and a class-based SDK interface, handling authentication headers, cookie credentials, and response parsing so your app code never has to.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Overview](#overview)
|
|
17
|
+
- [Installation](#installation)
|
|
18
|
+
- [Peer Dependencies](#peer-dependencies)
|
|
19
|
+
- [Authentication](#authentication)
|
|
20
|
+
- [SDK Class](#codeswayamsdk-class)
|
|
21
|
+
- [API Reference](#api-reference)
|
|
22
|
+
- [Auth Functions](#auth-functions)
|
|
23
|
+
- [Subscription Functions](#subscription-functions)
|
|
24
|
+
- [Credit Functions](#credit-functions)
|
|
25
|
+
- [Referral Functions](#referral-functions)
|
|
26
|
+
- [Entitlement Functions](#entitlement-functions)
|
|
27
|
+
- [Notification Functions](#notification-functions)
|
|
28
|
+
- [Admin Functions](#admin-functions)
|
|
29
|
+
- [TypeScript Types](#typescript-types)
|
|
30
|
+
- [Code Examples](#code-examples)
|
|
31
|
+
- [Integration Guide (Next.js)](#integration-guide-nextjs)
|
|
32
|
+
- [Error Handling](#error-handling)
|
|
33
|
+
- [Changelog](#changelog)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Overview
|
|
38
|
+
|
|
39
|
+
`@codeswayam/api-client` is the foundation layer of the CodeSwayam SDK stack:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
@codeswayam/auth — Auth, guards, SSO, notifications
|
|
43
|
+
↓
|
|
44
|
+
@codeswayam/access — Entitlements, feature gates, usage
|
|
45
|
+
↓
|
|
46
|
+
@codeswayam/api-client — HTTP client, types, raw API functions
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
All packages in the CodeSwayam ecosystem call into `@codeswayam/api-client` for network requests. You can use this package directly for advanced use cases, admin tooling, or building custom integrations.
|
|
50
|
+
|
|
51
|
+
**Key design decisions:**
|
|
52
|
+
|
|
53
|
+
| Decision | Detail |
|
|
54
|
+
|---|---|
|
|
55
|
+
| HTTP library | Axios — consistent request/response interceptors |
|
|
56
|
+
| Auth strategy | Dual: `credentials: 'include'` (cookie) + `Authorization: Bearer` header fallback |
|
|
57
|
+
| Token source | `localStorage` via `getAuthHeaders()` |
|
|
58
|
+
| TypeScript | All functions and types are fully typed |
|
|
59
|
+
| Tree-shaking | Named exports only — import only what you use |
|
|
60
|
+
|
|
61
|
+
---
|
|
4
62
|
|
|
5
63
|
## Installation
|
|
6
64
|
|
|
7
65
|
```bash
|
|
8
66
|
npm install @codeswayam/api-client
|
|
67
|
+
# or
|
|
68
|
+
yarn add @codeswayam/api-client
|
|
69
|
+
# or
|
|
70
|
+
pnpm add @codeswayam/api-client
|
|
9
71
|
```
|
|
10
72
|
|
|
11
73
|
---
|
|
12
74
|
|
|
13
|
-
##
|
|
75
|
+
## Peer Dependencies
|
|
14
76
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- You need functions not exposed by `@codeswayam/auth`
|
|
77
|
+
| Package | Version |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `axios` | `^1.0.0` |
|
|
19
80
|
|
|
20
|
-
|
|
81
|
+
```bash
|
|
82
|
+
npm install axios
|
|
83
|
+
```
|
|
21
84
|
|
|
22
85
|
---
|
|
23
86
|
|
|
24
|
-
##
|
|
87
|
+
## Authentication
|
|
25
88
|
|
|
26
|
-
|
|
89
|
+
All API functions in this package authenticate using a dual strategy:
|
|
90
|
+
|
|
91
|
+
### 1. HTTP Cookies (primary)
|
|
92
|
+
All requests are made with `withCredentials: true`, which sends the `csw_session` HttpOnly cookie automatically if present.
|
|
93
|
+
|
|
94
|
+
### 2. Bearer Token (fallback)
|
|
95
|
+
`getAuthHeaders()` reads the JWT from localStorage and returns an `Authorization` header. Used as a fallback when cookies are unavailable (e.g. cross-origin requests).
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { getAuthHeaders } from '@codeswayam/api-client';
|
|
99
|
+
|
|
100
|
+
// Returns: { Authorization: 'Bearer eyJ...' }
|
|
101
|
+
// Returns: {} if no token is stored
|
|
102
|
+
const headers = getAuthHeaders();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The token is stored under the key `CSW_TOKEN_KEY` (re-exported from `@codeswayam/auth`).
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## `CodeSwayamSDK` Class
|
|
110
|
+
|
|
111
|
+
For applications that need a configured SDK instance (e.g. with a custom base URL), use the `CodeSwayamSDK` class.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
27
114
|
import { CodeSwayamSDK } from '@codeswayam/api-client';
|
|
28
115
|
|
|
29
116
|
const sdk = new CodeSwayamSDK({
|
|
30
|
-
baseUrl:
|
|
31
|
-
|
|
117
|
+
baseUrl: 'https://api.codeswayam.com',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Generic request method
|
|
121
|
+
const data = await sdk.request<ResponseType>({
|
|
122
|
+
method: 'GET',
|
|
123
|
+
path: '/v1/some-endpoint',
|
|
124
|
+
params: { foo: 'bar' },
|
|
32
125
|
});
|
|
33
126
|
|
|
34
|
-
//
|
|
127
|
+
// Namespaced API groups
|
|
35
128
|
const profile = await sdk.auth.getProfile();
|
|
129
|
+
const entitlements = await sdk.entitlements.fetchMyEntitlements('auraflow');
|
|
130
|
+
```
|
|
36
131
|
|
|
37
|
-
|
|
38
|
-
const subs = await sdk.billing.getSubscriptions();
|
|
132
|
+
**Constructor options:**
|
|
39
133
|
|
|
40
|
-
|
|
41
|
-
|
|
134
|
+
| Option | Type | Required | Description |
|
|
135
|
+
|---|---|---|---|
|
|
136
|
+
| `baseUrl` | `string` | ✅ | Base URL for all API requests |
|
|
137
|
+
| `timeout` | `number` | — | Request timeout in ms (default: `10000`) |
|
|
138
|
+
| `headers` | `Record<string, string>` | — | Additional headers for every request |
|
|
42
139
|
|
|
43
|
-
|
|
44
|
-
const canUse = sdk.entitlements.canAccess('smart_ai', activeSubs);
|
|
45
|
-
const remaining = sdk.entitlements.getRemainingLimit('max_automations', 5, activeSubs);
|
|
140
|
+
**SDK namespaces:**
|
|
46
141
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
142
|
+
| Namespace | Methods |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `sdk.auth` | `getProfile`, `login`, `logout`, `getUsersBatch` |
|
|
145
|
+
| `sdk.entitlements` | `fetchMyEntitlements`, `trackUsage`, `getAllAppsEntitlements` |
|
|
50
146
|
|
|
51
147
|
---
|
|
52
148
|
|
|
53
|
-
##
|
|
149
|
+
## API Reference
|
|
54
150
|
|
|
55
|
-
|
|
56
|
-
import { getSession, fetchProfile, updateProfile, logout } from '@codeswayam/api-client';
|
|
151
|
+
### Auth Functions
|
|
57
152
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
153
|
+
```ts
|
|
154
|
+
import {
|
|
155
|
+
getProfile,
|
|
156
|
+
login,
|
|
157
|
+
logout,
|
|
158
|
+
getUsersBatch,
|
|
159
|
+
} from '@codeswayam/api-client';
|
|
62
160
|
```
|
|
63
161
|
|
|
162
|
+
| Function | Signature | Description |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `getProfile` | `() => Promise<CSWUser>` | Fetch the authenticated user's profile |
|
|
165
|
+
| `login` | `(email: string, password: string) => Promise<{ token: string; user: CSWUser }>` | Email/password login (non-SSO apps) |
|
|
166
|
+
| `logout` | `() => Promise<void>` | Invalidate the current session |
|
|
167
|
+
| `getUsersBatch` | `(userIds: string[]) => Promise<CSWUser[]>` | Fetch multiple user profiles by ID |
|
|
168
|
+
|
|
64
169
|
---
|
|
65
170
|
|
|
66
|
-
|
|
171
|
+
### Subscription Functions
|
|
67
172
|
|
|
68
|
-
```
|
|
173
|
+
```ts
|
|
69
174
|
import {
|
|
70
|
-
fetchPublicPlans,
|
|
71
175
|
fetchUserSubscriptions,
|
|
72
176
|
fetchSubscriptionById,
|
|
73
|
-
|
|
74
|
-
verifyRazorpayPayment,
|
|
177
|
+
fetchPublicPlans,
|
|
75
178
|
changeSubscriptionPlan,
|
|
76
179
|
cancelUserSubscription,
|
|
77
180
|
} from '@codeswayam/api-client';
|
|
181
|
+
```
|
|
78
182
|
|
|
79
|
-
|
|
80
|
-
|
|
183
|
+
| Function | Signature | Description |
|
|
184
|
+
|---|---|---|
|
|
185
|
+
| `fetchUserSubscriptions` | `() => Promise<UserSubscription[]>` | All subscriptions for the authenticated user |
|
|
186
|
+
| `fetchSubscriptionById` | `(id: string) => Promise<UserSubscription>` | Single subscription by ID |
|
|
187
|
+
| `fetchPublicPlans` | `(appId?: string) => Promise<SaasProduct[]>` | Publicly listed plans (for pricing pages) |
|
|
188
|
+
| `changeSubscriptionPlan` | `(subscriptionId: string, newPlanId: string) => Promise<UserSubscription>` | Upgrade or downgrade a subscription |
|
|
189
|
+
| `cancelUserSubscription` | `(subscriptionId: string) => Promise<void>` | Cancel a subscription |
|
|
81
190
|
|
|
82
|
-
|
|
83
|
-
const subs = await fetchUserSubscriptions();
|
|
84
|
-
const sub = await fetchSubscriptionById(123);
|
|
191
|
+
---
|
|
85
192
|
|
|
86
|
-
|
|
87
|
-
const order = await createRazorpayOrder({
|
|
88
|
-
saasProductId: 1,
|
|
89
|
-
billingCycle: 'monthly',
|
|
90
|
-
currency: 'INR',
|
|
91
|
-
returnUrl: `${window.location.origin}/dashboard`,
|
|
92
|
-
upgradeFromSubscriptionId: 123, // Optional: old subscription ID to upgrade from (prorates cost)
|
|
93
|
-
});
|
|
193
|
+
### Credit Functions
|
|
94
194
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
195
|
+
```ts
|
|
196
|
+
import {
|
|
197
|
+
fetchMyWallet,
|
|
198
|
+
useCredits,
|
|
199
|
+
fetchCreditPacks,
|
|
200
|
+
fetchFeatureCosts,
|
|
201
|
+
createCreditPurchaseOrder,
|
|
202
|
+
verifyCreditPurchase,
|
|
203
|
+
} from '@codeswayam/api-client';
|
|
204
|
+
```
|
|
105
205
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
206
|
+
| Function | Signature | Description |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| `fetchMyWallet` | `() => Promise<UserWalletResponse>` | Current balance, transactions, and feature costs |
|
|
209
|
+
| `useCredits` | `(feature: string) => Promise<CreditTransaction>` | Deduct credits for a feature use |
|
|
210
|
+
| `fetchCreditPacks` | `() => Promise<CreditPack[]>` | Available credit packs for purchase |
|
|
211
|
+
| `fetchFeatureCosts` | `() => Promise<FeatureCreditCost[]>` | Per-feature credit cost table |
|
|
212
|
+
| `createCreditPurchaseOrder` | `(packId: string) => Promise<{ orderId: string; amount: number; currency: string }>` | Create a Razorpay order for a credit pack |
|
|
213
|
+
| `verifyCreditPurchase` | `(payload: VerifyPurchasePayload) => Promise<UserWalletResponse>` | Verify a Razorpay payment and credit the wallet |
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
### Referral Functions
|
|
112
218
|
|
|
113
|
-
|
|
219
|
+
```ts
|
|
220
|
+
import {
|
|
221
|
+
fetchReferralStats,
|
|
222
|
+
redeemReferralCode,
|
|
223
|
+
redeemCouponCode,
|
|
224
|
+
} from '@codeswayam/api-client';
|
|
114
225
|
```
|
|
115
226
|
|
|
227
|
+
| Function | Signature | Description |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| `fetchReferralStats` | `() => Promise<ReferralStats>` | Referral link, history, and earned rewards |
|
|
230
|
+
| `redeemReferralCode` | `(code: string) => Promise<{ creditsEarned: number }>` | Apply a friend's referral code |
|
|
231
|
+
| `redeemCouponCode` | `(code: string) => Promise<{ creditsEarned: number; discount?: number }>` | Apply a promotional coupon code |
|
|
232
|
+
|
|
116
233
|
---
|
|
117
234
|
|
|
118
|
-
|
|
235
|
+
### Entitlement Functions
|
|
236
|
+
|
|
237
|
+
The core functions consumed by `@codeswayam/access`. You can call these directly for server-side data fetching.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import {
|
|
241
|
+
fetchMyEntitlements,
|
|
242
|
+
trackUsage,
|
|
243
|
+
getAllAppsEntitlements,
|
|
244
|
+
} from '@codeswayam/api-client';
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
| Function | Signature | Description |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `fetchMyEntitlements` | `(appId: string) => Promise<EntitlementResult>` | Full entitlements for a specific app |
|
|
250
|
+
| `trackUsage` | `(payload: TrackUsagePayload) => Promise<TrackUsageResult>` | Increment a usage counter |
|
|
251
|
+
| `getAllAppsEntitlements` | `() => Promise<AppEntitlementSummary[]>` | Entitlements across all apps (admin / dashboard use) |
|
|
252
|
+
|
|
253
|
+
**`TrackUsagePayload`:**
|
|
119
254
|
|
|
120
255
|
```typescript
|
|
256
|
+
interface TrackUsagePayload {
|
|
257
|
+
appId: string;
|
|
258
|
+
counterKey: string;
|
|
259
|
+
increment?: number; // defaults to 1
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Notification Functions
|
|
266
|
+
|
|
267
|
+
```ts
|
|
121
268
|
import {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
269
|
+
registerPushSubscription,
|
|
270
|
+
unregisterPushSubscription,
|
|
271
|
+
fetchVapidPublicKey,
|
|
272
|
+
sendNotificationCampaign,
|
|
273
|
+
fetchNotificationCampaigns,
|
|
274
|
+
fetchNotificationStats,
|
|
275
|
+
deleteNotificationCampaign,
|
|
128
276
|
} from '@codeswayam/api-client';
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
| Function | Signature | Description |
|
|
280
|
+
|---|---|---|
|
|
281
|
+
| `fetchVapidPublicKey` | `() => Promise<{ publicKey: string }>` | Fetch the VAPID public key for Web Push |
|
|
282
|
+
| `registerPushSubscription` | `(subscription: PushSubscription) => Promise<void>` | Register a browser push subscription |
|
|
283
|
+
| `unregisterPushSubscription` | `(endpoint: string) => Promise<void>` | Remove a push subscription |
|
|
284
|
+
| `sendNotificationCampaign` | `(payload: NotificationPayload) => Promise<NotificationCampaign>` | Send a push notification campaign (admin) |
|
|
285
|
+
| `fetchNotificationCampaigns` | `() => Promise<NotificationCampaign[]>` | List all notification campaigns (admin) |
|
|
286
|
+
| `fetchNotificationStats` | `(campaignId: string) => Promise<NotificationStats>` | Delivery and click stats for a campaign (admin) |
|
|
287
|
+
| `deleteNotificationCampaign` | `(campaignId: string) => Promise<void>` | Delete a notification campaign (admin) |
|
|
288
|
+
|
|
289
|
+
---
|
|
129
290
|
|
|
130
|
-
|
|
131
|
-
const packs = await fetchCreditPacks();
|
|
132
|
-
const costs = await fetchFeatureCosts('auraflow');
|
|
291
|
+
### Admin Functions
|
|
133
292
|
|
|
134
|
-
|
|
135
|
-
|
|
293
|
+
Admin-only functions. All require the caller to have an `admin` role; the API will return `403` otherwise.
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import {
|
|
297
|
+
// User admin
|
|
298
|
+
adminListUsers,
|
|
299
|
+
adminGetUser,
|
|
300
|
+
adminUpdateUser,
|
|
301
|
+
adminDeleteUser,
|
|
302
|
+
// Subscription admin
|
|
303
|
+
adminListSubscriptions,
|
|
304
|
+
adminUpdateSubscription,
|
|
305
|
+
// Credit admin
|
|
306
|
+
adminAdjustCredits,
|
|
307
|
+
adminListCreditTransactions,
|
|
308
|
+
// Settings admin
|
|
309
|
+
adminGetSettings,
|
|
310
|
+
adminUpdateSettings,
|
|
311
|
+
} from '@codeswayam/api-client';
|
|
136
312
|
```
|
|
137
313
|
|
|
314
|
+
| Function | Description |
|
|
315
|
+
|---|---|
|
|
316
|
+
| `adminListUsers` | Paginated list of all users |
|
|
317
|
+
| `adminGetUser(userId)` | Fetch a single user by ID |
|
|
318
|
+
| `adminUpdateUser(userId, data)` | Update user fields (role, name, etc.) |
|
|
319
|
+
| `adminDeleteUser(userId)` | Permanently delete a user account |
|
|
320
|
+
| `adminListSubscriptions` | List all subscriptions (all users) |
|
|
321
|
+
| `adminUpdateSubscription(id, data)` | Override subscription fields |
|
|
322
|
+
| `adminAdjustCredits(userId, amount, reason)` | Manually add or remove credits |
|
|
323
|
+
| `adminListCreditTransactions` | Paginated credit transaction log |
|
|
324
|
+
| `adminGetSettings` | Fetch platform-wide settings |
|
|
325
|
+
| `adminUpdateSettings(settings)` | Update platform settings |
|
|
326
|
+
|
|
138
327
|
---
|
|
139
328
|
|
|
140
|
-
##
|
|
329
|
+
## TypeScript Types
|
|
330
|
+
|
|
331
|
+
All types are exported from the package root:
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
import type {
|
|
335
|
+
// Products & subscriptions
|
|
336
|
+
SaasProduct,
|
|
337
|
+
UserSubscription,
|
|
338
|
+
// Credits
|
|
339
|
+
CreditPack,
|
|
340
|
+
UserCredits,
|
|
341
|
+
CreditTransaction,
|
|
342
|
+
FeatureCreditCost,
|
|
343
|
+
UserWalletResponse,
|
|
344
|
+
// Referrals
|
|
345
|
+
ReferralStats,
|
|
346
|
+
ReferralHistoryItem,
|
|
347
|
+
// Entitlements
|
|
348
|
+
EntitlementResult,
|
|
349
|
+
AppEntitlementSummary,
|
|
350
|
+
TrackUsagePayload,
|
|
351
|
+
TrackUsageResult,
|
|
352
|
+
UsageSummary,
|
|
353
|
+
// Notifications
|
|
354
|
+
NotificationPayload,
|
|
355
|
+
NotificationCampaign,
|
|
356
|
+
NotificationStats,
|
|
357
|
+
} from '@codeswayam/api-client';
|
|
358
|
+
```
|
|
141
359
|
|
|
142
|
-
|
|
360
|
+
### Interface Definitions
|
|
143
361
|
|
|
144
362
|
```typescript
|
|
145
|
-
|
|
363
|
+
interface SaasProduct {
|
|
364
|
+
id: string;
|
|
365
|
+
name: string;
|
|
366
|
+
appId: string;
|
|
367
|
+
planType: string; // e.g. "pro_monthly"
|
|
368
|
+
billingCycle: 'monthly' | 'annual';
|
|
369
|
+
price: number;
|
|
370
|
+
currency: string;
|
|
371
|
+
features: Record<string, boolean | number>;
|
|
372
|
+
isActive: boolean;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
interface UserSubscription {
|
|
376
|
+
id: string;
|
|
377
|
+
userId: string;
|
|
378
|
+
productId: string;
|
|
379
|
+
appId: string;
|
|
380
|
+
status: 'active' | 'cancelled' | 'expired' | 'trialing';
|
|
381
|
+
planType: string;
|
|
382
|
+
billingCycle: 'monthly' | 'annual';
|
|
383
|
+
currentPeriodStart: string;
|
|
384
|
+
currentPeriodEnd: string;
|
|
385
|
+
expiresAt: string | null;
|
|
386
|
+
cancelledAt: string | null;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
interface CreditPack {
|
|
390
|
+
id: string;
|
|
391
|
+
name: string;
|
|
392
|
+
credits: number;
|
|
393
|
+
price: number;
|
|
394
|
+
currency: string;
|
|
395
|
+
bonus?: number; // Bonus credits for promotional packs
|
|
396
|
+
isPopular?: boolean;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
interface UserCredits {
|
|
400
|
+
userId: string;
|
|
401
|
+
balance: number;
|
|
402
|
+
lifetimeEarned: number;
|
|
403
|
+
lifetimeSpent: number;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface CreditTransaction {
|
|
407
|
+
id: string;
|
|
408
|
+
userId: string;
|
|
409
|
+
type: 'earned' | 'spent' | 'purchased' | 'adjusted' | 'refunded';
|
|
410
|
+
amount: number;
|
|
411
|
+
feature?: string;
|
|
412
|
+
description: string;
|
|
413
|
+
createdAt: string;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
interface FeatureCreditCost {
|
|
417
|
+
featureKey: string;
|
|
418
|
+
cost: number;
|
|
419
|
+
appId?: string;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
interface UserWalletResponse {
|
|
423
|
+
credits: UserCredits;
|
|
424
|
+
recentTransactions: CreditTransaction[];
|
|
425
|
+
featureCosts: FeatureCreditCost[];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
interface ReferralStats {
|
|
429
|
+
referralCode: string;
|
|
430
|
+
referralUrl: string;
|
|
431
|
+
totalReferrals: number;
|
|
432
|
+
creditsEarned: number;
|
|
433
|
+
history: ReferralHistoryItem[];
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
interface ReferralHistoryItem {
|
|
437
|
+
id: string;
|
|
438
|
+
referredUserId: string;
|
|
439
|
+
referredUserName: string;
|
|
440
|
+
creditsEarned: number;
|
|
441
|
+
createdAt: string;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
interface EntitlementResult {
|
|
445
|
+
appId: string;
|
|
446
|
+
userId: string;
|
|
447
|
+
role: string;
|
|
448
|
+
tier: {
|
|
449
|
+
name: string;
|
|
450
|
+
label: string;
|
|
451
|
+
aiIncluded: boolean;
|
|
452
|
+
};
|
|
453
|
+
subscription: {
|
|
454
|
+
id: string;
|
|
455
|
+
status: string;
|
|
456
|
+
planType: string;
|
|
457
|
+
expiresAt: string | null;
|
|
458
|
+
billingCycle: string;
|
|
459
|
+
} | null;
|
|
460
|
+
credits: {
|
|
461
|
+
balance: number;
|
|
462
|
+
featureCosts: Record<string, number>;
|
|
463
|
+
};
|
|
464
|
+
usage: Record<string, UsageSummary>;
|
|
465
|
+
features: Record<string, boolean | number>;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
interface AppEntitlementSummary {
|
|
469
|
+
appId: string;
|
|
470
|
+
tier: string;
|
|
471
|
+
hasActivePlan: boolean;
|
|
472
|
+
usageSummaries: Record<string, UsageSummary>;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
interface TrackUsagePayload {
|
|
476
|
+
appId: string;
|
|
477
|
+
counterKey: string;
|
|
478
|
+
increment?: number;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
interface TrackUsageResult {
|
|
482
|
+
counterKey: string;
|
|
483
|
+
used: number;
|
|
484
|
+
limit: number;
|
|
485
|
+
remaining: number;
|
|
486
|
+
percentage: number;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
interface UsageSummary {
|
|
490
|
+
used: number;
|
|
491
|
+
limit: number;
|
|
492
|
+
remaining: number;
|
|
493
|
+
percentage: number;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
interface NotificationPayload {
|
|
497
|
+
title: string;
|
|
498
|
+
body: string;
|
|
499
|
+
icon?: string;
|
|
500
|
+
url?: string;
|
|
501
|
+
targetUserIds?: string[]; // empty = broadcast to all
|
|
502
|
+
appId?: string;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
interface NotificationCampaign {
|
|
506
|
+
id: string;
|
|
507
|
+
title: string;
|
|
508
|
+
body: string;
|
|
509
|
+
sentAt: string;
|
|
510
|
+
targetCount: number;
|
|
511
|
+
deliveredCount: number;
|
|
512
|
+
status: 'pending' | 'sent' | 'failed';
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
interface NotificationStats {
|
|
516
|
+
campaignId: string;
|
|
517
|
+
sent: number;
|
|
518
|
+
delivered: number;
|
|
519
|
+
clicked: number;
|
|
520
|
+
failed: number;
|
|
521
|
+
deliveryRate: number;
|
|
522
|
+
clickRate: number;
|
|
523
|
+
}
|
|
524
|
+
```
|
|
146
525
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Code Examples
|
|
529
|
+
|
|
530
|
+
### 1. SDK Initialization
|
|
531
|
+
|
|
532
|
+
```ts
|
|
533
|
+
import { CodeSwayamSDK } from '@codeswayam/api-client';
|
|
534
|
+
|
|
535
|
+
// Create a configured SDK instance
|
|
536
|
+
export const sdk = new CodeSwayamSDK({
|
|
537
|
+
baseUrl: process.env.NEXT_PUBLIC_API_URL ?? 'https://api.codeswayam.com',
|
|
538
|
+
timeout: 15_000,
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
// Use throughout your app
|
|
542
|
+
export default sdk;
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
Or use standalone functions (recommended for tree-shaking):
|
|
546
|
+
|
|
547
|
+
```ts
|
|
548
|
+
// Import only what you need
|
|
549
|
+
import { fetchMyEntitlements, trackUsage } from '@codeswayam/api-client';
|
|
150
550
|
```
|
|
151
551
|
|
|
152
552
|
---
|
|
153
553
|
|
|
154
|
-
|
|
554
|
+
### 2. `fetchMyEntitlements` Usage
|
|
155
555
|
|
|
156
|
-
```
|
|
157
|
-
import {
|
|
556
|
+
```ts
|
|
557
|
+
import { fetchMyEntitlements } from '@codeswayam/api-client';
|
|
558
|
+
|
|
559
|
+
// Fetch full entitlements for the 'auraflow' app
|
|
560
|
+
async function loadAccess() {
|
|
561
|
+
const entitlements = await fetchMyEntitlements('auraflow');
|
|
158
562
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
563
|
+
console.log('Tier:', entitlements.tier.name);
|
|
564
|
+
console.log('DM usage:', entitlements.usage['dms']);
|
|
565
|
+
console.log('AI chat feature:', entitlements.features['ai_chat']);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Server-side usage in Next.js (App Router)
|
|
569
|
+
import { cookies } from 'next/headers';
|
|
570
|
+
|
|
571
|
+
export async function getUserEntitlements(appId: string) {
|
|
572
|
+
// fetchMyEntitlements uses cookies: 'include' — works server-side
|
|
573
|
+
// when the request context has the session cookie
|
|
574
|
+
return fetchMyEntitlements(appId);
|
|
575
|
+
}
|
|
162
576
|
```
|
|
163
577
|
|
|
164
578
|
---
|
|
165
579
|
|
|
166
|
-
|
|
580
|
+
### 3. `trackUsage` Usage
|
|
167
581
|
|
|
168
|
-
```
|
|
169
|
-
import {
|
|
582
|
+
```ts
|
|
583
|
+
import { trackUsage } from '@codeswayam/api-client';
|
|
584
|
+
|
|
585
|
+
// Track a single DM send
|
|
586
|
+
async function onMessageSent() {
|
|
587
|
+
const result = await trackUsage({
|
|
588
|
+
appId: 'auraflow',
|
|
589
|
+
counterKey: 'dms',
|
|
590
|
+
increment: 1, // optional, defaults to 1
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
console.log(`DMs used: ${result.used}/${result.limit}`);
|
|
594
|
+
|
|
595
|
+
if (result.remaining === 0) {
|
|
596
|
+
showUpgradePrompt();
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Track a bulk operation
|
|
601
|
+
async function onBulkExport(count: number) {
|
|
602
|
+
const result = await trackUsage({
|
|
603
|
+
appId: 'auraflow',
|
|
604
|
+
counterKey: 'exports',
|
|
605
|
+
increment: count,
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
return result;
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
### 4. `fetchMyWallet` + `useCredits`
|
|
615
|
+
|
|
616
|
+
```ts
|
|
617
|
+
import { fetchMyWallet, useCredits } from '@codeswayam/api-client';
|
|
618
|
+
|
|
619
|
+
// Load the wallet on component mount
|
|
620
|
+
async function initWallet() {
|
|
621
|
+
const wallet = await fetchMyWallet();
|
|
622
|
+
|
|
623
|
+
console.log('Balance:', wallet.credits.balance);
|
|
624
|
+
console.log('AI chat costs:', wallet.featureCosts.find(f => f.featureKey === 'ai_chat')?.cost);
|
|
625
|
+
|
|
626
|
+
return wallet;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Deduct credits when a feature is used
|
|
630
|
+
async function consumeAiCredit() {
|
|
631
|
+
try {
|
|
632
|
+
const transaction = await useCredits('ai_chat');
|
|
633
|
+
console.log('Credits deducted:', transaction.amount);
|
|
634
|
+
console.log('New balance available via fetchMyWallet()');
|
|
635
|
+
} catch (error) {
|
|
636
|
+
// API returns 402 when balance is insufficient
|
|
637
|
+
if ((error as any).response?.status === 402) {
|
|
638
|
+
console.error('Insufficient credits');
|
|
639
|
+
showBuyCreditsModal();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
### 5. Push Notification Registration
|
|
648
|
+
|
|
649
|
+
```ts
|
|
650
|
+
import {
|
|
651
|
+
fetchVapidPublicKey,
|
|
652
|
+
registerPushSubscription,
|
|
653
|
+
unregisterPushSubscription,
|
|
654
|
+
} from '@codeswayam/api-client';
|
|
655
|
+
|
|
656
|
+
// Register the browser for push notifications
|
|
657
|
+
async function enablePushNotifications() {
|
|
658
|
+
// 1. Check browser support
|
|
659
|
+
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
|
|
660
|
+
console.warn('Push notifications not supported');
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// 2. Request permission
|
|
665
|
+
const permission = await Notification.requestPermission();
|
|
666
|
+
if (permission !== 'granted') return;
|
|
667
|
+
|
|
668
|
+
// 3. Fetch VAPID public key from server
|
|
669
|
+
const { publicKey } = await fetchVapidPublicKey();
|
|
670
|
+
|
|
671
|
+
// 4. Get push subscription from browser
|
|
672
|
+
const registration = await navigator.serviceWorker.ready;
|
|
673
|
+
const subscription = await registration.pushManager.subscribe({
|
|
674
|
+
userVisibleOnly: true,
|
|
675
|
+
applicationServerKey: publicKey,
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// 5. Register with CodeSwayam API
|
|
679
|
+
await registerPushSubscription(subscription);
|
|
680
|
+
console.log('Push notifications enabled');
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Unregister
|
|
684
|
+
async function disablePushNotifications(endpoint: string) {
|
|
685
|
+
await unregisterPushSubscription(endpoint);
|
|
686
|
+
console.log('Push notifications disabled');
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
### 6. `CodeSwayamSDK` Class Usage
|
|
693
|
+
|
|
694
|
+
```ts
|
|
695
|
+
import { CodeSwayamSDK } from '@codeswayam/api-client';
|
|
696
|
+
|
|
697
|
+
const sdk = new CodeSwayamSDK({
|
|
698
|
+
baseUrl: 'https://api.codeswayam.com',
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
// Using namespaced methods
|
|
702
|
+
async function bootstrap(appId: string) {
|
|
703
|
+
const [profile, entitlements] = await Promise.all([
|
|
704
|
+
sdk.auth.getProfile(),
|
|
705
|
+
sdk.entitlements.fetchMyEntitlements(appId),
|
|
706
|
+
]);
|
|
707
|
+
|
|
708
|
+
return { profile, entitlements };
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Using the generic request method for custom endpoints
|
|
712
|
+
async function fetchCustomData<T>(path: string): Promise<T> {
|
|
713
|
+
return sdk.request<T>({
|
|
714
|
+
method: 'GET',
|
|
715
|
+
path,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
// POST with body
|
|
720
|
+
async function postCustomData<T>(path: string, body: unknown): Promise<T> {
|
|
721
|
+
return sdk.request<T>({
|
|
722
|
+
method: 'POST',
|
|
723
|
+
path,
|
|
724
|
+
data: body,
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
### 7. Subscription Management
|
|
732
|
+
|
|
733
|
+
```ts
|
|
734
|
+
import {
|
|
735
|
+
fetchUserSubscriptions,
|
|
736
|
+
fetchPublicPlans,
|
|
737
|
+
changeSubscriptionPlan,
|
|
738
|
+
cancelUserSubscription,
|
|
739
|
+
} from '@codeswayam/api-client';
|
|
170
740
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
)
|
|
175
|
-
|
|
741
|
+
// Load current subscriptions + available plans
|
|
742
|
+
async function loadSubscriptionPage(appId: string) {
|
|
743
|
+
const [subscriptions, plans] = await Promise.all([
|
|
744
|
+
fetchUserSubscriptions(),
|
|
745
|
+
fetchPublicPlans(appId),
|
|
746
|
+
]);
|
|
747
|
+
|
|
748
|
+
const active = subscriptions.find(
|
|
749
|
+
s => s.appId === appId && s.status === 'active'
|
|
750
|
+
);
|
|
751
|
+
|
|
752
|
+
return { active, plans };
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Upgrade subscription
|
|
756
|
+
async function upgradeToPro(subscriptionId: string, proPlanId: string) {
|
|
757
|
+
const updated = await changeSubscriptionPlan(subscriptionId, proPlanId);
|
|
758
|
+
console.log('Upgraded to:', updated.planType);
|
|
759
|
+
return updated;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Cancel subscription
|
|
763
|
+
async function cancelPlan(subscriptionId: string) {
|
|
764
|
+
await cancelUserSubscription(subscriptionId);
|
|
765
|
+
console.log('Subscription cancelled');
|
|
766
|
+
}
|
|
176
767
|
```
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
771
|
+
### 8. Admin: Adjust Credits
|
|
772
|
+
|
|
773
|
+
```ts
|
|
774
|
+
import { adminAdjustCredits } from '@codeswayam/api-client';
|
|
775
|
+
|
|
776
|
+
// Grant 100 bonus credits to a user (admin only)
|
|
777
|
+
async function grantBonusCredits(userId: string) {
|
|
778
|
+
await adminAdjustCredits(userId, 100, 'Promotional bonus — Q4 campaign');
|
|
779
|
+
console.log('Credited 100 bonus credits to user', userId);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// Deduct credits as penalty (negative amount)
|
|
783
|
+
async function deductCredits(userId: string) {
|
|
784
|
+
await adminAdjustCredits(userId, -50, 'Chargeback adjustment');
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
## Integration Guide (Next.js)
|
|
791
|
+
|
|
792
|
+
### Server-Side Data Fetching (App Router)
|
|
793
|
+
|
|
794
|
+
```ts
|
|
795
|
+
// app/dashboard/page.tsx
|
|
796
|
+
import { fetchMyEntitlements } from '@codeswayam/api-client';
|
|
797
|
+
|
|
798
|
+
export default async function DashboardPage() {
|
|
799
|
+
// Server Component — runs on the server with the user's cookie
|
|
800
|
+
const entitlements = await fetchMyEntitlements('auraflow');
|
|
801
|
+
|
|
802
|
+
return (
|
|
803
|
+
<main>
|
|
804
|
+
<p>Tier: {entitlements.tier.label}</p>
|
|
805
|
+
<p>Credits: {entitlements.credits.balance}</p>
|
|
806
|
+
</main>
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
```
|
|
810
|
+
|
|
811
|
+
### API Route Handler
|
|
812
|
+
|
|
813
|
+
```ts
|
|
814
|
+
// app/api/usage/route.ts
|
|
815
|
+
import { trackUsage } from '@codeswayam/api-client';
|
|
816
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
817
|
+
|
|
818
|
+
export async function POST(req: NextRequest) {
|
|
819
|
+
const { appId, counterKey, increment } = await req.json();
|
|
820
|
+
|
|
821
|
+
const result = await trackUsage({ appId, counterKey, increment });
|
|
822
|
+
|
|
823
|
+
return NextResponse.json(result);
|
|
824
|
+
}
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Client-Side Usage
|
|
828
|
+
|
|
829
|
+
```tsx
|
|
830
|
+
// components/WalletWidget.tsx
|
|
831
|
+
'use client';
|
|
832
|
+
import { fetchMyWallet } from '@codeswayam/api-client';
|
|
833
|
+
import { useEffect, useState } from 'react';
|
|
834
|
+
import type { UserWalletResponse } from '@codeswayam/api-client';
|
|
835
|
+
|
|
836
|
+
export function WalletWidget() {
|
|
837
|
+
const [wallet, setWallet] = useState<UserWalletResponse | null>(null);
|
|
838
|
+
|
|
839
|
+
useEffect(() => {
|
|
840
|
+
fetchMyWallet().then(setWallet);
|
|
841
|
+
}, []);
|
|
842
|
+
|
|
843
|
+
if (!wallet) return <span>Loading...</span>;
|
|
844
|
+
|
|
845
|
+
return <span>{wallet.credits.balance} credits</span>;
|
|
846
|
+
}
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
> **Note:** For React-based apps, prefer `@codeswayam/access` hooks (`useAppAccess`, `useCSWCredits`) over calling `@codeswayam/api-client` functions directly in components. The hooks provide SWR caching and auto-revalidation.
|
|
850
|
+
|
|
851
|
+
---
|
|
852
|
+
|
|
853
|
+
## Error Handling
|
|
854
|
+
|
|
855
|
+
All functions throw Axios errors on HTTP failures. The response body contains error details:
|
|
856
|
+
|
|
857
|
+
```ts
|
|
858
|
+
import { fetchMyEntitlements } from '@codeswayam/api-client';
|
|
859
|
+
import axios from 'axios';
|
|
860
|
+
|
|
861
|
+
async function safeLoad(appId: string) {
|
|
862
|
+
try {
|
|
863
|
+
return await fetchMyEntitlements(appId);
|
|
864
|
+
} catch (error) {
|
|
865
|
+
if (axios.isAxiosError(error)) {
|
|
866
|
+
const status = error.response?.status;
|
|
867
|
+
const message = error.response?.data?.message;
|
|
868
|
+
|
|
869
|
+
if (status === 401) {
|
|
870
|
+
// Token expired or missing — redirect to login
|
|
871
|
+
redirectToLogin();
|
|
872
|
+
} else if (status === 403) {
|
|
873
|
+
// Authenticated but not authorized (e.g. wrong role)
|
|
874
|
+
console.error('Access denied:', message);
|
|
875
|
+
} else if (status === 402) {
|
|
876
|
+
// Insufficient credits
|
|
877
|
+
showBuyCreditsModal();
|
|
878
|
+
} else {
|
|
879
|
+
console.error('API error:', status, message);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
throw error;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
**Common HTTP status codes:**
|
|
888
|
+
|
|
889
|
+
| Status | Meaning |
|
|
890
|
+
|---|---|
|
|
891
|
+
| `200` | Success |
|
|
892
|
+
| `400` | Bad request (invalid params) |
|
|
893
|
+
| `401` | Unauthenticated — token missing or expired |
|
|
894
|
+
| `402` | Payment required — insufficient credits |
|
|
895
|
+
| `403` | Forbidden — authenticated but not authorized |
|
|
896
|
+
| `404` | Resource not found |
|
|
897
|
+
| `429` | Rate limited |
|
|
898
|
+
| `500` | Internal server error |
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
902
|
+
## Source Structure
|
|
903
|
+
|
|
904
|
+
```
|
|
905
|
+
packages/api-client/src/
|
|
906
|
+
├── index.ts — Barrel exports (all functions and types)
|
|
907
|
+
├── client.ts — Axios instance configuration
|
|
908
|
+
├── auth.ts — getAuthHeaders(), token utilities
|
|
909
|
+
├── sdk.ts — CodeSwayamSDK class
|
|
910
|
+
├── functions/
|
|
911
|
+
│ ├── auth.ts — getProfile, login, logout, getUsersBatch
|
|
912
|
+
│ ├── subscriptions.ts — Subscription CRUD functions
|
|
913
|
+
│ ├── credits.ts — Wallet, purchase, usage functions
|
|
914
|
+
│ ├── referrals.ts — Referral and coupon functions
|
|
915
|
+
│ ├── entitlements.ts — fetchMyEntitlements, trackUsage
|
|
916
|
+
│ ├── notifications.ts — Push notification functions
|
|
917
|
+
│ └── admin.ts — Admin-only functions
|
|
918
|
+
└── types/
|
|
919
|
+
├── index.ts — Re-exports all types
|
|
920
|
+
├── subscriptions.ts
|
|
921
|
+
├── credits.ts
|
|
922
|
+
├── entitlements.ts
|
|
923
|
+
└── notifications.ts
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
---
|
|
927
|
+
|
|
928
|
+
## Changelog
|
|
929
|
+
|
|
930
|
+
### v1.3.1
|
|
931
|
+
- Fixed `fetchVapidPublicKey` timeout on slow networks
|
|
932
|
+
- `trackUsage` now returns full `TrackUsageResult` including `percentage`
|
|
933
|
+
|
|
934
|
+
### v1.3.0
|
|
935
|
+
- Added `getAllAppsEntitlements()` for cross-app dashboard use cases
|
|
936
|
+
- Added `deleteNotificationCampaign()`
|
|
937
|
+
- Added `fetchNotificationStats()` with delivery and click rate fields
|
|
938
|
+
|
|
939
|
+
### v1.2.0
|
|
940
|
+
- Added `sendNotificationCampaign()` for admin push campaigns
|
|
941
|
+
- Added `fetchNotificationCampaigns()`
|
|
942
|
+
- `CodeSwayamSDK` class: added `sdk.entitlements` namespace
|
|
943
|
+
|
|
944
|
+
### v1.1.0
|
|
945
|
+
- Added `redeemCouponCode()` for promotional codes
|
|
946
|
+
- Added `createCreditPurchaseOrder()` and `verifyCreditPurchase()` (Razorpay integration)
|
|
947
|
+
- `fetchMyWallet` now includes `featureCosts` in the response
|
|
948
|
+
|
|
949
|
+
### v1.0.0 — Initial Release
|
|
950
|
+
- Auth functions: `getProfile`, `login`, `logout`, `getUsersBatch`
|
|
951
|
+
- Subscription functions: full CRUD
|
|
952
|
+
- Credit functions: wallet, packs, feature costs
|
|
953
|
+
- Referral functions: stats and redeem
|
|
954
|
+
- Entitlement functions: `fetchMyEntitlements`, `trackUsage`
|
|
955
|
+
- `CodeSwayamSDK` class with `sdk.auth` namespace
|
|
956
|
+
- `getAuthHeaders()` utility
|
|
957
|
+
- Full TypeScript types
|
|
958
|
+
|
|
959
|
+
---
|
|
960
|
+
|
|
961
|
+
*Part of the [CodeSwayam](https://codeswayam.com) platform. For support, open an issue in the monorepo.*
|