From db8d269944d44ebf2f3a5e4a5c554aac2804b6a5 Mon Sep 17 00:00:00 2001 From: Cody Date: Tue, 10 Mar 2026 19:22:58 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E7=BB=9C=20SDK=20=E5=8C=85=E5=90=AB?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=84=9A=E6=9C=AC=EF=BC=8C=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=EF=BC=8C=E9=9A=94=E7=A6=BB=20pre-co?= =?UTF-8?q?mmit=20=E8=84=9A=E6=9C=AC=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/networks_sdk/.gitignore | 4 + .../domain/entities/api_error.freezed.dart | 572 ++++++++++++++++ .../domain/entities/socket_error.freezed.dart | 642 ++++++++++++++++++ packages/networks_sdk/pubspec.yaml | 2 +- packages/networks_sdk/scripts/gen.sh | 30 + pubspec.lock | 207 ------ scripts/pre-commit | 63 +- 7 files changed, 1294 insertions(+), 226 deletions(-) create mode 100644 packages/networks_sdk/lib/src/domain/entities/api_error.freezed.dart create mode 100644 packages/networks_sdk/lib/src/domain/entities/socket_error.freezed.dart create mode 100755 packages/networks_sdk/scripts/gen.sh diff --git a/packages/networks_sdk/.gitignore b/packages/networks_sdk/.gitignore index b9d7f25..378d3b2 100644 --- a/packages/networks_sdk/.gitignore +++ b/packages/networks_sdk/.gitignore @@ -31,3 +31,7 @@ migrate_working_dir/ .flutter-plugins-dependencies /build/ /coverage/ + +# Generated files are committed so git-tag consumers can build without running build_runner +!*.g.dart +!*.freezed.dart diff --git a/packages/networks_sdk/lib/src/domain/entities/api_error.freezed.dart b/packages/networks_sdk/lib/src/domain/entities/api_error.freezed.dart new file mode 100644 index 0000000..6c93c5f --- /dev/null +++ b/packages/networks_sdk/lib/src/domain/entities/api_error.freezed.dart @@ -0,0 +1,572 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'api_error.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$ApiError { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ApiError); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ApiError()'; +} + + +} + +/// @nodoc +class $ApiErrorCopyWith<$Res> { +$ApiErrorCopyWith(ApiError _, $Res Function(ApiError) __); +} + + +/// Adds pattern-matching-related methods to [ApiError]. +extension ApiErrorPatterns on ApiError { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _NoNetworkConnection value)? noNetworkConnection,TResult Function( _Timeout value)? timeout,TResult Function( _NetworkError value)? networkError,TResult Function( _DecodingError value)? decodingError,TResult Function( _ApiError value)? apiError,TResult Function( _Cancelled value)? cancelled,TResult Function( _Unknown value)? unknown,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _NoNetworkConnection() when noNetworkConnection != null: +return noNetworkConnection(_that);case _Timeout() when timeout != null: +return timeout(_that);case _NetworkError() when networkError != null: +return networkError(_that);case _DecodingError() when decodingError != null: +return decodingError(_that);case _ApiError() when apiError != null: +return apiError(_that);case _Cancelled() when cancelled != null: +return cancelled(_that);case _Unknown() when unknown != null: +return unknown(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _NoNetworkConnection value) noNetworkConnection,required TResult Function( _Timeout value) timeout,required TResult Function( _NetworkError value) networkError,required TResult Function( _DecodingError value) decodingError,required TResult Function( _ApiError value) apiError,required TResult Function( _Cancelled value) cancelled,required TResult Function( _Unknown value) unknown,}){ +final _that = this; +switch (_that) { +case _NoNetworkConnection(): +return noNetworkConnection(_that);case _Timeout(): +return timeout(_that);case _NetworkError(): +return networkError(_that);case _DecodingError(): +return decodingError(_that);case _ApiError(): +return apiError(_that);case _Cancelled(): +return cancelled(_that);case _Unknown(): +return unknown(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _NoNetworkConnection value)? noNetworkConnection,TResult? Function( _Timeout value)? timeout,TResult? Function( _NetworkError value)? networkError,TResult? Function( _DecodingError value)? decodingError,TResult? Function( _ApiError value)? apiError,TResult? Function( _Cancelled value)? cancelled,TResult? Function( _Unknown value)? unknown,}){ +final _that = this; +switch (_that) { +case _NoNetworkConnection() when noNetworkConnection != null: +return noNetworkConnection(_that);case _Timeout() when timeout != null: +return timeout(_that);case _NetworkError() when networkError != null: +return networkError(_that);case _DecodingError() when decodingError != null: +return decodingError(_that);case _ApiError() when apiError != null: +return apiError(_that);case _Cancelled() when cancelled != null: +return cancelled(_that);case _Unknown() when unknown != null: +return unknown(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function()? noNetworkConnection,TResult Function()? timeout,TResult Function( String message)? networkError,TResult Function( String message)? decodingError,TResult Function( int code, String message)? apiError,TResult Function()? cancelled,TResult Function( String? message)? unknown,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _NoNetworkConnection() when noNetworkConnection != null: +return noNetworkConnection();case _Timeout() when timeout != null: +return timeout();case _NetworkError() when networkError != null: +return networkError(_that.message);case _DecodingError() when decodingError != null: +return decodingError(_that.message);case _ApiError() when apiError != null: +return apiError(_that.code,_that.message);case _Cancelled() when cancelled != null: +return cancelled();case _Unknown() when unknown != null: +return unknown(_that.message);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function() noNetworkConnection,required TResult Function() timeout,required TResult Function( String message) networkError,required TResult Function( String message) decodingError,required TResult Function( int code, String message) apiError,required TResult Function() cancelled,required TResult Function( String? message) unknown,}) {final _that = this; +switch (_that) { +case _NoNetworkConnection(): +return noNetworkConnection();case _Timeout(): +return timeout();case _NetworkError(): +return networkError(_that.message);case _DecodingError(): +return decodingError(_that.message);case _ApiError(): +return apiError(_that.code,_that.message);case _Cancelled(): +return cancelled();case _Unknown(): +return unknown(_that.message);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function()? noNetworkConnection,TResult? Function()? timeout,TResult? Function( String message)? networkError,TResult? Function( String message)? decodingError,TResult? Function( int code, String message)? apiError,TResult? Function()? cancelled,TResult? Function( String? message)? unknown,}) {final _that = this; +switch (_that) { +case _NoNetworkConnection() when noNetworkConnection != null: +return noNetworkConnection();case _Timeout() when timeout != null: +return timeout();case _NetworkError() when networkError != null: +return networkError(_that.message);case _DecodingError() when decodingError != null: +return decodingError(_that.message);case _ApiError() when apiError != null: +return apiError(_that.code,_that.message);case _Cancelled() when cancelled != null: +return cancelled();case _Unknown() when unknown != null: +return unknown(_that.message);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _NoNetworkConnection implements ApiError { + const _NoNetworkConnection(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _NoNetworkConnection); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ApiError.noNetworkConnection()'; +} + + +} + + + + +/// @nodoc + + +class _Timeout implements ApiError { + const _Timeout(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Timeout); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ApiError.timeout()'; +} + + +} + + + + +/// @nodoc + + +class _NetworkError implements ApiError { + const _NetworkError(this.message); + + + final String message; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$NetworkErrorCopyWith<_NetworkError> get copyWith => __$NetworkErrorCopyWithImpl<_NetworkError>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _NetworkError&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'ApiError.networkError(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$NetworkErrorCopyWith<$Res> implements $ApiErrorCopyWith<$Res> { + factory _$NetworkErrorCopyWith(_NetworkError value, $Res Function(_NetworkError) _then) = __$NetworkErrorCopyWithImpl; +@useResult +$Res call({ + String message +}); + + + + +} +/// @nodoc +class __$NetworkErrorCopyWithImpl<$Res> + implements _$NetworkErrorCopyWith<$Res> { + __$NetworkErrorCopyWithImpl(this._self, this._then); + + final _NetworkError _self; + final $Res Function(_NetworkError) _then; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = null,}) { + return _then(_NetworkError( +null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _DecodingError implements ApiError { + const _DecodingError(this.message); + + + final String message; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$DecodingErrorCopyWith<_DecodingError> get copyWith => __$DecodingErrorCopyWithImpl<_DecodingError>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _DecodingError&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'ApiError.decodingError(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$DecodingErrorCopyWith<$Res> implements $ApiErrorCopyWith<$Res> { + factory _$DecodingErrorCopyWith(_DecodingError value, $Res Function(_DecodingError) _then) = __$DecodingErrorCopyWithImpl; +@useResult +$Res call({ + String message +}); + + + + +} +/// @nodoc +class __$DecodingErrorCopyWithImpl<$Res> + implements _$DecodingErrorCopyWith<$Res> { + __$DecodingErrorCopyWithImpl(this._self, this._then); + + final _DecodingError _self; + final $Res Function(_DecodingError) _then; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = null,}) { + return _then(_DecodingError( +null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _ApiError implements ApiError { + const _ApiError({required this.code, required this.message}); + + + final int code; + final String message; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ApiErrorCopyWith<_ApiError> get copyWith => __$ApiErrorCopyWithImpl<_ApiError>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ApiError&&(identical(other.code, code) || other.code == code)&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,code,message); + +@override +String toString() { + return 'ApiError.apiError(code: $code, message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$ApiErrorCopyWith<$Res> implements $ApiErrorCopyWith<$Res> { + factory _$ApiErrorCopyWith(_ApiError value, $Res Function(_ApiError) _then) = __$ApiErrorCopyWithImpl; +@useResult +$Res call({ + int code, String message +}); + + + + +} +/// @nodoc +class __$ApiErrorCopyWithImpl<$Res> + implements _$ApiErrorCopyWith<$Res> { + __$ApiErrorCopyWithImpl(this._self, this._then); + + final _ApiError _self; + final $Res Function(_ApiError) _then; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? code = null,Object? message = null,}) { + return _then(_ApiError( +code: null == code ? _self.code : code // ignore: cast_nullable_to_non_nullable +as int,message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _Cancelled implements ApiError { + const _Cancelled(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Cancelled); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'ApiError.cancelled()'; +} + + +} + + + + +/// @nodoc + + +class _Unknown implements ApiError { + const _Unknown(this.message); + + + final String? message; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UnknownCopyWith<_Unknown> get copyWith => __$UnknownCopyWithImpl<_Unknown>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Unknown&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'ApiError.unknown(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$UnknownCopyWith<$Res> implements $ApiErrorCopyWith<$Res> { + factory _$UnknownCopyWith(_Unknown value, $Res Function(_Unknown) _then) = __$UnknownCopyWithImpl; +@useResult +$Res call({ + String? message +}); + + + + +} +/// @nodoc +class __$UnknownCopyWithImpl<$Res> + implements _$UnknownCopyWith<$Res> { + __$UnknownCopyWithImpl(this._self, this._then); + + final _Unknown _self; + final $Res Function(_Unknown) _then; + +/// Create a copy of ApiError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = freezed,}) { + return _then(_Unknown( +freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/packages/networks_sdk/lib/src/domain/entities/socket_error.freezed.dart b/packages/networks_sdk/lib/src/domain/entities/socket_error.freezed.dart new file mode 100644 index 0000000..7db7e4a --- /dev/null +++ b/packages/networks_sdk/lib/src/domain/entities/socket_error.freezed.dart @@ -0,0 +1,642 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'socket_error.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; +/// @nodoc +mixin _$SocketError { + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SocketError); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'SocketError()'; +} + + +} + +/// @nodoc +class $SocketErrorCopyWith<$Res> { +$SocketErrorCopyWith(SocketError _, $Res Function(SocketError) __); +} + + +/// Adds pattern-matching-related methods to [SocketError]. +extension SocketErrorPatterns on SocketError { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap({TResult Function( _ConnectionFailed value)? connectionFailed,TResult Function( _ConnectionTimeout value)? connectionTimeout,TResult Function( _Disconnected value)? disconnected,TResult Function( _PingTimeout value)? pingTimeout,TResult Function( _NetworkUnavailable value)? networkUnavailable,TResult Function( _InvalidURL value)? invalidURL,TResult Function( _SendFailed value)? sendFailed,TResult Function( _Unknown value)? unknown,required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ConnectionFailed() when connectionFailed != null: +return connectionFailed(_that);case _ConnectionTimeout() when connectionTimeout != null: +return connectionTimeout(_that);case _Disconnected() when disconnected != null: +return disconnected(_that);case _PingTimeout() when pingTimeout != null: +return pingTimeout(_that);case _NetworkUnavailable() when networkUnavailable != null: +return networkUnavailable(_that);case _InvalidURL() when invalidURL != null: +return invalidURL(_that);case _SendFailed() when sendFailed != null: +return sendFailed(_that);case _Unknown() when unknown != null: +return unknown(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map({required TResult Function( _ConnectionFailed value) connectionFailed,required TResult Function( _ConnectionTimeout value) connectionTimeout,required TResult Function( _Disconnected value) disconnected,required TResult Function( _PingTimeout value) pingTimeout,required TResult Function( _NetworkUnavailable value) networkUnavailable,required TResult Function( _InvalidURL value) invalidURL,required TResult Function( _SendFailed value) sendFailed,required TResult Function( _Unknown value) unknown,}){ +final _that = this; +switch (_that) { +case _ConnectionFailed(): +return connectionFailed(_that);case _ConnectionTimeout(): +return connectionTimeout(_that);case _Disconnected(): +return disconnected(_that);case _PingTimeout(): +return pingTimeout(_that);case _NetworkUnavailable(): +return networkUnavailable(_that);case _InvalidURL(): +return invalidURL(_that);case _SendFailed(): +return sendFailed(_that);case _Unknown(): +return unknown(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull({TResult? Function( _ConnectionFailed value)? connectionFailed,TResult? Function( _ConnectionTimeout value)? connectionTimeout,TResult? Function( _Disconnected value)? disconnected,TResult? Function( _PingTimeout value)? pingTimeout,TResult? Function( _NetworkUnavailable value)? networkUnavailable,TResult? Function( _InvalidURL value)? invalidURL,TResult? Function( _SendFailed value)? sendFailed,TResult? Function( _Unknown value)? unknown,}){ +final _that = this; +switch (_that) { +case _ConnectionFailed() when connectionFailed != null: +return connectionFailed(_that);case _ConnectionTimeout() when connectionTimeout != null: +return connectionTimeout(_that);case _Disconnected() when disconnected != null: +return disconnected(_that);case _PingTimeout() when pingTimeout != null: +return pingTimeout(_that);case _NetworkUnavailable() when networkUnavailable != null: +return networkUnavailable(_that);case _InvalidURL() when invalidURL != null: +return invalidURL(_that);case _SendFailed() when sendFailed != null: +return sendFailed(_that);case _Unknown() when unknown != null: +return unknown(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen({TResult Function( String message)? connectionFailed,TResult Function()? connectionTimeout,TResult Function( String? reason)? disconnected,TResult Function()? pingTimeout,TResult Function()? networkUnavailable,TResult Function( String url)? invalidURL,TResult Function( String message)? sendFailed,TResult Function( String? message)? unknown,required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ConnectionFailed() when connectionFailed != null: +return connectionFailed(_that.message);case _ConnectionTimeout() when connectionTimeout != null: +return connectionTimeout();case _Disconnected() when disconnected != null: +return disconnected(_that.reason);case _PingTimeout() when pingTimeout != null: +return pingTimeout();case _NetworkUnavailable() when networkUnavailable != null: +return networkUnavailable();case _InvalidURL() when invalidURL != null: +return invalidURL(_that.url);case _SendFailed() when sendFailed != null: +return sendFailed(_that.message);case _Unknown() when unknown != null: +return unknown(_that.message);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when({required TResult Function( String message) connectionFailed,required TResult Function() connectionTimeout,required TResult Function( String? reason) disconnected,required TResult Function() pingTimeout,required TResult Function() networkUnavailable,required TResult Function( String url) invalidURL,required TResult Function( String message) sendFailed,required TResult Function( String? message) unknown,}) {final _that = this; +switch (_that) { +case _ConnectionFailed(): +return connectionFailed(_that.message);case _ConnectionTimeout(): +return connectionTimeout();case _Disconnected(): +return disconnected(_that.reason);case _PingTimeout(): +return pingTimeout();case _NetworkUnavailable(): +return networkUnavailable();case _InvalidURL(): +return invalidURL(_that.url);case _SendFailed(): +return sendFailed(_that.message);case _Unknown(): +return unknown(_that.message);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull({TResult? Function( String message)? connectionFailed,TResult? Function()? connectionTimeout,TResult? Function( String? reason)? disconnected,TResult? Function()? pingTimeout,TResult? Function()? networkUnavailable,TResult? Function( String url)? invalidURL,TResult? Function( String message)? sendFailed,TResult? Function( String? message)? unknown,}) {final _that = this; +switch (_that) { +case _ConnectionFailed() when connectionFailed != null: +return connectionFailed(_that.message);case _ConnectionTimeout() when connectionTimeout != null: +return connectionTimeout();case _Disconnected() when disconnected != null: +return disconnected(_that.reason);case _PingTimeout() when pingTimeout != null: +return pingTimeout();case _NetworkUnavailable() when networkUnavailable != null: +return networkUnavailable();case _InvalidURL() when invalidURL != null: +return invalidURL(_that.url);case _SendFailed() when sendFailed != null: +return sendFailed(_that.message);case _Unknown() when unknown != null: +return unknown(_that.message);case _: + return null; + +} +} + +} + +/// @nodoc + + +class _ConnectionFailed implements SocketError { + const _ConnectionFailed(this.message); + + + final String message; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ConnectionFailedCopyWith<_ConnectionFailed> get copyWith => __$ConnectionFailedCopyWithImpl<_ConnectionFailed>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ConnectionFailed&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'SocketError.connectionFailed(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$ConnectionFailedCopyWith<$Res> implements $SocketErrorCopyWith<$Res> { + factory _$ConnectionFailedCopyWith(_ConnectionFailed value, $Res Function(_ConnectionFailed) _then) = __$ConnectionFailedCopyWithImpl; +@useResult +$Res call({ + String message +}); + + + + +} +/// @nodoc +class __$ConnectionFailedCopyWithImpl<$Res> + implements _$ConnectionFailedCopyWith<$Res> { + __$ConnectionFailedCopyWithImpl(this._self, this._then); + + final _ConnectionFailed _self; + final $Res Function(_ConnectionFailed) _then; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = null,}) { + return _then(_ConnectionFailed( +null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _ConnectionTimeout implements SocketError { + const _ConnectionTimeout(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ConnectionTimeout); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'SocketError.connectionTimeout()'; +} + + +} + + + + +/// @nodoc + + +class _Disconnected implements SocketError { + const _Disconnected({this.reason}); + + + final String? reason; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$DisconnectedCopyWith<_Disconnected> get copyWith => __$DisconnectedCopyWithImpl<_Disconnected>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Disconnected&&(identical(other.reason, reason) || other.reason == reason)); +} + + +@override +int get hashCode => Object.hash(runtimeType,reason); + +@override +String toString() { + return 'SocketError.disconnected(reason: $reason)'; +} + + +} + +/// @nodoc +abstract mixin class _$DisconnectedCopyWith<$Res> implements $SocketErrorCopyWith<$Res> { + factory _$DisconnectedCopyWith(_Disconnected value, $Res Function(_Disconnected) _then) = __$DisconnectedCopyWithImpl; +@useResult +$Res call({ + String? reason +}); + + + + +} +/// @nodoc +class __$DisconnectedCopyWithImpl<$Res> + implements _$DisconnectedCopyWith<$Res> { + __$DisconnectedCopyWithImpl(this._self, this._then); + + final _Disconnected _self; + final $Res Function(_Disconnected) _then; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? reason = freezed,}) { + return _then(_Disconnected( +reason: freezed == reason ? _self.reason : reason // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +/// @nodoc + + +class _PingTimeout implements SocketError { + const _PingTimeout(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PingTimeout); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'SocketError.pingTimeout()'; +} + + +} + + + + +/// @nodoc + + +class _NetworkUnavailable implements SocketError { + const _NetworkUnavailable(); + + + + + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _NetworkUnavailable); +} + + +@override +int get hashCode => runtimeType.hashCode; + +@override +String toString() { + return 'SocketError.networkUnavailable()'; +} + + +} + + + + +/// @nodoc + + +class _InvalidURL implements SocketError { + const _InvalidURL(this.url); + + + final String url; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$InvalidURLCopyWith<_InvalidURL> get copyWith => __$InvalidURLCopyWithImpl<_InvalidURL>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _InvalidURL&&(identical(other.url, url) || other.url == url)); +} + + +@override +int get hashCode => Object.hash(runtimeType,url); + +@override +String toString() { + return 'SocketError.invalidURL(url: $url)'; +} + + +} + +/// @nodoc +abstract mixin class _$InvalidURLCopyWith<$Res> implements $SocketErrorCopyWith<$Res> { + factory _$InvalidURLCopyWith(_InvalidURL value, $Res Function(_InvalidURL) _then) = __$InvalidURLCopyWithImpl; +@useResult +$Res call({ + String url +}); + + + + +} +/// @nodoc +class __$InvalidURLCopyWithImpl<$Res> + implements _$InvalidURLCopyWith<$Res> { + __$InvalidURLCopyWithImpl(this._self, this._then); + + final _InvalidURL _self; + final $Res Function(_InvalidURL) _then; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? url = null,}) { + return _then(_InvalidURL( +null == url ? _self.url : url // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _SendFailed implements SocketError { + const _SendFailed(this.message); + + + final String message; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SendFailedCopyWith<_SendFailed> get copyWith => __$SendFailedCopyWithImpl<_SendFailed>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SendFailed&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'SocketError.sendFailed(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$SendFailedCopyWith<$Res> implements $SocketErrorCopyWith<$Res> { + factory _$SendFailedCopyWith(_SendFailed value, $Res Function(_SendFailed) _then) = __$SendFailedCopyWithImpl; +@useResult +$Res call({ + String message +}); + + + + +} +/// @nodoc +class __$SendFailedCopyWithImpl<$Res> + implements _$SendFailedCopyWith<$Res> { + __$SendFailedCopyWithImpl(this._self, this._then); + + final _SendFailed _self; + final $Res Function(_SendFailed) _then; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = null,}) { + return _then(_SendFailed( +null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String, + )); +} + + +} + +/// @nodoc + + +class _Unknown implements SocketError { + const _Unknown(this.message); + + + final String? message; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UnknownCopyWith<_Unknown> get copyWith => __$UnknownCopyWithImpl<_Unknown>(this, _$identity); + + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Unknown&&(identical(other.message, message) || other.message == message)); +} + + +@override +int get hashCode => Object.hash(runtimeType,message); + +@override +String toString() { + return 'SocketError.unknown(message: $message)'; +} + + +} + +/// @nodoc +abstract mixin class _$UnknownCopyWith<$Res> implements $SocketErrorCopyWith<$Res> { + factory _$UnknownCopyWith(_Unknown value, $Res Function(_Unknown) _then) = __$UnknownCopyWithImpl; +@useResult +$Res call({ + String? message +}); + + + + +} +/// @nodoc +class __$UnknownCopyWithImpl<$Res> + implements _$UnknownCopyWith<$Res> { + __$UnknownCopyWithImpl(this._self, this._then); + + final _Unknown _self; + final $Res Function(_Unknown) _then; + +/// Create a copy of SocketError +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') $Res call({Object? message = freezed,}) { + return _then(_Unknown( +freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/packages/networks_sdk/pubspec.yaml b/packages/networks_sdk/pubspec.yaml index 8e6ded0..74b348e 100644 --- a/packages/networks_sdk/pubspec.yaml +++ b/packages/networks_sdk/pubspec.yaml @@ -1,7 +1,7 @@ name: networks_sdk description: HTTP and WebSocket communication SDK. resolution: workspace -version: 0.0.1 +version: 0.0.2 homepage: environment: diff --git a/packages/networks_sdk/scripts/gen.sh b/packages/networks_sdk/scripts/gen.sh new file mode 100755 index 0000000..18be09a --- /dev/null +++ b/packages/networks_sdk/scripts/gen.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Code generation for networks_sdk — clean lock/cache, resolve deps, run build_runner +# +# Usage: +# bash scripts/gen.sh +# +# Generated files (*.freezed.dart, *.g.dart) are committed to git so that +# git-tag consumers can build without running build_runner themselves. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SDK_DIR="$(dirname "$SCRIPT_DIR")" + +cd "$SDK_DIR" + +# ── Clean stale lock and tool cache ──────────────────────────────────────── +echo "==> Removing pubspec.lock and .dart_tool..." +rm -rf pubspec.lock .dart_tool + +# ── Resolve dependencies ──────────────────────────────────────────────────── +echo "==> Running flutter pub get..." +flutter pub get + +# ── Run build_runner ──────────────────────────────────────────────────────── +echo "==> Running build_runner build..." +dart run build_runner build --delete-conflicting-outputs + +echo "" +echo "networks_sdk code generation complete." diff --git a/pubspec.lock b/pubspec.lock index 9e5d8ce..1e57ffe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,14 +9,6 @@ packages: url: "https://pub.dev" source: hosted version: "92.0.0" - adaptive_number: - dependency: transitive - description: - name: adaptive_number - sha256: "3a567544e9b5c9c803006f51140ad544aedc79604fd4f3f2c1380003f97c1d77" - url: "https://pub.dev" - source: hosted - version: "1.0.0" analyzer: dependency: transitive description: @@ -25,14 +17,6 @@ packages: url: "https://pub.dev" source: hosted version: "9.0.0" - analyzer_buffer: - dependency: transitive - description: - name: analyzer_buffer - sha256: ff4bd291778c7417fe53fe24ee0d0a1f1ffe281a2d4ea887e7094f16e36eace7 - url: "https://pub.dev" - source: hosted - version: "0.3.0" ansi_styles: dependency: transitive description: @@ -201,22 +185,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" - connectivity_plus: - dependency: transitive - description: - name: connectivity_plus - sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec - url: "https://pub.dev" - source: hosted - version: "6.1.5" - connectivity_plus_platform_interface: - dependency: transitive - description: - name: connectivity_plus_platform_interface - sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://pub.dev" - source: hosted - version: "2.0.1" conventional_commit: dependency: transitive description: @@ -249,14 +217,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.7" - dart_jsonwebtoken: - dependency: transitive - description: - name: dart_jsonwebtoken - sha256: c6ecb3bb991c459b91c5adf9e871113dcb32bbe8fe7ca2c92723f88ffc1e0b7a - url: "https://pub.dev" - source: hosted - version: "3.3.2" dart_style: dependency: transitive description: @@ -265,30 +225,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.3" - dbus: - dependency: transitive - description: - name: dbus - sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270 - url: "https://pub.dev" - source: hosted - version: "0.7.12" - device_info_plus: - dependency: transitive - description: - name: device_info_plus - sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a" - url: "https://pub.dev" - source: hosted - version: "11.5.0" - device_info_plus_platform_interface: - dependency: transitive - description: - name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.dev" - source: hosted - version: "7.0.3" dio: dependency: transitive description: @@ -329,14 +265,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.8" - ed25519_edwards: - dependency: transitive - description: - name: ed25519_edwards - sha256: "6ce0112d131327ec6d42beede1e5dfd526069b18ad45dcf654f15074ad9276cd" - url: "https://pub.dev" - source: hosted - version: "0.3.1" encrypt: dependency: transitive description: @@ -382,11 +310,6 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_driver: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" flutter_lints: dependency: transitive description: @@ -395,14 +318,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" - flutter_riverpod: - dependency: transitive - description: - name: flutter_riverpod - sha256: e2026c72738a925a60db30258ff1f29974e40716749f3c9850aabf34ffc1a14c - url: "https://pub.dev" - source: hosted - version: "3.2.1" flutter_test: dependency: transitive description: flutter @@ -437,11 +352,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" glob: dependency: transitive description: @@ -450,14 +360,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" - go_router: - dependency: transitive - description: - name: go_router - sha256: c5fa45fa502ee880839e3b2152d987c44abae26d064a2376d4aad434cf0f7b15 - url: "https://pub.dev" - source: hosted - version: "12.1.3" graphs: dependency: transitive description: @@ -498,11 +400,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" - integration_test: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" io: dependency: transitive description: @@ -607,22 +504,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - mockito: - dependency: transitive - description: - name: mockito - sha256: a45d1aa065b796922db7b9e7e7e45f921aed17adf3a8318a1f47097e7e695566 - url: "https://pub.dev" - source: hosted - version: "5.6.3" - mocktail: - dependency: transitive - description: - name: mocktail - sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" - url: "https://pub.dev" - source: hosted - version: "1.0.4" mustache_template: dependency: transitive description: @@ -639,14 +520,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.17.4" - nm: - dependency: transitive - description: - name: nm - sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.dev" - source: hosted - version: "0.5.0" node_preamble: dependency: transitive description: @@ -815,38 +688,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.0" - riverpod: - dependency: transitive - description: - name: riverpod - sha256: "8c22216be8ad3ef2b44af3a329693558c98eca7b8bd4ef495c92db0bba279f83" - url: "https://pub.dev" - source: hosted - version: "3.2.1" - riverpod_analyzer_utils: - dependency: transitive - description: - name: riverpod_analyzer_utils - sha256: e55bc08c084a424e1bbdc303fe8ea75daafe4269b68fd0e0f6f1678413715b66 - url: "https://pub.dev" - source: hosted - version: "1.0.0-dev.9" - riverpod_annotation: - dependency: transitive - description: - name: riverpod_annotation - sha256: "16471a1260b94e939394d78f1c63a9350936ac4a68c9fbdab40be47268c0b04f" - url: "https://pub.dev" - source: hosted - version: "4.0.2" - riverpod_generator: - dependency: transitive - description: - name: riverpod_generator - sha256: "6f9220534d7a353b53c875ea191a84d28cb4e52ac420a66a1bd7318329d977b0" - url: "https://pub.dev" - source: hosted - version: "4.0.3" shared_preferences: dependency: transitive description: @@ -1012,14 +853,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.12.1" - state_notifier: - dependency: transitive - description: - name: state_notifier - sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb - url: "https://pub.dev" - source: hosted - version: "1.0.0" stream_channel: dependency: transitive description: @@ -1044,14 +877,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" - sync_http: - dependency: transitive - description: - name: sync_http - sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dev" - source: hosted - version: "0.3.1" term_glyph: dependency: transitive description: @@ -1100,14 +925,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" - very_good_analysis: - dependency: transitive - description: - name: very_good_analysis - sha256: "9ae7f3a3bd5764fb021b335ca28a34f040cd0ab6eec00a1b213b445dae58a4b8" - url: "https://pub.dev" - source: hosted - version: "5.1.0" vm_service: dependency: transitive description: @@ -1148,14 +965,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - webdriver: - dependency: transitive - description: - name: webdriver - sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" - url: "https://pub.dev" - source: hosted - version: "3.1.0" webkit_inspection_protocol: dependency: transitive description: @@ -1164,22 +973,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" - win32: - dependency: transitive - description: - name: win32 - sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e - url: "https://pub.dev" - source: hosted - version: "5.15.0" - win32_registry: - dependency: transitive - description: - name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" - url: "https://pub.dev" - source: hosted - version: "2.1.0" xdg_directories: dependency: transitive description: diff --git a/scripts/pre-commit b/scripts/pre-commit index 7502da0..7532fcc 100644 --- a/scripts/pre-commit +++ b/scripts/pre-commit @@ -1,5 +1,7 @@ #!/bin/bash -# Git pre-commit hook:提交前自动 format,analyze 有 error 则拦截提交 +# Git pre-commit hook:analyze 有 error / warning 则拦截提交 +# +# 只分析包含暂存 .dart 文件的包,不跑全局 analyze,避免其他包的错误阻断无关提交。 # # 安装:bash scripts/setup.sh(setup.sh 自动把本文件复制到 .git/hooks/pre-commit) # 手动安装:cp scripts/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit @@ -24,35 +26,60 @@ LOCK_STAGED=$(git diff --cached --name-only pubspec.lock 2>/dev/null || true) if [[ -n "$LOCK_UNSTAGED" && -z "$LOCK_STAGED" ]]; then git checkout HEAD -- pubspec.lock echo "[pre-commit] pubspec.lock was auto-modified by flutter, restored to HEAD." - echo " To intentionally update: run 'dart pub get' or 'dart pub upgrade'," + echo " To intentionally update: run 'flutter pub get' or 'flutter pub upgrade'," echo " then 'git add pubspec.lock' before committing." fi -# ── dart format + analyze ──────────────────────────────────────────────────── +# ── dart analyze(只分析涉及的包)──────────────────────────────────────────── STAGED_DART=$(git diff --cached --name-only --diff-filter=ACM | grep '\.dart$' || true) if [[ -z "$STAGED_DART" ]]; then exit 0 fi -echo "[pre-commit] formatting staged dart files..." -echo "$STAGED_DART" | xargs dart format --line-length=80 -echo "$STAGED_DART" | xargs git add +# 找到每个暂存 .dart 文件所在的包根目录(最近的 pubspec.yaml 所在目录) +PKG_DIRS_LIST=() +while IFS= read -r file; do + dir="$ROOT_DIR/$(dirname "$file")" + while [[ "$dir" != "$ROOT_DIR" && "$dir" != "/" ]]; do + if [[ -f "$dir/pubspec.yaml" ]]; then + PKG_DIRS_LIST+=("$dir") + break + fi + dir="$(dirname "$dir")" + done +done <<< "$STAGED_DART" -echo "[pre-commit] running dart analyze..." -cd "$ROOT_DIR" - -ANALYZE_OUTPUT=$(dart analyze 2>&1) - -if echo "$ANALYZE_OUTPUT" | grep -q "^ error"; then - echo "[pre-commit] dart analyze found errors, commit blocked." - echo "$ANALYZE_OUTPUT" | grep "^ error" - exit 1 +if [[ ${#PKG_DIRS_LIST[@]} -eq 0 ]]; then + exit 0 fi -if echo "$ANALYZE_OUTPUT" | grep -q "^ warning"; then - echo "[pre-commit] dart analyze found warnings, commit blocked." - echo "$ANALYZE_OUTPUT" | grep "^ warning" +# 去重 +UNIQUE_PKGS=$(printf '%s\n' "${PKG_DIRS_LIST[@]}" | sort -u) + +echo "[pre-commit] running dart analyze on affected packages..." + +FAILED=0 +while IFS= read -r pkg_dir; do + pkg_name="$(basename "$pkg_dir")" + echo "[pre-commit] → $pkg_name" + ANALYZE_OUTPUT=$(dart analyze "$pkg_dir" 2>&1) + + if echo "$ANALYZE_OUTPUT" | grep -q "^ error"; then + echo "[pre-commit] errors in $pkg_name:" + echo "$ANALYZE_OUTPUT" | grep "^ error" + FAILED=1 + fi + + if echo "$ANALYZE_OUTPUT" | grep -q "^ warning"; then + echo "[pre-commit] warnings in $pkg_name:" + echo "$ANALYZE_OUTPUT" | grep "^ warning" + FAILED=1 + fi +done <<< "$UNIQUE_PKGS" + +if [[ $FAILED -eq 1 ]]; then + echo "[pre-commit] commit blocked due to errors/warnings above." exit 1 fi