@fluxbase/sdk 0.0.1-rc.17 → 0.0.1-rc.19
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 +360 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +145 -60
- package/dist/index.d.ts +145 -60
- package/dist/index.js +360 -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,14 @@ 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(
|
|
457
|
+
"/api/v1/auth/magiclink",
|
|
458
|
+
{
|
|
459
|
+
email,
|
|
460
|
+
redirect_to: options?.redirect_to
|
|
461
|
+
}
|
|
462
|
+
);
|
|
398
463
|
});
|
|
399
464
|
}
|
|
400
465
|
/**
|
|
@@ -402,41 +467,47 @@ var FluxbaseAuth = class {
|
|
|
402
467
|
* @param token - Magic link token from email
|
|
403
468
|
*/
|
|
404
469
|
async verifyMagicLink(token) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
470
|
+
return wrapAsync(async () => {
|
|
471
|
+
const response = await this.fetch.post(
|
|
472
|
+
"/api/v1/auth/magiclink/verify",
|
|
473
|
+
{
|
|
474
|
+
token
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
const session = {
|
|
478
|
+
...response,
|
|
479
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
480
|
+
};
|
|
481
|
+
this.setSession(session);
|
|
482
|
+
return { user: session.user, session };
|
|
483
|
+
});
|
|
417
484
|
}
|
|
418
485
|
/**
|
|
419
486
|
* Sign in anonymously
|
|
420
487
|
* Creates a temporary anonymous user session
|
|
421
488
|
*/
|
|
422
489
|
async signInAnonymously() {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
490
|
+
return wrapAsync(async () => {
|
|
491
|
+
const response = await this.fetch.post(
|
|
492
|
+
"/api/v1/auth/signin/anonymous"
|
|
493
|
+
);
|
|
494
|
+
const session = {
|
|
495
|
+
...response,
|
|
496
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
497
|
+
};
|
|
498
|
+
this.setSession(session);
|
|
499
|
+
return { user: session.user, session };
|
|
500
|
+
});
|
|
432
501
|
}
|
|
433
502
|
/**
|
|
434
503
|
* Get list of enabled OAuth providers
|
|
435
504
|
*/
|
|
436
505
|
async getOAuthProviders() {
|
|
437
|
-
return
|
|
438
|
-
|
|
439
|
-
|
|
506
|
+
return wrapAsync(async () => {
|
|
507
|
+
return await this.fetch.get(
|
|
508
|
+
"/api/v1/auth/oauth/providers"
|
|
509
|
+
);
|
|
510
|
+
});
|
|
440
511
|
}
|
|
441
512
|
/**
|
|
442
513
|
* Get OAuth authorization URL for a provider
|
|
@@ -444,17 +515,19 @@ var FluxbaseAuth = class {
|
|
|
444
515
|
* @param options - Optional OAuth configuration
|
|
445
516
|
*/
|
|
446
517
|
async getOAuthUrl(provider, options) {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
518
|
+
return wrapAsync(async () => {
|
|
519
|
+
const params = new URLSearchParams();
|
|
520
|
+
if (options?.redirect_to) {
|
|
521
|
+
params.append("redirect_to", options.redirect_to);
|
|
522
|
+
}
|
|
523
|
+
if (options?.scopes && options.scopes.length > 0) {
|
|
524
|
+
params.append("scopes", options.scopes.join(","));
|
|
525
|
+
}
|
|
526
|
+
const queryString = params.toString();
|
|
527
|
+
const url = queryString ? `/api/v1/auth/oauth/${provider}/authorize?${queryString}` : `/api/v1/auth/oauth/${provider}/authorize`;
|
|
528
|
+
const response = await this.fetch.get(url);
|
|
529
|
+
return response;
|
|
530
|
+
});
|
|
458
531
|
}
|
|
459
532
|
/**
|
|
460
533
|
* Exchange OAuth authorization code for session
|
|
@@ -462,16 +535,18 @@ var FluxbaseAuth = class {
|
|
|
462
535
|
* @param code - Authorization code from OAuth callback
|
|
463
536
|
*/
|
|
464
537
|
async exchangeCodeForSession(code) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
538
|
+
return wrapAsync(async () => {
|
|
539
|
+
const response = await this.fetch.post(
|
|
540
|
+
"/api/v1/auth/oauth/callback",
|
|
541
|
+
{ code }
|
|
542
|
+
);
|
|
543
|
+
const session = {
|
|
544
|
+
...response,
|
|
545
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
546
|
+
};
|
|
547
|
+
this.setSession(session);
|
|
548
|
+
return { user: session.user, session };
|
|
549
|
+
});
|
|
475
550
|
}
|
|
476
551
|
/**
|
|
477
552
|
* Convenience method to initiate OAuth sign-in
|
|
@@ -480,14 +555,21 @@ var FluxbaseAuth = class {
|
|
|
480
555
|
* @param options - Optional OAuth configuration
|
|
481
556
|
*/
|
|
482
557
|
async signInWithOAuth(provider, options) {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
)
|
|
490
|
-
|
|
558
|
+
return wrapAsync(async () => {
|
|
559
|
+
const result = await this.getOAuthUrl(provider, options);
|
|
560
|
+
if (result.error) {
|
|
561
|
+
throw result.error;
|
|
562
|
+
}
|
|
563
|
+
const url = result.data.url;
|
|
564
|
+
if (typeof window !== "undefined") {
|
|
565
|
+
window.location.href = url;
|
|
566
|
+
} else {
|
|
567
|
+
throw new Error(
|
|
568
|
+
"signInWithOAuth can only be called in a browser environment"
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
return { provider, url };
|
|
572
|
+
});
|
|
491
573
|
}
|
|
492
574
|
/**
|
|
493
575
|
* Internal: Set the session and persist it
|
|
@@ -535,11 +617,12 @@ var FluxbaseAuth = class {
|
|
|
535
617
|
const refreshAt = this.session.expires_at - 60 * 1e3;
|
|
536
618
|
const delay = refreshAt - Date.now();
|
|
537
619
|
if (delay > 0) {
|
|
538
|
-
this.refreshTimer = setTimeout(() => {
|
|
539
|
-
this.refreshToken()
|
|
540
|
-
|
|
620
|
+
this.refreshTimer = setTimeout(async () => {
|
|
621
|
+
const result = await this.refreshToken();
|
|
622
|
+
if (result.error) {
|
|
623
|
+
console.error("Failed to refresh token:", result.error);
|
|
541
624
|
this.clearSession();
|
|
542
|
-
}
|
|
625
|
+
}
|
|
543
626
|
}, delay);
|
|
544
627
|
}
|
|
545
628
|
}
|
|
@@ -3131,9 +3214,11 @@ var FluxbaseAdmin = class {
|
|
|
3131
3214
|
* ```
|
|
3132
3215
|
*/
|
|
3133
3216
|
async getSetupStatus() {
|
|
3134
|
-
return
|
|
3135
|
-
|
|
3136
|
-
|
|
3217
|
+
return wrapAsync(async () => {
|
|
3218
|
+
return await this.fetch.get(
|
|
3219
|
+
"/api/v1/admin/setup/status"
|
|
3220
|
+
);
|
|
3221
|
+
});
|
|
3137
3222
|
}
|
|
3138
3223
|
/**
|
|
3139
3224
|
* Perform initial admin setup
|
|
@@ -3159,12 +3244,14 @@ var FluxbaseAdmin = class {
|
|
|
3159
3244
|
* ```
|
|
3160
3245
|
*/
|
|
3161
3246
|
async setup(request) {
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3247
|
+
return wrapAsync(async () => {
|
|
3248
|
+
const response = await this.fetch.post(
|
|
3249
|
+
"/api/v1/admin/setup",
|
|
3250
|
+
request
|
|
3251
|
+
);
|
|
3252
|
+
this.setToken(response.access_token);
|
|
3253
|
+
return response;
|
|
3254
|
+
});
|
|
3168
3255
|
}
|
|
3169
3256
|
/**
|
|
3170
3257
|
* Admin login
|
|
@@ -3187,12 +3274,14 @@ var FluxbaseAdmin = class {
|
|
|
3187
3274
|
* ```
|
|
3188
3275
|
*/
|
|
3189
3276
|
async login(request) {
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3277
|
+
return wrapAsync(async () => {
|
|
3278
|
+
const response = await this.fetch.post(
|
|
3279
|
+
"/api/v1/admin/login",
|
|
3280
|
+
request
|
|
3281
|
+
);
|
|
3282
|
+
this.setToken(response.access_token);
|
|
3283
|
+
return response;
|
|
3284
|
+
});
|
|
3196
3285
|
}
|
|
3197
3286
|
/**
|
|
3198
3287
|
* Refresh admin access token
|
|
@@ -3211,12 +3300,14 @@ var FluxbaseAdmin = class {
|
|
|
3211
3300
|
* ```
|
|
3212
3301
|
*/
|
|
3213
3302
|
async refreshToken(request) {
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3303
|
+
return wrapAsync(async () => {
|
|
3304
|
+
const response = await this.fetch.post(
|
|
3305
|
+
"/api/v1/admin/refresh",
|
|
3306
|
+
request
|
|
3307
|
+
);
|
|
3308
|
+
this.setToken(response.access_token);
|
|
3309
|
+
return response;
|
|
3310
|
+
});
|
|
3220
3311
|
}
|
|
3221
3312
|
/**
|
|
3222
3313
|
* Admin logout
|
|
@@ -3230,8 +3321,10 @@ var FluxbaseAdmin = class {
|
|
|
3230
3321
|
* ```
|
|
3231
3322
|
*/
|
|
3232
3323
|
async logout() {
|
|
3233
|
-
|
|
3234
|
-
|
|
3324
|
+
return wrapAsyncVoid(async () => {
|
|
3325
|
+
await this.fetch.post("/api/v1/admin/logout", {});
|
|
3326
|
+
this.clearToken();
|
|
3327
|
+
});
|
|
3235
3328
|
}
|
|
3236
3329
|
/**
|
|
3237
3330
|
* Get current admin user information
|
|
@@ -3246,7 +3339,9 @@ var FluxbaseAdmin = class {
|
|
|
3246
3339
|
* ```
|
|
3247
3340
|
*/
|
|
3248
3341
|
async me() {
|
|
3249
|
-
return
|
|
3342
|
+
return wrapAsync(async () => {
|
|
3343
|
+
return await this.fetch.get("/api/v1/admin/me");
|
|
3344
|
+
});
|
|
3250
3345
|
}
|
|
3251
3346
|
// ============================================================================
|
|
3252
3347
|
// User Management
|
|
@@ -3272,22 +3367,24 @@ var FluxbaseAdmin = class {
|
|
|
3272
3367
|
* ```
|
|
3273
3368
|
*/
|
|
3274
3369
|
async listUsers(options = {}) {
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3370
|
+
return wrapAsync(async () => {
|
|
3371
|
+
const params = new URLSearchParams();
|
|
3372
|
+
if (options.exclude_admins !== void 0) {
|
|
3373
|
+
params.append("exclude_admins", String(options.exclude_admins));
|
|
3374
|
+
}
|
|
3375
|
+
if (options.search) {
|
|
3376
|
+
params.append("search", options.search);
|
|
3377
|
+
}
|
|
3378
|
+
if (options.limit !== void 0) {
|
|
3379
|
+
params.append("limit", String(options.limit));
|
|
3380
|
+
}
|
|
3381
|
+
if (options.type) {
|
|
3382
|
+
params.append("type", options.type);
|
|
3383
|
+
}
|
|
3384
|
+
const queryString = params.toString();
|
|
3385
|
+
const url = queryString ? `/api/v1/admin/users?${queryString}` : "/api/v1/admin/users";
|
|
3386
|
+
return await this.fetch.get(url);
|
|
3387
|
+
});
|
|
3291
3388
|
}
|
|
3292
3389
|
/**
|
|
3293
3390
|
* Get a user by ID
|
|
@@ -3310,8 +3407,10 @@ var FluxbaseAdmin = class {
|
|
|
3310
3407
|
* ```
|
|
3311
3408
|
*/
|
|
3312
3409
|
async getUserById(userId, type = "app") {
|
|
3313
|
-
|
|
3314
|
-
|
|
3410
|
+
return wrapAsync(async () => {
|
|
3411
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3412
|
+
return await this.fetch.get(url);
|
|
3413
|
+
});
|
|
3315
3414
|
}
|
|
3316
3415
|
/**
|
|
3317
3416
|
* Invite a new user
|
|
@@ -3335,8 +3434,10 @@ var FluxbaseAdmin = class {
|
|
|
3335
3434
|
* ```
|
|
3336
3435
|
*/
|
|
3337
3436
|
async inviteUser(request, type = "app") {
|
|
3338
|
-
|
|
3339
|
-
|
|
3437
|
+
return wrapAsync(async () => {
|
|
3438
|
+
const url = `/api/v1/admin/users/invite?type=${type}`;
|
|
3439
|
+
return await this.fetch.post(url, request);
|
|
3440
|
+
});
|
|
3340
3441
|
}
|
|
3341
3442
|
/**
|
|
3342
3443
|
* Delete a user
|
|
@@ -3354,8 +3455,10 @@ var FluxbaseAdmin = class {
|
|
|
3354
3455
|
* ```
|
|
3355
3456
|
*/
|
|
3356
3457
|
async deleteUser(userId, type = "app") {
|
|
3357
|
-
|
|
3358
|
-
|
|
3458
|
+
return wrapAsync(async () => {
|
|
3459
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3460
|
+
return await this.fetch.delete(url);
|
|
3461
|
+
});
|
|
3359
3462
|
}
|
|
3360
3463
|
/**
|
|
3361
3464
|
* Update user role
|
|
@@ -3374,8 +3477,10 @@ var FluxbaseAdmin = class {
|
|
|
3374
3477
|
* ```
|
|
3375
3478
|
*/
|
|
3376
3479
|
async updateUserRole(userId, role, type = "app") {
|
|
3377
|
-
|
|
3378
|
-
|
|
3480
|
+
return wrapAsync(async () => {
|
|
3481
|
+
const url = `/api/v1/admin/users/${userId}/role?type=${type}`;
|
|
3482
|
+
return await this.fetch.patch(url, { role });
|
|
3483
|
+
});
|
|
3379
3484
|
}
|
|
3380
3485
|
/**
|
|
3381
3486
|
* Reset user password
|
|
@@ -3393,8 +3498,10 @@ var FluxbaseAdmin = class {
|
|
|
3393
3498
|
* ```
|
|
3394
3499
|
*/
|
|
3395
3500
|
async resetUserPassword(userId, type = "app") {
|
|
3396
|
-
|
|
3397
|
-
|
|
3501
|
+
return wrapAsync(async () => {
|
|
3502
|
+
const url = `/api/v1/admin/users/${userId}/reset-password?type=${type}`;
|
|
3503
|
+
return await this.fetch.post(url, {});
|
|
3504
|
+
});
|
|
3398
3505
|
}
|
|
3399
3506
|
};
|
|
3400
3507
|
|
|
@@ -3952,25 +4059,44 @@ var QueryBuilder = class {
|
|
|
3952
4059
|
var FluxbaseClient = class {
|
|
3953
4060
|
/**
|
|
3954
4061
|
* Create a new Fluxbase client instance
|
|
3955
|
-
*
|
|
4062
|
+
*
|
|
4063
|
+
* @param fluxbaseUrl - The URL of your Fluxbase instance
|
|
4064
|
+
* @param fluxbaseKey - The anon key (JWT token with "anon" role). Generate using scripts/generate-keys.sh
|
|
4065
|
+
* @param options - Additional client configuration options
|
|
4066
|
+
*
|
|
4067
|
+
* @example
|
|
4068
|
+
* ```typescript
|
|
4069
|
+
* const client = new FluxbaseClient(
|
|
4070
|
+
* 'http://localhost:8080',
|
|
4071
|
+
* 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Anon JWT token
|
|
4072
|
+
* { timeout: 30000 }
|
|
4073
|
+
* )
|
|
4074
|
+
* ```
|
|
3956
4075
|
*/
|
|
3957
|
-
constructor(options) {
|
|
3958
|
-
this.
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
4076
|
+
constructor(fluxbaseUrl, fluxbaseKey, options) {
|
|
4077
|
+
this.fluxbaseUrl = fluxbaseUrl;
|
|
4078
|
+
this.fluxbaseKey = fluxbaseKey;
|
|
4079
|
+
const headers = {
|
|
4080
|
+
"apikey": fluxbaseKey,
|
|
4081
|
+
"Authorization": `Bearer ${fluxbaseKey}`,
|
|
4082
|
+
...options?.headers
|
|
4083
|
+
};
|
|
4084
|
+
this.fetch = new FluxbaseFetch(fluxbaseUrl, {
|
|
4085
|
+
headers,
|
|
4086
|
+
timeout: options?.timeout,
|
|
4087
|
+
debug: options?.debug
|
|
3962
4088
|
});
|
|
3963
4089
|
this.auth = new FluxbaseAuth(
|
|
3964
4090
|
this.fetch,
|
|
3965
|
-
options
|
|
3966
|
-
options
|
|
4091
|
+
options?.auth?.autoRefresh ?? true,
|
|
4092
|
+
options?.auth?.persist ?? true
|
|
3967
4093
|
);
|
|
3968
|
-
if (options
|
|
4094
|
+
if (options?.auth?.token) {
|
|
3969
4095
|
this.fetch.setAuthToken(options.auth.token);
|
|
3970
4096
|
}
|
|
3971
4097
|
this.realtime = new FluxbaseRealtime(
|
|
3972
|
-
|
|
3973
|
-
options
|
|
4098
|
+
fluxbaseUrl,
|
|
4099
|
+
options?.auth?.token || null
|
|
3974
4100
|
);
|
|
3975
4101
|
this.storage = new FluxbaseStorage(this.fetch);
|
|
3976
4102
|
this.functions = new FluxbaseFunctions(this.fetch);
|
|
@@ -4120,8 +4246,12 @@ var FluxbaseClient = class {
|
|
|
4120
4246
|
return this.fetch;
|
|
4121
4247
|
}
|
|
4122
4248
|
};
|
|
4123
|
-
function createClient(options) {
|
|
4124
|
-
return new FluxbaseClient(
|
|
4249
|
+
function createClient(fluxbaseUrl, fluxbaseKey, options) {
|
|
4250
|
+
return new FluxbaseClient(
|
|
4251
|
+
fluxbaseUrl,
|
|
4252
|
+
fluxbaseKey,
|
|
4253
|
+
options
|
|
4254
|
+
);
|
|
4125
4255
|
}
|
|
4126
4256
|
|
|
4127
4257
|
exports.APIKeysManager = APIKeysManager;
|