@fluxbase/sdk 0.0.2-rc.2 → 0.1.0-rc.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.
- package/dist/index.cjs +122 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +121 -6
- package/dist/index.d.ts +121 -6
- package/dist/index.js +122 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -120,6 +120,7 @@ var FluxbaseAuth = class {
|
|
|
120
120
|
constructor(fetch2, autoRefresh = true, persist = true) {
|
|
121
121
|
this.session = null;
|
|
122
122
|
this.refreshTimer = null;
|
|
123
|
+
this.stateChangeListeners = /* @__PURE__ */ new Set();
|
|
123
124
|
this.fetch = fetch2;
|
|
124
125
|
this.persist = persist;
|
|
125
126
|
this.autoRefresh = autoRefresh;
|
|
@@ -156,6 +157,29 @@ var FluxbaseAuth = class {
|
|
|
156
157
|
getAccessToken() {
|
|
157
158
|
return this.session?.access_token ?? null;
|
|
158
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Listen to auth state changes
|
|
162
|
+
* @param callback - Function called when auth state changes
|
|
163
|
+
* @returns Subscription object with unsubscribe method
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const { data: { subscription } } = client.auth.onAuthStateChange((event, session) => {
|
|
168
|
+
* console.log('Auth event:', event, session)
|
|
169
|
+
* })
|
|
170
|
+
*
|
|
171
|
+
* // Later, to unsubscribe:
|
|
172
|
+
* subscription.unsubscribe()
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
onAuthStateChange(callback) {
|
|
176
|
+
this.stateChangeListeners.add(callback);
|
|
177
|
+
return {
|
|
178
|
+
unsubscribe: () => {
|
|
179
|
+
this.stateChangeListeners.delete(callback);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
159
183
|
/**
|
|
160
184
|
* Sign in with email and password
|
|
161
185
|
* Returns AuthSession if successful, or SignInWith2FAResponse if 2FA is required
|
|
@@ -212,7 +236,7 @@ var FluxbaseAuth = class {
|
|
|
212
236
|
...response,
|
|
213
237
|
expires_at: Date.now() + response.expires_in * 1e3
|
|
214
238
|
};
|
|
215
|
-
this.setSession(session);
|
|
239
|
+
this.setSession(session, "TOKEN_REFRESHED");
|
|
216
240
|
return session;
|
|
217
241
|
}
|
|
218
242
|
/**
|
|
@@ -235,6 +259,7 @@ var FluxbaseAuth = class {
|
|
|
235
259
|
if (this.session) {
|
|
236
260
|
this.session.user = user;
|
|
237
261
|
this.saveSession();
|
|
262
|
+
this.emitAuthChange("USER_UPDATED", this.session);
|
|
238
263
|
}
|
|
239
264
|
return user;
|
|
240
265
|
}
|
|
@@ -296,7 +321,7 @@ var FluxbaseAuth = class {
|
|
|
296
321
|
...response,
|
|
297
322
|
expires_at: Date.now() + response.expires_in * 1e3
|
|
298
323
|
};
|
|
299
|
-
this.setSession(session);
|
|
324
|
+
this.setSession(session, "MFA_CHALLENGE_VERIFIED");
|
|
300
325
|
return session;
|
|
301
326
|
}
|
|
302
327
|
/**
|
|
@@ -423,11 +448,12 @@ var FluxbaseAuth = class {
|
|
|
423
448
|
/**
|
|
424
449
|
* Internal: Set the session and persist it
|
|
425
450
|
*/
|
|
426
|
-
setSession(session) {
|
|
451
|
+
setSession(session, event = "SIGNED_IN") {
|
|
427
452
|
this.session = session;
|
|
428
453
|
this.fetch.setAuthToken(session.access_token);
|
|
429
454
|
this.saveSession();
|
|
430
455
|
this.scheduleTokenRefresh();
|
|
456
|
+
this.emitAuthChange(event, session);
|
|
431
457
|
}
|
|
432
458
|
/**
|
|
433
459
|
* Internal: Clear the session
|
|
@@ -442,6 +468,7 @@ var FluxbaseAuth = class {
|
|
|
442
468
|
clearTimeout(this.refreshTimer);
|
|
443
469
|
this.refreshTimer = null;
|
|
444
470
|
}
|
|
471
|
+
this.emitAuthChange("SIGNED_OUT", null);
|
|
445
472
|
}
|
|
446
473
|
/**
|
|
447
474
|
* Internal: Save session to storage
|
|
@@ -472,6 +499,18 @@ var FluxbaseAuth = class {
|
|
|
472
499
|
}, delay);
|
|
473
500
|
}
|
|
474
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Internal: Emit auth state change event to all listeners
|
|
504
|
+
*/
|
|
505
|
+
emitAuthChange(event, session) {
|
|
506
|
+
this.stateChangeListeners.forEach((callback) => {
|
|
507
|
+
try {
|
|
508
|
+
callback(event, session);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
console.error("Error in auth state change listener:", error);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
475
514
|
};
|
|
476
515
|
|
|
477
516
|
// src/realtime.ts
|
|
@@ -479,6 +518,7 @@ var RealtimeChannel = class {
|
|
|
479
518
|
constructor(url, channelName, token = null) {
|
|
480
519
|
this.ws = null;
|
|
481
520
|
this.callbacks = /* @__PURE__ */ new Map();
|
|
521
|
+
this.subscriptionConfig = null;
|
|
482
522
|
this.reconnectAttempts = 0;
|
|
483
523
|
this.maxReconnectAttempts = 10;
|
|
484
524
|
this.reconnectDelay = 1e3;
|
|
@@ -487,16 +527,25 @@ var RealtimeChannel = class {
|
|
|
487
527
|
this.channelName = channelName;
|
|
488
528
|
this.token = token;
|
|
489
529
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
this.callbacks.
|
|
530
|
+
// Implementation
|
|
531
|
+
on(event, configOrCallback, callback) {
|
|
532
|
+
if (event === "postgres_changes" && typeof configOrCallback !== "function") {
|
|
533
|
+
const config = configOrCallback;
|
|
534
|
+
this.subscriptionConfig = config;
|
|
535
|
+
const actualCallback = callback;
|
|
536
|
+
const eventType = config.event;
|
|
537
|
+
if (!this.callbacks.has(eventType)) {
|
|
538
|
+
this.callbacks.set(eventType, /* @__PURE__ */ new Set());
|
|
539
|
+
}
|
|
540
|
+
this.callbacks.get(eventType).add(actualCallback);
|
|
541
|
+
} else {
|
|
542
|
+
const actualEvent = event;
|
|
543
|
+
const actualCallback = configOrCallback;
|
|
544
|
+
if (!this.callbacks.has(actualEvent)) {
|
|
545
|
+
this.callbacks.set(actualEvent, /* @__PURE__ */ new Set());
|
|
546
|
+
}
|
|
547
|
+
this.callbacks.get(actualEvent).add(actualCallback);
|
|
498
548
|
}
|
|
499
|
-
this.callbacks.get(event).add(callback);
|
|
500
549
|
return this;
|
|
501
550
|
}
|
|
502
551
|
/**
|
|
@@ -545,10 +594,14 @@ var RealtimeChannel = class {
|
|
|
545
594
|
this.ws.onopen = () => {
|
|
546
595
|
console.log("[Fluxbase Realtime] Connected");
|
|
547
596
|
this.reconnectAttempts = 0;
|
|
548
|
-
|
|
597
|
+
const subscribeMessage = {
|
|
549
598
|
type: "subscribe",
|
|
550
599
|
channel: this.channelName
|
|
551
|
-
}
|
|
600
|
+
};
|
|
601
|
+
if (this.subscriptionConfig) {
|
|
602
|
+
subscribeMessage.config = this.subscriptionConfig;
|
|
603
|
+
}
|
|
604
|
+
this.send(subscribeMessage);
|
|
552
605
|
this.startHeartbeat();
|
|
553
606
|
};
|
|
554
607
|
this.ws.onmessage = (event) => {
|
|
@@ -2223,7 +2276,9 @@ var FluxbaseAdmin = class {
|
|
|
2223
2276
|
* ```
|
|
2224
2277
|
*/
|
|
2225
2278
|
async getSetupStatus() {
|
|
2226
|
-
return await this.fetch.get(
|
|
2279
|
+
return await this.fetch.get(
|
|
2280
|
+
"/api/v1/admin/setup/status"
|
|
2281
|
+
);
|
|
2227
2282
|
}
|
|
2228
2283
|
/**
|
|
2229
2284
|
* Perform initial admin setup
|
|
@@ -2249,7 +2304,10 @@ var FluxbaseAdmin = class {
|
|
|
2249
2304
|
* ```
|
|
2250
2305
|
*/
|
|
2251
2306
|
async setup(request) {
|
|
2252
|
-
const response = await this.fetch.post(
|
|
2307
|
+
const response = await this.fetch.post(
|
|
2308
|
+
"/api/v1/admin/setup",
|
|
2309
|
+
request
|
|
2310
|
+
);
|
|
2253
2311
|
this.setToken(response.access_token);
|
|
2254
2312
|
return response;
|
|
2255
2313
|
}
|
|
@@ -2274,7 +2332,10 @@ var FluxbaseAdmin = class {
|
|
|
2274
2332
|
* ```
|
|
2275
2333
|
*/
|
|
2276
2334
|
async login(request) {
|
|
2277
|
-
const response = await this.fetch.post(
|
|
2335
|
+
const response = await this.fetch.post(
|
|
2336
|
+
"/api/v1/admin/login",
|
|
2337
|
+
request
|
|
2338
|
+
);
|
|
2278
2339
|
this.setToken(response.access_token);
|
|
2279
2340
|
return response;
|
|
2280
2341
|
}
|
|
@@ -2295,7 +2356,10 @@ var FluxbaseAdmin = class {
|
|
|
2295
2356
|
* ```
|
|
2296
2357
|
*/
|
|
2297
2358
|
async refreshToken(request) {
|
|
2298
|
-
const response = await this.fetch.post(
|
|
2359
|
+
const response = await this.fetch.post(
|
|
2360
|
+
"/api/v1/admin/refresh",
|
|
2361
|
+
request
|
|
2362
|
+
);
|
|
2299
2363
|
this.setToken(response.access_token);
|
|
2300
2364
|
return response;
|
|
2301
2365
|
}
|
|
@@ -2370,6 +2434,30 @@ var FluxbaseAdmin = class {
|
|
|
2370
2434
|
const url = queryString ? `/api/v1/admin/users?${queryString}` : "/api/v1/admin/users";
|
|
2371
2435
|
return await this.fetch.get(url);
|
|
2372
2436
|
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Get a user by ID
|
|
2439
|
+
*
|
|
2440
|
+
* Fetch a single user's details by their user ID
|
|
2441
|
+
*
|
|
2442
|
+
* @param userId - User ID to fetch
|
|
2443
|
+
* @param type - User type ('app' or 'dashboard')
|
|
2444
|
+
* @returns User details with metadata
|
|
2445
|
+
*
|
|
2446
|
+
* @example
|
|
2447
|
+
* ```typescript
|
|
2448
|
+
* // Get an app user
|
|
2449
|
+
* const user = await admin.getUserById('user-123');
|
|
2450
|
+
*
|
|
2451
|
+
* // Get a dashboard user
|
|
2452
|
+
* const dashboardUser = await admin.getUserById('admin-456', 'dashboard');
|
|
2453
|
+
* console.log('User email:', dashboardUser.email);
|
|
2454
|
+
* console.log('Last login:', dashboardUser.last_login_at);
|
|
2455
|
+
* ```
|
|
2456
|
+
*/
|
|
2457
|
+
async getUserById(userId, type = "app") {
|
|
2458
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
2459
|
+
return await this.fetch.get(url);
|
|
2460
|
+
}
|
|
2373
2461
|
/**
|
|
2374
2462
|
* Invite a new user
|
|
2375
2463
|
*
|
|
@@ -2942,6 +3030,22 @@ var QueryBuilder = class {
|
|
|
2942
3030
|
};
|
|
2943
3031
|
}
|
|
2944
3032
|
}
|
|
3033
|
+
/**
|
|
3034
|
+
* Make QueryBuilder awaitable (implements PromiseLike)
|
|
3035
|
+
* This allows using `await client.from('table').select()` without calling `.execute()`
|
|
3036
|
+
*
|
|
3037
|
+
* @example
|
|
3038
|
+
* ```typescript
|
|
3039
|
+
* // Without .execute() (new way)
|
|
3040
|
+
* const { data } = await client.from('users').select('*')
|
|
3041
|
+
*
|
|
3042
|
+
* // With .execute() (old way, still supported)
|
|
3043
|
+
* const { data } = await client.from('users').select('*').execute()
|
|
3044
|
+
* ```
|
|
3045
|
+
*/
|
|
3046
|
+
then(onfulfilled, onrejected) {
|
|
3047
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
3048
|
+
}
|
|
2945
3049
|
/**
|
|
2946
3050
|
* Build the query string from filters, ordering, etc.
|
|
2947
3051
|
*/
|