@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.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,11 @@ 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("/api/v1/auth/magiclink", {
|
|
455
|
+
email,
|
|
456
|
+
redirect_to: options?.redirect_to
|
|
457
|
+
});
|
|
396
458
|
});
|
|
397
459
|
}
|
|
398
460
|
/**
|
|
@@ -400,41 +462,47 @@ var FluxbaseAuth = class {
|
|
|
400
462
|
* @param token - Magic link token from email
|
|
401
463
|
*/
|
|
402
464
|
async verifyMagicLink(token) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
465
|
+
return wrapAsync(async () => {
|
|
466
|
+
const response = await this.fetch.post(
|
|
467
|
+
"/api/v1/auth/magiclink/verify",
|
|
468
|
+
{
|
|
469
|
+
token
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
const session = {
|
|
473
|
+
...response,
|
|
474
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
475
|
+
};
|
|
476
|
+
this.setSession(session);
|
|
477
|
+
return { user: session.user, session };
|
|
478
|
+
});
|
|
415
479
|
}
|
|
416
480
|
/**
|
|
417
481
|
* Sign in anonymously
|
|
418
482
|
* Creates a temporary anonymous user session
|
|
419
483
|
*/
|
|
420
484
|
async signInAnonymously() {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
485
|
+
return wrapAsync(async () => {
|
|
486
|
+
const response = await this.fetch.post(
|
|
487
|
+
"/api/v1/auth/signin/anonymous"
|
|
488
|
+
);
|
|
489
|
+
const session = {
|
|
490
|
+
...response,
|
|
491
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
492
|
+
};
|
|
493
|
+
this.setSession(session);
|
|
494
|
+
return { user: session.user, session };
|
|
495
|
+
});
|
|
430
496
|
}
|
|
431
497
|
/**
|
|
432
498
|
* Get list of enabled OAuth providers
|
|
433
499
|
*/
|
|
434
500
|
async getOAuthProviders() {
|
|
435
|
-
return
|
|
436
|
-
|
|
437
|
-
|
|
501
|
+
return wrapAsync(async () => {
|
|
502
|
+
return await this.fetch.get(
|
|
503
|
+
"/api/v1/auth/oauth/providers"
|
|
504
|
+
);
|
|
505
|
+
});
|
|
438
506
|
}
|
|
439
507
|
/**
|
|
440
508
|
* Get OAuth authorization URL for a provider
|
|
@@ -442,17 +510,19 @@ var FluxbaseAuth = class {
|
|
|
442
510
|
* @param options - Optional OAuth configuration
|
|
443
511
|
*/
|
|
444
512
|
async getOAuthUrl(provider, options) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
513
|
+
return wrapAsync(async () => {
|
|
514
|
+
const params = new URLSearchParams();
|
|
515
|
+
if (options?.redirect_to) {
|
|
516
|
+
params.append("redirect_to", options.redirect_to);
|
|
517
|
+
}
|
|
518
|
+
if (options?.scopes && options.scopes.length > 0) {
|
|
519
|
+
params.append("scopes", options.scopes.join(","));
|
|
520
|
+
}
|
|
521
|
+
const queryString = params.toString();
|
|
522
|
+
const url = queryString ? `/api/v1/auth/oauth/${provider}/authorize?${queryString}` : `/api/v1/auth/oauth/${provider}/authorize`;
|
|
523
|
+
const response = await this.fetch.get(url);
|
|
524
|
+
return response;
|
|
525
|
+
});
|
|
456
526
|
}
|
|
457
527
|
/**
|
|
458
528
|
* Exchange OAuth authorization code for session
|
|
@@ -460,16 +530,18 @@ var FluxbaseAuth = class {
|
|
|
460
530
|
* @param code - Authorization code from OAuth callback
|
|
461
531
|
*/
|
|
462
532
|
async exchangeCodeForSession(code) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
533
|
+
return wrapAsync(async () => {
|
|
534
|
+
const response = await this.fetch.post(
|
|
535
|
+
"/api/v1/auth/oauth/callback",
|
|
536
|
+
{ code }
|
|
537
|
+
);
|
|
538
|
+
const session = {
|
|
539
|
+
...response,
|
|
540
|
+
expires_at: Date.now() + response.expires_in * 1e3
|
|
541
|
+
};
|
|
542
|
+
this.setSession(session);
|
|
543
|
+
return { user: session.user, session };
|
|
544
|
+
});
|
|
473
545
|
}
|
|
474
546
|
/**
|
|
475
547
|
* Convenience method to initiate OAuth sign-in
|
|
@@ -478,14 +550,21 @@ var FluxbaseAuth = class {
|
|
|
478
550
|
* @param options - Optional OAuth configuration
|
|
479
551
|
*/
|
|
480
552
|
async signInWithOAuth(provider, options) {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
)
|
|
488
|
-
|
|
553
|
+
return wrapAsync(async () => {
|
|
554
|
+
const result = await this.getOAuthUrl(provider, options);
|
|
555
|
+
if (result.error) {
|
|
556
|
+
throw result.error;
|
|
557
|
+
}
|
|
558
|
+
const url = result.data.url;
|
|
559
|
+
if (typeof window !== "undefined") {
|
|
560
|
+
window.location.href = url;
|
|
561
|
+
} else {
|
|
562
|
+
throw new Error(
|
|
563
|
+
"signInWithOAuth can only be called in a browser environment"
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
return { provider, url };
|
|
567
|
+
});
|
|
489
568
|
}
|
|
490
569
|
/**
|
|
491
570
|
* Internal: Set the session and persist it
|
|
@@ -533,11 +612,12 @@ var FluxbaseAuth = class {
|
|
|
533
612
|
const refreshAt = this.session.expires_at - 60 * 1e3;
|
|
534
613
|
const delay = refreshAt - Date.now();
|
|
535
614
|
if (delay > 0) {
|
|
536
|
-
this.refreshTimer = setTimeout(() => {
|
|
537
|
-
this.refreshToken()
|
|
538
|
-
|
|
615
|
+
this.refreshTimer = setTimeout(async () => {
|
|
616
|
+
const result = await this.refreshToken();
|
|
617
|
+
if (result.error) {
|
|
618
|
+
console.error("Failed to refresh token:", result.error);
|
|
539
619
|
this.clearSession();
|
|
540
|
-
}
|
|
620
|
+
}
|
|
541
621
|
}, delay);
|
|
542
622
|
}
|
|
543
623
|
}
|
|
@@ -3129,9 +3209,11 @@ var FluxbaseAdmin = class {
|
|
|
3129
3209
|
* ```
|
|
3130
3210
|
*/
|
|
3131
3211
|
async getSetupStatus() {
|
|
3132
|
-
return
|
|
3133
|
-
|
|
3134
|
-
|
|
3212
|
+
return wrapAsync(async () => {
|
|
3213
|
+
return await this.fetch.get(
|
|
3214
|
+
"/api/v1/admin/setup/status"
|
|
3215
|
+
);
|
|
3216
|
+
});
|
|
3135
3217
|
}
|
|
3136
3218
|
/**
|
|
3137
3219
|
* Perform initial admin setup
|
|
@@ -3157,12 +3239,14 @@ var FluxbaseAdmin = class {
|
|
|
3157
3239
|
* ```
|
|
3158
3240
|
*/
|
|
3159
3241
|
async setup(request) {
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3242
|
+
return wrapAsync(async () => {
|
|
3243
|
+
const response = await this.fetch.post(
|
|
3244
|
+
"/api/v1/admin/setup",
|
|
3245
|
+
request
|
|
3246
|
+
);
|
|
3247
|
+
this.setToken(response.access_token);
|
|
3248
|
+
return response;
|
|
3249
|
+
});
|
|
3166
3250
|
}
|
|
3167
3251
|
/**
|
|
3168
3252
|
* Admin login
|
|
@@ -3185,12 +3269,14 @@ var FluxbaseAdmin = class {
|
|
|
3185
3269
|
* ```
|
|
3186
3270
|
*/
|
|
3187
3271
|
async login(request) {
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3272
|
+
return wrapAsync(async () => {
|
|
3273
|
+
const response = await this.fetch.post(
|
|
3274
|
+
"/api/v1/admin/login",
|
|
3275
|
+
request
|
|
3276
|
+
);
|
|
3277
|
+
this.setToken(response.access_token);
|
|
3278
|
+
return response;
|
|
3279
|
+
});
|
|
3194
3280
|
}
|
|
3195
3281
|
/**
|
|
3196
3282
|
* Refresh admin access token
|
|
@@ -3209,12 +3295,14 @@ var FluxbaseAdmin = class {
|
|
|
3209
3295
|
* ```
|
|
3210
3296
|
*/
|
|
3211
3297
|
async refreshToken(request) {
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3298
|
+
return wrapAsync(async () => {
|
|
3299
|
+
const response = await this.fetch.post(
|
|
3300
|
+
"/api/v1/admin/refresh",
|
|
3301
|
+
request
|
|
3302
|
+
);
|
|
3303
|
+
this.setToken(response.access_token);
|
|
3304
|
+
return response;
|
|
3305
|
+
});
|
|
3218
3306
|
}
|
|
3219
3307
|
/**
|
|
3220
3308
|
* Admin logout
|
|
@@ -3228,8 +3316,10 @@ var FluxbaseAdmin = class {
|
|
|
3228
3316
|
* ```
|
|
3229
3317
|
*/
|
|
3230
3318
|
async logout() {
|
|
3231
|
-
|
|
3232
|
-
|
|
3319
|
+
return wrapAsyncVoid(async () => {
|
|
3320
|
+
await this.fetch.post("/api/v1/admin/logout", {});
|
|
3321
|
+
this.clearToken();
|
|
3322
|
+
});
|
|
3233
3323
|
}
|
|
3234
3324
|
/**
|
|
3235
3325
|
* Get current admin user information
|
|
@@ -3244,7 +3334,9 @@ var FluxbaseAdmin = class {
|
|
|
3244
3334
|
* ```
|
|
3245
3335
|
*/
|
|
3246
3336
|
async me() {
|
|
3247
|
-
return
|
|
3337
|
+
return wrapAsync(async () => {
|
|
3338
|
+
return await this.fetch.get("/api/v1/admin/me");
|
|
3339
|
+
});
|
|
3248
3340
|
}
|
|
3249
3341
|
// ============================================================================
|
|
3250
3342
|
// User Management
|
|
@@ -3270,22 +3362,24 @@ var FluxbaseAdmin = class {
|
|
|
3270
3362
|
* ```
|
|
3271
3363
|
*/
|
|
3272
3364
|
async listUsers(options = {}) {
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3365
|
+
return wrapAsync(async () => {
|
|
3366
|
+
const params = new URLSearchParams();
|
|
3367
|
+
if (options.exclude_admins !== void 0) {
|
|
3368
|
+
params.append("exclude_admins", String(options.exclude_admins));
|
|
3369
|
+
}
|
|
3370
|
+
if (options.search) {
|
|
3371
|
+
params.append("search", options.search);
|
|
3372
|
+
}
|
|
3373
|
+
if (options.limit !== void 0) {
|
|
3374
|
+
params.append("limit", String(options.limit));
|
|
3375
|
+
}
|
|
3376
|
+
if (options.type) {
|
|
3377
|
+
params.append("type", options.type);
|
|
3378
|
+
}
|
|
3379
|
+
const queryString = params.toString();
|
|
3380
|
+
const url = queryString ? `/api/v1/admin/users?${queryString}` : "/api/v1/admin/users";
|
|
3381
|
+
return await this.fetch.get(url);
|
|
3382
|
+
});
|
|
3289
3383
|
}
|
|
3290
3384
|
/**
|
|
3291
3385
|
* Get a user by ID
|
|
@@ -3308,8 +3402,10 @@ var FluxbaseAdmin = class {
|
|
|
3308
3402
|
* ```
|
|
3309
3403
|
*/
|
|
3310
3404
|
async getUserById(userId, type = "app") {
|
|
3311
|
-
|
|
3312
|
-
|
|
3405
|
+
return wrapAsync(async () => {
|
|
3406
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3407
|
+
return await this.fetch.get(url);
|
|
3408
|
+
});
|
|
3313
3409
|
}
|
|
3314
3410
|
/**
|
|
3315
3411
|
* Invite a new user
|
|
@@ -3333,8 +3429,10 @@ var FluxbaseAdmin = class {
|
|
|
3333
3429
|
* ```
|
|
3334
3430
|
*/
|
|
3335
3431
|
async inviteUser(request, type = "app") {
|
|
3336
|
-
|
|
3337
|
-
|
|
3432
|
+
return wrapAsync(async () => {
|
|
3433
|
+
const url = `/api/v1/admin/users/invite?type=${type}`;
|
|
3434
|
+
return await this.fetch.post(url, request);
|
|
3435
|
+
});
|
|
3338
3436
|
}
|
|
3339
3437
|
/**
|
|
3340
3438
|
* Delete a user
|
|
@@ -3352,8 +3450,10 @@ var FluxbaseAdmin = class {
|
|
|
3352
3450
|
* ```
|
|
3353
3451
|
*/
|
|
3354
3452
|
async deleteUser(userId, type = "app") {
|
|
3355
|
-
|
|
3356
|
-
|
|
3453
|
+
return wrapAsync(async () => {
|
|
3454
|
+
const url = `/api/v1/admin/users/${userId}?type=${type}`;
|
|
3455
|
+
return await this.fetch.delete(url);
|
|
3456
|
+
});
|
|
3357
3457
|
}
|
|
3358
3458
|
/**
|
|
3359
3459
|
* Update user role
|
|
@@ -3372,8 +3472,10 @@ var FluxbaseAdmin = class {
|
|
|
3372
3472
|
* ```
|
|
3373
3473
|
*/
|
|
3374
3474
|
async updateUserRole(userId, role, type = "app") {
|
|
3375
|
-
|
|
3376
|
-
|
|
3475
|
+
return wrapAsync(async () => {
|
|
3476
|
+
const url = `/api/v1/admin/users/${userId}/role?type=${type}`;
|
|
3477
|
+
return await this.fetch.patch(url, { role });
|
|
3478
|
+
});
|
|
3377
3479
|
}
|
|
3378
3480
|
/**
|
|
3379
3481
|
* Reset user password
|
|
@@ -3391,8 +3493,10 @@ var FluxbaseAdmin = class {
|
|
|
3391
3493
|
* ```
|
|
3392
3494
|
*/
|
|
3393
3495
|
async resetUserPassword(userId, type = "app") {
|
|
3394
|
-
|
|
3395
|
-
|
|
3496
|
+
return wrapAsync(async () => {
|
|
3497
|
+
const url = `/api/v1/admin/users/${userId}/reset-password?type=${type}`;
|
|
3498
|
+
return await this.fetch.post(url, {});
|
|
3499
|
+
});
|
|
3396
3500
|
}
|
|
3397
3501
|
};
|
|
3398
3502
|
|
|
@@ -3950,25 +4054,44 @@ var QueryBuilder = class {
|
|
|
3950
4054
|
var FluxbaseClient = class {
|
|
3951
4055
|
/**
|
|
3952
4056
|
* Create a new Fluxbase client instance
|
|
3953
|
-
*
|
|
4057
|
+
*
|
|
4058
|
+
* @param fluxbaseUrl - The URL of your Fluxbase instance
|
|
4059
|
+
* @param fluxbaseKey - The anon key (JWT token with "anon" role). Generate using scripts/generate-keys.sh
|
|
4060
|
+
* @param options - Additional client configuration options
|
|
4061
|
+
*
|
|
4062
|
+
* @example
|
|
4063
|
+
* ```typescript
|
|
4064
|
+
* const client = new FluxbaseClient(
|
|
4065
|
+
* 'http://localhost:8080',
|
|
4066
|
+
* 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Anon JWT token
|
|
4067
|
+
* { timeout: 30000 }
|
|
4068
|
+
* )
|
|
4069
|
+
* ```
|
|
3954
4070
|
*/
|
|
3955
|
-
constructor(options) {
|
|
3956
|
-
this.
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
4071
|
+
constructor(fluxbaseUrl, fluxbaseKey, options) {
|
|
4072
|
+
this.fluxbaseUrl = fluxbaseUrl;
|
|
4073
|
+
this.fluxbaseKey = fluxbaseKey;
|
|
4074
|
+
const headers = {
|
|
4075
|
+
"apikey": fluxbaseKey,
|
|
4076
|
+
"Authorization": `Bearer ${fluxbaseKey}`,
|
|
4077
|
+
...options?.headers
|
|
4078
|
+
};
|
|
4079
|
+
this.fetch = new FluxbaseFetch(fluxbaseUrl, {
|
|
4080
|
+
headers,
|
|
4081
|
+
timeout: options?.timeout,
|
|
4082
|
+
debug: options?.debug
|
|
3960
4083
|
});
|
|
3961
4084
|
this.auth = new FluxbaseAuth(
|
|
3962
4085
|
this.fetch,
|
|
3963
|
-
options
|
|
3964
|
-
options
|
|
4086
|
+
options?.auth?.autoRefresh ?? true,
|
|
4087
|
+
options?.auth?.persist ?? true
|
|
3965
4088
|
);
|
|
3966
|
-
if (options
|
|
4089
|
+
if (options?.auth?.token) {
|
|
3967
4090
|
this.fetch.setAuthToken(options.auth.token);
|
|
3968
4091
|
}
|
|
3969
4092
|
this.realtime = new FluxbaseRealtime(
|
|
3970
|
-
|
|
3971
|
-
options
|
|
4093
|
+
fluxbaseUrl,
|
|
4094
|
+
options?.auth?.token || null
|
|
3972
4095
|
);
|
|
3973
4096
|
this.storage = new FluxbaseStorage(this.fetch);
|
|
3974
4097
|
this.functions = new FluxbaseFunctions(this.fetch);
|
|
@@ -4118,8 +4241,12 @@ var FluxbaseClient = class {
|
|
|
4118
4241
|
return this.fetch;
|
|
4119
4242
|
}
|
|
4120
4243
|
};
|
|
4121
|
-
function createClient(options) {
|
|
4122
|
-
return new FluxbaseClient(
|
|
4244
|
+
function createClient(fluxbaseUrl, fluxbaseKey, options) {
|
|
4245
|
+
return new FluxbaseClient(
|
|
4246
|
+
fluxbaseUrl,
|
|
4247
|
+
fluxbaseKey,
|
|
4248
|
+
options
|
|
4249
|
+
);
|
|
4123
4250
|
}
|
|
4124
4251
|
|
|
4125
4252
|
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 };
|