@fluxbase/sdk 0.0.1-rc.17 → 0.0.1-rc.18
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 +357 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -60
- package/dist/index.d.ts +138 -60
- package/dist/index.js +357 -230
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -116,6 +116,29 @@ var FluxbaseFetch = class {
|
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
+
// src/utils/error-handling.ts
|
|
120
|
+
async function wrapAsync(operation) {
|
|
121
|
+
try {
|
|
122
|
+
const data = await operation();
|
|
123
|
+
return { data, error: null };
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
data: null,
|
|
127
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function wrapAsyncVoid(operation) {
|
|
132
|
+
try {
|
|
133
|
+
await operation();
|
|
134
|
+
return { error: null };
|
|
135
|
+
} catch (error) {
|
|
136
|
+
return {
|
|
137
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
119
142
|
// src/auth.ts
|
|
120
143
|
var AUTH_STORAGE_KEY = "fluxbase.auth.session";
|
|
121
144
|
var FluxbaseAuth = class {
|
|
@@ -187,17 +210,19 @@ var FluxbaseAuth = class {
|
|
|
187
210
|
* Returns AuthSession if successful, or SignInWith2FAResponse if 2FA is required
|
|
188
211
|
*/
|
|
189
212
|
async signIn(credentials) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
return wrapAsync(async () => {
|
|
214
|
+
const response = await this.fetch.post("/api/v1/auth/signin", credentials);
|
|
215
|
+
if ("requires_2fa" in response && response.requires_2fa) {
|
|
216
|
+
return response;
|
|
217
|
+
}
|
|
218
|
+
const authResponse = response;
|
|
219
|
+
const session = {
|
|
220
|
+
...authResponse,
|
|
221
|
+
expires_at: Date.now() + authResponse.expires_in * 1e3
|
|
222
|
+
};
|
|
223
|
+
this.setSession(session);
|
|
224
|
+
return session;
|
|
225
|
+
});
|
|
201
226
|
}
|
|
202
227
|
/**
|
|
203
228
|
* Sign in with email and password
|
|
@@ -211,70 +236,81 @@ var FluxbaseAuth = class {
|
|
|
211
236
|
* Sign up with email and password
|
|
212
237
|
*/
|
|
213
238
|
async signUp(credentials) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
239
|
+
return wrapAsync(async () => {
|
|
240
|
+
const response = await this.fetch.post(
|
|
241
|
+
"/api/v1/auth/signup",
|
|
242
|
+
credentials
|
|
243
|
+
);
|
|
244
|
+
const session = {
|
|
245
|
+
...response,
|
|
246
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
247
|
+
};
|
|
248
|
+
this.setSession(session);
|
|
249
|
+
return { user: session.user, session };
|
|
250
|
+
});
|
|
224
251
|
}
|
|
225
252
|
/**
|
|
226
253
|
* Sign out the current user
|
|
227
254
|
*/
|
|
228
255
|
async signOut() {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
256
|
+
return wrapAsyncVoid(async () => {
|
|
257
|
+
try {
|
|
258
|
+
await this.fetch.post("/api/v1/auth/signout");
|
|
259
|
+
} finally {
|
|
260
|
+
this.clearSession();
|
|
261
|
+
}
|
|
262
|
+
});
|
|
234
263
|
}
|
|
235
264
|
/**
|
|
236
265
|
* Refresh the access token
|
|
237
266
|
*/
|
|
238
267
|
async refreshToken() {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const response = await this.fetch.post(
|
|
243
|
-
"/api/v1/auth/refresh",
|
|
244
|
-
{
|
|
245
|
-
refresh_token: this.session.refresh_token
|
|
268
|
+
return wrapAsync(async () => {
|
|
269
|
+
if (!this.session?.refresh_token) {
|
|
270
|
+
throw new Error("No refresh token available");
|
|
246
271
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
272
|
+
const response = await this.fetch.post(
|
|
273
|
+
"/api/v1/auth/refresh",
|
|
274
|
+
{
|
|
275
|
+
refresh_token: this.session.refresh_token
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
const session = {
|
|
279
|
+
...response,
|
|
280
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
281
|
+
};
|
|
282
|
+
this.setSession(session, "TOKEN_REFRESHED");
|
|
283
|
+
return { session };
|
|
284
|
+
});
|
|
254
285
|
}
|
|
255
286
|
/**
|
|
256
287
|
* Get the current user from the server
|
|
257
288
|
*/
|
|
258
289
|
async getCurrentUser() {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
290
|
+
return wrapAsync(async () => {
|
|
291
|
+
if (!this.session) {
|
|
292
|
+
throw new Error("Not authenticated");
|
|
293
|
+
}
|
|
294
|
+
const user = await this.fetch.get("/api/v1/auth/user");
|
|
295
|
+
return { user };
|
|
296
|
+
});
|
|
263
297
|
}
|
|
264
298
|
/**
|
|
265
299
|
* Update the current user
|
|
266
300
|
*/
|
|
267
301
|
async updateUser(data) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
this.session
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
302
|
+
return wrapAsync(async () => {
|
|
303
|
+
if (!this.session) {
|
|
304
|
+
throw new Error("Not authenticated");
|
|
305
|
+
}
|
|
306
|
+
const user = await this.fetch.patch("/api/v1/auth/user", data);
|
|
307
|
+
if (this.session) {
|
|
308
|
+
this.session.user = user;
|
|
309
|
+
this.saveSession();
|
|
310
|
+
this.emitAuthChange("USER_UPDATED", this.session);
|
|
311
|
+
}
|
|
312
|
+
return { user };
|
|
313
|
+
});
|
|
278
314
|
}
|
|
279
315
|
/**
|
|
280
316
|
* Set the auth token manually
|
|
@@ -287,65 +323,75 @@ var FluxbaseAuth = class {
|
|
|
287
323
|
* Returns TOTP secret and QR code URL
|
|
288
324
|
*/
|
|
289
325
|
async setup2FA() {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
326
|
+
return wrapAsync(async () => {
|
|
327
|
+
if (!this.session) {
|
|
328
|
+
throw new Error("Not authenticated");
|
|
329
|
+
}
|
|
330
|
+
return await this.fetch.post(
|
|
331
|
+
"/api/v1/auth/2fa/setup"
|
|
332
|
+
);
|
|
333
|
+
});
|
|
296
334
|
}
|
|
297
335
|
/**
|
|
298
336
|
* Enable 2FA after verifying the TOTP code
|
|
299
337
|
* Returns backup codes that should be saved by the user
|
|
300
338
|
*/
|
|
301
339
|
async enable2FA(code) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
340
|
+
return wrapAsync(async () => {
|
|
341
|
+
if (!this.session) {
|
|
342
|
+
throw new Error("Not authenticated");
|
|
343
|
+
}
|
|
344
|
+
return await this.fetch.post(
|
|
345
|
+
"/api/v1/auth/2fa/enable",
|
|
346
|
+
{ code }
|
|
347
|
+
);
|
|
348
|
+
});
|
|
309
349
|
}
|
|
310
350
|
/**
|
|
311
351
|
* Disable 2FA for the current user
|
|
312
352
|
* Requires password confirmation
|
|
313
353
|
*/
|
|
314
354
|
async disable2FA(password) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
355
|
+
return wrapAsync(async () => {
|
|
356
|
+
if (!this.session) {
|
|
357
|
+
throw new Error("Not authenticated");
|
|
358
|
+
}
|
|
359
|
+
return await this.fetch.post(
|
|
360
|
+
"/api/v1/auth/2fa/disable",
|
|
361
|
+
{ password }
|
|
362
|
+
);
|
|
363
|
+
});
|
|
322
364
|
}
|
|
323
365
|
/**
|
|
324
366
|
* Check 2FA status for the current user
|
|
325
367
|
*/
|
|
326
368
|
async get2FAStatus() {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
369
|
+
return wrapAsync(async () => {
|
|
370
|
+
if (!this.session) {
|
|
371
|
+
throw new Error("Not authenticated");
|
|
372
|
+
}
|
|
373
|
+
return await this.fetch.get(
|
|
374
|
+
"/api/v1/auth/2fa/status"
|
|
375
|
+
);
|
|
376
|
+
});
|
|
333
377
|
}
|
|
334
378
|
/**
|
|
335
379
|
* Verify 2FA code during login
|
|
336
380
|
* Call this after signIn returns requires_2fa: true
|
|
337
381
|
*/
|
|
338
382
|
async verify2FA(request) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
383
|
+
return wrapAsync(async () => {
|
|
384
|
+
const response = await this.fetch.post(
|
|
385
|
+
"/api/v1/auth/2fa/verify",
|
|
386
|
+
request
|
|
387
|
+
);
|
|
388
|
+
const session = {
|
|
389
|
+
...response,
|
|
390
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
391
|
+
};
|
|
392
|
+
this.setSession(session, "MFA_CHALLENGE_VERIFIED");
|
|
393
|
+
return { user: session.user, session };
|
|
394
|
+
});
|
|
349
395
|
}
|
|
350
396
|
/**
|
|
351
397
|
* Send password reset email
|
|
@@ -353,10 +399,20 @@ var FluxbaseAuth = class {
|
|
|
353
399
|
* @param email - Email address to send reset link to
|
|
354
400
|
*/
|
|
355
401
|
async sendPasswordReset(email) {
|
|
356
|
-
return
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
402
|
+
return wrapAsync(async () => {
|
|
403
|
+
return await this.fetch.post(
|
|
404
|
+
"/api/v1/auth/password/reset",
|
|
405
|
+
{ email }
|
|
406
|
+
);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Supabase-compatible alias for sendPasswordReset()
|
|
411
|
+
* @param email - Email address to send reset link to
|
|
412
|
+
* @param _options - Optional redirect configuration (currently not used)
|
|
413
|
+
*/
|
|
414
|
+
async resetPasswordForEmail(email, _options) {
|
|
415
|
+
return this.sendPasswordReset(email);
|
|
360
416
|
}
|
|
361
417
|
/**
|
|
362
418
|
* Verify password reset token
|
|
@@ -364,12 +420,14 @@ var FluxbaseAuth = class {
|
|
|
364
420
|
* @param token - Password reset token to verify
|
|
365
421
|
*/
|
|
366
422
|
async verifyResetToken(token) {
|
|
367
|
-
return
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
423
|
+
return wrapAsync(async () => {
|
|
424
|
+
return await this.fetch.post(
|
|
425
|
+
"/api/v1/auth/password/reset/verify",
|
|
426
|
+
{
|
|
427
|
+
token
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
});
|
|
373
431
|
}
|
|
374
432
|
/**
|
|
375
433
|
* Reset password with token
|
|
@@ -378,13 +436,15 @@ var FluxbaseAuth = class {
|
|
|
378
436
|
* @param newPassword - New password to set
|
|
379
437
|
*/
|
|
380
438
|
async resetPassword(token, newPassword) {
|
|
381
|
-
return
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
439
|
+
return wrapAsync(async () => {
|
|
440
|
+
return await this.fetch.post(
|
|
441
|
+
"/api/v1/auth/password/reset/confirm",
|
|
442
|
+
{
|
|
443
|
+
token,
|
|
444
|
+
new_password: newPassword
|
|
445
|
+
}
|
|
446
|
+
);
|
|
447
|
+
});
|
|
388
448
|
}
|
|
389
449
|
/**
|
|
390
450
|
* Send magic link for passwordless authentication
|
|
@@ -392,9 +452,11 @@ var FluxbaseAuth = class {
|
|
|
392
452
|
* @param options - Optional configuration for magic link
|
|
393
453
|
*/
|
|
394
454
|
async sendMagicLink(email, options) {
|
|
395
|
-
return
|
|
396
|
-
|
|
397
|
-
|
|
455
|
+
return wrapAsync(async () => {
|
|
456
|
+
return await this.fetch.post("/api/v1/auth/magiclink", {
|
|
457
|
+
email,
|
|
458
|
+
redirect_to: options?.redirect_to
|
|
459
|
+
});
|
|
398
460
|
});
|
|
399
461
|
}
|
|
400
462
|
/**
|
|
@@ -402,41 +464,47 @@ var FluxbaseAuth = class {
|
|
|
402
464
|
* @param token - Magic link token from email
|
|
403
465
|
*/
|
|
404
466
|
async verifyMagicLink(token) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
467
|
+
return wrapAsync(async () => {
|
|
468
|
+
const response = await this.fetch.post(
|
|
469
|
+
"/api/v1/auth/magiclink/verify",
|
|
470
|
+
{
|
|
471
|
+
token
|
|
472
|
+
}
|
|
473
|
+
);
|
|
474
|
+
const session = {
|
|
475
|
+
...response,
|
|
476
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
477
|
+
};
|
|
478
|
+
this.setSession(session);
|
|
479
|
+
return { user: session.user, session };
|
|
480
|
+
});
|
|
417
481
|
}
|
|
418
482
|
/**
|
|
419
483
|
* Sign in anonymously
|
|
420
484
|
* Creates a temporary anonymous user session
|
|
421
485
|
*/
|
|
422
486
|
async signInAnonymously() {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
487
|
+
return wrapAsync(async () => {
|
|
488
|
+
const response = await this.fetch.post(
|
|
489
|
+
"/api/v1/auth/signin/anonymous"
|
|
490
|
+
);
|
|
491
|
+
const session = {
|
|
492
|
+
...response,
|
|
493
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
494
|
+
};
|
|
495
|
+
this.setSession(session);
|
|
496
|
+
return { user: session.user, session };
|
|
497
|
+
});
|
|
432
498
|
}
|
|
433
499
|
/**
|
|
434
500
|
* Get list of enabled OAuth providers
|
|
435
501
|
*/
|
|
436
502
|
async getOAuthProviders() {
|
|
437
|
-
return
|
|
438
|
-
|
|
439
|
-
|
|
503
|
+
return wrapAsync(async () => {
|
|
504
|
+
return await this.fetch.get(
|
|
505
|
+
"/api/v1/auth/oauth/providers"
|
|
506
|
+
);
|
|
507
|
+
});
|
|
440
508
|
}
|
|
441
509
|
/**
|
|
442
510
|
* Get OAuth authorization URL for a provider
|
|
@@ -444,17 +512,19 @@ var FluxbaseAuth = class {
|
|
|
444
512
|
* @param options - Optional OAuth configuration
|
|
445
513
|
*/
|
|
446
514
|
async getOAuthUrl(provider, options) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
515
|
+
return wrapAsync(async () => {
|
|
516
|
+
const params = new URLSearchParams();
|
|
517
|
+
if (options?.redirect_to) {
|
|
518
|
+
params.append("redirect_to", options.redirect_to);
|
|
519
|
+
}
|
|
520
|
+
if (options?.scopes && options.scopes.length > 0) {
|
|
521
|
+
params.append("scopes", options.scopes.join(","));
|
|
522
|
+
}
|
|
523
|
+
const queryString = params.toString();
|
|
524
|
+
const url = queryString ? `/api/v1/auth/oauth/${provider}/authorize?${queryString}` : `/api/v1/auth/oauth/${provider}/authorize`;
|
|
525
|
+
const response = await this.fetch.get(url);
|
|
526
|
+
return response;
|
|
527
|
+
});
|
|
458
528
|
}
|
|
459
529
|
/**
|
|
460
530
|
* Exchange OAuth authorization code for session
|
|
@@ -462,16 +532,18 @@ var FluxbaseAuth = class {
|
|
|
462
532
|
* @param code - Authorization code from OAuth callback
|
|
463
533
|
*/
|
|
464
534
|
async exchangeCodeForSession(code) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
535
|
+
return wrapAsync(async () => {
|
|
536
|
+
const response = await this.fetch.post(
|
|
537
|
+
"/api/v1/auth/oauth/callback",
|
|
538
|
+
{ code }
|
|
539
|
+
);
|
|
540
|
+
const session = {
|
|
541
|
+
...response,
|
|
542
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
543
|
+
};
|
|
544
|
+
this.setSession(session);
|
|
545
|
+
return { user: session.user, session };
|
|
546
|
+
});
|
|
475
547
|
}
|
|
476
548
|
/**
|
|
477
549
|
* Convenience method to initiate OAuth sign-in
|
|
@@ -480,14 +552,21 @@ var FluxbaseAuth = class {
|
|
|
480
552
|
* @param options - Optional OAuth configuration
|
|
481
553
|
*/
|
|
482
554
|
async signInWithOAuth(provider, options) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
)
|
|
490
|
-
|
|
555
|
+
return wrapAsync(async () => {
|
|
556
|
+
const result = await this.getOAuthUrl(provider, options);
|
|
557
|
+
if (result.error) {
|
|
558
|
+
throw result.error;
|
|
559
|
+
}
|
|
560
|
+
const url = result.data.url;
|
|
561
|
+
if (typeof window !== "undefined") {
|
|
562
|
+
window.location.href = url;
|
|
563
|
+
} else {
|
|
564
|
+
throw new Error(
|
|
565
|
+
"signInWithOAuth can only be called in a browser environment"
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
return { provider, url };
|
|
569
|
+
});
|
|
491
570
|
}
|
|
492
571
|
/**
|
|
493
572
|
* Internal: Set the session and persist it
|
|
@@ -535,11 +614,12 @@ var FluxbaseAuth = class {
|
|
|
535
614
|
const refreshAt = this.session.expires_at - 60 * 1e3;
|
|
536
615
|
const delay = refreshAt - Date.now();
|
|
537
616
|
if (delay > 0) {
|
|
538
|
-
this.refreshTimer = setTimeout(() => {
|
|
539
|
-
this.refreshToken()
|
|
540
|
-
|
|
617
|
+
this.refreshTimer = setTimeout(async () => {
|
|
618
|
+
const result = await this.refreshToken();
|
|
619
|
+
if (result.error) {
|
|
620
|
+
console.error("Failed to refresh token:", result.error);
|
|
541
621
|
this.clearSession();
|
|
542
|
-
}
|
|
622
|
+
}
|
|
543
623
|
}, delay);
|
|
544
624
|
}
|
|
545
625
|
}
|
|
@@ -3131,9 +3211,11 @@ var FluxbaseAdmin = class {
|
|
|
3131
3211
|
* ```
|
|
3132
3212
|
*/
|
|
3133
3213
|
async getSetupStatus() {
|
|
3134
|
-
return
|
|
3135
|
-
|
|
3136
|
-
|
|
3214
|
+
return wrapAsync(async () => {
|
|
3215
|
+
return await this.fetch.get(
|
|
3216
|
+
"/api/v1/admin/setup/status"
|
|
3217
|
+
);
|
|
3218
|
+
});
|
|
3137
3219
|
}
|
|
3138
3220
|
/**
|
|
3139
3221
|
* Perform initial admin setup
|
|
@@ -3159,12 +3241,14 @@ var FluxbaseAdmin = class {
|
|
|
3159
3241
|
* ```
|
|
3160
3242
|
*/
|
|
3161
3243
|
async setup(request) {
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3244
|
+
return wrapAsync(async () => {
|
|
3245
|
+
const response = await this.fetch.post(
|
|
3246
|
+
"/api/v1/admin/setup",
|
|
3247
|
+
request
|
|
3248
|
+
);
|
|
3249
|
+
this.setToken(response.access_token);
|
|
3250
|
+
return response;
|
|
3251
|
+
});
|
|
3168
3252
|
}
|
|
3169
3253
|
/**
|
|
3170
3254
|
* Admin login
|
|
@@ -3187,12 +3271,14 @@ var FluxbaseAdmin = class {
|
|
|
3187
3271
|
* ```
|
|
3188
3272
|
*/
|
|
3189
3273
|
async login(request) {
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3274
|
+
return wrapAsync(async () => {
|
|
3275
|
+
const response = await this.fetch.post(
|
|
3276
|
+
"/api/v1/admin/login",
|
|
3277
|
+
request
|
|
3278
|
+
);
|
|
3279
|
+
this.setToken(response.access_token);
|
|
3280
|
+
return response;
|
|
3281
|
+
});
|
|
3196
3282
|
}
|
|
3197
3283
|
/**
|
|
3198
3284
|
* Refresh admin access token
|
|
@@ -3211,12 +3297,14 @@ var FluxbaseAdmin = class {
|
|
|
3211
3297
|
* ```
|
|
3212
3298
|
*/
|
|
3213
3299
|
async refreshToken(request) {
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3300
|
+
return wrapAsync(async () => {
|
|
3301
|
+
const response = await this.fetch.post(
|
|
3302
|
+
"/api/v1/admin/refresh",
|
|
3303
|
+
request
|
|
3304
|
+
);
|
|
3305
|
+
this.setToken(response.access_token);
|
|
3306
|
+
return response;
|
|
3307
|
+
});
|
|
3220
3308
|
}
|
|
3221
3309
|
/**
|
|
3222
3310
|
* Admin logout
|
|
@@ -3230,8 +3318,10 @@ var FluxbaseAdmin = class {
|
|
|
3230
3318
|
* ```
|
|
3231
3319
|
*/
|
|
3232
3320
|
async logout() {
|
|
3233
|
-
|
|
3234
|
-
|
|
3321
|
+
return wrapAsyncVoid(async () => {
|
|
3322
|
+
await this.fetch.post("/api/v1/admin/logout", {});
|
|
3323
|
+
this.clearToken();
|
|
3324
|
+
});
|
|
3235
3325
|
}
|
|
3236
3326
|
/**
|
|
3237
3327
|
* Get current admin user information
|
|
@@ -3246,7 +3336,9 @@ var FluxbaseAdmin = class {
|
|
|
3246
3336
|
* ```
|
|
3247
3337
|
*/
|
|
3248
3338
|
async me() {
|
|
3249
|
-
return
|
|
3339
|
+
return wrapAsync(async () => {
|
|
3340
|
+
return await this.fetch.get("/api/v1/admin/me");
|
|
3341
|
+
});
|
|
3250
3342
|
}
|
|
3251
3343
|
// ============================================================================
|
|
3252
3344
|
// User Management
|
|
@@ -3272,22 +3364,24 @@ var FluxbaseAdmin = class {
|
|
|
3272
3364
|
* ```
|
|
3273
3365
|
*/
|
|
3274
3366
|
async listUsers(options = {}) {
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3367
|
+
return wrapAsync(async () => {
|
|
3368
|
+
const params = new URLSearchParams();
|
|
3369
|
+
if (options.exclude_admins !== void 0) {
|
|
3370
|
+
params.append("exclude_admins", String(options.exclude_admins));
|
|
3371
|
+
}
|
|
3372
|
+
if (options.search) {
|
|
3373
|
+
params.append("search", options.search);
|
|
3374
|
+
}
|
|
3375
|
+
if (options.limit !== void 0) {
|
|
3376
|
+
params.append("limit", String(options.limit));
|
|
3377
|
+
}
|
|
3378
|
+
if (options.type) {
|
|
3379
|
+
params.append("type", options.type);
|
|
3380
|
+
}
|
|
3381
|
+
const queryString = params.toString();
|
|
3382
|
+
const url = queryString ? `/api/v1/admin/users?${queryString}` : "/api/v1/admin/users";
|
|
3383
|
+
return await this.fetch.get(url);
|
|
3384
|
+
});
|
|
3291
3385
|
}
|
|
3292
3386
|
/**
|
|
3293
3387
|
* Get a user by ID
|
|
@@ -3310,8 +3404,10 @@ var FluxbaseAdmin = class {
|
|
|
3310
3404
|
* ```
|
|
3311
3405
|
*/
|
|
3312
3406
|
async getUserById(userId, type = "app") {
|
|
3313
|
-
|
|
3314
|
-
|
|
3407
|
+
return wrapAsync(async () => {
|
|
3408
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3409
|
+
return await this.fetch.get(url);
|
|
3410
|
+
});
|
|
3315
3411
|
}
|
|
3316
3412
|
/**
|
|
3317
3413
|
* Invite a new user
|
|
@@ -3335,8 +3431,10 @@ var FluxbaseAdmin = class {
|
|
|
3335
3431
|
* ```
|
|
3336
3432
|
*/
|
|
3337
3433
|
async inviteUser(request, type = "app") {
|
|
3338
|
-
|
|
3339
|
-
|
|
3434
|
+
return wrapAsync(async () => {
|
|
3435
|
+
const url = `/api/v1/admin/users/invite?type=${type}`;
|
|
3436
|
+
return await this.fetch.post(url, request);
|
|
3437
|
+
});
|
|
3340
3438
|
}
|
|
3341
3439
|
/**
|
|
3342
3440
|
* Delete a user
|
|
@@ -3354,8 +3452,10 @@ var FluxbaseAdmin = class {
|
|
|
3354
3452
|
* ```
|
|
3355
3453
|
*/
|
|
3356
3454
|
async deleteUser(userId, type = "app") {
|
|
3357
|
-
|
|
3358
|
-
|
|
3455
|
+
return wrapAsync(async () => {
|
|
3456
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3457
|
+
return await this.fetch.delete(url);
|
|
3458
|
+
});
|
|
3359
3459
|
}
|
|
3360
3460
|
/**
|
|
3361
3461
|
* Update user role
|
|
@@ -3374,8 +3474,10 @@ var FluxbaseAdmin = class {
|
|
|
3374
3474
|
* ```
|
|
3375
3475
|
*/
|
|
3376
3476
|
async updateUserRole(userId, role, type = "app") {
|
|
3377
|
-
|
|
3378
|
-
|
|
3477
|
+
return wrapAsync(async () => {
|
|
3478
|
+
const url = `/api/v1/admin/users/${userId}/role?type=${type}`;
|
|
3479
|
+
return await this.fetch.patch(url, { role });
|
|
3480
|
+
});
|
|
3379
3481
|
}
|
|
3380
3482
|
/**
|
|
3381
3483
|
* Reset user password
|
|
@@ -3393,8 +3495,10 @@ var FluxbaseAdmin = class {
|
|
|
3393
3495
|
* ```
|
|
3394
3496
|
*/
|
|
3395
3497
|
async resetUserPassword(userId, type = "app") {
|
|
3396
|
-
|
|
3397
|
-
|
|
3498
|
+
return wrapAsync(async () => {
|
|
3499
|
+
const url = `/api/v1/admin/users/${userId}/reset-password?type=${type}`;
|
|
3500
|
+
return await this.fetch.post(url, {});
|
|
3501
|
+
});
|
|
3398
3502
|
}
|
|
3399
3503
|
};
|
|
3400
3504
|
|
|
@@ -3952,25 +4056,44 @@ var QueryBuilder = class {
|
|
|
3952
4056
|
var FluxbaseClient = class {
|
|
3953
4057
|
/**
|
|
3954
4058
|
* Create a new Fluxbase client instance
|
|
3955
|
-
*
|
|
4059
|
+
*
|
|
4060
|
+
* @param fluxbaseUrl - The URL of your Fluxbase instance
|
|
4061
|
+
* @param fluxbaseKey - The anon key (JWT token with "anon" role). Generate using scripts/generate-keys.sh
|
|
4062
|
+
* @param options - Additional client configuration options
|
|
4063
|
+
*
|
|
4064
|
+
* @example
|
|
4065
|
+
* ```typescript
|
|
4066
|
+
* const client = new FluxbaseClient(
|
|
4067
|
+
* 'http://localhost:8080',
|
|
4068
|
+
* 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Anon JWT token
|
|
4069
|
+
* { timeout: 30000 }
|
|
4070
|
+
* )
|
|
4071
|
+
* ```
|
|
3956
4072
|
*/
|
|
3957
|
-
constructor(options) {
|
|
3958
|
-
this.
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
4073
|
+
constructor(fluxbaseUrl, fluxbaseKey, options) {
|
|
4074
|
+
this.fluxbaseUrl = fluxbaseUrl;
|
|
4075
|
+
this.fluxbaseKey = fluxbaseKey;
|
|
4076
|
+
const headers = {
|
|
4077
|
+
"apikey": fluxbaseKey,
|
|
4078
|
+
"Authorization": `Bearer ${fluxbaseKey}`,
|
|
4079
|
+
...options?.headers
|
|
4080
|
+
};
|
|
4081
|
+
this.fetch = new FluxbaseFetch(fluxbaseUrl, {
|
|
4082
|
+
headers,
|
|
4083
|
+
timeout: options?.timeout,
|
|
4084
|
+
debug: options?.debug
|
|
3962
4085
|
});
|
|
3963
4086
|
this.auth = new FluxbaseAuth(
|
|
3964
4087
|
this.fetch,
|
|
3965
|
-
options
|
|
3966
|
-
options
|
|
4088
|
+
options?.auth?.autoRefresh ?? true,
|
|
4089
|
+
options?.auth?.persist ?? true
|
|
3967
4090
|
);
|
|
3968
|
-
if (options
|
|
4091
|
+
if (options?.auth?.token) {
|
|
3969
4092
|
this.fetch.setAuthToken(options.auth.token);
|
|
3970
4093
|
}
|
|
3971
4094
|
this.realtime = new FluxbaseRealtime(
|
|
3972
|
-
|
|
3973
|
-
options
|
|
4095
|
+
fluxbaseUrl,
|
|
4096
|
+
options?.auth?.token || null
|
|
3974
4097
|
);
|
|
3975
4098
|
this.storage = new FluxbaseStorage(this.fetch);
|
|
3976
4099
|
this.functions = new FluxbaseFunctions(this.fetch);
|
|
@@ -4120,8 +4243,12 @@ var FluxbaseClient = class {
|
|
|
4120
4243
|
return this.fetch;
|
|
4121
4244
|
}
|
|
4122
4245
|
};
|
|
4123
|
-
function createClient(options) {
|
|
4124
|
-
return new FluxbaseClient(
|
|
4246
|
+
function createClient(fluxbaseUrl, fluxbaseKey, options) {
|
|
4247
|
+
return new FluxbaseClient(
|
|
4248
|
+
fluxbaseUrl,
|
|
4249
|
+
fluxbaseKey,
|
|
4250
|
+
options
|
|
4251
|
+
);
|
|
4125
4252
|
}
|
|
4126
4253
|
|
|
4127
4254
|
exports.APIKeysManager = APIKeysManager;
|