@baasix/sdk 0.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1197 -0
  3. package/dist/client-DeXa-R9w.d.ts +680 -0
  4. package/dist/client-VT7NckyI.d.cts +680 -0
  5. package/dist/index.cjs +4567 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.cts +1788 -0
  8. package/dist/index.d.ts +1788 -0
  9. package/dist/index.js +4543 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/modules/auth.cjs +650 -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 +648 -0
  16. package/dist/modules/auth.js.map +1 -0
  17. package/dist/modules/files.cjs +269 -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 +267 -0
  22. package/dist/modules/files.js.map +1 -0
  23. package/dist/modules/items.cjs +640 -0
  24. package/dist/modules/items.cjs.map +1 -0
  25. package/dist/modules/items.d.cts +465 -0
  26. package/dist/modules/items.d.ts +465 -0
  27. package/dist/modules/items.js +637 -0
  28. package/dist/modules/items.js.map +1 -0
  29. package/dist/modules/schemas.cjs +322 -0
  30. package/dist/modules/schemas.cjs.map +1 -0
  31. package/dist/modules/schemas.d.cts +260 -0
  32. package/dist/modules/schemas.d.ts +260 -0
  33. package/dist/modules/schemas.js +320 -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 +108 -0
@@ -0,0 +1,648 @@
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.get(
307
+ `/auth/magiclink/${encodeURIComponent(token)}`,
308
+ { skipAuth: true }
309
+ );
310
+ await this.storeTokens(response);
311
+ this.emitAuthStateChange("SIGNED_IN", response.user);
312
+ return response;
313
+ }
314
+ /**
315
+ * Request a password reset
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * await baasix.auth.forgotPassword({
320
+ * email: 'user@example.com',
321
+ * redirectUrl: 'https://myapp.com/reset-password'
322
+ * });
323
+ * ```
324
+ */
325
+ async forgotPassword(options) {
326
+ await this.client.post(
327
+ "/auth/forgot-password",
328
+ {
329
+ email: options.email,
330
+ link: options.redirectUrl
331
+ },
332
+ { skipAuth: true }
333
+ );
334
+ }
335
+ /**
336
+ * Reset password using a reset token
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * await baasix.auth.resetPassword('reset-token', 'newpassword123');
341
+ * ```
342
+ */
343
+ async resetPassword(token, newPassword) {
344
+ await this.client.post(
345
+ "/auth/reset-password",
346
+ { token, password: newPassword },
347
+ { skipAuth: true }
348
+ );
349
+ }
350
+ /**
351
+ * Change the current user's password
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * await baasix.auth.changePassword('currentPassword', 'newPassword');
356
+ * ```
357
+ */
358
+ async changePassword(currentPassword, newPassword) {
359
+ await this.client.post("/auth/change-password", {
360
+ currentPassword,
361
+ newPassword
362
+ });
363
+ }
364
+ /**
365
+ * Update the current user's profile
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * const updatedUser = await baasix.auth.updateProfile({
370
+ * firstName: 'Jane',
371
+ * lastName: 'Doe'
372
+ * });
373
+ * ```
374
+ */
375
+ async updateProfile(data) {
376
+ const response = await this.client.patch("/auth/me", data);
377
+ await this.storage.set(STORAGE_KEYS.USER, JSON.stringify(response.data));
378
+ this.emitAuthStateChange("USER_UPDATED", response.data);
379
+ return response.data;
380
+ }
381
+ /**
382
+ * Get available tenants for the current user (multi-tenant mode)
383
+ *
384
+ * @example
385
+ * ```typescript
386
+ * const tenants = await baasix.auth.getTenants();
387
+ * ```
388
+ */
389
+ async getTenants() {
390
+ const response = await this.client.get("/auth/tenants");
391
+ return response.data;
392
+ }
393
+ /**
394
+ * Switch to a different tenant (multi-tenant mode)
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * const { user, token } = await baasix.auth.switchTenant('tenant-uuid');
399
+ * ```
400
+ */
401
+ async switchTenant(tenantId) {
402
+ const response = await this.client.post("/auth/switch-tenant", {
403
+ tenant_Id: tenantId
404
+ });
405
+ await this.storeTokens(response);
406
+ await this.storage.set(STORAGE_KEYS.TENANT, tenantId);
407
+ this.emitAuthStateChange("TENANT_SWITCHED", response.user);
408
+ return response;
409
+ }
410
+ /**
411
+ * Get the current authentication state
412
+ *
413
+ * @example
414
+ * ```typescript
415
+ * const state = await baasix.auth.getState();
416
+ * console.log(state.isAuthenticated, state.user);
417
+ * ```
418
+ */
419
+ async getState() {
420
+ const isAuthenticated = await this.isAuthenticated();
421
+ const user = await this.getCachedUser();
422
+ return {
423
+ user,
424
+ isAuthenticated,
425
+ isLoading: false,
426
+ error: null
427
+ };
428
+ }
429
+ /**
430
+ * Initialize authentication state from storage
431
+ * Call this on app startup to restore previous session
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * await baasix.auth.initialize();
436
+ * ```
437
+ */
438
+ async initialize() {
439
+ const state = await this.getState();
440
+ if (state.isAuthenticated && state.user) {
441
+ this.emitAuthStateChange("SIGNED_IN", state.user);
442
+ }
443
+ return state;
444
+ }
445
+ // ===================
446
+ // OAuth / Social Login
447
+ // ===================
448
+ /**
449
+ * Get the OAuth authorization URL for a provider
450
+ * Redirect the user to this URL to start the OAuth flow
451
+ *
452
+ * @example
453
+ * ```typescript
454
+ * const url = baasix.auth.getOAuthUrl({
455
+ * provider: 'google',
456
+ * redirectUrl: 'https://myapp.com/auth/callback'
457
+ * });
458
+ * window.location.href = url;
459
+ * ```
460
+ */
461
+ getOAuthUrl(options) {
462
+ const baseUrl = this.client.getBaseUrl();
463
+ const params = new URLSearchParams({
464
+ redirect_url: options.redirectUrl
465
+ });
466
+ if (options.scopes?.length) {
467
+ params.set("scopes", options.scopes.join(","));
468
+ }
469
+ if (options.state) {
470
+ params.set("state", options.state);
471
+ }
472
+ return `${baseUrl}/auth/signin/${options.provider}?${params.toString()}`;
473
+ }
474
+ /**
475
+ * Handle OAuth callback and complete login
476
+ * Call this from your callback page with the token from URL
477
+ *
478
+ * @example
479
+ * ```typescript
480
+ * // In your callback page
481
+ * const params = new URLSearchParams(window.location.search);
482
+ * const token = params.get('token');
483
+ *
484
+ * if (token) {
485
+ * await baasix.auth.handleOAuthCallback(token);
486
+ * }
487
+ * ```
488
+ */
489
+ async handleOAuthCallback(token) {
490
+ await this.storage.set(STORAGE_KEYS.ACCESS_TOKEN, token);
491
+ const user = await this.getUser();
492
+ const response = {
493
+ token,
494
+ user
495
+ };
496
+ this.emitAuthStateChange("SIGNED_IN", user);
497
+ return response;
498
+ }
499
+ // ===================
500
+ // Email Verification
501
+ // ===================
502
+ /**
503
+ * Request email verification
504
+ * Sends a verification email to the current user
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * await baasix.auth.requestEmailVerification('https://myapp.com/verify-email');
509
+ * ```
510
+ */
511
+ async requestEmailVerification(redirectUrl) {
512
+ await this.client.post("/auth/request-verify-email", {
513
+ link: redirectUrl
514
+ });
515
+ }
516
+ /**
517
+ * Verify email with token
518
+ *
519
+ * @example
520
+ * ```typescript
521
+ * const params = new URLSearchParams(window.location.search);
522
+ * const token = params.get('token');
523
+ *
524
+ * await baasix.auth.verifyEmail(token);
525
+ * ```
526
+ */
527
+ async verifyEmail(token) {
528
+ await this.client.get("/auth/verify-email", {
529
+ params: { token },
530
+ skipAuth: true
531
+ });
532
+ }
533
+ /**
534
+ * Check if current session/token is valid
535
+ *
536
+ * @example
537
+ * ```typescript
538
+ * const isValid = await baasix.auth.checkSession();
539
+ * ```
540
+ */
541
+ async checkSession() {
542
+ try {
543
+ const response = await this.client.get("/auth/check");
544
+ return response.data.valid;
545
+ } catch {
546
+ return false;
547
+ }
548
+ }
549
+ // ===================
550
+ // Invitation System
551
+ // ===================
552
+ /**
553
+ * Send an invitation to a user (multi-tenant mode)
554
+ *
555
+ * @example
556
+ * ```typescript
557
+ * await baasix.auth.sendInvite({
558
+ * email: 'newuser@example.com',
559
+ * roleId: 'role-uuid',
560
+ * tenantId: 'tenant-uuid',
561
+ * redirectUrl: 'https://myapp.com/accept-invite'
562
+ * });
563
+ * ```
564
+ */
565
+ async sendInvite(options) {
566
+ await this.client.post("/auth/invite", {
567
+ email: options.email,
568
+ role_Id: options.roleId,
569
+ tenant_Id: options.tenantId,
570
+ link: options.redirectUrl
571
+ });
572
+ }
573
+ /**
574
+ * Verify an invitation token
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * const params = new URLSearchParams(window.location.search);
579
+ * const token = params.get('token');
580
+ *
581
+ * const result = await baasix.auth.verifyInvite(token);
582
+ * if (result.valid) {
583
+ * // Show registration form with pre-filled email
584
+ * }
585
+ * ```
586
+ */
587
+ async verifyInvite(token, redirectUrl) {
588
+ const response = await this.client.get(
589
+ "/auth/verify-invite",
590
+ {
591
+ params: {
592
+ token,
593
+ link: redirectUrl
594
+ },
595
+ skipAuth: true
596
+ }
597
+ );
598
+ return response.data;
599
+ }
600
+ /**
601
+ * Accept an invitation (for existing users)
602
+ *
603
+ * @example
604
+ * ```typescript
605
+ * await baasix.auth.acceptInvite(token);
606
+ * ```
607
+ */
608
+ async acceptInvite(token) {
609
+ const response = await this.client.post(
610
+ "/auth/accept-invite",
611
+ { token }
612
+ );
613
+ await this.storeTokens(response);
614
+ this.emitAuthStateChange("SIGNED_IN", response.user);
615
+ return response;
616
+ }
617
+ /**
618
+ * Register with an invitation token
619
+ *
620
+ * @example
621
+ * ```typescript
622
+ * const { user, token } = await baasix.auth.registerWithInvite({
623
+ * email: 'user@example.com',
624
+ * password: 'password',
625
+ * firstName: 'John',
626
+ * lastName: 'Doe',
627
+ * inviteToken: 'invite-token'
628
+ * });
629
+ * ```
630
+ */
631
+ async registerWithInvite(data) {
632
+ const response = await this.client.post(
633
+ "/auth/register",
634
+ {
635
+ ...data,
636
+ inviteToken: data.inviteToken
637
+ },
638
+ { skipAuth: true }
639
+ );
640
+ await this.storeTokens(response);
641
+ this.emitAuthStateChange("SIGNED_IN", response.user);
642
+ return response;
643
+ }
644
+ };
645
+
646
+ export { AuthModule };
647
+ //# sourceMappingURL=auth.js.map
648
+ //# sourceMappingURL=auth.js.map