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