diff --git a/examples/edge_functions/integration_test/invoke_test.dart b/examples/edge_functions/integration_test/invoke_test.dart index e9ea9dd7a..8041b7bde 100644 --- a/examples/edge_functions/integration_test/invoke_test.dart +++ b/examples/edge_functions/integration_test/invoke_test.dart @@ -57,7 +57,12 @@ void main() { }); testWidgets('every HTTP method reaches the function', (_) async { - for (final method in HttpMethod.values) { + // HEAD responses carry no body, so the echo function cannot report back + // which method it saw. + final methods = HttpMethod.values.where( + (method) => method != HttpMethod.head, + ); + for (final method in methods) { final response = await functions.invoke( 'echo', method: method, @@ -66,7 +71,7 @@ void main() { ? null : {'value': 1}, ); - expect(response.data['method'], method.name.toUpperCase()); + expect(response.data['method'], method.value); } }); diff --git a/packages/functions_client/lib/functions_client.dart b/packages/functions_client/lib/functions_client.dart index a79601b06..8228cf534 100644 --- a/packages/functions_client/lib/functions_client.dart +++ b/packages/functions_client/lib/functions_client.dart @@ -3,6 +3,7 @@ library; export 'package:http/http.dart' show ByteStream, MultipartFile, RequestAbortedException; +export 'package:supabase_common/supabase_common.dart' show HttpMethod; export 'src/functions_client.dart'; export 'src/types.dart'; diff --git a/packages/functions_client/lib/src/functions_client.dart b/packages/functions_client/lib/src/functions_client.dart index a4e599bae..97a78795c 100644 --- a/packages/functions_client/lib/src/functions_client.dart +++ b/packages/functions_client/lib/src/functions_client.dart @@ -169,7 +169,7 @@ class FunctionsClient { request = http.AbortableMultipartRequest( - method.name.toUpperCase(), + method.value, uri, abortTrigger: abortSignal, ) @@ -177,7 +177,7 @@ class FunctionsClient { ..files.addAll(files); } else { final bodyRequest = http.AbortableRequest( - method.name.toUpperCase(), + method.value, uri, abortTrigger: abortSignal, ); diff --git a/packages/functions_client/lib/src/types.dart b/packages/functions_client/lib/src/types.dart index a25edc4d0..8bb504cc7 100644 --- a/packages/functions_client/lib/src/types.dart +++ b/packages/functions_client/lib/src/types.dart @@ -3,14 +3,6 @@ import 'dart:typed_data'; import 'package:http/http.dart'; -enum HttpMethod { - get, - post, - put, - delete, - patch, -} - class FunctionResponse { /// The data returned by the function. Type depends on the header /// `Content-Type`: diff --git a/packages/functions_client/test/functions_dart_test.dart b/packages/functions_client/test/functions_dart_test.dart index ab400cddd..ff5ef124d 100644 --- a/packages/functions_client/test/functions_dart_test.dart +++ b/packages/functions_client/test/functions_dart_test.dart @@ -5,6 +5,7 @@ import 'dart:typed_data'; import 'package:functions_client/src/functions_client.dart'; import 'package:functions_client/src/types.dart'; import 'package:http/http.dart'; +import 'package:supabase_common/supabase_common.dart'; import 'package:test/test.dart'; import 'package:yet_another_json_isolate/yet_another_json_isolate.dart'; diff --git a/packages/gotrue/lib/src/fetch.dart b/packages/gotrue/lib/src/fetch.dart index 9be26f2ef..4b4a5248c 100644 --- a/packages/gotrue/lib/src/fetch.dart +++ b/packages/gotrue/lib/src/fetch.dart @@ -10,9 +10,6 @@ import 'package:http/http.dart'; import 'package:meta/meta.dart'; import 'package:supabase_common/supabase_common.dart'; -@internal -enum RequestMethodType { get, post, put, patch, delete } - @internal class GotrueFetch { final Client? httpClient; @@ -146,7 +143,7 @@ class GotrueFetch { Future request( String url, - RequestMethodType method, { + HttpMethod method, { GotrueRequestOptions? options, }) async { final result = await requestWithResponse(url, method, options: options); @@ -160,7 +157,7 @@ class GotrueFetch { @internal Future<({dynamic body, Response response})> requestWithResponse( String url, - RequestMethodType method, { + HttpMethod method, { GotrueRequestOptions? options, }) async { // Copy the maps before mutating them. Callers pass the client's shared @@ -211,39 +208,37 @@ class GotrueFetch { } Future _handleRequest({ - required RequestMethodType method, + required HttpMethod method, required Uri uri, required GotrueRequestOptions? options, required Map headers, }) async { final bodyStr = json.encode(options?.body ?? {}); - if (method != RequestMethodType.get) { + if (method != HttpMethod.get && method != HttpMethod.head) { headers['Content-Type'] = 'application/json'; } Response response; try { response = await switch (method) { - RequestMethodType.get => (httpClient?.get ?? get)( - uri, - headers: headers, - ), - RequestMethodType.post => (httpClient?.post ?? post)( + HttpMethod.get => (httpClient?.get ?? get)(uri, headers: headers), + HttpMethod.head => (httpClient?.head ?? head)(uri, headers: headers), + HttpMethod.post => (httpClient?.post ?? post)( uri, headers: headers, body: bodyStr, ), - RequestMethodType.put => (httpClient?.put ?? put)( + HttpMethod.put => (httpClient?.put ?? put)( uri, headers: headers, body: bodyStr, ), - RequestMethodType.patch => (httpClient?.patch ?? patch)( + HttpMethod.patch => (httpClient?.patch ?? patch)( uri, headers: headers, body: bodyStr, ), - RequestMethodType.delete => (httpClient?.delete ?? delete)( + HttpMethod.delete => (httpClient?.delete ?? delete)( uri, headers: headers, body: bodyStr, diff --git a/packages/gotrue/lib/src/gotrue_admin_api.dart b/packages/gotrue/lib/src/gotrue_admin_api.dart index 13e408f35..39766085d 100644 --- a/packages/gotrue/lib/src/gotrue_admin_api.dart +++ b/packages/gotrue/lib/src/gotrue_admin_api.dart @@ -97,7 +97,7 @@ class GoTrueAdminApi { await _fetch.request( '$_url/logout', - RequestMethodType.post, + HttpMethod.post, options: options, ); } @@ -115,7 +115,7 @@ class GoTrueAdminApi { ); final response = await _fetch.request( '$_url/admin/users', - RequestMethodType.post, + HttpMethod.post, options: options, ); return UserResponse.fromJson(response); @@ -139,7 +139,7 @@ class GoTrueAdminApi { ); await _fetch.request( '$_url/admin/users/$id', - RequestMethodType.delete, + HttpMethod.delete, options: options, ); } @@ -168,7 +168,7 @@ class GoTrueAdminApi { ); final result = await _fetch.requestWithResponse( '$_url/admin/users', - RequestMethodType.get, + HttpMethod.get, options: options, ); final body = result.body; @@ -202,7 +202,7 @@ class GoTrueAdminApi { final response = await _fetch.request( '$_url/invite', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ); return UserResponse.fromJson(response); @@ -250,7 +250,7 @@ class GoTrueAdminApi { final response = await _fetch.request( '$_url/admin/generate_link', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ); return GenerateLinkResponse.fromJson(response); @@ -262,7 +262,7 @@ class GoTrueAdminApi { final options = GotrueRequestOptions(headers: _headers); final response = await _fetch.request( '$_url/admin/users/$uid', - RequestMethodType.get, + HttpMethod.get, options: options, ); return UserResponse.fromJson(response); @@ -278,7 +278,7 @@ class GoTrueAdminApi { final options = GotrueRequestOptions(headers: _headers, body: body); final response = await _fetch.request( '$_url/admin/users/$uid', - RequestMethodType.put, + HttpMethod.put, options: options, ); return UserResponse.fromJson(response); diff --git a/packages/gotrue/lib/src/gotrue_admin_custom_providers_api.dart b/packages/gotrue/lib/src/gotrue_admin_custom_providers_api.dart index 9187fe1b3..1abbe6ec4 100644 --- a/packages/gotrue/lib/src/gotrue_admin_custom_providers_api.dart +++ b/packages/gotrue/lib/src/gotrue_admin_custom_providers_api.dart @@ -1,3 +1,5 @@ +import 'package:supabase_common/supabase_common.dart'; + import 'fetch.dart'; import 'types/custom_oauth_provider.dart'; import 'types/fetch_options.dart'; @@ -29,7 +31,7 @@ class GoTrueAdminCustomProvidersApi { }) async { final data = await _fetch.request( '$_url/admin/custom-providers', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, query: { @@ -60,7 +62,7 @@ class GoTrueAdminCustomProvidersApi { ) async { final data = await _fetch.request( '$_url/admin/custom-providers', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: params.toJson(), @@ -77,7 +79,7 @@ class GoTrueAdminCustomProvidersApi { Future getProvider(String identifier) async { final data = await _fetch.request( '$_url/admin/custom-providers/$identifier', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, ), @@ -101,7 +103,7 @@ class GoTrueAdminCustomProvidersApi { ) async { final data = await _fetch.request( '$_url/admin/custom-providers/$identifier', - RequestMethodType.put, + HttpMethod.put, options: GotrueRequestOptions( headers: _headers, body: params.toJson(), @@ -118,7 +120,7 @@ class GoTrueAdminCustomProvidersApi { Future deleteProvider(String identifier) async { await _fetch.request( '$_url/admin/custom-providers/$identifier', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _headers, noResolveJson: true, diff --git a/packages/gotrue/lib/src/gotrue_admin_mfa_api.dart b/packages/gotrue/lib/src/gotrue_admin_mfa_api.dart index 3c080bc41..a2efd7226 100644 --- a/packages/gotrue/lib/src/gotrue_admin_mfa_api.dart +++ b/packages/gotrue/lib/src/gotrue_admin_mfa_api.dart @@ -1,5 +1,6 @@ +import 'package:supabase_common/supabase_common.dart'; + import 'fetch.dart'; -import 'helper.dart'; import 'types/fetch_options.dart'; import 'types/mfa.dart'; @@ -23,7 +24,7 @@ class GoTrueAdminMFAApi { final data = await _fetch.request( '$_url/admin/users/$userId/factors', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, ), @@ -43,7 +44,7 @@ class GoTrueAdminMFAApi { final data = await _fetch.request( '$_url/admin/users/$userId/factors/$factorId', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _headers, ), diff --git a/packages/gotrue/lib/src/gotrue_admin_oauth_api.dart b/packages/gotrue/lib/src/gotrue_admin_oauth_api.dart index 7be5d78b4..4ef11a057 100644 --- a/packages/gotrue/lib/src/gotrue_admin_oauth_api.dart +++ b/packages/gotrue/lib/src/gotrue_admin_oauth_api.dart @@ -1,8 +1,9 @@ +import 'package:meta/meta.dart'; +import 'package:supabase_common/supabase_common.dart'; + import 'fetch.dart'; -import 'helper.dart'; import 'types/fetch_options.dart'; import 'types/types.dart'; -import 'package:meta/meta.dart'; /// Response type for OAuth client operations. /// Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. @@ -76,7 +77,7 @@ class GoTrueAdminOAuthApi { }) async { final data = await _fetch.request( '$_url/admin/oauth/clients', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, query: { @@ -99,7 +100,7 @@ class GoTrueAdminOAuthApi { ) async { final data = await _fetch.request( '$_url/admin/oauth/clients', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: params.toJson(), @@ -119,7 +120,7 @@ class GoTrueAdminOAuthApi { final data = await _fetch.request( '$_url/admin/oauth/clients/$clientId', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, ), @@ -141,7 +142,7 @@ class GoTrueAdminOAuthApi { final data = await _fetch.request( '$_url/admin/oauth/clients/$clientId', - RequestMethodType.put, + HttpMethod.put, options: GotrueRequestOptions( headers: _headers, body: params.toJson(), @@ -161,7 +162,7 @@ class GoTrueAdminOAuthApi { final data = await _fetch.request( '$_url/admin/oauth/clients/$clientId', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _headers, ), @@ -180,7 +181,7 @@ class GoTrueAdminOAuthApi { final data = await _fetch.request( '$_url/admin/oauth/clients/$clientId/regenerate_secret', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, ), diff --git a/packages/gotrue/lib/src/gotrue_admin_passkey_api.dart b/packages/gotrue/lib/src/gotrue_admin_passkey_api.dart index 4f7236dfc..8fecab7e6 100644 --- a/packages/gotrue/lib/src/gotrue_admin_passkey_api.dart +++ b/packages/gotrue/lib/src/gotrue_admin_passkey_api.dart @@ -1,7 +1,7 @@ import 'package:meta/meta.dart'; +import 'package:supabase_common/supabase_common.dart'; import 'fetch.dart'; -import 'helper.dart'; import 'types/fetch_options.dart'; import 'types/passkey.dart'; @@ -32,7 +32,7 @@ class GoTrueAdminPasskeyApi { final data = await _fetch.request( '$_url/admin/users/$userId/passkeys', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, ), @@ -57,7 +57,7 @@ class GoTrueAdminPasskeyApi { await _fetch.request( '$_url/admin/users/$userId/passkeys/$passkeyId', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _headers, ), diff --git a/packages/gotrue/lib/src/gotrue_client.dart b/packages/gotrue/lib/src/gotrue_client.dart index 17eba1db2..52856cfd8 100644 --- a/packages/gotrue/lib/src/gotrue_client.dart +++ b/packages/gotrue/lib/src/gotrue_client.dart @@ -249,7 +249,7 @@ class GoTrueClient { }) async { final response = await _fetch.request( '$_url/signup', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: { @@ -310,7 +310,7 @@ class GoTrueClient { response = await _fetch.request( '$_url/signup', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, redirectTo: emailRedirectTo, @@ -336,7 +336,7 @@ class GoTrueClient { response = await _fetch.request( '$_url/signup', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ) as Map; @@ -369,7 +369,7 @@ class GoTrueClient { if (email != null) { response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: { @@ -383,7 +383,7 @@ class GoTrueClient { } else if (phone != null) { response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: { @@ -450,7 +450,7 @@ class GoTrueClient { final Map response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: {'auth_code': authCode, 'code_verifier': codeVerifier}, @@ -521,7 +521,7 @@ class GoTrueClient { }) async { final response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: { @@ -569,7 +569,7 @@ class GoTrueClient { }) async { final response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, body: { @@ -632,7 +632,7 @@ class GoTrueClient { final codeChallenge = await _generatePKCECodeChallenge(); await _fetch.request( '$_url/otp', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, redirectTo: emailRedirectTo, @@ -660,7 +660,7 @@ class GoTrueClient { await _fetch.request( '$_url/otp', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ); return; @@ -729,7 +729,7 @@ class GoTrueClient { final fetchOptions = GotrueRequestOptions(headers: _headers, body: body); final response = await _fetch.request( '$_url/verify', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ); @@ -782,7 +782,7 @@ class GoTrueClient { final res = await _fetch.request( '$_url/sso', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( body: { 'provider_id': ?providerId, @@ -835,7 +835,7 @@ class GoTrueClient { await _fetch.request( '$_url/reauthenticate', - RequestMethodType.get, + HttpMethod.get, options: options, ); } @@ -893,7 +893,7 @@ class GoTrueClient { final response = await _fetch.request( '$_url/resend', - RequestMethodType.post, + HttpMethod.post, options: options, ); @@ -914,7 +914,7 @@ class GoTrueClient { ); final response = await _fetch.request( '$_url/user', - RequestMethodType.get, + HttpMethod.get, options: options, ); return UserResponse.fromJson(response); @@ -951,7 +951,7 @@ class GoTrueClient { ); final response = await _fetch.request( '$_url/user', - RequestMethodType.put, + HttpMethod.put, options: options, ); final userResponse = UserResponse.fromJson(response); @@ -1176,7 +1176,7 @@ class GoTrueClient { ); await _fetch.request( '$_url/recover', - RequestMethodType.post, + HttpMethod.post, options: fetchOptions, ); } @@ -1208,7 +1208,7 @@ class GoTrueClient { }) async { final response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _headers, jwt: _currentSession?.accessToken, @@ -1253,7 +1253,7 @@ class GoTrueClient { ); final res = await _fetch.request( urlResponse.url, - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _headers, jwt: _currentSession?.accessToken, @@ -1269,7 +1269,7 @@ class GoTrueClient { Future unlinkIdentity(UserIdentity identity) async { await _fetch.request( '$_url/user/identities/${identity.identityId}', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: headers, jwt: _currentSession?.accessToken, @@ -1446,7 +1446,7 @@ class GoTrueClient { ); final response = await _fetch.request( '$_url/token', - RequestMethodType.post, + HttpMethod.post, options: options, ); final authResponse = AuthResponse.fromJson(response); @@ -1752,7 +1752,7 @@ class GoTrueClient { // endpoint final jwksResponse = await _fetch.request( '$_url/.well-known/jwks.json', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions(headers: _headers), ); diff --git a/packages/gotrue/lib/src/gotrue_mfa_api.dart b/packages/gotrue/lib/src/gotrue_mfa_api.dart index b3add0a06..e99da3b5b 100644 --- a/packages/gotrue/lib/src/gotrue_mfa_api.dart +++ b/packages/gotrue/lib/src/gotrue_mfa_api.dart @@ -17,7 +17,7 @@ class GoTrueMFAApi { final data = await _fetch.request( '${_client._url}/factors/$factorId', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -80,7 +80,7 @@ class GoTrueMFAApi { final data = await _fetch.request( '${_client._url}/factors', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: body, @@ -110,7 +110,7 @@ class GoTrueMFAApi { final data = await _fetch.request( '${_client._url}/factors/$factorId/verify', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: { @@ -151,7 +151,7 @@ class GoTrueMFAApi { final data = await _fetch.request( '${_client._url}/factors/$factorId/challenge', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: channel == null ? null : {'channel': channel.name}, diff --git a/packages/gotrue/lib/src/gotrue_oauth_api.dart b/packages/gotrue/lib/src/gotrue_oauth_api.dart index 6cb279140..a996bbe68 100644 --- a/packages/gotrue/lib/src/gotrue_oauth_api.dart +++ b/packages/gotrue/lib/src/gotrue_oauth_api.dart @@ -239,7 +239,7 @@ class GoTrueOAuthApi { final data = await _fetch.request( '${_client._url}/oauth/authorizations/$authorizationId', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -262,7 +262,7 @@ class GoTrueOAuthApi { final data = await _fetch.request( '${_client._url}/oauth/authorizations/$authorizationId/consent', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -288,7 +288,7 @@ class GoTrueOAuthApi { final data = await _fetch.request( '${_client._url}/oauth/authorizations/$authorizationId/consent', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -309,7 +309,7 @@ class GoTrueOAuthApi { final data = await _fetch.request( '${_client._url}/user/oauth/grants', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -328,7 +328,7 @@ class GoTrueOAuthApi { await _fetch.request( '${_client._url}/user/oauth/grants', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, diff --git a/packages/gotrue/lib/src/gotrue_passkey_api.dart b/packages/gotrue/lib/src/gotrue_passkey_api.dart index 618162739..9dd7efe8e 100644 --- a/packages/gotrue/lib/src/gotrue_passkey_api.dart +++ b/packages/gotrue/lib/src/gotrue_passkey_api.dart @@ -69,7 +69,7 @@ class GoTruePasskeyApi { final data = await _fetch.request( '${_client._url}/passkeys/registration/options', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: {}, @@ -123,7 +123,7 @@ class GoTruePasskeyApi { final data = await _fetch.request( '${_client._url}/passkeys/registration/verify', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: { @@ -148,7 +148,7 @@ class GoTruePasskeyApi { }) async { final data = await _fetch.request( '${_client._url}/passkeys/authentication/options', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: { @@ -176,7 +176,7 @@ class GoTruePasskeyApi { }) async { final data = await _fetch.request( '${_client._url}/passkeys/authentication/verify', - RequestMethodType.post, + HttpMethod.post, options: GotrueRequestOptions( headers: _client._headers, body: { @@ -202,7 +202,7 @@ class GoTruePasskeyApi { final data = await _fetch.request( '${_client._url}/passkeys', - RequestMethodType.get, + HttpMethod.get, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, @@ -227,7 +227,7 @@ class GoTruePasskeyApi { final data = await _fetch.request( '${_client._url}/passkeys/$passkeyId', - RequestMethodType.patch, + HttpMethod.patch, options: GotrueRequestOptions( headers: _client._headers, body: {'friendly_name': friendlyName}, @@ -247,7 +247,7 @@ class GoTruePasskeyApi { await _fetch.request( '${_client._url}/passkeys/$passkeyId', - RequestMethodType.delete, + HttpMethod.delete, options: GotrueRequestOptions( headers: _client._headers, jwt: session?.accessToken, diff --git a/packages/gotrue/test/fetch_test.dart b/packages/gotrue/test/fetch_test.dart index 1fc8263e6..966d089d6 100644 --- a/packages/gotrue/test/fetch_test.dart +++ b/packages/gotrue/test/fetch_test.dart @@ -2,6 +2,7 @@ import 'package:gotrue/gotrue.dart'; import 'package:gotrue/src/constants.dart'; import 'package:gotrue/src/fetch.dart'; import 'package:http/http.dart'; +import 'package:supabase_common/supabase_common.dart'; import 'package:test/test.dart'; import 'custom_http_client.dart'; @@ -197,7 +198,7 @@ void main() { ); await expectLater( - GotrueFetch(client).request(_mockUrl, RequestMethodType.get), + GotrueFetch(client).request(_mockUrl, HttpMethod.get), throwsA(isA()), ); }); @@ -210,7 +211,7 @@ Future _expectRetryableFetch( required String statusCode, }) async { await expectLater( - GotrueFetch(client).request(_mockUrl, RequestMethodType.get), + GotrueFetch(client).request(_mockUrl, HttpMethod.get), throwsA( isA() .having((e) => e.message, 'message', message) @@ -222,7 +223,7 @@ Future _expectRetryableFetch( Future _testFetchRequest(Client client) async { final GotrueFetch fetch = GotrueFetch(client); await expectLater( - fetch.request(_mockUrl, RequestMethodType.get), + fetch.request(_mockUrl, HttpMethod.get), throwsA( isA() .having((e) => e.code, 'code', 'weak_password') diff --git a/packages/postgrest/lib/postgrest.dart b/packages/postgrest/lib/postgrest.dart index da0e86ff9..891ae39e7 100644 --- a/packages/postgrest/lib/postgrest.dart +++ b/packages/postgrest/lib/postgrest.dart @@ -5,3 +5,4 @@ export 'src/postgrest.dart'; export 'src/postgrest_builder.dart'; export 'src/types.dart'; export 'package:http/http.dart' show RequestAbortedException; +export 'package:supabase_common/supabase_common.dart' show HttpMethod; diff --git a/packages/postgrest/lib/src/postgrest_builder.dart b/packages/postgrest/lib/src/postgrest_builder.dart index 60772cb6a..9ee73bdf6 100644 --- a/packages/postgrest/lib/src/postgrest_builder.dart +++ b/packages/postgrest/lib/src/postgrest_builder.dart @@ -18,17 +18,6 @@ part 'postgrest_transform_builder.dart'; part 'raw_postgrest_builder.dart'; part 'response_postgrest_builder.dart'; -enum HttpMethod { - get, - head, - post, - put, - patch, - delete; - - String get value => name.toUpperCase(); -} - typedef _Nullable = T?; /// Bundles the automatic retry configuration so it can be carried through the diff --git a/packages/storage_client/lib/src/fetch.dart b/packages/storage_client/lib/src/fetch.dart index c352ec95d..7c005d87c 100644 --- a/packages/storage_client/lib/src/fetch.dart +++ b/packages/storage_client/lib/src/fetch.dart @@ -57,13 +57,13 @@ class Fetch { } Future _handleRequest( - String method, + HttpMethod method, String url, Map? body, FetchOptions? options, ) async { final headers = {...?options?.headers}; - if (method != 'GET') { + if (method != HttpMethod.get) { final hasContentType = headers.keys.any( (key) => key.toLowerCase() == 'content-type', ); @@ -72,13 +72,13 @@ class Fetch { } } - final request = http.Request(method, Uri.parse(url)) + final request = http.Request(method.value, Uri.parse(url)) ..headers.addAll(headers); if (body != null) { request.body = json.encode(body); } - _log.finest('Request: $method $url $headers'); + _log.finest('Request: ${method.value} $url $headers'); final http.StreamedResponse streamedResponse; if (httpClient != null) { streamedResponse = await httpClient!.send(request); @@ -89,7 +89,7 @@ class Fetch { } Future _handleFileRequest( - String method, + HttpMethod method, String url, File file, FileOptions fileOptions, @@ -118,7 +118,7 @@ class Fetch { } Future _handleBinaryFileRequest( - String method, + HttpMethod method, String url, Uint8List data, FileOptions fileOptions, @@ -147,7 +147,7 @@ class Fetch { } Future _handleMultipartRequest( - String method, + HttpMethod method, String url, MultipartFile Function() createMultipartFile, FileOptions fileOptions, @@ -160,7 +160,7 @@ class Fetch { // Create a factory function that generates a fresh MultipartRequest for // each attempt http.MultipartRequest createRequest() { - final request = http.MultipartRequest(method, Uri.parse(url)) + final request = http.MultipartRequest(method.value, Uri.parse(url)) ..headers.addAll(headers) ..files.add(createMultipartFile()) ..fields['cacheControl'] = fileOptions.cacheControl @@ -180,7 +180,9 @@ class Fetch { streamedResponse = await r.retry( () async { attempts++; - _log.finest('Request: attempt: $attempts $method $url $headers'); + _log.finest( + 'Request: attempt: $attempts ${method.value} $url $headers', + ); // Create a fresh request for each retry attempt final request = createRequest(); @@ -223,7 +225,7 @@ class Fetch { Future head(String url, {FetchOptions? options}) { return _handleRequest( - 'HEAD', + HttpMethod.head, url, null, FetchOptions(options?.headers, noResolveJson: true), @@ -231,7 +233,7 @@ class Fetch { } Future get(String url, {FetchOptions? options}) { - return _handleRequest('GET', url, null, options); + return _handleRequest(HttpMethod.get, url, null, options); } /// Performs a GET request and yields the response body as a byte stream @@ -245,7 +247,7 @@ class Fetch { String url, { FetchOptions? options, }) async* { - final request = http.Request('GET', Uri.parse(url)) + final request = http.Request(HttpMethod.get.value, Uri.parse(url)) ..headers.addAll({...?options?.headers}); _log.finest('Request: GET (stream) $url ${request.headers}'); @@ -276,7 +278,7 @@ class Fetch { Map? body, { FetchOptions? options, }) { - return _handleRequest('POST', url, body, options); + return _handleRequest(HttpMethod.post, url, body, options); } Future put( @@ -284,7 +286,7 @@ class Fetch { Map? body, { FetchOptions? options, }) { - return _handleRequest('PUT', url, body, options); + return _handleRequest(HttpMethod.put, url, body, options); } Future delete( @@ -292,7 +294,7 @@ class Fetch { Map? body, { FetchOptions? options, }) { - return _handleRequest('DELETE', url, body, options); + return _handleRequest(HttpMethod.delete, url, body, options); } Future postFile( @@ -304,7 +306,7 @@ class Fetch { required StorageRetryController? retryController, }) { return _handleFileRequest( - 'POST', + HttpMethod.post, url, file, fileOptions, @@ -323,7 +325,7 @@ class Fetch { required StorageRetryController? retryController, }) { return _handleFileRequest( - 'PUT', + HttpMethod.put, url, file, fileOptions, @@ -342,7 +344,7 @@ class Fetch { required StorageRetryController? retryController, }) { return _handleBinaryFileRequest( - 'POST', + HttpMethod.post, url, data, fileOptions, @@ -361,7 +363,7 @@ class Fetch { required StorageRetryController? retryController, }) { return _handleBinaryFileRequest( - 'PUT', + HttpMethod.put, url, data, fileOptions, diff --git a/packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart b/packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart index 6e430f5d6..f61a4eb43 100644 --- a/packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart +++ b/packages/storage_client/lib/src/iceberg/iceberg_rest_catalog.dart @@ -7,6 +7,7 @@ import 'package:storage_client/src/iceberg/iceberg_error.dart'; import 'package:storage_client/src/iceberg/iceberg_types.dart'; import 'package:storage_client/src/iceberg/table_requirement.dart'; import 'package:storage_client/src/iceberg/table_update.dart'; +import 'package:supabase_common/supabase_common.dart'; class _IcebergResponse { final int statusCode; @@ -90,7 +91,7 @@ class IcebergRestCatalog { } try { final response = await _request( - 'GET', + HttpMethod.get, 'v1/config', query: {'warehouse': _warehouse}, ); @@ -124,7 +125,7 @@ class IcebergRestCatalog { } Future<_IcebergResponse> _request( - String method, + HttpMethod method, String path, { Map? query, Object? body, @@ -137,12 +138,13 @@ class IcebergRestCatalog { ...?headers, }; - final request = http.Request(method, uri)..headers.addAll(requestHeaders); + final request = http.Request(method.value, uri) + ..headers.addAll(requestHeaders); if (body != null) { request.body = json.encode(body); } - _log.finest('Request: $method $uri'); + _log.finest('Request: ${method.value} $uri'); final http.StreamedResponse streamedResponse; try { @@ -190,7 +192,7 @@ class IcebergRestCatalog { if (options?.pageSize != null) 'pageSize': '${options!.pageSize}', }; final response = await _request( - 'GET', + HttpMethod.get, '$prefix/namespaces', query: query.isEmpty ? null : query, ); @@ -210,7 +212,7 @@ class IcebergRestCatalog { }) async { final prefix = await _resolvePrefix(); final response = await _request( - 'POST', + HttpMethod.post, '$prefix/namespaces', body: { 'namespace': namespace, @@ -228,7 +230,7 @@ class IcebergRestCatalog { ) async { final prefix = await _resolvePrefix(); final response = await _request( - 'GET', + HttpMethod.get, '$prefix/namespaces/${_namespaceToPath(namespace)}', ); final body = response.body as Map; @@ -243,7 +245,7 @@ class IcebergRestCatalog { }) async { final prefix = await _resolvePrefix(); final response = await _request( - 'POST', + HttpMethod.post, '$prefix/namespaces/${_namespaceToPath(namespace)}/properties', body: { 'updates': ?updates, @@ -260,7 +262,7 @@ class IcebergRestCatalog { Future dropNamespace(List namespace) async { final prefix = await _resolvePrefix(); await _request( - 'DELETE', + HttpMethod.delete, '$prefix/namespaces/${_namespaceToPath(namespace)}', headers: {'Idempotency-Key': _idempotencyKey()}, ); @@ -271,7 +273,7 @@ class IcebergRestCatalog { final prefix = await _resolvePrefix(); try { await _request( - 'HEAD', + HttpMethod.head, '$prefix/namespaces/${_namespaceToPath(namespace)}', ); return true; @@ -303,7 +305,7 @@ class IcebergRestCatalog { if (options?.pageSize != null) 'pageSize': '${options!.pageSize}', }; final response = await _request( - 'GET', + HttpMethod.get, '$prefix/namespaces/${_namespaceToPath(namespace)}/tables', query: query.isEmpty ? null : query, ); @@ -336,7 +338,7 @@ class IcebergRestCatalog { ) async { final prefix = await _resolvePrefix(); final response = await _request( - 'POST', + HttpMethod.post, '$prefix/namespaces/${_namespaceToPath(namespace)}/tables', body: request.toJson(), headers: { @@ -371,7 +373,7 @@ class IcebergRestCatalog { ) async { final prefix = await _resolvePrefix(); final response = await _request( - 'POST', + HttpMethod.post, '$prefix/namespaces/${_namespaceToPath(namespace)}/register', body: request.toJson(), headers: { @@ -406,9 +408,9 @@ class IcebergRestCatalog { if (options?.snapshots != null) 'snapshots': options!.snapshots!.value, }; final response = await _request( - 'GET', + HttpMethod.get, '$prefix/namespaces/${_namespaceToPath(id.namespace)}/tables/' - '${Uri.encodeComponent(id.name)}', + '${Uri.encodeComponent(id.name)}', query: query.isEmpty ? null : query, headers: { ..._accessDelegationHeader(), @@ -430,9 +432,9 @@ class IcebergRestCatalog { final prefix = await _resolvePrefix(); try { await _request( - 'HEAD', + HttpMethod.head, '$prefix/namespaces/${_namespaceToPath(id.namespace)}/tables/' - '${Uri.encodeComponent(id.name)}', + '${Uri.encodeComponent(id.name)}', headers: _accessDelegationHeader(), ); return true; @@ -449,9 +451,9 @@ class IcebergRestCatalog { }) async { final prefix = await _resolvePrefix(); final response = await _request( - 'POST', + HttpMethod.post, '$prefix/namespaces/${_namespaceToPath(id.namespace)}/tables/' - '${Uri.encodeComponent(id.name)}', + '${Uri.encodeComponent(id.name)}', body: { 'requirements': requirements .map((requirement) => requirement.toJson()) @@ -482,9 +484,9 @@ class IcebergRestCatalog { Future dropTable(TableIdentifier id, {bool purge = false}) async { final prefix = await _resolvePrefix(); await _request( - 'DELETE', + HttpMethod.delete, '$prefix/namespaces/${_namespaceToPath(id.namespace)}/tables/' - '${Uri.encodeComponent(id.name)}', + '${Uri.encodeComponent(id.name)}', query: {'purgeRequested': '$purge'}, headers: {'Idempotency-Key': _idempotencyKey()}, ); @@ -497,7 +499,7 @@ class IcebergRestCatalog { ) async { final prefix = await _resolvePrefix(); await _request( - 'POST', + HttpMethod.post, '$prefix/tables/rename', body: {'source': source.toJson(), 'destination': destination.toJson()}, headers: {'Idempotency-Key': _idempotencyKey()}, diff --git a/packages/supabase/lib/supabase.dart b/packages/supabase/lib/supabase.dart index 00b3e8cca..fe2f3898d 100644 --- a/packages/supabase/lib/supabase.dart +++ b/packages/supabase/lib/supabase.dart @@ -5,7 +5,7 @@ library; export 'package:functions_client/functions_client.dart'; export 'package:gotrue/gotrue.dart'; -export 'package:postgrest/postgrest.dart' hide HttpMethod; +export 'package:postgrest/postgrest.dart'; export 'package:realtime_client/realtime_client.dart'; export 'package:storage_client/storage_client.dart'; diff --git a/packages/supabase_common/lib/src/http_method.dart b/packages/supabase_common/lib/src/http_method.dart new file mode 100644 index 000000000..b1535d575 --- /dev/null +++ b/packages/supabase_common/lib/src/http_method.dart @@ -0,0 +1,10 @@ +enum HttpMethod { + get, + head, + post, + put, + patch, + delete; + + String get value => name.toUpperCase(); +} diff --git a/packages/supabase_common/lib/supabase_common.dart b/packages/supabase_common/lib/supabase_common.dart index ae17fc531..46ddccb28 100644 --- a/packages/supabase_common/lib/supabase_common.dart +++ b/packages/supabase_common/lib/supabase_common.dart @@ -8,6 +8,7 @@ library; export 'src/base64url.dart'; export 'src/client_info.dart'; export 'src/fetch_options.dart'; +export 'src/http_method.dart'; export 'src/http_status.dart'; export 'src/pkce.dart'; export 'src/platform/platform_info.dart'; diff --git a/sdk-compliance.yaml b/sdk-compliance.yaml index 918aa29eb..15c9e654e 100644 --- a/sdk-compliance.yaml +++ b/sdk-compliance.yaml @@ -1424,8 +1424,9 @@ features: - FunctionsClient.setAuth functions.invocation.method_override: status: implemented + note: "The HttpMethod enum is shared with postgrest, so it also offers head, which supabase-js does not expose for function invocation." symbols: - - HttpMethod + - FunctionsClient.invoke functions.invocation.streaming_response: status: implemented symbols: