Skip to content

Commit

Permalink
refactor!: create package specific configs (#640)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinzent03 committed Sep 28, 2023
1 parent c9ec6bf commit 53cd3e0
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 131 deletions.
67 changes: 30 additions & 37 deletions packages/supabase/lib/src/supabase_client.dart
@@ -1,14 +1,8 @@
import 'dart:async';

import 'package:functions_client/functions_client.dart';
import 'package:gotrue/gotrue.dart';
import 'package:http/http.dart';
import 'package:postgrest/postgrest.dart';
import 'package:realtime_client/realtime_client.dart';
import 'package:storage_client/storage_client.dart';
import 'package:supabase/src/constants.dart';
import 'package:supabase/src/realtime_client_options.dart';
import 'package:supabase/src/supabase_query_builder.dart';
import 'package:supabase/supabase.dart';
import 'package:yet_another_json_isolate/yet_another_json_isolate.dart';

import 'auth_http_client.dart';
Expand Down Expand Up @@ -38,12 +32,13 @@ import 'auth_http_client.dart';
class SupabaseClient {
final String supabaseUrl;
final String supabaseKey;
final String schema;
final String restUrl;
final String realtimeUrl;
final String authUrl;
final String storageUrl;
final String functionsUrl;
final PostgrestClientOptions _postgrestOptions;

final String _restUrl;
final String _realtimeUrl;
final String _authUrl;
final String _storageUrl;
final String _functionsUrl;
final Map<String, String> _headers;
final Client? _httpClient;
late final Client _authHttpClient;
Expand Down Expand Up @@ -125,49 +120,47 @@ class SupabaseClient {
SupabaseClient(
this.supabaseUrl,
this.supabaseKey, {
String? schema,
bool autoRefreshToken = true,
PostgrestClientOptions postgrestOptions = const PostgrestClientOptions(),
AuthClientOptions authOptions = const AuthClientOptions(),
StorageClientOptions storageOptions = const StorageClientOptions(),
RealtimeClientOptions realtimeClientOptions = const RealtimeClientOptions(),
Map<String, String>? headers,
Client? httpClient,
int storageRetryAttempts = 0,
RealtimeClientOptions realtimeClientOptions = const RealtimeClientOptions(),
YAJsonIsolate? isolate,
GotrueAsyncStorage? gotrueAsyncStorage,
AuthFlowType authFlowType = AuthFlowType.pkce,
}) : restUrl = '$supabaseUrl/rest/v1',
realtimeUrl = '$supabaseUrl/realtime/v1'.replaceAll('http', 'ws'),
authUrl = '$supabaseUrl/auth/v1',
storageUrl = '$supabaseUrl/storage/v1',
functionsUrl = '$supabaseUrl/functions/v1',
schema = schema ?? 'public',
}) : _restUrl = '$supabaseUrl/rest/v1',
_realtimeUrl = '$supabaseUrl/realtime/v1'.replaceAll('http', 'ws'),
_authUrl = '$supabaseUrl/auth/v1',
_storageUrl = '$supabaseUrl/storage/v1',
_functionsUrl = '$supabaseUrl/functions/v1',
_postgrestOptions = postgrestOptions,
_headers = {
...Constants.defaultHeaders,
if (headers != null) ...headers
},
_httpClient = httpClient,
_isolate = isolate ?? (YAJsonIsolate()..initialize()) {
auth = _initSupabaseAuthClient(
autoRefreshToken: autoRefreshToken,
gotrueAsyncStorage: gotrueAsyncStorage,
authFlowType: authFlowType,
autoRefreshToken: authOptions.autoRefreshToken,
gotrueAsyncStorage: authOptions.pkceAsyncStorage,
authFlowType: authOptions.authFlowType,
);
_authHttpClient = AuthHttpClient(supabaseKey, httpClient ?? Client(), auth);
rest = _initRestClient();
functions = _initFunctionsClient();
storage = _initStorageClient(storageRetryAttempts);
storage = _initStorageClient(storageOptions.retryAttempts);
realtime = _initRealtimeClient(options: realtimeClientOptions);
_listenForAuthEvents();
}

/// Perform a table operation.
SupabaseQueryBuilder from(String table) {
final url = '$restUrl/$table';
final url = '$_restUrl/$table';
_incrementId++;
return SupabaseQueryBuilder(
url,
realtime,
headers: {...rest.headers, ...headers},
schema: schema,
schema: _postgrestOptions.schema,
table: table,
httpClient: _authHttpClient,
incrementId: _incrementId,
Expand Down Expand Up @@ -229,7 +222,7 @@ class SupabaseClient {
authHeaders['Authorization'] = 'Bearer $supabaseKey';

return GoTrueClient(
url: authUrl,
url: _authUrl,
headers: authHeaders,
autoRefreshToken: autoRefreshToken,
httpClient: _httpClient,
Expand All @@ -240,17 +233,17 @@ class SupabaseClient {

PostgrestClient _initRestClient() {
return PostgrestClient(
restUrl,
_restUrl,
headers: {...headers},
schema: schema,
schema: _postgrestOptions.schema,
httpClient: _authHttpClient,
isolate: _isolate,
);
}

FunctionsClient _initFunctionsClient() {
return FunctionsClient(
functionsUrl,
_functionsUrl,
{...headers},
httpClient: _authHttpClient,
isolate: _isolate,
Expand All @@ -259,7 +252,7 @@ class SupabaseClient {

SupabaseStorageClient _initStorageClient(int storageRetryAttempts) {
return SupabaseStorageClient(
storageUrl,
_storageUrl,
{...headers},
httpClient: _authHttpClient,
retryAttempts: storageRetryAttempts,
Expand All @@ -271,7 +264,7 @@ class SupabaseClient {
}) {
final eventsPerSecond = options.eventsPerSecond;
return RealtimeClient(
realtimeUrl,
_realtimeUrl,
params: {
'apikey': supabaseKey,
if (eventsPerSecond != null) 'eventsPerSecond': '$eventsPerSecond'
Expand Down
25 changes: 25 additions & 0 deletions packages/supabase/lib/src/supabase_client_options.dart
@@ -0,0 +1,25 @@
import 'package:supabase/supabase.dart';

class PostgrestClientOptions {
final String schema;

const PostgrestClientOptions({this.schema = 'public'});
}

class AuthClientOptions {
final bool autoRefreshToken;
final GotrueAsyncStorage? pkceAsyncStorage;
final AuthFlowType authFlowType;

const AuthClientOptions({
this.autoRefreshToken = true,
this.pkceAsyncStorage,
this.authFlowType = AuthFlowType.pkce,
});
}

class StorageClientOptions {
final int retryAttempts;

const StorageClientOptions({this.retryAttempts = 0});
}
1 change: 1 addition & 0 deletions packages/supabase/lib/supabase.dart
Expand Up @@ -14,6 +14,7 @@ export 'src/auth_user.dart';
export 'src/realtime_client_options.dart';
export 'src/remove_subscription_result.dart';
export 'src/supabase_client.dart';
export 'src/supabase_client_options.dart';
export 'src/supabase_event_types.dart';
export 'src/supabase_query_builder.dart';
export 'src/supabase_realtime_error.dart';
Expand Down
4 changes: 2 additions & 2 deletions packages/supabase/test/client_test.dart
Expand Up @@ -69,7 +69,7 @@ void main() {
final client = SupabaseClient(
'http://${mockServer.address.host}:${mockServer.port}',
"supabaseKey",
autoRefreshToken: false,
authOptions: AuthClientOptions(autoRefreshToken: false),
);
await client.auth.recoverSession(sessionString);

Expand Down Expand Up @@ -101,7 +101,7 @@ void main() {
final client = SupabaseClient(
'http://${mockServer.address.host}:${mockServer.port}',
"supabaseKey",
autoRefreshToken: false,
authOptions: AuthClientOptions(autoRefreshToken: false),
);
final sessionData = getSessionData(expiresAt);
await client.auth.recoverSession(sessionData.sessionString);
Expand Down
@@ -0,0 +1,26 @@
import 'package:supabase_flutter/supabase_flutter.dart';

class FlutterAuthClientOptions extends AuthClientOptions {
final LocalStorage? localStorage;

const FlutterAuthClientOptions({
super.authFlowType,
super.autoRefreshToken,
super.pkceAsyncStorage,
this.localStorage,
});

FlutterAuthClientOptions copyWith({
AuthFlowType? authFlowType,
bool? autoRefreshToken,
LocalStorage? localStorage,
dynamic pkceAsyncStorage,
}) {
return FlutterAuthClientOptions(
authFlowType: authFlowType ?? this.authFlowType,
autoRefreshToken: autoRefreshToken ?? this.autoRefreshToken,
localStorage: localStorage ?? this.localStorage,
pkceAsyncStorage: pkceAsyncStorage ?? this.pkceAsyncStorage,
);
}
}
59 changes: 33 additions & 26 deletions packages/supabase_flutter/lib/src/supabase.dart
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:supabase/supabase.dart';
import 'package:supabase_flutter/src/constants.dart';
import 'package:supabase_flutter/src/flutter_go_true_client_options.dart';
import 'package:supabase_flutter/src/local_storage.dart';
import 'package:supabase_flutter/src/supabase_auth.dart';

Expand Down Expand Up @@ -65,42 +66,47 @@ class Supabase {
static Future<Supabase> initialize({
required String url,
required String anonKey,
String? schema,
Map<String, String>? headers,
LocalStorage? localStorage,
Client? httpClient,
int storageRetryAttempts = 0,
RealtimeClientOptions realtimeClientOptions = const RealtimeClientOptions(),
AuthFlowType authFlowType = AuthFlowType.pkce,
GotrueAsyncStorage? pkceAsyncStorage,
PostgrestClientOptions postgrestOptions = const PostgrestClientOptions(),
StorageClientOptions storageOptions = const StorageClientOptions(),
FlutterAuthClientOptions authOptions =
const FlutterAuthClientOptions(),
bool? debug,
}) async {
assert(
!_instance._initialized,
'This instance is already initialized',
);
if (authOptions.pkceAsyncStorage == null) {
authOptions = authOptions.copyWith(
pkceAsyncStorage: SharedPreferencesGotrueAsyncStorage(),
);
}
if (authOptions.localStorage == null) {
authOptions = authOptions.copyWith(
localStorage: MigrationLocalStorage(
persistSessionKey:
"sb-${Uri.parse(url).host.split(".").first}-auth-token",
),
);
}
_instance._init(
url,
anonKey,
httpClient: httpClient,
customHeaders: headers,
schema: schema,
storageRetryAttempts: storageRetryAttempts,
realtimeClientOptions: realtimeClientOptions,
gotrueAsyncStorage:
pkceAsyncStorage ?? SharedPreferencesGotrueAsyncStorage(),
authFlowType: authFlowType,
authOptions: authOptions,
postgrestOptions: postgrestOptions,
storageOptions: storageOptions,
);
_instance._debugEnable = debug ?? kDebugMode;
_instance.log('***** Supabase init completed $_instance');

await SupabaseAuth.initialize(
localStorage: localStorage ??
MigrationLocalStorage(
persistSessionKey:
"sb-${Uri.parse(url).host.split(".").first}-auth-token"),
authFlowType: authFlowType,
);
_instance._supabaseAuth = SupabaseAuth();
await _instance._supabaseAuth.initialize(options: authOptions);

return _instance;
}
Expand All @@ -114,12 +120,15 @@ class Supabase {
///
/// Throws an error if [Supabase.initialize] was not called.
late SupabaseClient client;

late SupabaseAuth _supabaseAuth;

bool _debugEnable = false;

/// Dispose the instance to free up resources.
void dispose() {
client.dispose();
SupabaseAuth.instance.dispose();
_instance._supabaseAuth.dispose();
_initialized = false;
}

Expand All @@ -128,11 +137,10 @@ class Supabase {
String supabaseAnonKey, {
Client? httpClient,
Map<String, String>? customHeaders,
String? schema,
required int storageRetryAttempts,
required RealtimeClientOptions realtimeClientOptions,
required GotrueAsyncStorage gotrueAsyncStorage,
required AuthFlowType authFlowType,
required PostgrestClientOptions postgrestOptions,
required StorageClientOptions storageOptions,
required AuthClientOptions authOptions,
}) {
final headers = {
...Constants.defaultHeaders,
Expand All @@ -143,11 +151,10 @@ class Supabase {
supabaseAnonKey,
httpClient: httpClient,
headers: headers,
schema: schema,
storageRetryAttempts: storageRetryAttempts,
realtimeClientOptions: realtimeClientOptions,
gotrueAsyncStorage: gotrueAsyncStorage,
authFlowType: authFlowType,
postgrestOptions: postgrestOptions,
storageOptions: storageOptions,
authOptions: authOptions,
);
_initialized = true;
}
Expand Down

0 comments on commit 53cd3e0

Please sign in to comment.