Skip to content

Commit 72e0fb0

Browse files
committed
feat: add compatibility_layer library
1 parent 5cb7445 commit 72e0fb0

12 files changed

Lines changed: 235 additions & 154 deletions

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## 1.0.0-dev.3
22
- **BREAKING**: Renamed extensions from `<Class>Extension` to `<Class>InstanceMembers`.
3+
- Added `fetch_api.compatibility_layer` library to support Dart 2.19.
4+
- Added `createHeadersFromMap`
5+
- Added `createHeadersFromArray`
6+
- Added `createRequestInit`
7+
- Added `createAbortSignalTimeout`
8+
39
- `AbortSignal`
410
- Added `timeout` constructor-like method.
511
- Added `abort` constructor-like method.
@@ -14,7 +20,6 @@
1420
- Added docs.
1521
- `Headers`
1622
- Added docs.
17-
- Add methods `headersFromMap` and `headersFromArray` to support Dart 2.19.
1823
- `Iterator` and `IteratorResult`
1924
- Added docs.
2025
- `ReadableStreamDefaultReader` and `ReadableStreamDefaultReaderChunk`

lib/compatibility_layer.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/// Dart 1.19 compatibility layer.
2+
///
3+
/// Provides [createHeadersFromArray], [createHeadersFromMap],
4+
/// [createAbortSignalTimeout] and [createRequestInit] functions, in replacement
5+
/// of unsupported [Headers.fromArray], [Headers.fromMap], [AbortSignal.timeout]
6+
/// and [RequestInit] respectively.
7+
library fetch_api.compatibility_layer;
8+
9+
import 'src/abort_signal/abort_signal.dart';
10+
import 'src/headers/headers.dart';
11+
import 'src/request_init/request_init.dart';
12+
13+
export 'src/abort_signal/abort_signal.dart' show createAbortSignalTimeout;
14+
export 'src/headers/headers.dart' show createHeadersFromArray, createHeadersFromMap;
15+
export 'src/request_init/request_init.dart' show createRequestInit;

lib/fetch_api.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/// The Fetch API provides an interface for fetching resources
2+
/// (including across the network). It will seem familiar to anyone who has used
3+
/// `XMLHttpRequest`, but the new API provides a more powerful and flexible
4+
/// feature set.
5+
library fetch_api;
6+
17
export 'src/abort_controller.dart';
28
export 'src/abort_signal.dart';
39
export 'src/fetch.dart';

lib/src/abort_signal.dart

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1 @@
1-
import '_js.dart';
2-
import 'abort_controller.dart';
3-
4-
5-
/// The [AbortSignal] interface represents a signal object that allows you
6-
/// to communicate with a DOM request (such as a fetch request) and abort it
7-
/// if required via an [AbortController] object.
8-
@JS()
9-
@staticInterop
10-
class AbortSignal {
11-
/// Returns an [AbortSignal] instance that will automatically abort
12-
/// after a specified [time].
13-
factory AbortSignal.timeout(Duration time)
14-
=> AbortSignal._timeout(time.inMilliseconds);
15-
16-
/// Returns an [AbortSignal] instance that is already set as aborted.
17-
external static AbortSignal abort([dynamic reason]);
18-
19-
/// Returns an [AbortSignal] instance that will automatically abort
20-
/// after a specified [time] in milliseconds.
21-
@JS('timeout')
22-
external static AbortSignal _timeout(int time);
23-
}
24-
25-
26-
extension AbortSignalInstanceMembers on AbortSignal {
27-
/// A [bool] that indicates whether the request(s) the signal is
28-
/// communicating with is/are aborted (`true`) or not (`false`).
29-
external final bool aborted;
30-
31-
/// A JavaScript value providing the abort reason, once the signal has aborted.
32-
external final dynamic reason;
33-
34-
/// Throws the signal's abort [reason] if the signal has been aborted;
35-
/// otherwise it does nothing.
36-
external void throwIfAborted();
37-
}
1+
export 'abort_signal/abort_signal.dart' hide createAbortSignalTimeout;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
part of 'abort_signal.dart';
2+
3+
4+
/// Returns an [AbortSignal] instance that will automatically abort
5+
/// after a specified [time].
6+
AbortSignal createAbortSignalTimeout(Duration time)
7+
=> AbortSignal._timeout(time.inMilliseconds);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import '../_js.dart';
2+
import '../abort_controller.dart';
3+
4+
part 'abort_signal.compatibility_layer.dart';
5+
6+
7+
/// The [AbortSignal] interface represents a signal object that allows you
8+
/// to communicate with a DOM request (such as a fetch request) and abort it
9+
/// if required via an [AbortController] object.
10+
@JS()
11+
@staticInterop
12+
class AbortSignal {
13+
/// Returns an [AbortSignal] instance that will automatically abort
14+
/// after a specified [time].
15+
factory AbortSignal.timeout(Duration time)
16+
=> AbortSignal._timeout(time.inMilliseconds);
17+
18+
/// Returns an [AbortSignal] instance that is already set as aborted.
19+
external static AbortSignal abort([dynamic reason]);
20+
21+
/// Returns an [AbortSignal] instance that will automatically abort
22+
/// after a specified [time] in milliseconds.
23+
@JS('timeout')
24+
external static AbortSignal _timeout(int time);
25+
}
26+
27+
28+
extension AbortSignalInstanceMembers on AbortSignal {
29+
/// A [bool] that indicates whether the request(s) the signal is
30+
/// communicating with is/are aborted (`true`) or not (`false`).
31+
external final bool aborted;
32+
33+
/// A JavaScript value providing the abort reason, once the signal has aborted.
34+
external final dynamic reason;
35+
36+
/// Throws the signal's abort [reason] if the signal has been aborted;
37+
/// otherwise it does nothing.
38+
external void throwIfAborted();
39+
}

lib/src/headers.dart

Lines changed: 1 addition & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1 @@
1-
import '_js.dart';
2-
import 'iterator.dart' as js;
3-
import 'iterator_wrapper.dart';
4-
import 'response.dart';
5-
6-
7-
/// The [Headers] interface of the Fetch API allows you to perform various
8-
/// actions on HTTP request and response headers. These actions include
9-
/// retrieving, setting, adding to, and removing headers from the list of
10-
/// the request's headers.
11-
///
12-
/// A [Headers] object has an associated header list, which is initially empty
13-
/// and consists of zero or more name and value pairs. You can add to this using
14-
/// methods like `append()`. In all methods of this interface, header names are
15-
/// matched by case-insensitive byte sequence.
16-
///
17-
/// For security reasons, some headers can only be controlled by the user agent.
18-
/// These headers include the forbidden header names and forbidden response
19-
/// header names.
20-
///
21-
/// A [Headers] object also has an associated guard, which takes
22-
/// a value of `immutable`, `request`, `request-no-cors`, `response`, or `none`.
23-
/// This affects whether the `set()`, `delete()`, and `append()` methods will
24-
/// mutate the header.
25-
///
26-
/// You can retrieve a [Headers] object via the `Request.headers` and
27-
/// [ResponseInstanceMembers.headers] properties, and create
28-
/// a new [Headers] object using the `Headers()` constructor.
29-
@JS()
30-
@staticInterop
31-
class Headers {
32-
/// Creates a new [Headers] object.
33-
@JS('Headers')
34-
external factory Headers();
35-
36-
/// Creates a new [Headers] object.
37-
@JS('Headers')
38-
external factory Headers._init(dynamic init);
39-
40-
/// Warning: available only with Dart 3.0 or higher.
41-
/// Creates [Headers] from [Map].
42-
factory Headers.fromMap(Map<String, String> init) =>
43-
headersFromMap(init);
44-
45-
/// Warning: available only with Dart 3.0 or higher.
46-
/// Creates [Headers] from array of 2 items arrays.
47-
factory Headers.fromArray(List<List<String>> init) =>
48-
headersFromArray(init);
49-
}
50-
51-
extension HeadersInstanceMembers on Headers {
52-
/// Appends a new value onto an existing header inside a [Headers] object,
53-
/// or adds the header if it does not already exist.
54-
external void append(String name, String value);
55-
56-
/// Deletes a header from a [Headers] object.
57-
external void delete(String name);
58-
59-
/// Returns an [js.Iterator] allowing to go through all key/value pairs
60-
/// contained in this object.
61-
@JS('entries')
62-
external js.Iterator<List<String>> _entries();
63-
64-
// forEach()
65-
66-
/// Returns a [String] sequence of all the values of a header within
67-
/// a [Headers] object with a given name.
68-
external String? get(String name);
69-
70-
/// Returns a [bool] stating whether a [Headers] object contains
71-
/// a certain header.
72-
external bool has(String name);
73-
74-
/// Returns an [js.Iterator] allowing you to go through all keys of
75-
/// the key/value pairs contained in this object.
76-
@JS('keys')
77-
external js.Iterator<String> _keys();
78-
79-
/// Sets a new value for an existing header inside a [Headers] object,
80-
/// or adds the header if it does not already exist.
81-
external void set(String name, String value);
82-
83-
/// Returns an [js.Iterator] allowing you to go through all values of
84-
/// the key/value pairs contained in this object.
85-
@JS('values')
86-
external js.Iterator<String> _values();
87-
88-
/// Returns an [IteratorWrapper] allowing to go through all key/value pairs
89-
/// contained in this object.
90-
IteratorWrapper<List<String>> entries() => IteratorWrapper(_entries());
91-
92-
/// Returns an [IteratorWrapper] allowing you to go through all keys of the
93-
/// key/value pairs contained in this object.
94-
IteratorWrapper<String> keys() => IteratorWrapper(_keys());
95-
96-
/// Returns an [IteratorWrapper] allowing you to go through all values of
97-
/// the key/value pairs contained in this object.
98-
IteratorWrapper<String> values() => IteratorWrapper(_values());
99-
}
100-
101-
/// Creates [Headers] from [Map].
102-
Headers headersFromMap(Map<String, String> init) =>
103-
Headers._init(init.toJsObject());
104-
105-
/// Creates [Headers] from array of 2 items arrays.
106-
Headers headersFromArray(List<List<String>> init) {
107-
final _init = JsArray<JsArray<dynamic>>();
108-
for (final header in init) {
109-
if (header.length != 2)
110-
throw Exception('Bad argument');
111-
112-
_init.add(header.toJsArray());
113-
}
114-
return Headers._init(_init);
115-
}
1+
export 'headers/headers.dart' hide createHeadersFromArray, createHeadersFromMap;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
part of 'headers.dart';
2+
3+
4+
/// Creates [Headers] from [Map].
5+
Headers createHeadersFromMap(Map<String, String> init) =>
6+
Headers._init(init.toJsObject());
7+
8+
/// Creates [Headers] from array of 2 items arrays.
9+
Headers createHeadersFromArray(List<List<String>> init) {
10+
final _init = JsArray<JsArray<dynamic>>();
11+
for (final header in init) {
12+
if (header.length != 2)
13+
throw Exception('Bad argument');
14+
15+
_init.add(header.toJsArray());
16+
}
17+
return Headers._init(_init);
18+
}

lib/src/headers/headers.dart

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import '../_js.dart';
2+
import '../iterator.dart' as js;
3+
import '../iterator_wrapper.dart';
4+
import '../response.dart';
5+
6+
part 'headers.compatibility_layer.dart';
7+
8+
9+
/// The [Headers] interface of the Fetch API allows you to perform various
10+
/// actions on HTTP request and response headers. These actions include
11+
/// retrieving, setting, adding to, and removing headers from the list of
12+
/// the request's headers.
13+
///
14+
/// A [Headers] object has an associated header list, which is initially empty
15+
/// and consists of zero or more name and value pairs. You can add to this using
16+
/// methods like `append()`. In all methods of this interface, header names are
17+
/// matched by case-insensitive byte sequence.
18+
///
19+
/// For security reasons, some headers can only be controlled by the user agent.
20+
/// These headers include the forbidden header names and forbidden response
21+
/// header names.
22+
///
23+
/// A [Headers] object also has an associated guard, which takes
24+
/// a value of `immutable`, `request`, `request-no-cors`, `response`, or `none`.
25+
/// This affects whether the `set()`, `delete()`, and `append()` methods will
26+
/// mutate the header.
27+
///
28+
/// You can retrieve a [Headers] object via the `Request.headers` and
29+
/// [ResponseInstanceMembers.headers] properties, and create
30+
/// a new [Headers] object using the `Headers()` constructor.
31+
@JS()
32+
@staticInterop
33+
class Headers {
34+
/// Creates a new [Headers] object.
35+
@JS('Headers')
36+
external factory Headers();
37+
38+
/// Creates a new [Headers] object.
39+
@JS('Headers')
40+
external factory Headers._init(dynamic init);
41+
42+
/// Warning: available only with Dart 3.0 or higher.
43+
/// Creates [Headers] from [Map].
44+
factory Headers.fromMap(Map<String, String> init) =>
45+
Headers._init(init.toJsObject());
46+
47+
/// Warning: available only with Dart 3.0 or higher.
48+
/// Creates [Headers] from array of 2 items arrays.
49+
factory Headers.fromArray(List<List<String>> init) {
50+
final _init = JsArray<JsArray<dynamic>>();
51+
for (final header in init) {
52+
if (header.length != 2)
53+
throw Exception('Bad argument');
54+
55+
_init.add(header.toJsArray());
56+
}
57+
return Headers._init(_init);
58+
}
59+
}
60+
61+
extension HeadersInstanceMembers on Headers {
62+
/// Appends a new value onto an existing header inside a [Headers] object,
63+
/// or adds the header if it does not already exist.
64+
external void append(String name, String value);
65+
66+
/// Deletes a header from a [Headers] object.
67+
external void delete(String name);
68+
69+
/// Returns an [js.Iterator] allowing to go through all key/value pairs
70+
/// contained in this object.
71+
@JS('entries')
72+
external js.Iterator<List<String>> _entries();
73+
74+
// forEach()
75+
76+
/// Returns a [String] sequence of all the values of a header within
77+
/// a [Headers] object with a given name.
78+
external String? get(String name);
79+
80+
/// Returns a [bool] stating whether a [Headers] object contains
81+
/// a certain header.
82+
external bool has(String name);
83+
84+
/// Returns an [js.Iterator] allowing you to go through all keys of
85+
/// the key/value pairs contained in this object.
86+
@JS('keys')
87+
external js.Iterator<String> _keys();
88+
89+
/// Sets a new value for an existing header inside a [Headers] object,
90+
/// or adds the header if it does not already exist.
91+
external void set(String name, String value);
92+
93+
/// Returns an [js.Iterator] allowing you to go through all values of
94+
/// the key/value pairs contained in this object.
95+
@JS('values')
96+
external js.Iterator<String> _values();
97+
98+
/// Returns an [IteratorWrapper] allowing to go through all key/value pairs
99+
/// contained in this object.
100+
IteratorWrapper<List<String>> entries() => IteratorWrapper(_entries());
101+
102+
/// Returns an [IteratorWrapper] allowing you to go through all keys of the
103+
/// key/value pairs contained in this object.
104+
IteratorWrapper<String> keys() => IteratorWrapper(_keys());
105+
106+
/// Returns an [IteratorWrapper] allowing you to go through all values of
107+
/// the key/value pairs contained in this object.
108+
IteratorWrapper<String> values() => IteratorWrapper(_values());
109+
}

lib/src/request_init.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export 'request_init/request_cache.dart';
22
export 'request_init/request_credentials.dart';
3-
export 'request_init/request_init.dart';
3+
export 'request_init/request_init.dart' hide createRequestInit;
44
export 'request_init/request_mode.dart';
55
export 'request_init/request_redirect.dart';
66
export 'request_init/request_referrer_policy.dart';

0 commit comments

Comments
 (0)