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