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