@afribase/afribase-js 0.2.0

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.
@@ -0,0 +1,1113 @@
1
+ interface AfribaseClientOptions {
2
+ /**
3
+ * The base URL of your Afribase project (e.g. https://your-project.useafribase.app)
4
+ */
5
+ baseUrl: string;
6
+ /**
7
+ * The anonymous/public API key for your project
8
+ */
9
+ anonKey: string;
10
+ /**
11
+ * Custom auth URL override
12
+ */
13
+ authUrl?: string;
14
+ /**
15
+ * Custom REST API URL override
16
+ */
17
+ restUrl?: string;
18
+ /**
19
+ * Custom realtime URL override
20
+ */
21
+ realtimeUrl?: string;
22
+ /**
23
+ * Custom storage URL override
24
+ */
25
+ storageUrl?: string;
26
+ /**
27
+ * Custom functions URL override
28
+ */
29
+ functionsUrl?: string;
30
+ /**
31
+ * Auto-refresh token when it's about to expire
32
+ * @default true
33
+ */
34
+ autoRefreshToken?: boolean;
35
+ /**
36
+ * Persist the session to storage (localStorage in browser)
37
+ * @default true
38
+ */
39
+ persistSession?: boolean;
40
+ /**
41
+ * Custom fetch implementation
42
+ */
43
+ fetch?: typeof fetch;
44
+ }
45
+ interface Session {
46
+ access_token: string;
47
+ refresh_token: string;
48
+ expires_in: number;
49
+ expires_at?: number;
50
+ token_type: string;
51
+ user: User;
52
+ }
53
+ interface User {
54
+ id: string;
55
+ email?: string;
56
+ phone?: string;
57
+ app_metadata: Record<string, any>;
58
+ user_metadata: Record<string, any>;
59
+ aud: string;
60
+ created_at: string;
61
+ updated_at?: string;
62
+ is_anonymous?: boolean;
63
+ role?: string;
64
+ confirmed_at?: string;
65
+ last_sign_in_at?: string;
66
+ identities?: UserIdentity[];
67
+ factors?: Factor[];
68
+ }
69
+ interface UserIdentity {
70
+ id: string;
71
+ user_id: string;
72
+ identity_data: Record<string, any>;
73
+ provider: string;
74
+ created_at: string;
75
+ updated_at: string;
76
+ }
77
+ interface Factor {
78
+ id: string;
79
+ friendly_name?: string;
80
+ factor_type: 'totp' | 'phone' | 'webauthn';
81
+ status: 'verified' | 'unverified';
82
+ created_at: string;
83
+ updated_at: string;
84
+ }
85
+ interface SignUpCredentials {
86
+ email?: string;
87
+ phone?: string;
88
+ password: string;
89
+ options?: {
90
+ data?: Record<string, any>;
91
+ emailRedirectTo?: string;
92
+ captchaToken?: string;
93
+ };
94
+ }
95
+ interface SignInWithPasswordCredentials {
96
+ email?: string;
97
+ phone?: string;
98
+ password: string;
99
+ options?: {
100
+ captchaToken?: string;
101
+ };
102
+ }
103
+ interface SignInWithOAuthCredentials {
104
+ provider: OAuthProvider;
105
+ options?: {
106
+ redirectTo?: string;
107
+ scopes?: string;
108
+ queryParams?: Record<string, string>;
109
+ };
110
+ }
111
+ interface SignInWithOtpCredentials {
112
+ email?: string;
113
+ phone?: string;
114
+ options?: {
115
+ emailRedirectTo?: string;
116
+ shouldCreateUser?: boolean;
117
+ data?: Record<string, any>;
118
+ captchaToken?: string;
119
+ };
120
+ }
121
+ interface VerifyOtpParams {
122
+ email?: string;
123
+ phone?: string;
124
+ token: string;
125
+ type: 'sms' | 'email' | 'signup' | 'magiclink' | 'recovery';
126
+ }
127
+ interface ResetPasswordCredentials {
128
+ email: string;
129
+ options?: {
130
+ redirectTo?: string;
131
+ captchaToken?: string;
132
+ };
133
+ }
134
+ interface UserAttributes {
135
+ email?: string;
136
+ phone?: string;
137
+ password?: string;
138
+ data?: Record<string, any>;
139
+ }
140
+ type OAuthProvider = 'apple' | 'azure' | 'bitbucket' | 'discord' | 'facebook' | 'figma' | 'fly' | 'github' | 'gitlab' | 'google' | 'kakao' | 'keycloak' | 'linkedin' | 'linkedin_oidc' | 'notion' | 'slack' | 'slack_oidc' | 'snapchat' | 'spotify' | 'twitch' | 'twitter' | 'workos' | 'x' | 'zoom';
141
+ type AuthChangeEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY' | 'INITIAL_SESSION';
142
+ interface AuthChangeCallback {
143
+ (event: AuthChangeEvent, session: Session | null): void;
144
+ }
145
+ interface Subscription {
146
+ id: string;
147
+ unsubscribe: () => void;
148
+ }
149
+ type RealtimeChannelEvent = 'INSERT' | 'UPDATE' | 'DELETE' | '*';
150
+ interface RealtimePostgresChangesPayload<T = any> {
151
+ eventType: 'INSERT' | 'UPDATE' | 'DELETE';
152
+ new: T;
153
+ old: Partial<T>;
154
+ schema: string;
155
+ table: string;
156
+ commit_timestamp: string;
157
+ errors: string[] | null;
158
+ }
159
+ interface RealtimePresenceState {
160
+ [key: string]: PresenceEntry[];
161
+ }
162
+ interface PresenceEntry {
163
+ presence_ref: string;
164
+ [key: string]: any;
165
+ }
166
+ type RealtimeListenTypes = 'postgres_changes' | 'broadcast' | 'presence';
167
+ interface RealtimeChannelOptions {
168
+ /** Channel config (e.g. for Postgres changes) */
169
+ config?: {
170
+ broadcast?: {
171
+ self?: boolean;
172
+ ack?: boolean;
173
+ };
174
+ presence?: {
175
+ key?: string;
176
+ };
177
+ postgres_changes?: Array<{
178
+ event: RealtimeChannelEvent;
179
+ schema: string;
180
+ table?: string;
181
+ filter?: string;
182
+ }>;
183
+ };
184
+ }
185
+ interface StorageBucket {
186
+ id: string;
187
+ name: string;
188
+ public: boolean;
189
+ file_size_limit?: number;
190
+ allowed_mime_types?: string[];
191
+ created_at: string;
192
+ updated_at: string;
193
+ }
194
+ interface StorageObject {
195
+ id: string;
196
+ bucket_id: string;
197
+ name: string;
198
+ mime_type: string;
199
+ size: number;
200
+ etag?: string;
201
+ created_at: string;
202
+ updated_at: string;
203
+ metadata?: Record<string, any>;
204
+ }
205
+ interface UploadOptions {
206
+ contentType?: string;
207
+ cacheControl?: string;
208
+ upsert?: boolean;
209
+ duplex?: string;
210
+ }
211
+ interface TransformOptions {
212
+ width?: number;
213
+ height?: number;
214
+ resize?: 'cover' | 'contain' | 'fill';
215
+ quality?: number;
216
+ format?: 'origin' | 'avif' | 'webp';
217
+ }
218
+ interface SignedUrlOptions {
219
+ download?: string | boolean;
220
+ transform?: TransformOptions;
221
+ }
222
+ interface CreateSignedUrlResponse {
223
+ signedUrl: string;
224
+ path: string;
225
+ token: string;
226
+ }
227
+ interface FunctionInvokeOptions {
228
+ body?: any;
229
+ headers?: Record<string, string>;
230
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
231
+ region?: string;
232
+ }
233
+ interface FunctionInvokeResponse<T = any> {
234
+ data: T | null;
235
+ error: Error | null;
236
+ }
237
+ type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'is' | 'in' | 'cs' | 'cd' | 'sl' | 'sr' | 'nxl' | 'nxr' | 'adj' | 'ov' | 'fts' | 'plfts' | 'phfts' | 'wfts';
238
+ interface PostgrestError {
239
+ message: string;
240
+ details: string;
241
+ hint: string;
242
+ code: string;
243
+ }
244
+ interface PostgrestResponse<T> {
245
+ data: T | null;
246
+ error: PostgrestError | null;
247
+ count: number | null;
248
+ status: number;
249
+ statusText: string;
250
+ }
251
+ interface PostgrestSingleResponse<T> extends PostgrestResponse<T> {
252
+ data: T;
253
+ }
254
+
255
+ /**
256
+ * AfribaseAuthClient handles authentication state, token refresh,
257
+ * OAuth sign-in, OTP, anonymous auth, and auth state change listeners.
258
+ */
259
+ declare class AfribaseAuthClient {
260
+ private url;
261
+ private apiKey;
262
+ private currentSession;
263
+ private refreshTimer;
264
+ private listeners;
265
+ private autoRefresh;
266
+ private persistSession;
267
+ private customFetch?;
268
+ private listenerIdCounter;
269
+ constructor(options: {
270
+ url: string;
271
+ apiKey: string;
272
+ autoRefreshToken?: boolean;
273
+ persistSession?: boolean;
274
+ customFetch?: typeof fetch;
275
+ });
276
+ /**
277
+ * Initialize the auth client — restores persisted session and emits INITIAL_SESSION.
278
+ * Call this once after creating the client.
279
+ */
280
+ initialize(): Promise<{
281
+ data: {
282
+ session: Session | null;
283
+ };
284
+ error: any;
285
+ }>;
286
+ /**
287
+ * Returns the current session if it exists.
288
+ */
289
+ getSession(): Promise<{
290
+ data: {
291
+ session: Session | null;
292
+ };
293
+ error: null;
294
+ }>;
295
+ /**
296
+ * Returns the current user if authenticated.
297
+ */
298
+ getUser(): Promise<{
299
+ data: {
300
+ user: User | null;
301
+ };
302
+ error: any;
303
+ }>;
304
+ /**
305
+ * Create a new user with email/phone and password.
306
+ */
307
+ signUp(credentials: SignUpCredentials): Promise<{
308
+ data: {
309
+ user: User | null;
310
+ session: Session | null;
311
+ };
312
+ error: any;
313
+ }>;
314
+ /**
315
+ * Sign in with email/phone and password.
316
+ */
317
+ signInWithPassword(credentials: SignInWithPasswordCredentials): Promise<{
318
+ data: {
319
+ user: User;
320
+ session: Session;
321
+ };
322
+ error: any;
323
+ }>;
324
+ /**
325
+ * Sign in with a third-party OAuth provider.
326
+ * Returns a URL to redirect the user to.
327
+ */
328
+ signInWithOAuth(credentials: SignInWithOAuthCredentials): Promise<{
329
+ data: {
330
+ provider: string;
331
+ url: string;
332
+ };
333
+ error: null;
334
+ }>;
335
+ /**
336
+ * Sign in with a one-time password (magic link or SMS OTP).
337
+ */
338
+ signInWithOtp(credentials: SignInWithOtpCredentials): Promise<{
339
+ data: {
340
+ messageId?: string;
341
+ } | null;
342
+ error: any;
343
+ }>;
344
+ /**
345
+ * Verify an OTP or magic link token.
346
+ */
347
+ verifyOtp(params: VerifyOtpParams): Promise<{
348
+ data: {
349
+ user: User;
350
+ session: Session;
351
+ };
352
+ error: any;
353
+ }>;
354
+ /**
355
+ * Sign in anonymously — creates an anonymous user.
356
+ */
357
+ signInAnonymously(options?: {
358
+ data?: Record<string, any>;
359
+ captchaToken?: string;
360
+ }): Promise<{
361
+ data: {
362
+ user: User;
363
+ session: Session;
364
+ };
365
+ error: any;
366
+ }>;
367
+ /**
368
+ * Sends a password reset email.
369
+ */
370
+ resetPasswordForEmail(email: string, options?: ResetPasswordCredentials['options']): Promise<{
371
+ data: {} | null;
372
+ error: any;
373
+ }>;
374
+ /**
375
+ * Update the current user (email, phone, password, metadata).
376
+ */
377
+ updateUser(attributes: UserAttributes): Promise<{
378
+ data: {
379
+ user: User;
380
+ };
381
+ error: any;
382
+ }>;
383
+ /**
384
+ * Sign out the current user.
385
+ */
386
+ signOut(): Promise<{
387
+ error: any;
388
+ }>;
389
+ /**
390
+ * Listen for auth state changes.
391
+ * Returns a subscription object with an unsubscribe method.
392
+ */
393
+ onAuthStateChange(callback: AuthChangeCallback): {
394
+ data: {
395
+ subscription: Subscription;
396
+ };
397
+ };
398
+ /**
399
+ * Manually refresh the session token.
400
+ */
401
+ refreshSession(): Promise<{
402
+ data: {
403
+ session: Session | null;
404
+ };
405
+ error: any;
406
+ }>;
407
+ /**
408
+ * Set the session manually (useful for server-side auth).
409
+ */
410
+ setSession(params: {
411
+ access_token: string;
412
+ refresh_token: string;
413
+ }): Promise<{
414
+ data: {
415
+ session: Session;
416
+ };
417
+ error: any;
418
+ }>;
419
+ /** @internal */
420
+ get accessToken(): string | null;
421
+ private _makeSession;
422
+ private _setSession;
423
+ private _removeSession;
424
+ private _refreshSession;
425
+ private _scheduleRefresh;
426
+ private _isSessionExpired;
427
+ private _notifyListeners;
428
+ private _persistSession;
429
+ private _getStoredSession;
430
+ private _clearStoredSession;
431
+ }
432
+
433
+ type ChannelStatus = 'SUBSCRIBED' | 'TIMED_OUT' | 'CLOSED' | 'CHANNEL_ERROR';
434
+ /**
435
+ * A Realtime Channel — subscribe to postgres_changes, broadcast, and presence events.
436
+ */
437
+ declare class RealtimeChannel {
438
+ private params;
439
+ private sendMessage;
440
+ private removeChannel;
441
+ private bindings;
442
+ private presenceState;
443
+ private presenceKey;
444
+ private _status;
445
+ /** @internal */
446
+ readonly topic: string;
447
+ constructor(topic: string, params: RealtimeChannelOptions, sendMessage: (msg: any) => void, removeChannel: (topic: string) => void);
448
+ /**
449
+ * Listen for events on this channel.
450
+ *
451
+ * @example
452
+ * channel.on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, (payload) => { ... })
453
+ * channel.on('broadcast', { event: 'cursor-pos' }, (payload) => { ... })
454
+ * channel.on('presence', { event: 'sync' }, () => { ... })
455
+ */
456
+ on(type: 'postgres_changes', filter: {
457
+ event: RealtimeChannelEvent;
458
+ schema: string;
459
+ table?: string;
460
+ filter?: string;
461
+ }, callback: (payload: RealtimePostgresChangesPayload) => void): this;
462
+ on(type: 'broadcast', filter: {
463
+ event: string;
464
+ }, callback: (payload: {
465
+ type: string;
466
+ event: string;
467
+ payload: any;
468
+ }) => void): this;
469
+ on(type: 'presence', filter: {
470
+ event: 'sync' | 'join' | 'leave';
471
+ }, callback: (payload: any) => void): this;
472
+ /**
473
+ * Subscribe to the channel — starts receiving events.
474
+ */
475
+ subscribe(callback?: (status: ChannelStatus, err?: Error) => void): this;
476
+ /**
477
+ * Send a broadcast message to all subscribers.
478
+ */
479
+ send(payload: {
480
+ type: 'broadcast';
481
+ event: string;
482
+ payload: any;
483
+ }): this;
484
+ /**
485
+ * Track presence for the current user.
486
+ */
487
+ track(payload: Record<string, any>): this;
488
+ /**
489
+ * Untrack presence for the current user.
490
+ */
491
+ untrack(): this;
492
+ /**
493
+ * Get current presence state.
494
+ */
495
+ presenceState_(): RealtimePresenceState;
496
+ /**
497
+ * Unsubscribe from this channel.
498
+ */
499
+ unsubscribe(): void;
500
+ get status(): ChannelStatus;
501
+ /** @internal — called by the RealtimeClient when a message arrives */
502
+ _handleMessage(msg: {
503
+ event: string;
504
+ payload: any;
505
+ }): void;
506
+ }
507
+ interface RealtimeClientOptions {
508
+ url: string;
509
+ apiKey: string;
510
+ accessToken?: string | null;
511
+ }
512
+ /**
513
+ * AfribaseRealtimeClient — manages the WebSocket connection to the
514
+ * Supabase-compatible Realtime service and multiplexes channels.
515
+ */
516
+ declare class AfribaseRealtimeClient {
517
+ private url;
518
+ private apiKey;
519
+ private accessToken;
520
+ private ws;
521
+ private channels;
522
+ private heartbeatTimer;
523
+ private reconnectTimer;
524
+ private reconnectAttempts;
525
+ private maxReconnectAttempts;
526
+ private reconnectBaseDelay;
527
+ private connected;
528
+ constructor(options: RealtimeClientOptions);
529
+ /**
530
+ * Set the access token (called by AfribaseClient when auth state changes).
531
+ */
532
+ setAuth(token: string | null): void;
533
+ /**
534
+ * Create a channel for a given topic.
535
+ */
536
+ channel(topic: string, options?: RealtimeChannelOptions): RealtimeChannel;
537
+ /**
538
+ * Remove all channels and disconnect.
539
+ */
540
+ removeAllChannels(): void;
541
+ /**
542
+ * Disconnect the WebSocket.
543
+ */
544
+ disconnect(): void;
545
+ private _connect;
546
+ private _disconnect;
547
+ private _send;
548
+ private _handleMessage;
549
+ private _startHeartbeat;
550
+ private _stopHeartbeat;
551
+ private _scheduleReconnect;
552
+ }
553
+
554
+ /**
555
+ * AfribaseStorageClient — upload, download, list, and manage files
556
+ * in Afribase Storage buckets.
557
+ */
558
+ declare class AfribaseStorageClient {
559
+ private url;
560
+ private apiKey;
561
+ private getAccessToken;
562
+ private customFetch?;
563
+ constructor(options: {
564
+ url: string;
565
+ apiKey: string;
566
+ getAccessToken: () => string | null;
567
+ customFetch?: typeof fetch;
568
+ });
569
+ /**
570
+ * Get a reference to a specific bucket for file operations.
571
+ */
572
+ from(bucketId: string): StorageFileApi;
573
+ /**
574
+ * List all buckets.
575
+ */
576
+ listBuckets(): Promise<{
577
+ data: StorageBucket[] | null;
578
+ error: any;
579
+ }>;
580
+ /**
581
+ * Get a bucket by ID.
582
+ */
583
+ getBucket(id: string): Promise<{
584
+ data: StorageBucket | null;
585
+ error: any;
586
+ }>;
587
+ /**
588
+ * Create a new bucket.
589
+ */
590
+ createBucket(id: string, options?: {
591
+ public?: boolean;
592
+ fileSizeLimit?: number;
593
+ allowedMimeTypes?: string[];
594
+ }): Promise<{
595
+ data: {
596
+ name: string;
597
+ } | null;
598
+ error: any;
599
+ }>;
600
+ /**
601
+ * Update a bucket.
602
+ */
603
+ updateBucket(id: string, options: {
604
+ public?: boolean;
605
+ fileSizeLimit?: number;
606
+ allowedMimeTypes?: string[];
607
+ }): Promise<{
608
+ data: {
609
+ message: string;
610
+ } | null;
611
+ error: any;
612
+ }>;
613
+ /**
614
+ * Delete a bucket (must be empty).
615
+ */
616
+ deleteBucket(id: string): Promise<{
617
+ data: {
618
+ message: string;
619
+ } | null;
620
+ error: any;
621
+ }>;
622
+ /**
623
+ * Empty a bucket (remove all files).
624
+ */
625
+ emptyBucket(id: string): Promise<{
626
+ data: {
627
+ message: string;
628
+ } | null;
629
+ error: any;
630
+ }>;
631
+ }
632
+ declare class StorageFileApi {
633
+ private storageUrl;
634
+ private bucketId;
635
+ private apiKey;
636
+ private getAccessToken;
637
+ private customFetch?;
638
+ constructor(storageUrl: string, bucketId: string, apiKey: string, getAccessToken: () => string | null, customFetch?: typeof fetch | undefined);
639
+ /**
640
+ * Upload a file to the bucket.
641
+ */
642
+ upload(path: string, fileBody: Blob | ArrayBuffer | ReadableStream | string | Buffer, options?: UploadOptions): Promise<{
643
+ data: {
644
+ path: string;
645
+ id?: string;
646
+ fullPath?: string;
647
+ } | null;
648
+ error: any;
649
+ }>;
650
+ /**
651
+ * Update (replace) an existing file.
652
+ */
653
+ update(path: string, fileBody: Blob | ArrayBuffer | ReadableStream | string | Buffer, options?: UploadOptions): Promise<{
654
+ data: {
655
+ path: string;
656
+ id?: string;
657
+ fullPath?: string;
658
+ } | null;
659
+ error: any;
660
+ }>;
661
+ /**
662
+ * Download a file from the bucket.
663
+ */
664
+ download(path: string, options?: {
665
+ transform?: TransformOptions;
666
+ }): Promise<{
667
+ data: Blob | null;
668
+ error: any;
669
+ }>;
670
+ /**
671
+ * List objects in the bucket.
672
+ */
673
+ list(path?: string, options?: {
674
+ limit?: number;
675
+ offset?: number;
676
+ sortBy?: {
677
+ column: string;
678
+ order: 'asc' | 'desc';
679
+ };
680
+ }): Promise<{
681
+ data: StorageObject[] | null;
682
+ error: any;
683
+ }>;
684
+ /**
685
+ * Move a file to a new path within the same bucket.
686
+ */
687
+ move(fromPath: string, toPath: string): Promise<{
688
+ data: {
689
+ message: string;
690
+ } | null;
691
+ error: any;
692
+ }>;
693
+ /**
694
+ * Copy a file to a new path within the same bucket.
695
+ */
696
+ copy(fromPath: string, toPath: string): Promise<{
697
+ data: {
698
+ path: string;
699
+ } | null;
700
+ error: any;
701
+ }>;
702
+ /**
703
+ * Remove one or more files from the bucket.
704
+ */
705
+ remove(paths: string[]): Promise<{
706
+ data: StorageObject[] | null;
707
+ error: any;
708
+ }>;
709
+ /**
710
+ * Create a signed URL for temporary access to a private file.
711
+ */
712
+ createSignedUrl(path: string, expiresIn: number, options?: SignedUrlOptions): Promise<{
713
+ data: CreateSignedUrlResponse | null;
714
+ error: any;
715
+ }>;
716
+ /**
717
+ * Create signed URLs for multiple files.
718
+ */
719
+ createSignedUrls(paths: string[], expiresIn: number): Promise<{
720
+ data: CreateSignedUrlResponse[] | null;
721
+ error: any;
722
+ }>;
723
+ /**
724
+ * Get the public URL for a file in a public bucket.
725
+ */
726
+ getPublicUrl(path: string, options?: {
727
+ download?: string | boolean;
728
+ transform?: TransformOptions;
729
+ }): {
730
+ data: {
731
+ publicUrl: string;
732
+ };
733
+ };
734
+ }
735
+
736
+ /**
737
+ * AfribaseFunctionsClient — invoke Afribase Edge Functions.
738
+ */
739
+ declare class AfribaseFunctionsClient {
740
+ private url;
741
+ private apiKey;
742
+ private getAccessToken;
743
+ private customFetch?;
744
+ constructor(options: {
745
+ url: string;
746
+ apiKey: string;
747
+ getAccessToken: () => string | null;
748
+ customFetch?: typeof fetch;
749
+ });
750
+ /**
751
+ * Invoke an edge function by name.
752
+ *
753
+ * @example
754
+ * const { data, error } = await client.functions.invoke('hello-world', {
755
+ * body: { name: 'Afribase' },
756
+ * });
757
+ */
758
+ invoke<T = any>(functionName: string, options?: FunctionInvokeOptions): Promise<{
759
+ data: T | null;
760
+ error: any;
761
+ }>;
762
+ }
763
+
764
+ /**
765
+ * AfribaseQueryBuilder — a PostgREST-compatible query builder with
766
+ * full filter/modifier support matching the supabase-js API.
767
+ */
768
+ declare class AfribaseQueryBuilder<T = any> {
769
+ private _url;
770
+ private _apiKey;
771
+ private _accessToken;
772
+ private _customFetch?;
773
+ private _query;
774
+ private _headers;
775
+ private _method;
776
+ private _body;
777
+ private _isSingle;
778
+ private _isMaybeSingle;
779
+ private _isHead;
780
+ private _countType;
781
+ constructor(url: string, options: {
782
+ apiKey: string;
783
+ accessToken: string | null;
784
+ customFetch?: typeof fetch;
785
+ });
786
+ /**
787
+ * Perform a SELECT query.
788
+ */
789
+ select(columns?: string, options?: {
790
+ count?: 'exact' | 'planned' | 'estimated';
791
+ head?: boolean;
792
+ }): this;
793
+ /**
794
+ * Perform an INSERT.
795
+ */
796
+ insert(values: Partial<T> | Partial<T>[], options?: {
797
+ count?: 'exact' | 'planned' | 'estimated';
798
+ defaultToNull?: boolean;
799
+ }): this;
800
+ /**
801
+ * Perform an UPSERT (insert or update on conflict).
802
+ */
803
+ upsert(values: Partial<T> | Partial<T>[], options?: {
804
+ onConflict?: string;
805
+ ignoreDuplicates?: boolean;
806
+ count?: 'exact' | 'planned' | 'estimated';
807
+ defaultToNull?: boolean;
808
+ }): this;
809
+ /**
810
+ * Perform an UPDATE (must be combined with filters).
811
+ */
812
+ update(values: Partial<T>, options?: {
813
+ count?: 'exact' | 'planned' | 'estimated';
814
+ }): this;
815
+ /**
816
+ * Perform a DELETE (must be combined with filters).
817
+ */
818
+ delete(options?: {
819
+ count?: 'exact' | 'planned' | 'estimated';
820
+ }): this;
821
+ eq(column: string, value: any): this;
822
+ neq(column: string, value: any): this;
823
+ gt(column: string, value: any): this;
824
+ gte(column: string, value: any): this;
825
+ lt(column: string, value: any): this;
826
+ lte(column: string, value: any): this;
827
+ like(column: string, pattern: string): this;
828
+ ilike(column: string, pattern: string): this;
829
+ is(column: string, value: 'null' | 'true' | 'false' | null | boolean): this;
830
+ in(column: string, values: any[]): this;
831
+ contains(column: string, value: any): this;
832
+ containedBy(column: string, value: any): this;
833
+ /**
834
+ * Full text search using to_tsquery.
835
+ */
836
+ textSearch(column: string, query: string, options?: {
837
+ type?: 'plain' | 'phrase' | 'websearch';
838
+ config?: string;
839
+ }): this;
840
+ /**
841
+ * Negate a filter.
842
+ */
843
+ not(column: string, operator: string, value: any): this;
844
+ /**
845
+ * Combine filters with OR.
846
+ */
847
+ or(filters: string, options?: {
848
+ foreignTable?: string;
849
+ }): this;
850
+ /**
851
+ * Generic filter — any PostgREST operator.
852
+ */
853
+ filter(column: string, operator: string, value: any): this;
854
+ /**
855
+ * Match multiple column values (shorthand for multiple .eq).
856
+ */
857
+ match(query: Record<string, any>): this;
858
+ /**
859
+ * Order results.
860
+ */
861
+ order(column: string, options?: {
862
+ ascending?: boolean;
863
+ nullsFirst?: boolean;
864
+ foreignTable?: string;
865
+ }): this;
866
+ /**
867
+ * Limit the number of results.
868
+ */
869
+ limit(count: number, options?: {
870
+ foreignTable?: string;
871
+ }): this;
872
+ /**
873
+ * Paginate with offset.
874
+ */
875
+ range(from: number, to: number, options?: {
876
+ foreignTable?: string;
877
+ }): this;
878
+ /**
879
+ * Return a single row (throws if 0 or 2+ rows).
880
+ */
881
+ single(): this;
882
+ /**
883
+ * Return at most one row (returns null if 0 rows).
884
+ */
885
+ maybeSingle(): this;
886
+ /**
887
+ * Return as CSV.
888
+ */
889
+ csv(): this;
890
+ /**
891
+ * Return a GeoJSON response.
892
+ */
893
+ geojson(): this;
894
+ /**
895
+ * Limit the fields returned (PostgREST explain).
896
+ */
897
+ explain(options?: {
898
+ analyze?: boolean;
899
+ verbose?: boolean;
900
+ settings?: boolean;
901
+ buffers?: boolean;
902
+ format?: 'json' | 'text';
903
+ }): this;
904
+ /**
905
+ * Execute the query and return the results.
906
+ */
907
+ then<TResult1 = PostgrestResponse<T[]>, TResult2 = never>(onfulfilled?: ((value: PostgrestResponse<T[]>) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
908
+ private _execute;
909
+ }
910
+ /**
911
+ * Call a Postgres function (RPC).
912
+ */
913
+ declare class AfribaseRpcBuilder<T = any> {
914
+ private _url;
915
+ private _apiKey;
916
+ private _accessToken;
917
+ private _customFetch?;
918
+ private _params;
919
+ private _query;
920
+ private _headers;
921
+ private _isSingle;
922
+ private _countType;
923
+ private _method;
924
+ constructor(url: string, fnName: string, params: Record<string, any>, options: {
925
+ apiKey: string;
926
+ accessToken: string | null;
927
+ customFetch?: typeof fetch;
928
+ head?: boolean;
929
+ count?: 'exact' | 'planned' | 'estimated';
930
+ get?: boolean;
931
+ });
932
+ single(): this;
933
+ maybeSingle(): this;
934
+ select(columns?: string): this;
935
+ order(column: string, options?: {
936
+ ascending?: boolean;
937
+ }): this;
938
+ limit(count: number): this;
939
+ range(from: number, to: number): this;
940
+ eq(column: string, value: any): this;
941
+ filter(column: string, operator: string, value: any): this;
942
+ then<TResult1 = PostgrestResponse<T>, TResult2 = never>(onfulfilled?: ((value: PostgrestResponse<T>) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
943
+ private _execute;
944
+ }
945
+
946
+ /**
947
+ * Functional-Fluent Query Operations for Afribase.
948
+ * This enables tree-shakable, modular query building.
949
+ */
950
+ type QueryOp<T = any> = (builder: AfribaseQueryBuilder<T>) => AfribaseQueryBuilder<T>;
951
+ /**
952
+ * The 'db' orchestrator allows piping multiple operations.
953
+ */
954
+ declare function db<T = any>(builder: AfribaseQueryBuilder<T>, ...ops: QueryOp<T>[]): Promise<any>;
955
+ declare const select: (columns?: string, options?: {
956
+ count?: "exact" | "planned" | "estimated";
957
+ head?: boolean;
958
+ }) => QueryOp;
959
+ declare const insert: <T>(values: Partial<T> | Partial<T>[], options?: {
960
+ count?: "exact" | "planned" | "estimated";
961
+ defaultToNull?: boolean;
962
+ }) => QueryOp<T>;
963
+ declare const update: <T>(values: Partial<T>, options?: {
964
+ count?: "exact" | "planned" | "estimated";
965
+ }) => QueryOp<T>;
966
+ declare const upsert: <T>(values: Partial<T> | Partial<T>[], options?: {
967
+ onConflict?: string;
968
+ ignoreDuplicates?: boolean;
969
+ count?: "exact" | "planned" | "estimated";
970
+ defaultToNull?: boolean;
971
+ }) => QueryOp<T>;
972
+ declare const del: (options?: {
973
+ count?: "exact" | "planned" | "estimated";
974
+ }) => QueryOp;
975
+ declare const eq: (column: string, value: any) => QueryOp;
976
+ declare const neq: (column: string, value: any) => QueryOp;
977
+ declare const gt: (column: string, value: any) => QueryOp;
978
+ declare const gte: (column: string, value: any) => QueryOp;
979
+ declare const lt: (column: string, value: any) => QueryOp;
980
+ declare const lte: (column: string, value: any) => QueryOp;
981
+ declare const like: (column: string, pattern: string) => QueryOp;
982
+ declare const ilike: (column: string, pattern: string) => QueryOp;
983
+ declare const is: (column: string, value: "null" | "true" | "false" | null | boolean) => QueryOp;
984
+ declare const isIn: (column: string, values: any[]) => QueryOp;
985
+ declare const contains: (column: string, value: any) => QueryOp;
986
+ declare const containedBy: (column: string, value: any) => QueryOp;
987
+ declare const textSearch: (column: string, query: string, options?: {
988
+ type?: "plain" | "phrase" | "websearch";
989
+ config?: string;
990
+ }) => QueryOp;
991
+ declare const not: (column: string, operator: string, value: any) => QueryOp;
992
+ declare const or: (filters: string, options?: {
993
+ foreignTable?: string;
994
+ }) => QueryOp;
995
+ declare const match: (query: Record<string, any>) => QueryOp;
996
+ declare const order: (column: string, options?: {
997
+ ascending?: boolean;
998
+ nullsFirst?: boolean;
999
+ foreignTable?: string;
1000
+ }) => QueryOp;
1001
+ declare const limit: (count: number, options?: {
1002
+ foreignTable?: string;
1003
+ }) => QueryOp;
1004
+ declare const range: (from: number, to: number, options?: {
1005
+ foreignTable?: string;
1006
+ }) => QueryOp;
1007
+ declare const single: () => QueryOp;
1008
+ declare const maybeSingle: () => QueryOp;
1009
+ declare const csv: () => QueryOp;
1010
+ declare const geojson: () => QueryOp;
1011
+ declare const explain: (options?: {
1012
+ analyze?: boolean;
1013
+ verbose?: boolean;
1014
+ settings?: boolean;
1015
+ buffers?: boolean;
1016
+ format?: "json" | "text";
1017
+ }) => QueryOp;
1018
+
1019
+ /**
1020
+ * The main Afribase client. Provides access to Auth, Database, Realtime,
1021
+ * Storage, and Edge Functions — matching the supabase-js API surface.
1022
+ *
1023
+ * @example
1024
+ * ```ts
1025
+ * import { createClient } from '@afribase/afribase-js';
1026
+ *
1027
+ * const afribase = createClient('https://your-project.useafribase.app', 'your-anon-key');
1028
+ *
1029
+ * // Auth
1030
+ * const { data } = await afribase.auth.signInWithPassword({ email: '...', password: '...' });
1031
+ *
1032
+ * // Database
1033
+ * const { data: rows } = await afribase.from('posts').select('*').eq('published', true);
1034
+ *
1035
+ * // Realtime
1036
+ * afribase.channel('room1')
1037
+ * .on('broadcast', { event: 'message' }, (payload) => console.log(payload))
1038
+ * .subscribe();
1039
+ *
1040
+ * // Storage
1041
+ * const { data: url } = afribase.storage.from('avatars').getPublicUrl('avatar.png');
1042
+ *
1043
+ * // Functions
1044
+ * const { data: result } = await afribase.functions.invoke('my-function', { body: { foo: 'bar' } });
1045
+ *
1046
+ * // RPC
1047
+ * const { data: total } = await afribase.rpc('get_total_count', { table_name: 'users' });
1048
+ * ```
1049
+ */
1050
+ declare class AfribaseClient {
1051
+ /**
1052
+ * The auth client for authentication and user management.
1053
+ */
1054
+ readonly auth: AfribaseAuthClient;
1055
+ /**
1056
+ * The storage client for file uploads, downloads, and bucket management.
1057
+ */
1058
+ readonly storage: AfribaseStorageClient;
1059
+ /**
1060
+ * The functions client for invoking Afribase Edge Functions.
1061
+ */
1062
+ readonly functions: AfribaseFunctionsClient;
1063
+ private readonly realtimeClient;
1064
+ private readonly baseUrl;
1065
+ private readonly anonKey;
1066
+ private readonly restUrl;
1067
+ private readonly customFetch?;
1068
+ constructor(baseUrl: string, anonKey: string, options?: Partial<AfribaseClientOptions>);
1069
+ /**
1070
+ * Query a table via PostgREST.
1071
+ *
1072
+ * @example
1073
+ * const { data } = await afribase.from('users').select('*').eq('id', 1);
1074
+ * const { data } = await afribase.from('posts').select('*, comments(*)').order('created_at', { ascending: false }).limit(10);
1075
+ */
1076
+ from<T = any>(table: string): AfribaseQueryBuilder<T>;
1077
+ /**
1078
+ * Call a Postgres function (RPC).
1079
+ *
1080
+ * @example
1081
+ * const { data } = await afribase.rpc('get_top_users', { limit_count: 10 });
1082
+ */
1083
+ rpc<T = any>(fn: string, params?: Record<string, any>, options?: {
1084
+ count?: 'exact' | 'planned' | 'estimated';
1085
+ head?: boolean;
1086
+ get?: boolean;
1087
+ }): AfribaseRpcBuilder<T>;
1088
+ /**
1089
+ * Create a realtime channel.
1090
+ *
1091
+ * @example
1092
+ * const channel = afribase.channel('room:lobby');
1093
+ * channel.on('broadcast', { event: 'message' }, (payload) => console.log(payload)).subscribe();
1094
+ */
1095
+ channel(name: string, options?: RealtimeChannelOptions): RealtimeChannel;
1096
+ /**
1097
+ * Remove all realtime channels and disconnect.
1098
+ */
1099
+ removeAllChannels(): void;
1100
+ /**
1101
+ * Get the underlying realtime client.
1102
+ */
1103
+ get realtime(): AfribaseRealtimeClient;
1104
+ }
1105
+ /**
1106
+ * Create a new AfribaseClient instance.
1107
+ *
1108
+ * @example
1109
+ * const afribase = createClient('https://your-project.useafribase.app', 'your-anon-key');
1110
+ */
1111
+ declare const createClient: (baseUrl: string, anonKey: string, options?: Partial<AfribaseClientOptions>) => AfribaseClient;
1112
+
1113
+ export { AfribaseAuthClient, AfribaseClient, type AfribaseClientOptions, AfribaseFunctionsClient, AfribaseQueryBuilder, AfribaseRealtimeClient, AfribaseRpcBuilder, AfribaseStorageClient, type AuthChangeCallback, type AuthChangeEvent, type CreateSignedUrlResponse, type Factor, type FilterOperator, type FunctionInvokeOptions, type FunctionInvokeResponse, type OAuthProvider, type PostgrestError, type PostgrestResponse, type PostgrestSingleResponse, type PresenceEntry, type QueryOp, RealtimeChannel, type RealtimeChannelEvent, type RealtimeChannelOptions, type RealtimeListenTypes, type RealtimePostgresChangesPayload, type RealtimePresenceState, type ResetPasswordCredentials, type Session, type SignInWithOAuthCredentials, type SignInWithOtpCredentials, type SignInWithPasswordCredentials, type SignUpCredentials, type SignedUrlOptions, type StorageBucket, StorageFileApi, type StorageObject, type Subscription, type TransformOptions, type UploadOptions, type User, type UserAttributes, type UserIdentity, type VerifyOtpParams, containedBy, contains, createClient, csv, db, del, eq, explain, geojson, gt, gte, ilike, insert, is, isIn, like, limit, lt, lte, match, maybeSingle, neq, not, or, order, range, select, single, textSearch, update, upsert };