Skip to content

Commit

Permalink
feat: add compatibility_layer library
Browse files Browse the repository at this point in the history
  • Loading branch information
Zekfad committed Jan 23, 2023
1 parent 5cb7445 commit 72e0fb0
Show file tree
Hide file tree
Showing 12 changed files with 235 additions and 154 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## 1.0.0-dev.3
- **BREAKING**: Renamed extensions from `<Class>Extension` to `<Class>InstanceMembers`.
- Added `fetch_api.compatibility_layer` library to support Dart 2.19.
- Added `createHeadersFromMap`
- Added `createHeadersFromArray`
- Added `createRequestInit`
- Added `createAbortSignalTimeout`

- `AbortSignal`
- Added `timeout` constructor-like method.
- Added `abort` constructor-like method.
Expand All @@ -14,7 +20,6 @@
- Added docs.
- `Headers`
- Added docs.
- Add methods `headersFromMap` and `headersFromArray` to support Dart 2.19.
- `Iterator` and `IteratorResult`
- Added docs.
- `ReadableStreamDefaultReader` and `ReadableStreamDefaultReaderChunk`
Expand Down
15 changes: 15 additions & 0 deletions lib/compatibility_layer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/// Dart 1.19 compatibility layer.
///
/// Provides [createHeadersFromArray], [createHeadersFromMap],
/// [createAbortSignalTimeout] and [createRequestInit] functions, in replacement
/// of unsupported [Headers.fromArray], [Headers.fromMap], [AbortSignal.timeout]
/// and [RequestInit] respectively.
library fetch_api.compatibility_layer;

import 'src/abort_signal/abort_signal.dart';
import 'src/headers/headers.dart';
import 'src/request_init/request_init.dart';

export 'src/abort_signal/abort_signal.dart' show createAbortSignalTimeout;
export 'src/headers/headers.dart' show createHeadersFromArray, createHeadersFromMap;
export 'src/request_init/request_init.dart' show createRequestInit;
6 changes: 6 additions & 0 deletions lib/fetch_api.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
/// The Fetch API provides an interface for fetching resources
/// (including across the network). It will seem familiar to anyone who has used
/// `XMLHttpRequest`, but the new API provides a more powerful and flexible
/// feature set.
library fetch_api;

export 'src/abort_controller.dart';
export 'src/abort_signal.dart';
export 'src/fetch.dart';
Expand Down
38 changes: 1 addition & 37 deletions lib/src/abort_signal.dart
Original file line number Diff line number Diff line change
@@ -1,37 +1 @@
import '_js.dart';
import 'abort_controller.dart';


/// The [AbortSignal] interface represents a signal object that allows you
/// to communicate with a DOM request (such as a fetch request) and abort it
/// if required via an [AbortController] object.
@JS()
@staticInterop
class AbortSignal {
/// Returns an [AbortSignal] instance that will automatically abort
/// after a specified [time].
factory AbortSignal.timeout(Duration time)
=> AbortSignal._timeout(time.inMilliseconds);

/// Returns an [AbortSignal] instance that is already set as aborted.
external static AbortSignal abort([dynamic reason]);

/// Returns an [AbortSignal] instance that will automatically abort
/// after a specified [time] in milliseconds.
@JS('timeout')
external static AbortSignal _timeout(int time);
}


extension AbortSignalInstanceMembers on AbortSignal {
/// A [bool] that indicates whether the request(s) the signal is
/// communicating with is/are aborted (`true`) or not (`false`).
external final bool aborted;

/// A JavaScript value providing the abort reason, once the signal has aborted.
external final dynamic reason;

/// Throws the signal's abort [reason] if the signal has been aborted;
/// otherwise it does nothing.
external void throwIfAborted();
}
export 'abort_signal/abort_signal.dart' hide createAbortSignalTimeout;
7 changes: 7 additions & 0 deletions lib/src/abort_signal/abort_signal.compatibility_layer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
part of 'abort_signal.dart';


/// Returns an [AbortSignal] instance that will automatically abort
/// after a specified [time].
AbortSignal createAbortSignalTimeout(Duration time)
=> AbortSignal._timeout(time.inMilliseconds);
39 changes: 39 additions & 0 deletions lib/src/abort_signal/abort_signal.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import '../_js.dart';
import '../abort_controller.dart';

part 'abort_signal.compatibility_layer.dart';


/// The [AbortSignal] interface represents a signal object that allows you
/// to communicate with a DOM request (such as a fetch request) and abort it
/// if required via an [AbortController] object.
@JS()
@staticInterop
class AbortSignal {
/// Returns an [AbortSignal] instance that will automatically abort
/// after a specified [time].
factory AbortSignal.timeout(Duration time)
=> AbortSignal._timeout(time.inMilliseconds);

/// Returns an [AbortSignal] instance that is already set as aborted.
external static AbortSignal abort([dynamic reason]);

/// Returns an [AbortSignal] instance that will automatically abort
/// after a specified [time] in milliseconds.
@JS('timeout')
external static AbortSignal _timeout(int time);
}


extension AbortSignalInstanceMembers on AbortSignal {
/// A [bool] that indicates whether the request(s) the signal is
/// communicating with is/are aborted (`true`) or not (`false`).
external final bool aborted;

/// A JavaScript value providing the abort reason, once the signal has aborted.
external final dynamic reason;

/// Throws the signal's abort [reason] if the signal has been aborted;
/// otherwise it does nothing.
external void throwIfAborted();
}
116 changes: 1 addition & 115 deletions lib/src/headers.dart
Original file line number Diff line number Diff line change
@@ -1,115 +1 @@
import '_js.dart';
import 'iterator.dart' as js;
import 'iterator_wrapper.dart';
import 'response.dart';


/// The [Headers] interface of the Fetch API allows you to perform various
/// actions on HTTP request and response headers. These actions include
/// retrieving, setting, adding to, and removing headers from the list of
/// the request's headers.
///
/// A [Headers] object has an associated header list, which is initially empty
/// and consists of zero or more name and value pairs. You can add to this using
/// methods like `append()`. In all methods of this interface, header names are
/// matched by case-insensitive byte sequence.
///
/// For security reasons, some headers can only be controlled by the user agent.
/// These headers include the forbidden header names and forbidden response
/// header names.
///
/// A [Headers] object also has an associated guard, which takes
/// a value of `immutable`, `request`, `request-no-cors`, `response`, or `none`.
/// This affects whether the `set()`, `delete()`, and `append()` methods will
/// mutate the header.
///
/// You can retrieve a [Headers] object via the `Request.headers` and
/// [ResponseInstanceMembers.headers] properties, and create
/// a new [Headers] object using the `Headers()` constructor.
@JS()
@staticInterop
class Headers {
/// Creates a new [Headers] object.
@JS('Headers')
external factory Headers();

/// Creates a new [Headers] object.
@JS('Headers')
external factory Headers._init(dynamic init);

/// Warning: available only with Dart 3.0 or higher.
/// Creates [Headers] from [Map].
factory Headers.fromMap(Map<String, String> init) =>
headersFromMap(init);

/// Warning: available only with Dart 3.0 or higher.
/// Creates [Headers] from array of 2 items arrays.
factory Headers.fromArray(List<List<String>> init) =>
headersFromArray(init);
}

extension HeadersInstanceMembers on Headers {
/// Appends a new value onto an existing header inside a [Headers] object,
/// or adds the header if it does not already exist.
external void append(String name, String value);

/// Deletes a header from a [Headers] object.
external void delete(String name);

/// Returns an [js.Iterator] allowing to go through all key/value pairs
/// contained in this object.
@JS('entries')
external js.Iterator<List<String>> _entries();

// forEach()

/// Returns a [String] sequence of all the values of a header within
/// a [Headers] object with a given name.
external String? get(String name);

/// Returns a [bool] stating whether a [Headers] object contains
/// a certain header.
external bool has(String name);

/// Returns an [js.Iterator] allowing you to go through all keys of
/// the key/value pairs contained in this object.
@JS('keys')
external js.Iterator<String> _keys();

/// Sets a new value for an existing header inside a [Headers] object,
/// or adds the header if it does not already exist.
external void set(String name, String value);

/// Returns an [js.Iterator] allowing you to go through all values of
/// the key/value pairs contained in this object.
@JS('values')
external js.Iterator<String> _values();

/// Returns an [IteratorWrapper] allowing to go through all key/value pairs
/// contained in this object.
IteratorWrapper<List<String>> entries() => IteratorWrapper(_entries());

/// Returns an [IteratorWrapper] allowing you to go through all keys of the
/// key/value pairs contained in this object.
IteratorWrapper<String> keys() => IteratorWrapper(_keys());

/// Returns an [IteratorWrapper] allowing you to go through all values of
/// the key/value pairs contained in this object.
IteratorWrapper<String> values() => IteratorWrapper(_values());
}

/// Creates [Headers] from [Map].
Headers headersFromMap(Map<String, String> init) =>
Headers._init(init.toJsObject());

/// Creates [Headers] from array of 2 items arrays.
Headers headersFromArray(List<List<String>> init) {
final _init = JsArray<JsArray<dynamic>>();
for (final header in init) {
if (header.length != 2)
throw Exception('Bad argument');

_init.add(header.toJsArray());
}
return Headers._init(_init);
}
export 'headers/headers.dart' hide createHeadersFromArray, createHeadersFromMap;
18 changes: 18 additions & 0 deletions lib/src/headers/headers.compatibility_layer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
part of 'headers.dart';


/// Creates [Headers] from [Map].
Headers createHeadersFromMap(Map<String, String> init) =>
Headers._init(init.toJsObject());

/// Creates [Headers] from array of 2 items arrays.
Headers createHeadersFromArray(List<List<String>> init) {
final _init = JsArray<JsArray<dynamic>>();
for (final header in init) {
if (header.length != 2)
throw Exception('Bad argument');

_init.add(header.toJsArray());
}
return Headers._init(_init);
}
109 changes: 109 additions & 0 deletions lib/src/headers/headers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import '../_js.dart';
import '../iterator.dart' as js;
import '../iterator_wrapper.dart';
import '../response.dart';

part 'headers.compatibility_layer.dart';


/// The [Headers] interface of the Fetch API allows you to perform various
/// actions on HTTP request and response headers. These actions include
/// retrieving, setting, adding to, and removing headers from the list of
/// the request's headers.
///
/// A [Headers] object has an associated header list, which is initially empty
/// and consists of zero or more name and value pairs. You can add to this using
/// methods like `append()`. In all methods of this interface, header names are
/// matched by case-insensitive byte sequence.
///
/// For security reasons, some headers can only be controlled by the user agent.
/// These headers include the forbidden header names and forbidden response
/// header names.
///
/// A [Headers] object also has an associated guard, which takes
/// a value of `immutable`, `request`, `request-no-cors`, `response`, or `none`.
/// This affects whether the `set()`, `delete()`, and `append()` methods will
/// mutate the header.
///
/// You can retrieve a [Headers] object via the `Request.headers` and
/// [ResponseInstanceMembers.headers] properties, and create
/// a new [Headers] object using the `Headers()` constructor.
@JS()
@staticInterop
class Headers {
/// Creates a new [Headers] object.
@JS('Headers')
external factory Headers();

/// Creates a new [Headers] object.
@JS('Headers')
external factory Headers._init(dynamic init);

/// Warning: available only with Dart 3.0 or higher.
/// Creates [Headers] from [Map].
factory Headers.fromMap(Map<String, String> init) =>
Headers._init(init.toJsObject());

/// Warning: available only with Dart 3.0 or higher.
/// Creates [Headers] from array of 2 items arrays.
factory Headers.fromArray(List<List<String>> init) {
final _init = JsArray<JsArray<dynamic>>();
for (final header in init) {
if (header.length != 2)
throw Exception('Bad argument');

_init.add(header.toJsArray());
}
return Headers._init(_init);
}
}

extension HeadersInstanceMembers on Headers {
/// Appends a new value onto an existing header inside a [Headers] object,
/// or adds the header if it does not already exist.
external void append(String name, String value);

/// Deletes a header from a [Headers] object.
external void delete(String name);

/// Returns an [js.Iterator] allowing to go through all key/value pairs
/// contained in this object.
@JS('entries')
external js.Iterator<List<String>> _entries();

// forEach()

/// Returns a [String] sequence of all the values of a header within
/// a [Headers] object with a given name.
external String? get(String name);

/// Returns a [bool] stating whether a [Headers] object contains
/// a certain header.
external bool has(String name);

/// Returns an [js.Iterator] allowing you to go through all keys of
/// the key/value pairs contained in this object.
@JS('keys')
external js.Iterator<String> _keys();

/// Sets a new value for an existing header inside a [Headers] object,
/// or adds the header if it does not already exist.
external void set(String name, String value);

/// Returns an [js.Iterator] allowing you to go through all values of
/// the key/value pairs contained in this object.
@JS('values')
external js.Iterator<String> _values();

/// Returns an [IteratorWrapper] allowing to go through all key/value pairs
/// contained in this object.
IteratorWrapper<List<String>> entries() => IteratorWrapper(_entries());

/// Returns an [IteratorWrapper] allowing you to go through all keys of the
/// key/value pairs contained in this object.
IteratorWrapper<String> keys() => IteratorWrapper(_keys());

/// Returns an [IteratorWrapper] allowing you to go through all values of
/// the key/value pairs contained in this object.
IteratorWrapper<String> values() => IteratorWrapper(_values());
}
2 changes: 1 addition & 1 deletion lib/src/request_init.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export 'request_init/request_cache.dart';
export 'request_init/request_credentials.dart';
export 'request_init/request_init.dart';
export 'request_init/request_init.dart' hide createRequestInit;
export 'request_init/request_mode.dart';
export 'request_init/request_redirect.dart';
export 'request_init/request_referrer_policy.dart';
Loading

0 comments on commit 72e0fb0

Please sign in to comment.