@fluxbase/sdk 0.0.2-rc.2 → 0.1.0-rc.1

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.d.cts CHANGED
@@ -135,8 +135,19 @@ interface OrderBy {
135
135
  interface RealtimeMessage {
136
136
  type: 'subscribe' | 'unsubscribe' | 'heartbeat' | 'broadcast' | 'ack' | 'error';
137
137
  channel?: string;
138
+ event?: string;
139
+ schema?: string;
140
+ table?: string;
141
+ filter?: string;
138
142
  payload?: unknown;
139
143
  error?: string;
144
+ config?: PostgresChangesConfig;
145
+ }
146
+ interface PostgresChangesConfig {
147
+ event: 'INSERT' | 'UPDATE' | 'DELETE' | '*';
148
+ schema: string;
149
+ table: string;
150
+ filter?: string;
140
151
  }
141
152
  interface RealtimeChangePayload {
142
153
  type: 'INSERT' | 'UPDATE' | 'DELETE';
@@ -788,6 +799,23 @@ interface ListImpersonationSessionsResponse {
788
799
  sessions: ImpersonationSession[];
789
800
  total: number;
790
801
  }
802
+ /**
803
+ * Auth state change events
804
+ */
805
+ type AuthChangeEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY' | 'MFA_CHALLENGE_VERIFIED';
806
+ /**
807
+ * Callback for auth state changes
808
+ */
809
+ type AuthStateChangeCallback = (event: AuthChangeEvent, session: AuthSession | null) => void;
810
+ /**
811
+ * Subscription object returned by onAuthStateChange
812
+ */
813
+ interface AuthSubscription {
814
+ /**
815
+ * Unsubscribe from auth state changes
816
+ */
817
+ unsubscribe: () => void;
818
+ }
791
819
 
792
820
  /**
793
821
  * HTTP client for making requests to the Fluxbase API
@@ -853,6 +881,7 @@ declare class FluxbaseAuth {
853
881
  private persist;
854
882
  private autoRefresh;
855
883
  private refreshTimer;
884
+ private stateChangeListeners;
856
885
  constructor(fetch: FluxbaseFetch, autoRefresh?: boolean, persist?: boolean);
857
886
  /**
858
887
  * Get the current session
@@ -866,6 +895,22 @@ declare class FluxbaseAuth {
866
895
  * Get the current access token
867
896
  */
868
897
  getAccessToken(): string | null;
898
+ /**
899
+ * Listen to auth state changes
900
+ * @param callback - Function called when auth state changes
901
+ * @returns Subscription object with unsubscribe method
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * const { data: { subscription } } = client.auth.onAuthStateChange((event, session) => {
906
+ * console.log('Auth event:', event, session)
907
+ * })
908
+ *
909
+ * // Later, to unsubscribe:
910
+ * subscription.unsubscribe()
911
+ * ```
912
+ */
913
+ onAuthStateChange(callback: AuthStateChangeCallback): AuthSubscription;
869
914
  /**
870
915
  * Sign in with email and password
871
916
  * Returns AuthSession if successful, or SignInWith2FAResponse if 2FA is required
@@ -996,6 +1041,10 @@ declare class FluxbaseAuth {
996
1041
  * Internal: Schedule automatic token refresh
997
1042
  */
998
1043
  private scheduleTokenRefresh;
1044
+ /**
1045
+ * Internal: Emit auth state change event to all listeners
1046
+ */
1047
+ private emitAuthChange;
999
1048
  }
1000
1049
 
1001
1050
  /**
@@ -1008,15 +1057,46 @@ declare class RealtimeChannel {
1008
1057
  private token;
1009
1058
  private channelName;
1010
1059
  private callbacks;
1060
+ private subscriptionConfig;
1011
1061
  private reconnectAttempts;
1012
1062
  private maxReconnectAttempts;
1013
1063
  private reconnectDelay;
1014
1064
  private heartbeatInterval;
1015
1065
  constructor(url: string, channelName: string, token?: string | null);
1016
1066
  /**
1017
- * Listen to a specific event type
1067
+ * Listen to postgres_changes with optional row-level filtering
1068
+ *
1069
+ * @param event - 'postgres_changes'
1070
+ * @param config - Configuration including optional filter
1071
+ * @param callback - Function to call when changes occur
1072
+ * @returns This channel for chaining
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * channel.on('postgres_changes', {
1077
+ * event: '*',
1078
+ * schema: 'public',
1079
+ * table: 'jobs',
1080
+ * filter: 'created_by=eq.user123'
1081
+ * }, (payload) => {
1082
+ * console.log('Job updated:', payload)
1083
+ * })
1084
+ * ```
1085
+ */
1086
+ on(event: 'postgres_changes', config: PostgresChangesConfig, callback: RealtimeCallback): this;
1087
+ /**
1088
+ * Listen to a specific event type (backwards compatibility)
1089
+ *
1018
1090
  * @param event - The event type (INSERT, UPDATE, DELETE, or '*' for all)
1019
1091
  * @param callback - The callback function
1092
+ * @returns This channel for chaining
1093
+ *
1094
+ * @example
1095
+ * ```typescript
1096
+ * channel.on('INSERT', (payload) => {
1097
+ * console.log('New record inserted:', payload.new_record)
1098
+ * })
1099
+ * ```
1020
1100
  */
1021
1101
  on(event: 'INSERT' | 'UPDATE' | 'DELETE' | '*', callback: RealtimeCallback): this;
1022
1102
  /**
@@ -2727,6 +2807,27 @@ declare class FluxbaseAdmin {
2727
2807
  * ```
2728
2808
  */
2729
2809
  listUsers(options?: ListUsersOptions): Promise<ListUsersResponse>;
2810
+ /**
2811
+ * Get a user by ID
2812
+ *
2813
+ * Fetch a single user's details by their user ID
2814
+ *
2815
+ * @param userId - User ID to fetch
2816
+ * @param type - User type ('app' or 'dashboard')
2817
+ * @returns User details with metadata
2818
+ *
2819
+ * @example
2820
+ * ```typescript
2821
+ * // Get an app user
2822
+ * const user = await admin.getUserById('user-123');
2823
+ *
2824
+ * // Get a dashboard user
2825
+ * const dashboardUser = await admin.getUserById('admin-456', 'dashboard');
2826
+ * console.log('User email:', dashboardUser.email);
2827
+ * console.log('Last login:', dashboardUser.last_login_at);
2828
+ * ```
2829
+ */
2830
+ getUserById(userId: string, type?: "app" | "dashboard"): Promise<EnrichedUser>;
2730
2831
  /**
2731
2832
  * Invite a new user
2732
2833
  *
@@ -2748,7 +2849,7 @@ declare class FluxbaseAdmin {
2748
2849
  * console.log('Invitation link:', response.invitation_link);
2749
2850
  * ```
2750
2851
  */
2751
- inviteUser(request: InviteUserRequest, type?: 'app' | 'dashboard'): Promise<InviteUserResponse>;
2852
+ inviteUser(request: InviteUserRequest, type?: "app" | "dashboard"): Promise<InviteUserResponse>;
2752
2853
  /**
2753
2854
  * Delete a user
2754
2855
  *
@@ -2764,7 +2865,7 @@ declare class FluxbaseAdmin {
2764
2865
  * console.log('User deleted');
2765
2866
  * ```
2766
2867
  */
2767
- deleteUser(userId: string, type?: 'app' | 'dashboard'): Promise<DeleteUserResponse>;
2868
+ deleteUser(userId: string, type?: "app" | "dashboard"): Promise<DeleteUserResponse>;
2768
2869
  /**
2769
2870
  * Update user role
2770
2871
  *
@@ -2781,7 +2882,7 @@ declare class FluxbaseAdmin {
2781
2882
  * console.log('User role updated:', user.role);
2782
2883
  * ```
2783
2884
  */
2784
- updateUserRole(userId: string, role: string, type?: 'app' | 'dashboard'): Promise<EnrichedUser>;
2885
+ updateUserRole(userId: string, role: string, type?: "app" | "dashboard"): Promise<EnrichedUser>;
2785
2886
  /**
2786
2887
  * Reset user password
2787
2888
  *
@@ -2797,7 +2898,7 @@ declare class FluxbaseAdmin {
2797
2898
  * console.log(response.message);
2798
2899
  * ```
2799
2900
  */
2800
- resetUserPassword(userId: string, type?: 'app' | 'dashboard'): Promise<ResetUserPasswordResponse>;
2901
+ resetUserPassword(userId: string, type?: "app" | "dashboard"): Promise<ResetUserPasswordResponse>;
2801
2902
  }
2802
2903
 
2803
2904
  /**
@@ -2805,7 +2906,7 @@ declare class FluxbaseAdmin {
2805
2906
  * Inspired by Supabase's PostgREST client
2806
2907
  */
2807
2908
 
2808
- declare class QueryBuilder<T = unknown> {
2909
+ declare class QueryBuilder<T = unknown> implements PromiseLike<PostgrestResponse<T>> {
2809
2910
  private fetch;
2810
2911
  private table;
2811
2912
  private selectQuery;
@@ -3122,6 +3223,20 @@ declare class QueryBuilder<T = unknown> {
3122
3223
  * Execute the query and return results
3123
3224
  */
3124
3225
  execute(): Promise<PostgrestResponse<T>>;
3226
+ /**
3227
+ * Make QueryBuilder awaitable (implements PromiseLike)
3228
+ * This allows using `await client.from('table').select()` without calling `.execute()`
3229
+ *
3230
+ * @example
3231
+ * ```typescript
3232
+ * // Without .execute() (new way)
3233
+ * const { data } = await client.from('users').select('*')
3234
+ *
3235
+ * // With .execute() (old way, still supported)
3236
+ * const { data } = await client.from('users').select('*').execute()
3237
+ * ```
3238
+ */
3239
+ then<TResult1 = PostgrestResponse<T>, TResult2 = never>(onfulfilled?: ((value: PostgrestResponse<T>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
3125
3240
  /**
3126
3241
  * Build the query string from filters, ordering, etc.
3127
3242
  */
package/dist/index.d.ts CHANGED
@@ -135,8 +135,19 @@ interface OrderBy {
135
135
  interface RealtimeMessage {
136
136
  type: 'subscribe' | 'unsubscribe' | 'heartbeat' | 'broadcast' | 'ack' | 'error';
137
137
  channel?: string;
138
+ event?: string;
139
+ schema?: string;
140
+ table?: string;
141
+ filter?: string;
138
142
  payload?: unknown;
139
143
  error?: string;
144
+ config?: PostgresChangesConfig;
145
+ }
146
+ interface PostgresChangesConfig {
147
+ event: 'INSERT' | 'UPDATE' | 'DELETE' | '*';
148
+ schema: string;
149
+ table: string;
150
+ filter?: string;
140
151
  }
141
152
  interface RealtimeChangePayload {
142
153
  type: 'INSERT' | 'UPDATE' | 'DELETE';
@@ -788,6 +799,23 @@ interface ListImpersonationSessionsResponse {
788
799
  sessions: ImpersonationSession[];
789
800
  total: number;
790
801
  }
802
+ /**
803
+ * Auth state change events
804
+ */
805
+ type AuthChangeEvent = 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY' | 'MFA_CHALLENGE_VERIFIED';
806
+ /**
807
+ * Callback for auth state changes
808
+ */
809
+ type AuthStateChangeCallback = (event: AuthChangeEvent, session: AuthSession | null) => void;
810
+ /**
811
+ * Subscription object returned by onAuthStateChange
812
+ */
813
+ interface AuthSubscription {
814
+ /**
815
+ * Unsubscribe from auth state changes
816
+ */
817
+ unsubscribe: () => void;
818
+ }
791
819
 
792
820
  /**
793
821
  * HTTP client for making requests to the Fluxbase API
@@ -853,6 +881,7 @@ declare class FluxbaseAuth {
853
881
  private persist;
854
882
  private autoRefresh;
855
883
  private refreshTimer;
884
+ private stateChangeListeners;
856
885
  constructor(fetch: FluxbaseFetch, autoRefresh?: boolean, persist?: boolean);
857
886
  /**
858
887
  * Get the current session
@@ -866,6 +895,22 @@ declare class FluxbaseAuth {
866
895
  * Get the current access token
867
896
  */
868
897
  getAccessToken(): string | null;
898
+ /**
899
+ * Listen to auth state changes
900
+ * @param callback - Function called when auth state changes
901
+ * @returns Subscription object with unsubscribe method
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * const { data: { subscription } } = client.auth.onAuthStateChange((event, session) => {
906
+ * console.log('Auth event:', event, session)
907
+ * })
908
+ *
909
+ * // Later, to unsubscribe:
910
+ * subscription.unsubscribe()
911
+ * ```
912
+ */
913
+ onAuthStateChange(callback: AuthStateChangeCallback): AuthSubscription;
869
914
  /**
870
915
  * Sign in with email and password
871
916
  * Returns AuthSession if successful, or SignInWith2FAResponse if 2FA is required
@@ -996,6 +1041,10 @@ declare class FluxbaseAuth {
996
1041
  * Internal: Schedule automatic token refresh
997
1042
  */
998
1043
  private scheduleTokenRefresh;
1044
+ /**
1045
+ * Internal: Emit auth state change event to all listeners
1046
+ */
1047
+ private emitAuthChange;
999
1048
  }
1000
1049
 
1001
1050
  /**
@@ -1008,15 +1057,46 @@ declare class RealtimeChannel {
1008
1057
  private token;
1009
1058
  private channelName;
1010
1059
  private callbacks;
1060
+ private subscriptionConfig;
1011
1061
  private reconnectAttempts;
1012
1062
  private maxReconnectAttempts;
1013
1063
  private reconnectDelay;
1014
1064
  private heartbeatInterval;
1015
1065
  constructor(url: string, channelName: string, token?: string | null);
1016
1066
  /**
1017
- * Listen to a specific event type
1067
+ * Listen to postgres_changes with optional row-level filtering
1068
+ *
1069
+ * @param event - 'postgres_changes'
1070
+ * @param config - Configuration including optional filter
1071
+ * @param callback - Function to call when changes occur
1072
+ * @returns This channel for chaining
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * channel.on('postgres_changes', {
1077
+ * event: '*',
1078
+ * schema: 'public',
1079
+ * table: 'jobs',
1080
+ * filter: 'created_by=eq.user123'
1081
+ * }, (payload) => {
1082
+ * console.log('Job updated:', payload)
1083
+ * })
1084
+ * ```
1085
+ */
1086
+ on(event: 'postgres_changes', config: PostgresChangesConfig, callback: RealtimeCallback): this;
1087
+ /**
1088
+ * Listen to a specific event type (backwards compatibility)
1089
+ *
1018
1090
  * @param event - The event type (INSERT, UPDATE, DELETE, or '*' for all)
1019
1091
  * @param callback - The callback function
1092
+ * @returns This channel for chaining
1093
+ *
1094
+ * @example
1095
+ * ```typescript
1096
+ * channel.on('INSERT', (payload) => {
1097
+ * console.log('New record inserted:', payload.new_record)
1098
+ * })
1099
+ * ```
1020
1100
  */
1021
1101
  on(event: 'INSERT' | 'UPDATE' | 'DELETE' | '*', callback: RealtimeCallback): this;
1022
1102
  /**
@@ -2727,6 +2807,27 @@ declare class FluxbaseAdmin {
2727
2807
  * ```
2728
2808
  */
2729
2809
  listUsers(options?: ListUsersOptions): Promise<ListUsersResponse>;
2810
+ /**
2811
+ * Get a user by ID
2812
+ *
2813
+ * Fetch a single user's details by their user ID
2814
+ *
2815
+ * @param userId - User ID to fetch
2816
+ * @param type - User type ('app' or 'dashboard')
2817
+ * @returns User details with metadata
2818
+ *
2819
+ * @example
2820
+ * ```typescript
2821
+ * // Get an app user
2822
+ * const user = await admin.getUserById('user-123');
2823
+ *
2824
+ * // Get a dashboard user
2825
+ * const dashboardUser = await admin.getUserById('admin-456', 'dashboard');
2826
+ * console.log('User email:', dashboardUser.email);
2827
+ * console.log('Last login:', dashboardUser.last_login_at);
2828
+ * ```
2829
+ */
2830
+ getUserById(userId: string, type?: "app" | "dashboard"): Promise<EnrichedUser>;
2730
2831
  /**
2731
2832
  * Invite a new user
2732
2833
  *
@@ -2748,7 +2849,7 @@ declare class FluxbaseAdmin {
2748
2849
  * console.log('Invitation link:', response.invitation_link);
2749
2850
  * ```
2750
2851
  */
2751
- inviteUser(request: InviteUserRequest, type?: 'app' | 'dashboard'): Promise<InviteUserResponse>;
2852
+ inviteUser(request: InviteUserRequest, type?: "app" | "dashboard"): Promise<InviteUserResponse>;
2752
2853
  /**
2753
2854
  * Delete a user
2754
2855
  *
@@ -2764,7 +2865,7 @@ declare class FluxbaseAdmin {
2764
2865
  * console.log('User deleted');
2765
2866
  * ```
2766
2867
  */
2767
- deleteUser(userId: string, type?: 'app' | 'dashboard'): Promise<DeleteUserResponse>;
2868
+ deleteUser(userId: string, type?: "app" | "dashboard"): Promise<DeleteUserResponse>;
2768
2869
  /**
2769
2870
  * Update user role
2770
2871
  *
@@ -2781,7 +2882,7 @@ declare class FluxbaseAdmin {
2781
2882
  * console.log('User role updated:', user.role);
2782
2883
  * ```
2783
2884
  */
2784
- updateUserRole(userId: string, role: string, type?: 'app' | 'dashboard'): Promise<EnrichedUser>;
2885
+ updateUserRole(userId: string, role: string, type?: "app" | "dashboard"): Promise<EnrichedUser>;
2785
2886
  /**
2786
2887
  * Reset user password
2787
2888
  *
@@ -2797,7 +2898,7 @@ declare class FluxbaseAdmin {
2797
2898
  * console.log(response.message);
2798
2899
  * ```
2799
2900
  */
2800
- resetUserPassword(userId: string, type?: 'app' | 'dashboard'): Promise<ResetUserPasswordResponse>;
2901
+ resetUserPassword(userId: string, type?: "app" | "dashboard"): Promise<ResetUserPasswordResponse>;
2801
2902
  }
2802
2903
 
2803
2904
  /**
@@ -2805,7 +2906,7 @@ declare class FluxbaseAdmin {
2805
2906
  * Inspired by Supabase's PostgREST client
2806
2907
  */
2807
2908
 
2808
- declare class QueryBuilder<T = unknown> {
2909
+ declare class QueryBuilder<T = unknown> implements PromiseLike<PostgrestResponse<T>> {
2809
2910
  private fetch;
2810
2911
  private table;
2811
2912
  private selectQuery;
@@ -3122,6 +3223,20 @@ declare class QueryBuilder<T = unknown> {
3122
3223
  * Execute the query and return results
3123
3224
  */
3124
3225
  execute(): Promise<PostgrestResponse<T>>;
3226
+ /**
3227
+ * Make QueryBuilder awaitable (implements PromiseLike)
3228
+ * This allows using `await client.from('table').select()` without calling `.execute()`
3229
+ *
3230
+ * @example
3231
+ * ```typescript
3232
+ * // Without .execute() (new way)
3233
+ * const { data } = await client.from('users').select('*')
3234
+ *
3235
+ * // With .execute() (old way, still supported)
3236
+ * const { data } = await client.from('users').select('*').execute()
3237
+ * ```
3238
+ */
3239
+ then<TResult1 = PostgrestResponse<T>, TResult2 = never>(onfulfilled?: ((value: PostgrestResponse<T>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
3125
3240
  /**
3126
3241
  * Build the query string from filters, ordering, etc.
3127
3242
  */