From c405e74ed4171246c046f4b5786e6dd151a3db71 Mon Sep 17 00:00:00 2001 From: Vinzent Date: Mon, 17 Apr 2023 21:50:37 +0200 Subject: [PATCH 1/2] feat: add SupabaseFunctionsShelf --- .../lib/supabase_functions_shelf.dart | 58 +++++++++++++++++++ packages/supabase_functions/pubspec.yaml | 1 + 2 files changed, 59 insertions(+) create mode 100644 packages/supabase_functions/lib/supabase_functions_shelf.dart diff --git a/packages/supabase_functions/lib/supabase_functions_shelf.dart b/packages/supabase_functions/lib/supabase_functions_shelf.dart new file mode 100644 index 0000000..89b107e --- /dev/null +++ b/packages/supabase_functions/lib/supabase_functions_shelf.dart @@ -0,0 +1,58 @@ +import 'dart:js_util' as js_util; + +import 'package:edge_runtime/edge_runtime.dart'; +import 'package:edge_runtime/src/interop/promise_interop.dart'; +import 'package:edge_runtime/src/response.dart'; +import 'package:js/js.dart'; +import 'package:js_bindings/js_bindings.dart' as interop; +import 'package:shelf/shelf.dart' as shelf; + +export 'package:deno_deploy/deno_deploy.dart' hide Response; + +@JS('__dartSupabaseFetchHandler') +external set __dartSupabaseFetchHandler( + Promise Function(interop.Request req) f); + +class SupabaseFunctionsShelf { + final FutureOr Function(shelf.Request request)? fetch; + + SupabaseFunctionsShelf({ + this.fetch, + }) { + // Setup the runtime environment. + setupRuntime(); + + if (fetch != null) { + __dartSupabaseFetchHandler = allowInterop((interop.Request request) { + return futureToPromise(Future(() async { + final clone = request.clone(); + final Map headers = {}; + + js_util.callMethod(request.headers, 'forEach', [ + allowInterop((value, key, _) { + headers[key] = value; + }) + ]); + + // Remove the first path segment, because it starts with `dart_edge/`. + var uri = Uri.parse(clone.url); + uri = uri.replace(pathSegments: uri.pathSegments.skip(1)); + + final shelfRequest = shelf.Request( + clone.method, + uri, + body: clone.body, + headers: headers, + ); + final response = await fetch!(shelfRequest); + + return Response( + await response.readAsString(), + status: response.statusCode, + headers: Headers(response.headers), + ).delegate; + })); + }); + } + } +} diff --git a/packages/supabase_functions/pubspec.yaml b/packages/supabase_functions/pubspec.yaml index b9ecc90..d03c117 100644 --- a/packages/supabase_functions/pubspec.yaml +++ b/packages/supabase_functions/pubspec.yaml @@ -13,6 +13,7 @@ dependencies: edge_runtime: ^0.0.4+1 js_bindings: ^0.1.0 js: ^0.6.5 + shelf: ^1.4.0 dev_dependencies: lints: ^2.0.0 From 0a7ee60b4fb87a0c72f3125438db2f80ec4f8455 Mon Sep 17 00:00:00 2001 From: Vinzent Date: Mon, 17 Apr 2023 23:06:21 +0200 Subject: [PATCH 2/2] fix: prevent empty path --- packages/supabase_functions/lib/supabase_functions_shelf.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/supabase_functions/lib/supabase_functions_shelf.dart b/packages/supabase_functions/lib/supabase_functions_shelf.dart index 89b107e..0a0f275 100644 --- a/packages/supabase_functions/lib/supabase_functions_shelf.dart +++ b/packages/supabase_functions/lib/supabase_functions_shelf.dart @@ -37,6 +37,9 @@ class SupabaseFunctionsShelf { // Remove the first path segment, because it starts with `dart_edge/`. var uri = Uri.parse(clone.url); uri = uri.replace(pathSegments: uri.pathSegments.skip(1)); + if (uri.path.isEmpty) { + uri = uri.replace(path: "/"); + } final shelfRequest = shelf.Request( clone.method,