@tspvivek/baasix-sdk 0.1.0-alpha.1

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +942 -0
  3. package/dist/client-CzF9B60b.d.ts +614 -0
  4. package/dist/client-aXK_gEyr.d.cts +614 -0
  5. package/dist/index.cjs +4159 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +1498 -0
  8. package/dist/index.d.ts +1498 -0
  9. package/dist/index.js +4135 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/modules/auth.cjs +651 -0
  12. package/dist/modules/auth.cjs.map +1 -0
  13. package/dist/modules/auth.d.cts +384 -0
  14. package/dist/modules/auth.d.ts +384 -0
  15. package/dist/modules/auth.js +649 -0
  16. package/dist/modules/auth.js.map +1 -0
  17. package/dist/modules/files.cjs +266 -0
  18. package/dist/modules/files.cjs.map +1 -0
  19. package/dist/modules/files.d.cts +187 -0
  20. package/dist/modules/files.d.ts +187 -0
  21. package/dist/modules/files.js +264 -0
  22. package/dist/modules/files.js.map +1 -0
  23. package/dist/modules/items.cjs +654 -0
  24. package/dist/modules/items.cjs.map +1 -0
  25. package/dist/modules/items.d.cts +472 -0
  26. package/dist/modules/items.d.ts +472 -0
  27. package/dist/modules/items.js +651 -0
  28. package/dist/modules/items.js.map +1 -0
  29. package/dist/modules/schemas.cjs +269 -0
  30. package/dist/modules/schemas.cjs.map +1 -0
  31. package/dist/modules/schemas.d.cts +239 -0
  32. package/dist/modules/schemas.d.ts +239 -0
  33. package/dist/modules/schemas.js +267 -0
  34. package/dist/modules/schemas.js.map +1 -0
  35. package/dist/storage/index.cjs +162 -0
  36. package/dist/storage/index.cjs.map +1 -0
  37. package/dist/storage/index.d.cts +96 -0
  38. package/dist/storage/index.d.ts +96 -0
  39. package/dist/storage/index.js +157 -0
  40. package/dist/storage/index.js.map +1 -0
  41. package/dist/types-BdjsGANq.d.cts +40 -0
  42. package/dist/types-BdjsGANq.d.ts +40 -0
  43. package/package.json +107 -0
@@ -0,0 +1,649 @@
1
+ // src/storage/types.ts
2
+ var STORAGE_KEYS = {
3
+ ACCESS_TOKEN: "baasix_access_token",
4
+ REFRESH_TOKEN: "baasix_refresh_token",
5
+ TOKEN_EXPIRY: "baasix_token_expiry",
6
+ USER: "baasix_user",
7
+ TENANT: "baasix_tenant"
8
+ };
9
+
10
+ // src/types.ts
11
+ var BaasixError = class _BaasixError extends Error {
12
+ status;
13
+ code;
14
+ details;
15
+ isRetryable;
16
+ constructor(message, status = 500, code, details) {
17
+ super(message);
18
+ this.name = "BaasixError";
19
+ this.status = status;
20
+ this.code = code;
21
+ this.details = details;
22
+ this.isRetryable = status >= 500 || status === 429;
23
+ if (Error.captureStackTrace) {
24
+ Error.captureStackTrace(this, _BaasixError);
25
+ }
26
+ }
27
+ toJSON() {
28
+ return {
29
+ name: this.name,
30
+ message: this.message,
31
+ status: this.status,
32
+ code: this.code,
33
+ details: this.details
34
+ };
35
+ }
36
+ };
37
+
38
+ // src/modules/auth.ts
39
+ var AuthModule = class {
40
+ client;
41
+ storage;
42
+ authMode;
43
+ onAuthStateChange;
44
+ currentUser = null;
45
+ constructor(config) {
46
+ this.client = config.client;
47
+ this.storage = config.storage;
48
+ this.authMode = config.authMode;
49
+ this.onAuthStateChange = config.onAuthStateChange;
50
+ }
51
+ /**
52
+ * Emit an authentication state change event
53
+ */
54
+ emitAuthStateChange(event, user) {
55
+ this.currentUser = user;
56
+ this.onAuthStateChange?.(event, user);
57
+ }
58
+ /**
59
+ * Store authentication tokens
60
+ */
61
+ async storeTokens(response) {
62
+ if (this.authMode === "jwt") {
63
+ await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, response.token);
64
+ if (response.refreshToken) {
65
+ await this.storage.set(STORAGE_KEYS.REFRESH_TOKEN, response.refreshToken);
66
+ }
67
+ if (response.expiresIn) {
68
+ const expiresAt = Date.now() + response.expiresIn * 1e3;
69
+ await this.storage.set(STORAGE_KEYS.TOKEN_EXPIRY, expiresAt.toString());
70
+ }
71
+ }
72
+ if (response.user) {
73
+ await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user));
74
+ }
75
+ }
76
+ /**
77
+ * Clear stored authentication data
78
+ */
79
+ async clearAuth() {
80
+ await this.storage.remove(STORAGE_KEYS.ACCESS_TOKEN);
81
+ await this.storage.remove(STORAGE_KEYS.REFRESH_TOKEN);
82
+ await this.storage.remove(STORAGE_KEYS.TOKEN_EXPIRY);
83
+ await this.storage.remove(STORAGE_KEYS.USER);
84
+ await this.storage.remove(STORAGE_KEYS.TENANT);
85
+ this.currentUser = null;
86
+ }
87
+ /**
88
+ * Register a new user
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const { user, token } = await baasix.auth.register({
93
+ * email: 'newuser@example.com',
94
+ * password: 'securepassword',
95
+ * firstName: 'John',
96
+ * lastName: 'Doe'
97
+ * });
98
+ * ```
99
+ */
100
+ async register(data) {
101
+ const response = await this.client.post("/auth/register", data, {
102
+ skipAuth: true
103
+ });
104
+ await this.storeTokens(response);
105
+ this.emitAuthStateChange("SIGNED_IN", response.user);
106
+ return response;
107
+ }
108
+ /**
109
+ * Login with email and password
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const { user, token } = await baasix.auth.login({
114
+ * email: 'user@example.com',
115
+ * password: 'password123'
116
+ * });
117
+ *
118
+ * // Login with tenant (multi-tenant mode)
119
+ * const result = await baasix.auth.login({
120
+ * email: 'user@example.com',
121
+ * password: 'password123',
122
+ * tenantId: 'tenant-uuid'
123
+ * });
124
+ * ```
125
+ */
126
+ async login(credentials) {
127
+ const response = await this.client.post(
128
+ "/auth/login",
129
+ {
130
+ email: credentials.email,
131
+ password: credentials.password,
132
+ tenant_Id: credentials.tenantId
133
+ },
134
+ { skipAuth: true }
135
+ );
136
+ await this.storeTokens(response);
137
+ this.emitAuthStateChange("SIGNED_IN", response.user);
138
+ return response;
139
+ }
140
+ /**
141
+ * Logout the current user
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * await baasix.auth.logout();
146
+ * ```
147
+ */
148
+ async logout() {
149
+ try {
150
+ await this.client.get("/auth/logout");
151
+ } catch {
152
+ }
153
+ await this.clearAuth();
154
+ this.emitAuthStateChange("SIGNED_OUT", null);
155
+ }
156
+ /**
157
+ * Get the current authenticated user from the server
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const user = await baasix.auth.getUser();
162
+ * console.log(user?.email);
163
+ * ```
164
+ */
165
+ async getUser() {
166
+ try {
167
+ const response = await this.client.get("/auth/me");
168
+ this.currentUser = response.data;
169
+ await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.data));
170
+ return response.data;
171
+ } catch (error) {
172
+ if (error instanceof BaasixError && error.status === 401) {
173
+ await this.clearAuth();
174
+ return null;
175
+ }
176
+ throw error;
177
+ }
178
+ }
179
+ /**
180
+ * Get the cached current user (does not make an API call)
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const user = await baasix.auth.getCachedUser();
185
+ * ```
186
+ */
187
+ async getCachedUser() {
188
+ if (this.currentUser) {
189
+ return this.currentUser;
190
+ }
191
+ const userJson = await this.storage.get(STORAGE_KEYS.USER);
192
+ if (userJson) {
193
+ try {
194
+ this.currentUser = JSON.parse(userJson);
195
+ return this.currentUser;
196
+ } catch {
197
+ return null;
198
+ }
199
+ }
200
+ return null;
201
+ }
202
+ /**
203
+ * Check if user is authenticated (has valid token)
204
+ *
205
+ * @example
206
+ * ```typescript
207
+ * if (await baasix.auth.isAuthenticated()) {
208
+ * // User is logged in
209
+ * }
210
+ * ```
211
+ */
212
+ async isAuthenticated() {
213
+ if (this.authMode === "cookie") {
214
+ const user = await this.getCachedUser();
215
+ return user !== null;
216
+ }
217
+ const token = await this.storage.get(STORAGE_KEYS.ACCESS_TOKEN);
218
+ if (!token) return false;
219
+ const expiry = await this.storage.get(STORAGE_KEYS.TOKEN_EXPIRY);
220
+ if (expiry && Date.now() >= parseInt(expiry, 10)) {
221
+ const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN);
222
+ return !!refreshToken;
223
+ }
224
+ return true;
225
+ }
226
+ /**
227
+ * Get the current access token
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * const token = await baasix.auth.getToken();
232
+ * ```
233
+ */
234
+ async getToken() {
235
+ if (this.authMode === "cookie") {
236
+ return null;
237
+ }
238
+ return await this.storage.get(STORAGE_KEYS.ACCESS_TOKEN);
239
+ }
240
+ /**
241
+ * Set a static token (useful for server-side or service accounts)
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * baasix.auth.setToken('your-api-token');
246
+ * ```
247
+ */
248
+ async setToken(token) {
249
+ await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, token);
250
+ }
251
+ /**
252
+ * Refresh the current token
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const tokens = await baasix.auth.refreshToken();
257
+ * ```
258
+ */
259
+ async refreshToken() {
260
+ const refreshToken = await this.storage.get(STORAGE_KEYS.REFRESH_TOKEN);
261
+ const response = await this.client.post(
262
+ "/auth/refresh",
263
+ this.authMode === "jwt" ? { refreshToken } : void 0
264
+ );
265
+ await this.storeTokens(response);
266
+ const tokens = {
267
+ accessToken: response.token,
268
+ refreshToken: response.refreshToken,
269
+ expiresIn: response.expiresIn,
270
+ expiresAt: response.expiresIn ? Date.now() + response.expiresIn * 1e3 : void 0
271
+ };
272
+ this.emitAuthStateChange("TOKEN_REFRESHED", response.user);
273
+ return tokens;
274
+ }
275
+ /**
276
+ * Request a magic link for passwordless login
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * await baasix.auth.sendMagicLink({
281
+ * email: 'user@example.com',
282
+ * redirectUrl: 'https://myapp.com/auth/callback'
283
+ * });
284
+ * ```
285
+ */
286
+ async sendMagicLink(options) {
287
+ await this.client.post(
288
+ "/auth/magiclink",
289
+ {
290
+ email: options.email,
291
+ link: options.redirectUrl,
292
+ mode: options.mode || "link"
293
+ },
294
+ { skipAuth: true }
295
+ );
296
+ }
297
+ /**
298
+ * Verify magic link/code and complete login
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * const { user, token } = await baasix.auth.verifyMagicLink('verification-token');
303
+ * ```
304
+ */
305
+ async verifyMagicLink(token) {
306
+ const response = await this.client.post(
307
+ "/auth/magiclink/verify",
308
+ { token },
309
+ { skipAuth: true }
310
+ );
311
+ await this.storeTokens(response);
312
+ this.emitAuthStateChange("SIGNED_IN", response.user);
313
+ return response;
314
+ }
315
+ /**
316
+ * Request a password reset
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * await baasix.auth.forgotPassword({
321
+ * email: 'user@example.com',
322
+ * redirectUrl: 'https://myapp.com/reset-password'
323
+ * });
324
+ * ```
325
+ */
326
+ async forgotPassword(options) {
327
+ await this.client.post(
328
+ "/auth/forgot-password",
329
+ {
330
+ email: options.email,
331
+ link: options.redirectUrl
332
+ },
333
+ { skipAuth: true }
334
+ );
335
+ }
336
+ /**
337
+ * Reset password using a reset token
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * await baasix.auth.resetPassword('reset-token', 'newpassword123');
342
+ * ```
343
+ */
344
+ async resetPassword(token, newPassword) {
345
+ await this.client.post(
346
+ "/auth/reset-password",
347
+ { token, password: newPassword },
348
+ { skipAuth: true }
349
+ );
350
+ }
351
+ /**
352
+ * Change the current user's password
353
+ *
354
+ * @example
355
+ * ```typescript
356
+ * await baasix.auth.changePassword('currentPassword', 'newPassword');
357
+ * ```
358
+ */
359
+ async changePassword(currentPassword, newPassword) {
360
+ await this.client.post("/auth/change-password", {
361
+ currentPassword,
362
+ newPassword
363
+ });
364
+ }
365
+ /**
366
+ * Update the current user's profile
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * const updatedUser = await baasix.auth.updateProfile({
371
+ * firstName: 'Jane',
372
+ * lastName: 'Doe'
373
+ * });
374
+ * ```
375
+ */
376
+ async updateProfile(data) {
377
+ const response = await this.client.patch("/auth/me", data);
378
+ await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.data));
379
+ this.emitAuthStateChange("USER_UPDATED", response.data);
380
+ return response.data;
381
+ }
382
+ /**
383
+ * Get available tenants for the current user (multi-tenant mode)
384
+ *
385
+ * @example
386
+ * ```typescript
387
+ * const tenants = await baasix.auth.getTenants();
388
+ * ```
389
+ */
390
+ async getTenants() {
391
+ const response = await this.client.get("/auth/tenants");
392
+ return response.data;
393
+ }
394
+ /**
395
+ * Switch to a different tenant (multi-tenant mode)
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * const { user, token } = await baasix.auth.switchTenant('tenant-uuid');
400
+ * ```
401
+ */
402
+ async switchTenant(tenantId) {
403
+ const response = await this.client.post("/auth/switch-tenant", {
404
+ tenant_Id: tenantId
405
+ });
406
+ await this.storeTokens(response);
407
+ await this.storage.set(STORAGE_KEYS.TENANT, tenantId);
408
+ this.emitAuthStateChange("TENANT_SWITCHED", response.user);
409
+ return response;
410
+ }
411
+ /**
412
+ * Get the current authentication state
413
+ *
414
+ * @example
415
+ * ```typescript
416
+ * const state = await baasix.auth.getState();
417
+ * console.log(state.isAuthenticated, state.user);
418
+ * ```
419
+ */
420
+ async getState() {
421
+ const isAuthenticated = await this.isAuthenticated();
422
+ const user = await this.getCachedUser();
423
+ return {
424
+ user,
425
+ isAuthenticated,
426
+ isLoading: false,
427
+ error: null
428
+ };
429
+ }
430
+ /**
431
+ * Initialize authentication state from storage
432
+ * Call this on app startup to restore previous session
433
+ *
434
+ * @example
435
+ * ```typescript
436
+ * await baasix.auth.initialize();
437
+ * ```
438
+ */
439
+ async initialize() {
440
+ const state = await this.getState();
441
+ if (state.isAuthenticated && state.user) {
442
+ this.emitAuthStateChange("SIGNED_IN", state.user);
443
+ }
444
+ return state;
445
+ }
446
+ // ===================
447
+ // OAuth / Social Login
448
+ // ===================
449
+ /**
450
+ * Get the OAuth authorization URL for a provider
451
+ * Redirect the user to this URL to start the OAuth flow
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * const url = baasix.auth.getOAuthUrl({
456
+ * provider: 'google',
457
+ * redirectUrl: 'https://myapp.com/auth/callback'
458
+ * });
459
+ * window.location.href = url;
460
+ * ```
461
+ */
462
+ getOAuthUrl(options) {
463
+ const baseUrl = this.client.getBaseUrl();
464
+ const params = new URLSearchParams({
465
+ redirect_url: options.redirectUrl
466
+ });
467
+ if (options.scopes?.length) {
468
+ params.set("scopes", options.scopes.join(","));
469
+ }
470
+ if (options.state) {
471
+ params.set("state", options.state);
472
+ }
473
+ return `${baseUrl}/auth/signin/${options.provider}?${params.toString()}`;
474
+ }
475
+ /**
476
+ * Handle OAuth callback and complete login
477
+ * Call this from your callback page with the token from URL
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * // In your callback page
482
+ * const params = new URLSearchParams(window.location.search);
483
+ * const token = params.get('token');
484
+ *
485
+ * if (token) {
486
+ * await baasix.auth.handleOAuthCallback(token);
487
+ * }
488
+ * ```
489
+ */
490
+ async handleOAuthCallback(token) {
491
+ await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, token);
492
+ const user = await this.getUser();
493
+ const response = {
494
+ token,
495
+ user
496
+ };
497
+ this.emitAuthStateChange("SIGNED_IN", user);
498
+ return response;
499
+ }
500
+ // ===================
501
+ // Email Verification
502
+ // ===================
503
+ /**
504
+ * Request email verification
505
+ * Sends a verification email to the current user
506
+ *
507
+ * @example
508
+ * ```typescript
509
+ * await baasix.auth.requestEmailVerification('https://myapp.com/verify-email');
510
+ * ```
511
+ */
512
+ async requestEmailVerification(redirectUrl) {
513
+ await this.client.post("/auth/request-verify-email", {
514
+ link: redirectUrl
515
+ });
516
+ }
517
+ /**
518
+ * Verify email with token
519
+ *
520
+ * @example
521
+ * ```typescript
522
+ * const params = new URLSearchParams(window.location.search);
523
+ * const token = params.get('token');
524
+ *
525
+ * await baasix.auth.verifyEmail(token);
526
+ * ```
527
+ */
528
+ async verifyEmail(token) {
529
+ await this.client.get("/auth/verify-email", {
530
+ params: { token },
531
+ skipAuth: true
532
+ });
533
+ }
534
+ /**
535
+ * Check if current session/token is valid
536
+ *
537
+ * @example
538
+ * ```typescript
539
+ * const isValid = await baasix.auth.checkSession();
540
+ * ```
541
+ */
542
+ async checkSession() {
543
+ try {
544
+ const response = await this.client.get("/auth/check");
545
+ return response.data.valid;
546
+ } catch {
547
+ return false;
548
+ }
549
+ }
550
+ // ===================
551
+ // Invitation System
552
+ // ===================
553
+ /**
554
+ * Send an invitation to a user (multi-tenant mode)
555
+ *
556
+ * @example
557
+ * ```typescript
558
+ * await baasix.auth.sendInvite({
559
+ * email: 'newuser@example.com',
560
+ * roleId: 'role-uuid',
561
+ * tenantId: 'tenant-uuid',
562
+ * redirectUrl: 'https://myapp.com/accept-invite'
563
+ * });
564
+ * ```
565
+ */
566
+ async sendInvite(options) {
567
+ await this.client.post("/auth/invite", {
568
+ email: options.email,
569
+ role_Id: options.roleId,
570
+ tenant_Id: options.tenantId,
571
+ link: options.redirectUrl
572
+ });
573
+ }
574
+ /**
575
+ * Verify an invitation token
576
+ *
577
+ * @example
578
+ * ```typescript
579
+ * const params = new URLSearchParams(window.location.search);
580
+ * const token = params.get('token');
581
+ *
582
+ * const result = await baasix.auth.verifyInvite(token);
583
+ * if (result.valid) {
584
+ * // Show registration form with pre-filled email
585
+ * }
586
+ * ```
587
+ */
588
+ async verifyInvite(token, redirectUrl) {
589
+ const response = await this.client.get(
590
+ "/auth/verify-invite",
591
+ {
592
+ params: {
593
+ token,
594
+ link: redirectUrl
595
+ },
596
+ skipAuth: true
597
+ }
598
+ );
599
+ return response.data;
600
+ }
601
+ /**
602
+ * Accept an invitation (for existing users)
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * await baasix.auth.acceptInvite(token);
607
+ * ```
608
+ */
609
+ async acceptInvite(token) {
610
+ const response = await this.client.post(
611
+ "/auth/accept-invite",
612
+ { token }
613
+ );
614
+ await this.storeTokens(response);
615
+ this.emitAuthStateChange("SIGNED_IN", response.user);
616
+ return response;
617
+ }
618
+ /**
619
+ * Register with an invitation token
620
+ *
621
+ * @example
622
+ * ```typescript
623
+ * const { user, token } = await baasix.auth.registerWithInvite({
624
+ * email: 'user@example.com',
625
+ * password: 'password',
626
+ * firstName: 'John',
627
+ * lastName: 'Doe',
628
+ * inviteToken: 'invite-token'
629
+ * });
630
+ * ```
631
+ */
632
+ async registerWithInvite(data) {
633
+ const response = await this.client.post(
634
+ "/auth/register",
635
+ {
636
+ ...data,
637
+ inviteToken: data.inviteToken
638
+ },
639
+ { skipAuth: true }
640
+ );
641
+ await this.storeTokens(response);
642
+ this.emitAuthStateChange("SIGNED_IN", response.user);
643
+ return response;
644
+ }
645
+ };
646
+
647
+ export { AuthModule };
648
+ //# sourceMappingURL=auth.js.map
649
+ //# sourceMappingURL=auth.js.map