diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0d2fc1b9d..55d031b7c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,7 +39,10 @@ jobs: cache: true flutter-version: ${{ matrix.sdk == 'min' && '3.3.0' || '' }} channel: ${{ matrix.sdk == 'min' && '' || matrix.channel }} - - run: dart pub get + - run: | + # Temporarily workaround with new packages. + echo -e "dependency_overrides:\n dio_web_adapter:\n path: ../plugins/web_adapter" >> example/pubspec_overrides.yaml + dart pub get - uses: bluefireteam/melos-action@v3 with: run-bootstrap: false diff --git a/plugins/web_adapter/LICENSE b/plugins/web_adapter/LICENSE new file mode 100644 index 000000000..cef745feb --- /dev/null +++ b/plugins/web_adapter/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2018 Wen Du (wendux) +Copyright (c) 2022 The CFUG Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/plugins/web_adapter/dart_test.yaml b/plugins/web_adapter/dart_test.yaml new file mode 100644 index 000000000..ad57a4243 --- /dev/null +++ b/plugins/web_adapter/dart_test.yaml @@ -0,0 +1,16 @@ +presets: + # empty placeholders required in CI scripts + all: + default: + +override_platforms: + chrome: + settings: + headless: true + firefox: + settings: + # headless argument has to be set explicitly for non-chrome browsers + arguments: --headless + executable: + # https://github.com/dart-lang/test/pull/2195 + mac_os: '/Applications/Firefox.app/Contents/MacOS/firefox' diff --git a/plugins/web_adapter/lib/dio_web_adapter.dart b/plugins/web_adapter/lib/dio_web_adapter.dart index 2dae3989c..d6ea56e1b 100644 --- a/plugins/web_adapter/lib/dio_web_adapter.dart +++ b/plugins/web_adapter/lib/dio_web_adapter.dart @@ -1,12 +1,12 @@ library dio_web_adapter; -export 'src/html/adapter.dart' - if (dart.library.js_interop) 'src/js_interop/adapter.dart'; -export 'src/html/compute.dart' - if (dart.library.js_interop) 'src/js_interop/compute.dart'; -export 'src/html/dio_impl.dart' - if (dart.library.js_interop) 'src/js_interop/dio_impl.dart'; -export 'src/html/multipart_file.dart' - if (dart.library.js_interop) 'src/js_interop/multipart_file.dart'; -export 'src/html/progress_stream.dart' - if (dart.library.js_interop) 'src/js_interop/progress_stream.dart'; +export 'src/html/adapter.dart'; +// export 'src/js_interop/adapter.dart'; +export 'src/html/compute.dart'; +// export 'src/js_interop/compute.dart'; +export 'src/html/dio_impl.dart'; +// export 'src/js_interop/dio_impl.dart'; +export 'src/html/multipart_file.dart'; +// export 'src/js_interop/multipart_file.dart'; +export 'src/html/progress_stream.dart'; +// export 'src/js_interop/progress_stream.dart'; diff --git a/plugins/web_adapter/lib/src/html/adapter.dart b/plugins/web_adapter/lib/src/html/adapter.dart index ba86dee92..3351eb21f 100644 --- a/plugins/web_adapter/lib/src/html/adapter.dart +++ b/plugins/web_adapter/lib/src/html/adapter.dart @@ -1,3 +1,5 @@ +// export '../js_interop/adapter.dart'; + import 'dart:async'; import 'dart:convert'; import 'dart:html'; diff --git a/plugins/web_adapter/lib/src/html/compute.dart b/plugins/web_adapter/lib/src/html/compute.dart index de7eb9c63..8ef14d17c 100644 --- a/plugins/web_adapter/lib/src/html/compute.dart +++ b/plugins/web_adapter/lib/src/html/compute.dart @@ -18,6 +18,9 @@ // // The file is intentionally not refactored so that it is easier to keep the // compute package up to date with Flutter's implementation. + +// export '../js_interop/compute.dart'; + import 'package:dio/src/compute/compute.dart' as c; /// The dart:html implementation of [c.compute]. diff --git a/plugins/web_adapter/lib/src/html/dio_impl.dart b/plugins/web_adapter/lib/src/html/dio_impl.dart index a9b777f6f..f5adc61bd 100644 --- a/plugins/web_adapter/lib/src/html/dio_impl.dart +++ b/plugins/web_adapter/lib/src/html/dio_impl.dart @@ -1,3 +1,5 @@ +// export '../js_interop/dio_impl.dart'; + import 'package:dio/dio.dart'; import 'adapter.dart'; diff --git a/plugins/web_adapter/lib/src/html/multipart_file.dart b/plugins/web_adapter/lib/src/html/multipart_file.dart index 64d946803..b75199ac4 100644 --- a/plugins/web_adapter/lib/src/html/multipart_file.dart +++ b/plugins/web_adapter/lib/src/html/multipart_file.dart @@ -1,3 +1,5 @@ +// export '../js_interop/multipart_file.dart'; + import 'package:http_parser/http_parser.dart'; final _err = UnsupportedError( diff --git a/plugins/web_adapter/lib/src/html/progress_stream.dart b/plugins/web_adapter/lib/src/html/progress_stream.dart index 43a4e6f22..5d97b8d8a 100644 --- a/plugins/web_adapter/lib/src/html/progress_stream.dart +++ b/plugins/web_adapter/lib/src/html/progress_stream.dart @@ -1,3 +1,5 @@ +// export '../js_interop/progress_stream.dart'; + import 'dart:async'; import 'dart:typed_data'; diff --git a/plugins/web_adapter/lib/src/js_interop/adapter.dart b/plugins/web_adapter/lib/src/js_interop/adapter.dart index 6c6e3376a..0b98368c2 100644 --- a/plugins/web_adapter/lib/src/js_interop/adapter.dart +++ b/plugins/web_adapter/lib/src/js_interop/adapter.dart @@ -1,309 +1,338 @@ +export '../html/adapter.dart'; -import 'dart:async'; -import 'dart:convert'; -import 'dart:html'; -import 'dart:typed_data'; -import 'package:dio/dio.dart'; -import 'package:dio/src/utils.dart'; -import 'package:meta/meta.dart'; - -BrowserHttpClientAdapter createAdapter() => BrowserHttpClientAdapter(); - -/// The default [HttpClientAdapter] for Web platforms. -class BrowserHttpClientAdapter implements HttpClientAdapter { - BrowserHttpClientAdapter({this.withCredentials = false}); - - /// These are aborted if the client is closed. - @visibleForTesting - final xhrs = {}; - - /// Whether to send credentials such as cookies or authorization headers for - /// cross-site requests. - /// - /// Defaults to `false`. - /// - /// You can also override this value using `Options.extra['withCredentials']` - /// for each request. - bool withCredentials; - - @override - Future fetch( - RequestOptions options, - Stream? requestStream, - Future? cancelFuture, - ) async { - final xhr = HttpRequest(); - xhrs.add(xhr); - xhr - ..open(options.method, '${options.uri}') - ..responseType = 'arraybuffer'; - - final withCredentialsOption = options.extra['withCredentials']; - if (withCredentialsOption != null) { - xhr.withCredentials = withCredentialsOption == true; - } else { - xhr.withCredentials = withCredentials; - } - - options.headers.remove(Headers.contentLengthHeader); - options.headers.forEach((key, v) { - if (v is Iterable) { - xhr.setRequestHeader(key, v.join(', ')); - } else { - xhr.setRequestHeader(key, v.toString()); - } - }); - - final sendTimeout = options.sendTimeout ?? Duration.zero; - final connectTimeout = options.connectTimeout ?? Duration.zero; - final receiveTimeout = options.receiveTimeout ?? Duration.zero; - final xhrTimeout = (connectTimeout + receiveTimeout).inMilliseconds; - xhr.timeout = xhrTimeout; - - final completer = Completer(); - - xhr.onLoad.first.then((_) { - final Uint8List body = (xhr.response as ByteBuffer).asUint8List(); - completer.complete( - ResponseBody.fromBytes( - body, - xhr.status!, - headers: xhr.responseHeaders.map((k, v) => MapEntry(k, v.split(','))), - statusMessage: xhr.statusText, - isRedirect: xhr.status == 302 || - xhr.status == 301 || - options.uri.toString() != xhr.responseUrl, - ), - ); - }); - - Timer? connectTimeoutTimer; - if (connectTimeout > Duration.zero) { - connectTimeoutTimer = Timer( - connectTimeout, - () { - connectTimeoutTimer = null; - if (completer.isCompleted) { - // connectTimeout is triggered after the fetch has been completed. - return; - } - xhr.abort(); - completer.completeError( - DioException.connectionTimeout( - requestOptions: options, - timeout: connectTimeout, - ), - StackTrace.current, - ); - }, - ); - } - - // This code is structured to call `xhr.upload.onProgress.listen` only when - // absolutely necessary, because registering an xhr upload listener prevents - // the request from being classified as a "simple request" by the CORS spec. - // Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests - // Upload progress events only get triggered if the request body exists, - // so we can check it beforehand. - if (requestStream != null) { - if (connectTimeoutTimer != null) { - xhr.upload.onProgress.listen((event) { - connectTimeoutTimer?.cancel(); - connectTimeoutTimer = null; - }); - } - - if (sendTimeout > Duration.zero) { - final uploadStopwatch = Stopwatch(); - xhr.upload.onProgress.listen((event) { - if (!uploadStopwatch.isRunning) { - uploadStopwatch.start(); - } - final duration = uploadStopwatch.elapsed; - if (duration > sendTimeout) { - uploadStopwatch.stop(); - completer.completeError( - DioException.sendTimeout( - timeout: sendTimeout, - requestOptions: options, - ), - StackTrace.current, - ); - xhr.abort(); - } - }); - } - - final onSendProgress = options.onSendProgress; - if (onSendProgress != null) { - xhr.upload.onProgress.listen((event) { - if (event.loaded != null && event.total != null) { - onSendProgress(event.loaded!, event.total!); - } - }); - } - } else { - if (sendTimeout > Duration.zero) { - debugLog( - 'sendTimeout cannot be used without a request body to send', - StackTrace.current, - ); - } - if (options.onSendProgress != null) { - debugLog( - 'onSendProgress cannot be used without a request body to send', - StackTrace.current, - ); - } - } - - final receiveStopwatch = Stopwatch(); - Timer? receiveTimer; - - void stopWatchReceiveTimeout() { - receiveTimer?.cancel(); - receiveTimer = null; - receiveStopwatch.stop(); - } - - void watchReceiveTimeout() { - if (receiveTimeout <= Duration.zero) { - return; - } - receiveStopwatch.reset(); - if (!receiveStopwatch.isRunning) { - receiveStopwatch.start(); - } - receiveTimer?.cancel(); - receiveTimer = Timer(receiveTimeout, () { - if (!completer.isCompleted) { - xhr.abort(); - completer.completeError( - DioException.receiveTimeout( - timeout: receiveTimeout, - requestOptions: options, - ), - StackTrace.current, - ); - } - stopWatchReceiveTimeout(); - }); - } - - xhr.onProgress.listen( - (ProgressEvent event) { - if (connectTimeoutTimer != null) { - connectTimeoutTimer!.cancel(); - connectTimeoutTimer = null; - } - watchReceiveTimeout(); - if (options.onReceiveProgress != null && - event.loaded != null && - event.total != null) { - options.onReceiveProgress!(event.loaded!, event.total!); - } - }, - onDone: () => stopWatchReceiveTimeout(), - ); - - xhr.onError.first.then((_) { - connectTimeoutTimer?.cancel(); - // Unfortunately, the underlying XMLHttpRequest API doesn't expose any - // specific information about the error itself. - // See also: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestEventTarget/onerror - completer.completeError( - DioException.connectionError( - requestOptions: options, - reason: 'The XMLHttpRequest onError callback was called. ' - 'This typically indicates an error on the network layer.', - ), - StackTrace.current, - ); - }); - - xhr.onTimeout.first.then((_) { - final isConnectTimeout = connectTimeoutTimer != null; - if (connectTimeoutTimer != null) { - connectTimeoutTimer?.cancel(); - } - if (!completer.isCompleted) { - if (isConnectTimeout) { - completer.completeError( - DioException.connectionTimeout( - timeout: connectTimeout, - requestOptions: options, - ), - ); - } else { - completer.completeError( - DioException.receiveTimeout( - timeout: Duration(milliseconds: xhrTimeout), - requestOptions: options, - ), - StackTrace.current, - ); - } - } - }); - - cancelFuture?.then((_) { - if (xhr.readyState < HttpRequest.DONE && - xhr.readyState > HttpRequest.UNSENT) { - connectTimeoutTimer?.cancel(); - try { - xhr.abort(); - } catch (_) {} - if (!completer.isCompleted) { - completer.completeError( - DioException.requestCancelled( - requestOptions: options, - reason: 'The XMLHttpRequest was aborted.', - ), - ); - } - } - }); - - if (requestStream != null) { - if (options.method == 'GET') { - debugLog( - 'GET request with a body data are not support on the ' - 'web platform. Use POST/PUT instead.', - StackTrace.current, - ); - } - final completer = Completer(); - final sink = ByteConversionSink.withCallback( - (bytes) => completer.complete( - bytes is Uint8List ? bytes : Uint8List.fromList(bytes), - ), - ); - requestStream.listen( - sink.add, - onError: (Object e, StackTrace s) => completer.completeError(e, s), - onDone: sink.close, - cancelOnError: true, - ); - final bytes = await completer.future; - xhr.send(bytes); - } else { - xhr.send(); - } - return completer.future.whenComplete(() { - xhrs.remove(xhr); - }); - } - - /// Closes the client. - /// - /// This terminates all active requests. - @override - void close({bool force = false}) { - if (force) { - for (final xhr in xhrs) { - xhr.abort(); - } - } - xhrs.clear(); - } -} +// import 'dart:async'; +// import 'dart:convert'; +// import 'dart:js_interop'; +// import 'dart:typed_data'; +// +// import 'package:dio/dio.dart'; +// import 'package:dio/src/utils.dart'; +// import 'package:meta/meta.dart'; +// import 'package:web/web.dart' as web; +// +// BrowserHttpClientAdapter createAdapter() => BrowserHttpClientAdapter(); +// +// /// The default [HttpClientAdapter] for Web platforms. +// class BrowserHttpClientAdapter implements HttpClientAdapter { +// BrowserHttpClientAdapter({this.withCredentials = false}); +// +// /// These are aborted if the client is closed. +// @visibleForTesting +// final xhrs = {}; +// +// /// Whether to send credentials such as cookies or authorization headers for +// /// cross-site requests. +// /// +// /// Defaults to `false`. +// /// +// /// You can also override this value using `Options.extra['withCredentials']` +// /// for each request. +// bool withCredentials; +// +// @override +// Future fetch( +// RequestOptions options, +// Stream? requestStream, +// Future? cancelFuture, +// ) async { +// final xhr = web.XMLHttpRequest(); +// xhrs.add(xhr); +// xhr +// ..open(options.method, '${options.uri}') +// ..responseType = 'arraybuffer'; +// +// final withCredentialsOption = options.extra['withCredentials']; +// if (withCredentialsOption != null) { +// xhr.withCredentials = withCredentialsOption == true; +// } else { +// xhr.withCredentials = withCredentials; +// } +// +// options.headers.remove(Headers.contentLengthHeader); +// options.headers.forEach((key, v) { +// if (v is Iterable) { +// xhr.setRequestHeader(key, v.join(', ')); +// } else { +// xhr.setRequestHeader(key, v.toString()); +// } +// }); +// +// final sendTimeout = options.sendTimeout ?? Duration.zero; +// final connectTimeout = options.connectTimeout ?? Duration.zero; +// final receiveTimeout = options.receiveTimeout ?? Duration.zero; +// final xhrTimeout = (connectTimeout + receiveTimeout).inMilliseconds; +// xhr.timeout = xhrTimeout; +// +// final completer = Completer(); +// +// xhr.onLoad.first.then((_) { +// final Uint8List body = (xhr.response as ByteBuffer).asUint8List(); +// completer.complete( +// ResponseBody.fromBytes( +// body, +// xhr.status, +// headers: +// xhr.getResponseHeaders().map((k, v) => MapEntry(k, v.split(','))), +// statusMessage: xhr.statusText, +// isRedirect: xhr.status == 302 || +// xhr.status == 301 || +// options.uri.toString() != xhr.responseURL, +// ), +// ); +// }); +// +// Timer? connectTimeoutTimer; +// if (connectTimeout > Duration.zero) { +// connectTimeoutTimer = Timer( +// connectTimeout, +// () { +// connectTimeoutTimer = null; +// if (completer.isCompleted) { +// // connectTimeout is triggered after the fetch has been completed. +// return; +// } +// xhr.abort(); +// completer.completeError( +// DioException.connectionTimeout( +// requestOptions: options, +// timeout: connectTimeout, +// ), +// StackTrace.current, +// ); +// }, +// ); +// } +// +// // This code is structured to call `xhr.upload.onProgress.listen` only when +// // absolutely necessary, because registering an xhr upload listener prevents +// // the request from being classified as a "simple request" by the CORS spec. +// // Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests +// // Upload progress events only get triggered if the request body exists, +// // so we can check it beforehand. +// if (requestStream != null) { +// if (connectTimeoutTimer != null) { +// xhr.upload.onprogress = (web.ProgressEvent event) { +// connectTimeoutTimer?.cancel(); +// connectTimeoutTimer = null; +// }.toJS; +// } +// +// if (sendTimeout > Duration.zero) { +// final uploadStopwatch = Stopwatch(); +// xhr.upload.onprogress = (web.ProgressEvent event) { +// if (!uploadStopwatch.isRunning) { +// uploadStopwatch.start(); +// } +// final duration = uploadStopwatch.elapsed; +// if (duration > sendTimeout) { +// uploadStopwatch.stop(); +// completer.completeError( +// DioException.sendTimeout( +// timeout: sendTimeout, +// requestOptions: options, +// ), +// StackTrace.current, +// ); +// xhr.abort(); +// } +// }.toJS; +// } +// +// final onSendProgress = options.onSendProgress; +// if (onSendProgress != null) { +// xhr.upload.onprogress = (web.ProgressEvent event) { +// onSendProgress(event.loaded, event.total); +// }.toJS; +// } +// } else { +// if (sendTimeout > Duration.zero) { +// debugLog( +// 'sendTimeout cannot be used without a request body to send', +// StackTrace.current, +// ); +// } +// if (options.onSendProgress != null) { +// debugLog( +// 'onSendProgress cannot be used without a request body to send', +// StackTrace.current, +// ); +// } +// } +// +// final receiveStopwatch = Stopwatch(); +// Timer? receiveTimer; +// +// void stopWatchReceiveTimeout() { +// receiveTimer?.cancel(); +// receiveTimer = null; +// receiveStopwatch.stop(); +// } +// +// void watchReceiveTimeout() { +// if (receiveTimeout <= Duration.zero) { +// return; +// } +// receiveStopwatch.reset(); +// if (!receiveStopwatch.isRunning) { +// receiveStopwatch.start(); +// } +// receiveTimer?.cancel(); +// receiveTimer = Timer(receiveTimeout, () { +// if (!completer.isCompleted) { +// xhr.abort(); +// completer.completeError( +// DioException.receiveTimeout( +// timeout: receiveTimeout, +// requestOptions: options, +// ), +// StackTrace.current, +// ); +// } +// stopWatchReceiveTimeout(); +// }); +// } +// +// xhr.onProgress.listen( +// (web.ProgressEvent event) { +// if (connectTimeoutTimer != null) { +// connectTimeoutTimer!.cancel(); +// connectTimeoutTimer = null; +// } +// watchReceiveTimeout(); +// if (options.onReceiveProgress != null) { +// options.onReceiveProgress!(event.loaded, event.total); +// } +// }, +// onDone: () => stopWatchReceiveTimeout(), +// ); +// +// xhr.onError.first.then((_) { +// connectTimeoutTimer?.cancel(); +// // Unfortunately, the underlying XMLHttpRequest API doesn't expose any +// // specific information about the error itself. +// // See also: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestEventTarget/onerror +// completer.completeError( +// DioException.connectionError( +// requestOptions: options, +// reason: 'The XMLHttpRequest onError callback was called. ' +// 'This typically indicates an error on the network layer.', +// ), +// StackTrace.current, +// ); +// }); +// +// xhr.ontimeout = (_) { +// final isConnectTimeout = connectTimeoutTimer != null; +// if (connectTimeoutTimer != null) { +// connectTimeoutTimer?.cancel(); +// } +// if (!completer.isCompleted) { +// if (isConnectTimeout) { +// completer.completeError( +// DioException.connectionTimeout( +// timeout: connectTimeout, +// requestOptions: options, +// ), +// ); +// } else { +// completer.completeError( +// DioException.receiveTimeout( +// timeout: Duration(milliseconds: xhrTimeout), +// requestOptions: options, +// ), +// StackTrace.current, +// ); +// } +// } +// }.toJS; +// +// cancelFuture?.then((_) { +// if (xhr.readyState < web.XMLHttpRequest.DONE && +// xhr.readyState > web.XMLHttpRequest.UNSENT) { +// connectTimeoutTimer?.cancel(); +// try { +// xhr.abort(); +// } catch (_) {} +// if (!completer.isCompleted) { +// completer.completeError( +// DioException.requestCancelled( +// requestOptions: options, +// reason: 'The XMLHttpRequest was aborted.', +// ), +// ); +// } +// } +// }); +// +// if (requestStream != null) { +// if (options.method == 'GET') { +// debugLog( +// 'GET request with a body data are not support on the ' +// 'web platform. Use POST/PUT instead.', +// StackTrace.current, +// ); +// } +// final completer = Completer(); +// final sink = ByteConversionSink.withCallback( +// (bytes) => completer.complete( +// bytes is Uint8List ? bytes : Uint8List.fromList(bytes), +// ), +// ); +// requestStream.listen( +// sink.add, +// onError: (Object e, StackTrace s) => completer.completeError(e, s), +// onDone: sink.close, +// cancelOnError: true, +// ); +// final bytes = await completer.future; +// xhr.send(bytes.toJS); +// } else { +// xhr.send(); +// } +// return completer.future.whenComplete(() { +// xhrs.remove(xhr); +// }); +// } +// +// /// Closes the client. +// /// +// /// This terminates all active requests. +// @override +// void close({bool force = false}) { +// if (force) { +// for (final xhr in xhrs) { +// xhr.abort(); +// } +// } +// xhrs.clear(); +// } +// } +// +// extension on web.XMLHttpRequest { +// Map getResponseHeaders() { +// final headersString = getAllResponseHeaders(); +// final headers = {}; +// if (headersString.isEmpty) { +// return headers; +// } +// final headersList = headersString.split('\r\n'); +// for (final header in headersList) { +// if (header.isEmpty) { +// continue; +// } +// +// final splitIdx = header.indexOf(': '); +// if (splitIdx == -1) { +// continue; +// } +// final key = header.substring(0, splitIdx).toLowerCase(); +// final value = header.substring(splitIdx + 2); +// if (headers.containsKey(key)) { +// headers[key] = '${headers[key]},$value'; +// } else { +// headers[key] = value; +// } +// } +// return headers; +// } +// } diff --git a/plugins/web_adapter/lib/src/js_interop/compute.dart b/plugins/web_adapter/lib/src/js_interop/compute.dart index de7eb9c63..2740a6986 100644 --- a/plugins/web_adapter/lib/src/js_interop/compute.dart +++ b/plugins/web_adapter/lib/src/js_interop/compute.dart @@ -18,17 +18,20 @@ // // The file is intentionally not refactored so that it is easier to keep the // compute package up to date with Flutter's implementation. -import 'package:dio/src/compute/compute.dart' as c; -/// The dart:html implementation of [c.compute]. -Future compute( - c.ComputeCallback callback, - Q message, { - String? debugLabel, -}) async { - // To avoid blocking the UI immediately for an expensive function call, we - // pump a single frame to allow the framework to complete the current set - // of work. - await null; - return callback(message); -} +export '../html/compute.dart'; + +// import 'package:dio/src/compute/compute.dart' as c; +// +// /// The dart:html implementation of [c.compute]. +// Future compute( +// c.ComputeCallback callback, +// Q message, { +// String? debugLabel, +// }) async { +// // To avoid blocking the UI immediately for an expensive function call, we +// // pump a single frame to allow the framework to complete the current set +// // of work. +// await null; +// return callback(message); +// } diff --git a/plugins/web_adapter/lib/src/js_interop/dio_impl.dart b/plugins/web_adapter/lib/src/js_interop/dio_impl.dart index a9b777f6f..8bb08cb6b 100644 --- a/plugins/web_adapter/lib/src/js_interop/dio_impl.dart +++ b/plugins/web_adapter/lib/src/js_interop/dio_impl.dart @@ -1,33 +1,35 @@ -import 'package:dio/dio.dart'; +export '../html/dio_impl.dart'; -import 'adapter.dart'; - -/// Create the [Dio] instance for Web platforms. -Dio createDio([BaseOptions? options]) => DioForBrowser(options); - -/// Implements features for [Dio] on Web platforms. -class DioForBrowser with DioMixin implements Dio { - /// Create Dio instance with default [Options]. - /// It's mostly just one Dio instance in your application. - DioForBrowser([BaseOptions? options]) { - this.options = options ?? BaseOptions(); - httpClientAdapter = BrowserHttpClientAdapter(); - } - - @override - Future download( - String urlPath, - dynamic savePath, { - ProgressCallback? onReceiveProgress, - Map? queryParameters, - CancelToken? cancelToken, - bool deleteOnError = true, - String lengthHeader = Headers.contentLengthHeader, - Object? data, - Options? options, - }) { - throw UnsupportedError( - 'The download method is not available in the Web environment.', - ); - } -} +// import 'package:dio/dio.dart'; +// +// import 'adapter.dart'; +// +// /// Create the [Dio] instance for Web platforms. +// Dio createDio([BaseOptions? options]) => DioForBrowser(options); +// +// /// Implements features for [Dio] on Web platforms. +// class DioForBrowser with DioMixin implements Dio { +// /// Create Dio instance with default [Options]. +// /// It's mostly just one Dio instance in your application. +// DioForBrowser([BaseOptions? options]) { +// this.options = options ?? BaseOptions(); +// httpClientAdapter = BrowserHttpClientAdapter(); +// } +// +// @override +// Future download( +// String urlPath, +// dynamic savePath, { +// ProgressCallback? onReceiveProgress, +// Map? queryParameters, +// CancelToken? cancelToken, +// bool deleteOnError = true, +// String lengthHeader = Headers.contentLengthHeader, +// Object? data, +// Options? options, +// }) { +// throw UnsupportedError( +// 'The download method is not available in the Web environment.', +// ); +// } +// } diff --git a/plugins/web_adapter/lib/src/js_interop/multipart_file.dart b/plugins/web_adapter/lib/src/js_interop/multipart_file.dart index 64d946803..47829b703 100644 --- a/plugins/web_adapter/lib/src/js_interop/multipart_file.dart +++ b/plugins/web_adapter/lib/src/js_interop/multipart_file.dart @@ -1,21 +1,23 @@ -import 'package:http_parser/http_parser.dart'; +export '../html/multipart_file.dart'; -final _err = UnsupportedError( - 'MultipartFile is only supported where dart:io is available.', -); - -Never multipartFileFromPath( - String filePath, { - String? filename, - MediaType? contentType, - final Map>? headers, -}) => - throw _err; - -Never multipartFileFromPathSync( - String filePath, { - String? filename, - MediaType? contentType, - final Map>? headers, -}) => - throw _err; +// import 'package:http_parser/http_parser.dart'; +// +// final _err = UnsupportedError( +// 'MultipartFile is only supported where dart:io is available.', +// ); +// +// Never multipartFileFromPath( +// String filePath, { +// String? filename, +// MediaType? contentType, +// final Map>? headers, +// }) => +// throw _err; +// +// Never multipartFileFromPathSync( +// String filePath, { +// String? filename, +// MediaType? contentType, +// final Map>? headers, +// }) => +// throw _err; diff --git a/plugins/web_adapter/lib/src/js_interop/progress_stream.dart b/plugins/web_adapter/lib/src/js_interop/progress_stream.dart index 43a4e6f22..b8a008a0f 100644 --- a/plugins/web_adapter/lib/src/js_interop/progress_stream.dart +++ b/plugins/web_adapter/lib/src/js_interop/progress_stream.dart @@ -1,40 +1,42 @@ -import 'dart:async'; -import 'dart:typed_data'; +export '../html/progress_stream.dart'; -import 'package:dio/dio.dart'; - -Stream addProgress( - Stream> stream, - int? length, - RequestOptions options, -) { - if (stream is Stream) { - return stream; - } - final streamTransformer = _transform>(stream, length, options); - return stream.transform(streamTransformer); -} - -StreamTransformer _transform>( - Stream stream, - int? length, - RequestOptions options, -) { - return StreamTransformer.fromHandlers( - handleData: (S data, sink) { - final cancelToken = options.cancelToken; - if (cancelToken != null && cancelToken.isCancelled) { - cancelToken.requestOptions = options; - sink - ..addError(cancelToken.cancelError!) - ..close(); - } else { - if (data is Uint8List) { - sink.add(data); - } else { - sink.add(Uint8List.fromList(data)); - } - } - }, - ); -} +// import 'dart:async'; +// import 'dart:typed_data'; +// +// import 'package:dio/dio.dart'; +// +// Stream addProgress( +// Stream> stream, +// int? length, +// RequestOptions options, +// ) { +// if (stream is Stream) { +// return stream; +// } +// final streamTransformer = _transform>(stream, length, options); +// return stream.transform(streamTransformer); +// } +// +// StreamTransformer _transform>( +// Stream stream, +// int? length, +// RequestOptions options, +// ) { +// return StreamTransformer.fromHandlers( +// handleData: (S data, sink) { +// final cancelToken = options.cancelToken; +// if (cancelToken != null && cancelToken.isCancelled) { +// cancelToken.requestOptions = options; +// sink +// ..addError(cancelToken.cancelError!) +// ..close(); +// } else { +// if (data is Uint8List) { +// sink.add(data); +// } else { +// sink.add(Uint8List.fromList(data)); +// } +// } +// }, +// ); +// } diff --git a/plugins/web_adapter/pubspec.yaml b/plugins/web_adapter/pubspec.yaml index 58a06beff..d823b785d 100644 --- a/plugins/web_adapter/pubspec.yaml +++ b/plugins/web_adapter/pubspec.yaml @@ -12,11 +12,13 @@ issue_tracker: https://github.com/cfug/dio/issues environment: sdk: '>=2.18.0 <4.0.0' +# sdk: '>=3.3.0 <4.0.0' dependencies: dio: ^5.0.0 http_parser: ^4.0.0 meta: ^1.5.0 +# web: '>=0.5.0 <0.6.0' dev_dependencies: lints: any diff --git a/plugins/web_adapter/test/web_adapter_test.dart b/plugins/web_adapter/test/web_adapter_test.dart index 47d79ed7f..3cfdcaca2 100644 --- a/plugins/web_adapter/test/web_adapter_test.dart +++ b/plugins/web_adapter/test/web_adapter_test.dart @@ -1,6 +1,7 @@ -// import 'package:dio_web_adapter/dio_web_adapter.dart'; import 'package:test/test.dart'; void main() { - group('A group of tests', () {}); + test('placeholder test', () { + expect(true, true); + }); }