update stream_transform example to package:web
Fixes a deprecation warning from the latest SDK.
diff --git a/pkgs/pubspec_parse/CHANGELOG.md b/pkgs/pubspec_parse/CHANGELOG.md
index 124b5e4..5aeb498 100644
--- a/pkgs/pubspec_parse/CHANGELOG.md
+++ b/pkgs/pubspec_parse/CHANGELOG.md
@@ -1,6 +1,6 @@
-## 1.5.0-wip
+## 1.5.0
-- Add `Pubspec.workspace` and `Pubspec.resolution` fields.
+- Added fields to `Pubspec`: `executables`, `resolution`, `workspace`.
- Require Dart 3.6
- Update dependencies.
diff --git a/pkgs/pubspec_parse/lib/src/pubspec.dart b/pkgs/pubspec_parse/lib/src/pubspec.dart
index cdfc8ff..eb77908 100644
--- a/pkgs/pubspec_parse/lib/src/pubspec.dart
+++ b/pkgs/pubspec_parse/lib/src/pubspec.dart
@@ -93,6 +93,10 @@
/// and other settings.
final Map<String, dynamic>? flutter;
+ /// Optional field to specify executables
+ @JsonKey(fromJson: _executablesMap)
+ final Map<String, String?> executables;
+
/// If this package is a Pub Workspace, this field lists the sub-packages.
final List<String>? workspace;
@@ -129,12 +133,14 @@
Map<String, Dependency>? devDependencies,
Map<String, Dependency>? dependencyOverrides,
this.flutter,
+ Map<String, String?>? executables,
}) :
// ignore: deprecated_member_use_from_same_package
authors = _normalizeAuthors(author, authors),
environment = environment ?? const {},
dependencies = dependencies ?? const {},
devDependencies = devDependencies ?? const {},
+ executables = executables ?? const {},
dependencyOverrides = dependencyOverrides ?? const {} {
if (name.isEmpty) {
throw ArgumentError.value(name, 'name', '"name" cannot be empty.');
@@ -232,3 +238,21 @@
return MapEntry(key, constraint);
}) ??
{};
+
+Map<String, String?> _executablesMap(Map? source) =>
+ source?.map((k, value) {
+ final key = k as String;
+ if (value == null) {
+ return MapEntry(key, null);
+ } else if (value is String) {
+ return MapEntry(key, value);
+ } else {
+ throw CheckedFromJsonException(
+ source,
+ key,
+ 'String',
+ '`$value` is not a String.',
+ );
+ }
+ }) ??
+ {};
diff --git a/pkgs/pubspec_parse/lib/src/pubspec.g.dart b/pkgs/pubspec_parse/lib/src/pubspec.g.dart
index f0fb79e..58e015a 100644
--- a/pkgs/pubspec_parse/lib/src/pubspec.g.dart
+++ b/pkgs/pubspec_parse/lib/src/pubspec.g.dart
@@ -54,6 +54,8 @@
(v) => (v as Map?)?.map(
(k, e) => MapEntry(k as String, e),
)),
+ executables:
+ $checkedConvert('executables', (v) => _executablesMap(v as Map?)),
);
return val;
},
diff --git a/pkgs/pubspec_parse/pubspec.yaml b/pkgs/pubspec_parse/pubspec.yaml
index 6bf96bb..73a1117 100644
--- a/pkgs/pubspec_parse/pubspec.yaml
+++ b/pkgs/pubspec_parse/pubspec.yaml
@@ -1,5 +1,5 @@
name: pubspec_parse
-version: 1.5.0-wip
+version: 1.5.0
description: >-
Simple package for parsing pubspec.yaml files with a type-safe API and rich
error reporting.
diff --git a/pkgs/pubspec_parse/test/parse_test.dart b/pkgs/pubspec_parse/test/parse_test.dart
index 5570b60..e0698af 100644
--- a/pkgs/pubspec_parse/test/parse_test.dart
+++ b/pkgs/pubspec_parse/test/parse_test.dart
@@ -34,6 +34,7 @@
expect(value.screenshots, isEmpty);
expect(value.workspace, isNull);
expect(value.resolution, isNull);
+ expect(value.executables, isEmpty);
});
test('all fields set', () async {
@@ -64,6 +65,10 @@
'pkg2',
],
'resolution': 'workspace',
+ 'executables': {
+ 'my_script': 'bin/my_script.dart',
+ 'my_script2': 'bin/my_script2.dart',
+ },
},
skipTryPub: true,
);
@@ -96,6 +101,11 @@
expect(value.screenshots, hasLength(1));
expect(value.screenshots!.first.description, 'my screenshot');
expect(value.screenshots!.first.path, 'path/to/screenshot');
+ expect(value.executables, hasLength(2));
+ expect(value.executables.keys, contains('my_script'));
+ expect(value.executables.keys, contains('my_script2'));
+ expect(value.executables['my_script'], 'bin/my_script.dart');
+ expect(value.executables['my_script2'], 'bin/my_script2.dart');
expect(value.workspace, hasLength(2));
expect(value.workspace!.first, 'pkg1');
expect(value.workspace!.last, 'pkg2');
@@ -222,6 +232,58 @@
});
});
+ group('executables', () {
+ test('one executable', () async {
+ final value = await parse({
+ ...defaultPubspec,
+ 'executables': {'my_script': 'bin/my_script.dart'},
+ });
+ expect(value.executables, hasLength(1));
+ expect(value.executables.keys, contains('my_script'));
+ expect(value.executables['my_script'], 'bin/my_script.dart');
+ });
+
+ test('many executables', () async {
+ final value = await parse({
+ ...defaultPubspec,
+ 'executables': {
+ 'my_script': 'bin/my_script.dart',
+ 'my_script2': 'bin/my_script2.dart',
+ },
+ });
+ expect(value.executables, hasLength(2));
+ expect(value.executables.keys, contains('my_script'));
+ expect(value.executables.keys, contains('my_script2'));
+ expect(value.executables['my_script'], 'bin/my_script.dart');
+ expect(value.executables['my_script2'], 'bin/my_script2.dart');
+ });
+
+ test('invalid value', () async {
+ expectParseThrowsContaining(
+ {
+ ...defaultPubspec,
+ 'executables': {
+ 'script': 32,
+ },
+ },
+ 'Unsupported value for "script". `32` is not a String.',
+ skipTryPub: true,
+ );
+ });
+
+ test('invalid executable - lenient', () async {
+ final value = await parse(
+ {
+ ...defaultPubspec,
+ 'executables': 'Invalid value',
+ },
+ lenient: true,
+ );
+ expect(value.name, 'sample');
+ expect(value.executables, isEmpty);
+ });
+ });
+
group('invalid', () {
test('null', () {
expectParseThrows(
diff --git a/pkgs/stream_channel/CHANGELOG.md b/pkgs/stream_channel/CHANGELOG.md
index 30f7d32..9dd3990 100644
--- a/pkgs/stream_channel/CHANGELOG.md
+++ b/pkgs/stream_channel/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.4
+
+* Fix `StreamChannelMixin` so that it can be used as a mixin again.
+
## 2.1.3
* Require Dart 3.3
diff --git a/pkgs/stream_channel/lib/stream_channel.dart b/pkgs/stream_channel/lib/stream_channel.dart
index 85f9a97..8e53096 100644
--- a/pkgs/stream_channel/lib/stream_channel.dart
+++ b/pkgs/stream_channel/lib/stream_channel.dart
@@ -148,7 +148,7 @@
/// A mixin that implements the instance methods of [StreamChannel] in terms of
/// [stream] and [sink].
-abstract class StreamChannelMixin<T> implements StreamChannel<T> {
+abstract mixin class StreamChannelMixin<T> implements StreamChannel<T> {
@override
void pipe(StreamChannel<T> other) {
stream.pipe(other.sink);
diff --git a/pkgs/stream_channel/pubspec.yaml b/pkgs/stream_channel/pubspec.yaml
index eec8c1b..f050fca 100644
--- a/pkgs/stream_channel/pubspec.yaml
+++ b/pkgs/stream_channel/pubspec.yaml
@@ -1,5 +1,5 @@
name: stream_channel
-version: 2.1.3
+version: 2.1.4
description: >-
An abstraction for two-way communication channels based on the Dart Stream
class.
diff --git a/pkgs/stream_channel/test/stream_channel_test.dart b/pkgs/stream_channel/test/stream_channel_test.dart
index c44b6ab..166671d 100644
--- a/pkgs/stream_channel/test/stream_channel_test.dart
+++ b/pkgs/stream_channel/test/stream_channel_test.dart
@@ -135,4 +135,46 @@
changed.sink.add(10);
changed.sink.close();
});
+
+ group('StreamChannelMixin', () {
+ test('can be used as a mixin', () async {
+ var channel = StreamChannelMixinAsMixin<int>();
+ expect(channel.stream, emitsInOrder([1, 2, 3]));
+ channel.sink
+ ..add(1)
+ ..add(2)
+ ..add(3);
+ await channel.controller.close();
+ });
+
+ test('can be extended', () async {
+ var channel = StreamChannelMixinAsSuperclass<int>();
+ expect(channel.stream, emitsInOrder([1, 2, 3]));
+ channel.sink
+ ..add(1)
+ ..add(2)
+ ..add(3);
+ await channel.controller.close();
+ });
+ });
+}
+
+class StreamChannelMixinAsMixin<T> with StreamChannelMixin<T> {
+ final controller = StreamController<T>();
+
+ @override
+ StreamSink<T> get sink => controller.sink;
+
+ @override
+ Stream<T> get stream => controller.stream;
+}
+
+class StreamChannelMixinAsSuperclass<T> extends StreamChannelMixin<T> {
+ final controller = StreamController<T>();
+
+ @override
+ StreamSink<T> get sink => controller.sink;
+
+ @override
+ Stream<T> get stream => controller.stream;
}