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..0a0f275 --- /dev/null +++ b/packages/supabase_functions/lib/supabase_functions_shelf.dart @@ -0,0 +1,61 @@ +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)); + if (uri.path.isEmpty) { + uri = uri.replace(path: "/"); + } + + 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