@ngxtm/devkit 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +59 -13
- package/cli/rules.js +248 -0
- package/package.json +2 -1
- package/rules/README.md +141 -0
- package/rules/dart/best-practices/SKILL.md +23 -0
- package/rules/dart/language/SKILL.md +52 -0
- package/rules/dart/tooling/SKILL.md +43 -0
- package/rules/dotnet/aspnet-core/SKILL.md +92 -0
- package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
- package/rules/dotnet/best-practices/SKILL.md +101 -0
- package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
- package/rules/dotnet/blazor/SKILL.md +146 -0
- package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
- package/rules/dotnet/language/SKILL.md +82 -0
- package/rules/dotnet/language/references/REFERENCE.md +222 -0
- package/rules/dotnet/patterns.rule.md +388 -0
- package/rules/dotnet/razor-pages/SKILL.md +124 -0
- package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
- package/rules/dotnet/security/SKILL.md +89 -0
- package/rules/dotnet/security/references/REFERENCE.md +295 -0
- package/rules/dotnet/tooling/SKILL.md +92 -0
- package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
- package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
- package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
- package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
- package/rules/flutter/bloc-state-management/SKILL.md +64 -0
- package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
- package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
- package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
- package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
- package/rules/flutter/bloc.rule.md +76 -0
- package/rules/flutter/cicd/SKILL.md +48 -0
- package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
- package/rules/flutter/cicd/references/fastlane.md +139 -0
- package/rules/flutter/cicd/references/github-actions.md +59 -0
- package/rules/flutter/dependency-injection/SKILL.md +42 -0
- package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
- package/rules/flutter/dependency-injection/references/modules.md +37 -0
- package/rules/flutter/error-handling/SKILL.md +32 -0
- package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
- package/rules/flutter/error-handling/references/error-mapping.md +31 -0
- package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
- package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
- package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
- package/rules/flutter/getx-navigation/SKILL.md +70 -0
- package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
- package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
- package/rules/flutter/getx-state-management/SKILL.md +76 -0
- package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
- package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
- package/rules/flutter/go-router-navigation/SKILL.md +57 -0
- package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
- package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
- package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
- package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
- package/rules/flutter/localization/SKILL.md +50 -0
- package/rules/flutter/localization/references/REFERENCE.md +48 -0
- package/rules/flutter/localization/references/sheet-loader.md +33 -0
- package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
- package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
- package/rules/flutter/performance/SKILL.md +24 -0
- package/rules/flutter/retrofit-networking/SKILL.md +51 -0
- package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
- package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
- package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
- package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
- package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
- package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
- package/rules/flutter/riverpod.rule.md +78 -0
- package/rules/flutter/security/SKILL.md +33 -0
- package/rules/flutter/security/references/REFERENCE.md +15 -0
- package/rules/flutter/security/references/network-security.md +28 -0
- package/rules/flutter/testing/SKILL.md +44 -0
- package/rules/flutter/testing/references/REFERENCE.md +21 -0
- package/rules/flutter/testing/references/bloc-testing.md +38 -0
- package/rules/flutter/testing/references/integration-testing.md +128 -0
- package/rules/flutter/testing/references/robot-pattern.md +82 -0
- package/rules/flutter/testing/references/unit-testing.md +130 -0
- package/rules/flutter/testing/references/widget-testing.md +120 -0
- package/rules/flutter/widgets/SKILL.md +37 -0
- package/rules/golang/chi-router/SKILL.md +219 -0
- package/rules/golang/chi-router/references/REFERENCE.md +13 -0
- package/rules/golang/chi-router/references/routing-patterns.md +205 -0
- package/rules/golang/cobra-cli/SKILL.md +227 -0
- package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
- package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
- package/rules/golang/core/SKILL.md +210 -0
- package/rules/golang/core/references/REFERENCE.md +14 -0
- package/rules/golang/core/references/concurrency-patterns.md +114 -0
- package/rules/golang/core/references/error-handling.md +87 -0
- package/rules/golang/echo-framework/SKILL.md +215 -0
- package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
- package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
- package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
- package/rules/golang/ent-orm/SKILL.md +239 -0
- package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
- package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
- package/rules/golang/fiber-framework/SKILL.md +196 -0
- package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
- package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
- package/rules/golang/gin-framework/SKILL.md +205 -0
- package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
- package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
- package/rules/golang/gorm-orm/SKILL.md +196 -0
- package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
- package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
- package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
- package/rules/golang/grpc/SKILL.md +231 -0
- package/rules/golang/grpc/references/REFERENCE.md +13 -0
- package/rules/golang/grpc/references/service-patterns.md +276 -0
- package/rules/golang/testify/SKILL.md +239 -0
- package/rules/golang/testify/references/REFERENCE.md +13 -0
- package/rules/golang/testify/references/assert-patterns.md +170 -0
- package/rules/golang/validator/SKILL.md +234 -0
- package/rules/golang/validator/references/REFERENCE.md +13 -0
- package/rules/golang/validator/references/validation-tags.md +211 -0
- package/rules/golang/viper-config/SKILL.md +244 -0
- package/rules/golang/viper-config/references/REFERENCE.md +13 -0
- package/rules/golang/viper-config/references/config-loading.md +181 -0
- package/rules/golang/wire-di/SKILL.md +243 -0
- package/rules/golang/wire-di/references/REFERENCE.md +13 -0
- package/rules/golang/wire-di/references/provider-patterns.md +193 -0
- package/rules/golang/zap-logging/SKILL.md +203 -0
- package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
- package/rules/golang/zap-logging/references/logger-config.md +165 -0
- package/rules/java/build-gradle/SKILL.md +92 -0
- package/rules/java/build-gradle/references/REFERENCE.md +14 -0
- package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
- package/rules/java/build-gradle/references/task-configuration.md +132 -0
- package/rules/java/build-maven/SKILL.md +86 -0
- package/rules/java/build-maven/references/REFERENCE.md +14 -0
- package/rules/java/build-maven/references/dependency-management.md +111 -0
- package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
- package/rules/java/graalvm-native/SKILL.md +105 -0
- package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
- package/rules/java/java-collections-streams/SKILL.md +148 -0
- package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
- package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
- package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
- package/rules/java/java-concurrency/SKILL.md +187 -0
- package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
- package/rules/java/java-concurrency/references/completable-future.md +165 -0
- package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
- package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
- package/rules/java/java-core-language/SKILL.md +121 -0
- package/rules/java/java-core-language/references/REFERENCE.md +15 -0
- package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
- package/rules/java/java-core-language/references/modern-java-features.md +168 -0
- package/rules/java/java-project-structure/SKILL.md +195 -0
- package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
- package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
- package/rules/java/java-project-structure/references/module-system.md +159 -0
- package/rules/java/micronaut-core/SKILL.md +99 -0
- package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
- package/rules/java/micronaut-reactive/SKILL.md +68 -0
- package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-core/SKILL.md +85 -0
- package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
- package/rules/java/quarkus-reactive/SKILL.md +67 -0
- package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
- package/rules/java/spring-batch/SKILL.md +102 -0
- package/rules/java/spring-batch/references/REFERENCE.md +12 -0
- package/rules/java/spring-boot-architecture/SKILL.md +206 -0
- package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
- package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
- package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
- package/rules/java/spring-boot-web/SKILL.md +217 -0
- package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
- package/rules/java/spring-cloud/SKILL.md +109 -0
- package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
- package/rules/java/spring-data-jpa/SKILL.md +241 -0
- package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/SKILL.md +161 -0
- package/rules/java/spring-security/references/REFERENCE.md +16 -0
- package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
- package/rules/java/testing-junit-mockito/SKILL.md +135 -0
- package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
- package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
- package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
- package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
- package/rules/javascript/best-practices/SKILL.md +64 -0
- package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
- package/rules/javascript/language/SKILL.md +71 -0
- package/rules/javascript/language/references/REFERENCE.md +106 -0
- package/rules/javascript/tooling/SKILL.md +60 -0
- package/rules/javascript/tooling/references/REFERENCE.md +107 -0
- package/rules/metadata.json +54 -0
- package/rules/nestjs/api-standards/SKILL.md +47 -0
- package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
- package/rules/nestjs/architecture/SKILL.md +68 -0
- package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
- package/rules/nestjs/caching/SKILL.md +51 -0
- package/rules/nestjs/caching/references/REFERENCE.md +13 -0
- package/rules/nestjs/caching/references/cache-patterns.md +183 -0
- package/rules/nestjs/configuration/SKILL.md +41 -0
- package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
- package/rules/nestjs/configuration/references/config-patterns.md +184 -0
- package/rules/nestjs/controllers-services/SKILL.md +63 -0
- package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
- package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
- package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
- package/rules/nestjs/database/SKILL.md +102 -0
- package/rules/nestjs/database/references/REFERENCE.md +14 -0
- package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
- package/rules/nestjs/deployment/SKILL.md +36 -0
- package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
- package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
- package/rules/nestjs/documentation/SKILL.md +64 -0
- package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
- package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
- package/rules/nestjs/error-handling/SKILL.md +55 -0
- package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
- package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
- package/rules/nestjs/file-uploads/SKILL.md +35 -0
- package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
- package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
- package/rules/nestjs/observability/SKILL.md +39 -0
- package/rules/nestjs/observability/references/REFERENCE.md +13 -0
- package/rules/nestjs/observability/references/logging-metrics.md +175 -0
- package/rules/nestjs/performance/SKILL.md +60 -0
- package/rules/nestjs/performance/references/REFERENCE.md +13 -0
- package/rules/nestjs/performance/references/performance-patterns.md +107 -0
- package/rules/nestjs/real-time/SKILL.md +45 -0
- package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
- package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
- package/rules/nestjs/scheduling/SKILL.md +39 -0
- package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
- package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
- package/rules/nestjs/search/SKILL.md +41 -0
- package/rules/nestjs/search/references/REFERENCE.md +13 -0
- package/rules/nestjs/search/references/search-patterns.md +137 -0
- package/rules/nestjs/security/SKILL.md +87 -0
- package/rules/nestjs/security/references/REFERENCE.md +14 -0
- package/rules/nestjs/security/references/authentication.md +151 -0
- package/rules/nestjs/testing/SKILL.md +40 -0
- package/rules/nestjs/testing/references/REFERENCE.md +14 -0
- package/rules/nestjs/testing/references/unit-testing.md +179 -0
- package/rules/nestjs/transport/SKILL.md +45 -0
- package/rules/nestjs/transport/references/REFERENCE.md +13 -0
- package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
- package/rules/nextjs/app-router/SKILL.md +46 -0
- package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
- package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
- package/rules/nextjs/architecture/SKILL.md +44 -0
- package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
- package/rules/nextjs/authentication/SKILL.md +29 -0
- package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
- package/rules/nextjs/caching/SKILL.md +66 -0
- package/rules/nextjs/caching/references/REFERENCE.md +13 -0
- package/rules/nextjs/caching/references/cache-strategies.md +168 -0
- package/rules/nextjs/data-access-layer/SKILL.md +33 -0
- package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
- package/rules/nextjs/data-fetching/SKILL.md +59 -0
- package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
- package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
- package/rules/nextjs/internationalization/SKILL.md +105 -0
- package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
- package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
- package/rules/nextjs/optimization/SKILL.md +64 -0
- package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
- package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
- package/rules/nextjs/rendering/SKILL.md +91 -0
- package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
- package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
- package/rules/nextjs/server-actions/SKILL.md +46 -0
- package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
- package/rules/nextjs/server-components/SKILL.md +52 -0
- package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
- package/rules/nextjs/server-components/references/component-patterns.md +175 -0
- package/rules/nextjs/state-management/SKILL.md +73 -0
- package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
- package/rules/nextjs/state-management/references/state-patterns.md +218 -0
- package/rules/nextjs/styling/SKILL.md +31 -0
- package/rules/nextjs/styling/references/implementation.md +56 -0
- package/rules/react/component-patterns/SKILL.md +66 -0
- package/rules/react/component-patterns/references/REFERENCE.md +126 -0
- package/rules/react/hooks/SKILL.md +60 -0
- package/rules/react/hooks/references/REFERENCE.md +132 -0
- package/rules/react/hooks.rule.md +79 -0
- package/rules/react/performance/SKILL.md +69 -0
- package/rules/react/performance/references/REFERENCE.md +143 -0
- package/rules/react/security/SKILL.md +46 -0
- package/rules/react/security/references/REFERENCE.md +170 -0
- package/rules/react/state-management/SKILL.md +56 -0
- package/rules/react/state-management/references/REFERENCE.md +137 -0
- package/rules/react/testing/SKILL.md +45 -0
- package/rules/react/testing/references/REFERENCE.md +149 -0
- package/rules/react/tooling/SKILL.md +39 -0
- package/rules/react/typescript/SKILL.md +53 -0
- package/rules/rust/actix-web/SKILL.md +160 -0
- package/rules/rust/actix-web/references/REFERENCE.md +13 -0
- package/rules/rust/actix-web/references/handler-patterns.md +198 -0
- package/rules/rust/async-graphql/SKILL.md +228 -0
- package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
- package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
- package/rules/rust/axum/SKILL.md +161 -0
- package/rules/rust/axum/references/REFERENCE.md +14 -0
- package/rules/rust/axum/references/handler-patterns.md +97 -0
- package/rules/rust/bevy/SKILL.md +206 -0
- package/rules/rust/bevy/references/REFERENCE.md +13 -0
- package/rules/rust/bevy/references/ecs-patterns.md +226 -0
- package/rules/rust/clap/SKILL.md +217 -0
- package/rules/rust/clap/references/REFERENCE.md +13 -0
- package/rules/rust/clap/references/derive-patterns.md +205 -0
- package/rules/rust/core/SKILL.md +154 -0
- package/rules/rust/core/references/REFERENCE.md +14 -0
- package/rules/rust/core/references/error-handling.md +92 -0
- package/rules/rust/diesel-orm/SKILL.md +176 -0
- package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
- package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
- package/rules/rust/rocket/SKILL.md +182 -0
- package/rules/rust/rocket/references/REFERENCE.md +13 -0
- package/rules/rust/rocket/references/handler-patterns.md +209 -0
- package/rules/rust/sea-orm/SKILL.md +230 -0
- package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
- package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
- package/rules/rust/serde-serialization/SKILL.md +150 -0
- package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
- package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
- package/rules/rust/sqlx-database/SKILL.md +140 -0
- package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
- package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
- package/rules/rust/tauri/SKILL.md +180 -0
- package/rules/rust/tauri/references/REFERENCE.md +13 -0
- package/rules/rust/tauri/references/command-patterns.md +209 -0
- package/rules/rust/tokio-runtime/SKILL.md +167 -0
- package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
- package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
- package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
- package/rules/rust/tonic/SKILL.md +231 -0
- package/rules/rust/tonic/references/REFERENCE.md +13 -0
- package/rules/rust/tonic/references/service-patterns.md +213 -0
- package/rules/rust/tracing/SKILL.md +214 -0
- package/rules/rust/tracing/references/REFERENCE.md +13 -0
- package/rules/rust/tracing/references/instrumentation.md +187 -0
- package/rules/typescript/best-practices/SKILL.md +108 -0
- package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
- package/rules/typescript/language/SKILL.md +72 -0
- package/rules/typescript/language/references/REFERENCE.md +67 -0
- package/rules/typescript/patterns.rule.md +85 -0
- package/rules/typescript/security/SKILL.md +59 -0
- package/rules/typescript/security/references/REFERENCE.md +113 -0
- package/rules/typescript/tooling/SKILL.md +52 -0
- package/rules/typescript/tooling/references/REFERENCE.md +110 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# BLoC with Equatable
|
|
2
|
+
|
|
3
|
+
Use `Equatable` as a lightweight alternative to `freezed` for state and event comparison.
|
|
4
|
+
|
|
5
|
+
```dart
|
|
6
|
+
import 'package:equatable/equatable.dart';
|
|
7
|
+
|
|
8
|
+
// --- Event ---
|
|
9
|
+
abstract class CounterEvent extends Equatable {
|
|
10
|
+
const CounterEvent();
|
|
11
|
+
|
|
12
|
+
@override
|
|
13
|
+
List<Object?> get props => [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class IncrementPressed extends CounterEvent {
|
|
17
|
+
final int amount;
|
|
18
|
+
const IncrementPressed(this.amount);
|
|
19
|
+
|
|
20
|
+
@override
|
|
21
|
+
List<Object?> get props => [amount];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// --- State ---
|
|
25
|
+
class CounterState extends Equatable {
|
|
26
|
+
final int count;
|
|
27
|
+
final bool isSubmitting;
|
|
28
|
+
|
|
29
|
+
const CounterState({
|
|
30
|
+
required this.count,
|
|
31
|
+
this.isSubmitting = false,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
CounterState copyWith({
|
|
35
|
+
int? count,
|
|
36
|
+
bool? isSubmitting,
|
|
37
|
+
}) {
|
|
38
|
+
return CounterState(
|
|
39
|
+
count: count ?? this.count,
|
|
40
|
+
isSubmitting: isSubmitting ?? this.isSubmitting,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@override
|
|
45
|
+
List<Object?> get props => [count, isSubmitting];
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## When to use Equatable over Freezed
|
|
50
|
+
|
|
51
|
+
- **Library Presence**: Primary choice when `equatable` is present in `pubspec.yaml` and code generation is not desired.
|
|
52
|
+
- **Minimal Dependencies**: When you want to avoid code generation (build_runner).
|
|
53
|
+
- **Simple Comparison**: When states don't have many properties or union cases.
|
|
54
|
+
- **Legacy Projects**: maintaining older codebases that already utilize Equatable.
|
|
55
|
+
|
|
56
|
+
> **Note**: For complex applications, `@freezed` is still prioritized due to exhaustive switch cases and built-in `copyWith` safety.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Property-Based State Pattern (Forms & Complex Data)
|
|
2
|
+
|
|
3
|
+
This pattern uses a single data class to maintain the entire state of a feature. It is the preferred approach for forms, multi-step wizards, and screens with persistent filtering.
|
|
4
|
+
|
|
5
|
+
## **Pattern Implementation**
|
|
6
|
+
|
|
7
|
+
```dart
|
|
8
|
+
@freezed
|
|
9
|
+
class NewRequestState with _$NewRequestState {
|
|
10
|
+
const factory NewRequestState({
|
|
11
|
+
// 1. Feature Data
|
|
12
|
+
required List<ReturnMaterial> selectedItems,
|
|
13
|
+
required String returnReference,
|
|
14
|
+
required SalesOrg salesOrg,
|
|
15
|
+
|
|
16
|
+
// 2. UI Flags
|
|
17
|
+
required bool showErrorMessages,
|
|
18
|
+
required bool isSubmitting,
|
|
19
|
+
|
|
20
|
+
// 3. Functional Communication (Failure/Success)
|
|
21
|
+
// - None: Operation not started
|
|
22
|
+
// - Some(Left): Operation failed
|
|
23
|
+
// - Some(Right): Operation succeeded
|
|
24
|
+
required Option<Either<ApiFailure, String>> failureOrSuccessOption,
|
|
25
|
+
}) = _NewRequestState;
|
|
26
|
+
|
|
27
|
+
factory NewRequestState.initial() => NewRequestState(
|
|
28
|
+
selectedItems: [],
|
|
29
|
+
returnReference: '',
|
|
30
|
+
salesOrg: SalesOrg.empty(),
|
|
31
|
+
showErrorMessages: false,
|
|
32
|
+
isSubmitting: false,
|
|
33
|
+
failureOrSuccessOption: none(),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## **When to use this vs. Union States?**
|
|
39
|
+
|
|
40
|
+
### **1. Use Property-Based (Flat) State when:**
|
|
41
|
+
|
|
42
|
+
- **Preservation is key**: You are building a **Form** or a **wizard** where users enter data. If you used a Union `Loading` state, the user's current input would be lost unless passed forward manually.
|
|
43
|
+
- **Overlapping UI**: You need to show a loading indicator *on top* of existing data (e.g., a "loading" overlay on a list).
|
|
44
|
+
- **Complex Filtering**: Multiple filters (search, date, category) that all need to persist.
|
|
45
|
+
|
|
46
|
+
### **2. Use Union States (Sealed Classes) when:**
|
|
47
|
+
|
|
48
|
+
- **Exclusive Phases**: The screen looks completely different in each state (e.g., Login Screen -> Loading Spinner -> Dashboard).
|
|
49
|
+
- **Simple Lifecycle**: Fetch data once -> Display it. No complex user input involved.
|
|
50
|
+
- **Type Safety**: The UI *must* have data in the `Success` state and *must not* have it in `Initial`.
|
|
51
|
+
|
|
52
|
+
## **UI Consumption (Option/Either)**
|
|
53
|
+
|
|
54
|
+
```dart
|
|
55
|
+
BlocListener<NewRequestBloc, NewRequestState>(
|
|
56
|
+
listenWhen: (p, c) => p.failureOrSuccessOption != c.failureOrSuccessOption,
|
|
57
|
+
listener: (context, state) {
|
|
58
|
+
state.failureOrSuccessOption.fold(
|
|
59
|
+
() => null, // Do nothing
|
|
60
|
+
(either) => either.fold(
|
|
61
|
+
(failure) => showErrorSnackbar(failure.message),
|
|
62
|
+
(success) => navigateToSummary(),
|
|
63
|
+
),
|
|
64
|
+
);
|
|
65
|
+
},
|
|
66
|
+
child: ...,
|
|
67
|
+
)
|
|
68
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: flutter-bloc
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
triggers: [bloc, state management, flutter bloc]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# BLoC Pattern
|
|
8
|
+
|
|
9
|
+
State management using flutter_bloc package.
|
|
10
|
+
|
|
11
|
+
## Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
lib/
|
|
15
|
+
├── blocs/
|
|
16
|
+
│ ├── auth/
|
|
17
|
+
│ │ ├── auth_bloc.dart
|
|
18
|
+
│ │ ├── auth_event.dart
|
|
19
|
+
│ │ └── auth_state.dart
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Event Naming
|
|
23
|
+
|
|
24
|
+
Events as actions in past tense:
|
|
25
|
+
- `AuthLoginRequested`
|
|
26
|
+
- `AuthLogoutRequested`
|
|
27
|
+
- `UserProfileUpdated`
|
|
28
|
+
|
|
29
|
+
## State Patterns
|
|
30
|
+
|
|
31
|
+
Use sealed classes (Dart 3+):
|
|
32
|
+
|
|
33
|
+
```dart
|
|
34
|
+
sealed class AuthState {}
|
|
35
|
+
|
|
36
|
+
final class AuthInitial extends AuthState {}
|
|
37
|
+
|
|
38
|
+
final class AuthLoading extends AuthState {}
|
|
39
|
+
|
|
40
|
+
final class AuthAuthenticated extends AuthState {
|
|
41
|
+
final User user;
|
|
42
|
+
AuthAuthenticated(this.user);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
final class AuthError extends AuthState {
|
|
46
|
+
final String message;
|
|
47
|
+
AuthError(this.message);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## BlocBuilder Usage
|
|
52
|
+
|
|
53
|
+
```dart
|
|
54
|
+
BlocBuilder<AuthBloc, AuthState>(
|
|
55
|
+
builder: (context, state) => switch (state) {
|
|
56
|
+
AuthInitial() => const LoginScreen(),
|
|
57
|
+
AuthLoading() => const LoadingIndicator(),
|
|
58
|
+
AuthAuthenticated(user: final user) => HomeScreen(user: user),
|
|
59
|
+
AuthError(message: final msg) => ErrorWidget(message: msg),
|
|
60
|
+
},
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Testing
|
|
65
|
+
|
|
66
|
+
```dart
|
|
67
|
+
blocTest<AuthBloc, AuthState>(
|
|
68
|
+
'emits [AuthLoading, AuthAuthenticated] on successful login',
|
|
69
|
+
build: () => AuthBloc(authRepo),
|
|
70
|
+
act: (bloc) => bloc.add(AuthLoginRequested(email, password)),
|
|
71
|
+
expect: () => [
|
|
72
|
+
isA<AuthLoading>(),
|
|
73
|
+
isA<AuthAuthenticated>(),
|
|
74
|
+
],
|
|
75
|
+
);
|
|
76
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Flutter CI/CD
|
|
3
|
+
description: Continuous Integration and Deployment standards for Flutter apps.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [cicd, github-actions, automation, codemagic, fastlane]
|
|
6
|
+
triggers:
|
|
7
|
+
files:
|
|
8
|
+
[
|
|
9
|
+
'.github/workflows/**.yml',
|
|
10
|
+
'fastlane/**',
|
|
11
|
+
'android/fastlane/**',
|
|
12
|
+
'ios/fastlane/**',
|
|
13
|
+
]
|
|
14
|
+
keywords: [ci, cd, pipeline, build, deploy, release, action, workflow]
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# CI/CD Standards
|
|
18
|
+
|
|
19
|
+
## **Priority: P1 (HIGH)**
|
|
20
|
+
|
|
21
|
+
Automates code quality checks, testing, and deployment to prevent regressions and accelerate delivery.
|
|
22
|
+
|
|
23
|
+
## Core Pipeline Steps
|
|
24
|
+
|
|
25
|
+
1. **Environment Setup**: Use stable Flutter channel. Cache dependencies (pub, gradle, cocoapods).
|
|
26
|
+
2. **Static Analysis**: Enforce `flutter analyze` and `dart format`. Fail on any warning in strict mode.
|
|
27
|
+
3. **Testing**: Run unit, widget, and integration tests. Upload coverage reports (e.g., Codecov).
|
|
28
|
+
4. **Build**:
|
|
29
|
+
- **Android**: Build App Bundle (`.aab`) for Play Store.
|
|
30
|
+
- **iOS**: Sign and build `.ipa` (requires macOS runner).
|
|
31
|
+
5. **Deployment** (CD): Automated upload to TestFlight/Play Console using standard tools (Fastlane, Codemagic).
|
|
32
|
+
|
|
33
|
+
## Best Practices
|
|
34
|
+
|
|
35
|
+
- **Timeout Limits**: Always set `timeout-minutes` (e.g., 30m) to save costs on hung jobs.
|
|
36
|
+
- **Fail Fast**: Run Analyze/Format _before_ Tests/Builds.
|
|
37
|
+
- **Secrets**: Never commit keys. Use GitHub Secrets or secure vaults for `keystore.jks` and `.p8` certs.
|
|
38
|
+
- **Versioning**: Automate version bumping based on git tags or semantic version scripts.
|
|
39
|
+
|
|
40
|
+
## Reference
|
|
41
|
+
|
|
42
|
+
- [**GitHub Actions Template**](references/github-actions.md) - Standard workflow file.
|
|
43
|
+
- [**Advanced Large-Scale Workflow**](references/advanced-workflow.md) - Parallel jobs, Caching, Strict Mode.
|
|
44
|
+
- [**Fastlane Standards**](references/fastlane.md) - Automated Signing & Deployment.
|
|
45
|
+
|
|
46
|
+
## Related Topics
|
|
47
|
+
|
|
48
|
+
flutter/testing | dart/tooling
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Advanced Large-Scale CI/CD
|
|
2
|
+
|
|
3
|
+
For large projects, a linear workflow is too slow. Use parallel jobs and aggressive caching.
|
|
4
|
+
|
|
5
|
+
## Optimized Workflow (`main.yml`)
|
|
6
|
+
|
|
7
|
+
Split your pipeline into parallel stages to fail fast.
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
name: Production CI
|
|
11
|
+
|
|
12
|
+
on: [push, pull_request]
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# 1. SETUP: Install & Cache Dependencies
|
|
20
|
+
# This job prepares the environment so others can just reuse the cache.
|
|
21
|
+
setup:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: subosito/flutter-action@v2
|
|
26
|
+
with:
|
|
27
|
+
channel: 'stable'
|
|
28
|
+
cache: true
|
|
29
|
+
- name: Install Dependencies
|
|
30
|
+
run: flutter pub get
|
|
31
|
+
|
|
32
|
+
# 2. QUALITY: Static Analysis & Formatting (Runs parallel to Test)
|
|
33
|
+
quality:
|
|
34
|
+
needs: setup
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: subosito/flutter-action@v2
|
|
39
|
+
- run: flutter pub get
|
|
40
|
+
- name: Verify Formatting
|
|
41
|
+
run: dart format --output=none --set-exit-if-changed .
|
|
42
|
+
- name: Static Analysis
|
|
43
|
+
run: flutter analyze --fatal-infos
|
|
44
|
+
|
|
45
|
+
# 3. TEST: Unit & Widget Tests
|
|
46
|
+
test:
|
|
47
|
+
needs: setup
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v4
|
|
51
|
+
- uses: subosito/flutter-action@v2
|
|
52
|
+
- run: flutter pub get
|
|
53
|
+
- name: Run Tests
|
|
54
|
+
# Usage of concurrency to speed up execution
|
|
55
|
+
run: flutter test --coverage --concurrency=4
|
|
56
|
+
- name: Upload Coverage
|
|
57
|
+
uses: codecov/codecov-action@v4
|
|
58
|
+
with:
|
|
59
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Key Optimizations
|
|
63
|
+
|
|
64
|
+
1. **Concurrency Group**: `cancel-in-progress: true` stops old runs when new code is pushed to the same PR, saving minutes.
|
|
65
|
+
2. **Parallel Jobs**: `quality` and `test` trigger at the same time. If formatting fails, you don't wait for tests to finish.
|
|
66
|
+
3. **Fatal Infos**: Enforce higher quality by treating info-level logic hints as failures.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Advanced Fastlane Standards
|
|
2
|
+
|
|
3
|
+
Automates signing, build versioning, flavors, and multi-channel distribution (Firebase vs. Stores).
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
1. **Versioning**: Use `flutter_version` or `cider` to sync Fastlane with `pubspec.yaml`.
|
|
8
|
+
2. **Firebase**: Install plugin: `bundle exec fastlane add_plugin firebase_app_distribution`.
|
|
9
|
+
3. **Flavors**: Ensure your Flutter app is set up with Flavors (e.g., `dev`, `prod` schemes).
|
|
10
|
+
|
|
11
|
+
## Android Configuration (`android/fastlane/Fastfile`)
|
|
12
|
+
|
|
13
|
+
Supported lanes:
|
|
14
|
+
|
|
15
|
+
- `staging`: Builds `dev` flavor -> Firebase App Distribution.
|
|
16
|
+
- `prod`: Builds `prod` flavor -> Play Store (Internal Track).
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
default_platform(:android)
|
|
20
|
+
|
|
21
|
+
platform :android do
|
|
22
|
+
# Helper: Read version from pubspec
|
|
23
|
+
def load_version
|
|
24
|
+
# Requires: gem install yaml
|
|
25
|
+
require 'yaml'
|
|
26
|
+
pubspec = YAML.load_file("../../pubspec.yaml")
|
|
27
|
+
return pubspec['version'].split('+') # Returns [version, build]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc "Deploy Staging to Firebase"
|
|
31
|
+
lane :staging do
|
|
32
|
+
version_name, version_code = load_version
|
|
33
|
+
|
|
34
|
+
# 1. Build APK (Flavor: Dev, Type: Release)
|
|
35
|
+
gradle(
|
|
36
|
+
task: "assemble",
|
|
37
|
+
flavor: "Dev",
|
|
38
|
+
build_type: "Release",
|
|
39
|
+
properties: {
|
|
40
|
+
"android.injected.version.code" => version_code,
|
|
41
|
+
"android.injected.version.name" => version_name
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# 2. Upload to Firebase
|
|
46
|
+
firebase_app_distribution(
|
|
47
|
+
app: ENV["FIREBASE_APP_ID_ANDROID_DEV"],
|
|
48
|
+
groups: "qa-team",
|
|
49
|
+
release_notes: "Staging Build v#{version_name} (#{version_code})"
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Deploy Production to Play Store"
|
|
54
|
+
lane :prod do
|
|
55
|
+
version_name, version_code = load_version
|
|
56
|
+
|
|
57
|
+
# 1. Build Bundle (Flavor: Prod)
|
|
58
|
+
gradle(
|
|
59
|
+
task: "bundle",
|
|
60
|
+
flavor: "Prod",
|
|
61
|
+
build_type: "Release",
|
|
62
|
+
properties: {
|
|
63
|
+
"android.injected.version.code" => version_code,
|
|
64
|
+
"android.injected.version.name" => version_name
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# 2. Upload to Play Store
|
|
69
|
+
upload_to_play_store(
|
|
70
|
+
track: "internal",
|
|
71
|
+
json_key: ENV["PLAY_STORE_JSON_KEY_FILE"],
|
|
72
|
+
skip_upload_metadata: true,
|
|
73
|
+
skip_upload_images: true,
|
|
74
|
+
skip_upload_screenshots: true
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## iOS Configuration (`ios/fastlane/Fastfile`)
|
|
81
|
+
|
|
82
|
+
Supported lanes:
|
|
83
|
+
|
|
84
|
+
- `staging`: Builds `Dev` Scheme -> Firebase (AdHoc).
|
|
85
|
+
- `prod`: Builds `Prod` Scheme -> TestFlight (AppStore).
|
|
86
|
+
|
|
87
|
+
**Note**: Creates separate `Matchfile` logic for AdHoc vs AppStore.
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
default_platform(:ios)
|
|
91
|
+
|
|
92
|
+
platform :ios do
|
|
93
|
+
before_all do
|
|
94
|
+
setup_ci if ENV['CI']
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
desc "Deploy Staging to Firebase (AdHoc)"
|
|
98
|
+
lane :staging do
|
|
99
|
+
# 1. Sync Signing (AdHoc for restricted devices)
|
|
100
|
+
match(type: "adhoc", app_identifier: "com.example.app.dev", readonly: is_ci)
|
|
101
|
+
|
|
102
|
+
# 2. Build IPA (Scheme: Dev)
|
|
103
|
+
build_app(
|
|
104
|
+
scheme: "Dev",
|
|
105
|
+
export_method: "ad-hoc",
|
|
106
|
+
include_bitcode: false
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# 3. Upload to Firebase
|
|
110
|
+
firebase_app_distribution(
|
|
111
|
+
app: ENV["FIREBASE_APP_ID_IOS_DEV"],
|
|
112
|
+
groups: "qa-team"
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
desc "Deploy Production to TestFlight"
|
|
117
|
+
lane :prod do
|
|
118
|
+
# 1. Sync Signing (AppStore)
|
|
119
|
+
match(type: "appstore", app_identifier: "com.example.app", readonly: is_ci)
|
|
120
|
+
|
|
121
|
+
# 2. Build IPA (Scheme: Prod)
|
|
122
|
+
build_app(
|
|
123
|
+
scheme: "Prod",
|
|
124
|
+
export_method: "app-store"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# 3. Upload to TestFlight
|
|
128
|
+
upload_to_testflight(
|
|
129
|
+
skip_waiting_for_build_processing: true
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Setup Checklist
|
|
136
|
+
|
|
137
|
+
1. **Google Play Key**: Define `PLAY_STORE_JSON_KEY_FILE`.
|
|
138
|
+
2. **Match Repo**: Ensure `git_url` in `Matchfile` points to your private cert repo.
|
|
139
|
+
3. **Firebase CLI**: Ensure firebase-tools is installed or the plugin authenticated via `FIREBASE_TOKEN`.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# GitHub Actions Workflow
|
|
2
|
+
|
|
3
|
+
This workflow builds the application, runs tests, and analyzes code.
|
|
4
|
+
|
|
5
|
+
## `flutter-ci.yml`
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
name: Flutter CI
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches: [main]
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [main]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
name: Build & Test
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 30
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repository
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Java
|
|
27
|
+
uses: actions/setup-java@v4
|
|
28
|
+
with:
|
|
29
|
+
distribution: 'zulu'
|
|
30
|
+
java-version: '17'
|
|
31
|
+
|
|
32
|
+
- name: Set up Flutter
|
|
33
|
+
uses: subosito/flutter-action@v2
|
|
34
|
+
with:
|
|
35
|
+
channel: 'stable'
|
|
36
|
+
cache: true
|
|
37
|
+
|
|
38
|
+
- name: Install dependencies
|
|
39
|
+
run: flutter pub get
|
|
40
|
+
|
|
41
|
+
- name: Format check
|
|
42
|
+
run: dart format --output=none --set-exit-if-changed .
|
|
43
|
+
|
|
44
|
+
- name: Analyze
|
|
45
|
+
run: flutter analyze
|
|
46
|
+
|
|
47
|
+
- name: Run tests
|
|
48
|
+
run: flutter test --coverage
|
|
49
|
+
|
|
50
|
+
- name: Upload coverage
|
|
51
|
+
uses: codecov/codecov-action@v4
|
|
52
|
+
with:
|
|
53
|
+
file: coverage/lcov.info
|
|
54
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Fastlane (Optional)
|
|
58
|
+
|
|
59
|
+
For automated store deployment, consider integrating `fastlane` into a separate `deploy` job that runs only on `push` to `main`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Flutter Dependency Injection (Injectable)
|
|
3
|
+
description: Standards for automated service locator setup using injectable and get_it.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [dependency-injection, injectable, get_it]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['**/injection.dart', '**/locator.dart']
|
|
8
|
+
keywords: [GetIt, injectable, singleton, module, lazySingleton, factory]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Dependency Injection
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (HIGH)**
|
|
14
|
+
|
|
15
|
+
Automated class dependency management using `get_it` and `injectable`.
|
|
16
|
+
|
|
17
|
+
## Structure
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
core/injection/
|
|
21
|
+
├── injection.dart # Initialization & setup
|
|
22
|
+
└── modules/ # Third-party dependency modules (Dio, Storage)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Implementation Guidelines
|
|
26
|
+
|
|
27
|
+
- **Automated Registration**: Use `@injectable` annotations; avoid manual registry calls.
|
|
28
|
+
- **@LazySingleton**: Default for repositories, services, and data sources (init on demand).
|
|
29
|
+
- **@injectable (Factory)**: Default for BLoCs to ensure state resets on every request.
|
|
30
|
+
- **Abstract Injection**: Always register implementations as abstract interfaces (`as: IService`).
|
|
31
|
+
- **Modules**: Use `@module` for registering third-party instances (e.g., `Dio`, `SharedPreferences`).
|
|
32
|
+
- **Constructor Injection**: Use mandatory constructor parameters; `injectable` resolves them.
|
|
33
|
+
- **Test Mocks**: Swap implementations in `setUp` using `getIt.registerLazySingleton` for testing.
|
|
34
|
+
|
|
35
|
+
## Reference & Examples
|
|
36
|
+
|
|
37
|
+
For module configuration and initialization templates:
|
|
38
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
39
|
+
|
|
40
|
+
## Related Topics
|
|
41
|
+
|
|
42
|
+
layer-based-clean-architecture | testing
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Dependency Injection Reference
|
|
2
|
+
|
|
3
|
+
Implementation patterns for `injectable` and `get_it` in massive Flutter projects.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**Injection Modules**](modules.md) - Registering third-party libraries (Dio, Hive).
|
|
8
|
+
- [**Production Initialization**](initialization.md) - Wiring everything in `main.dart`.
|
|
9
|
+
- [**Testing Mocks**](testing-mocks.md) - How to swap services during unit tests.
|
|
10
|
+
|
|
11
|
+
## **Quick Registration Guide**
|
|
12
|
+
|
|
13
|
+
- **@injectable**: Use for BLoCs (New instance every time).
|
|
14
|
+
- **@LazySingleton**: Use for Repositories and DataSources (Global, lazy-init).
|
|
15
|
+
- **@singleton**: Use only for truly shared resources (init on startup).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Third-party Dependency Modules
|
|
2
|
+
|
|
3
|
+
Since you cannot annotate third-party classes (like `Dio` or `SharedPreferences`) directly, use a `@module`.
|
|
4
|
+
|
|
5
|
+
## **Example: Network & Storage Module**
|
|
6
|
+
|
|
7
|
+
```dart
|
|
8
|
+
import 'package:injectable/injectable.dart';
|
|
9
|
+
import 'package:dio/dio.dart';
|
|
10
|
+
import 'package:shared_preferences/shared_preferences.dart';
|
|
11
|
+
|
|
12
|
+
@module
|
|
13
|
+
abstract class NetworkingModule {
|
|
14
|
+
@lazySingleton
|
|
15
|
+
Dio get dio => Dio(BaseOptions(baseUrl: 'https://api.example.com'));
|
|
16
|
+
|
|
17
|
+
@preResolve // Waits for this before finishing injection setup
|
|
18
|
+
Future<SharedPreferences> get prefs => SharedPreferences.getInstance();
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## **Named Injection**
|
|
23
|
+
|
|
24
|
+
Use for multiple instances of the same type:
|
|
25
|
+
|
|
26
|
+
```dart
|
|
27
|
+
@module
|
|
28
|
+
abstract class ServiceModule {
|
|
29
|
+
@Named("AuthDio")
|
|
30
|
+
Dio get authDio => Dio();
|
|
31
|
+
|
|
32
|
+
@Named("PublicDio")
|
|
33
|
+
Dio get publicDio => Dio();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Consumption: Repo(@Named("AuthDio") Dio dio)
|
|
37
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Flutter Error Handling
|
|
3
|
+
description: Functional error handling using Dartz and Either.
|
|
4
|
+
metadata:
|
|
5
|
+
labels: [error-handling, dartz, functional]
|
|
6
|
+
triggers:
|
|
7
|
+
files: ['lib/domain/**', 'lib/infrastructure/**']
|
|
8
|
+
keywords: [Either, fold, Left, Right, Failure, dartz]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Error Handling
|
|
12
|
+
|
|
13
|
+
## **Priority: P1 (HIGH)**
|
|
14
|
+
|
|
15
|
+
Standardized functional error handling using `dartz` and `freezed` failures.
|
|
16
|
+
|
|
17
|
+
## Implementation Guidelines
|
|
18
|
+
|
|
19
|
+
- **Either Pattern**: Return `Either<Failure, T>` from repositories. No exceptions in UI/BLoC.
|
|
20
|
+
- **Failures**: Define domain-specific failures using `@freezed` unions.
|
|
21
|
+
- **Mapping**: Infrastructure catches `Exception` and returns `Left(Failure)`.
|
|
22
|
+
- **Consumption**: Use `.fold(failure, success)` in BLoC to emit corresponding states.
|
|
23
|
+
- **Typed Errors**: Use `left(Failure())` and `right(Value())` from `Dartz`.
|
|
24
|
+
|
|
25
|
+
## Reference & Examples
|
|
26
|
+
|
|
27
|
+
For Failure definitions and API error mapping:
|
|
28
|
+
See [references/REFERENCE.md](references/REFERENCE.md).
|
|
29
|
+
|
|
30
|
+
## Related Topics
|
|
31
|
+
|
|
32
|
+
layer-based-clean-architecture | bloc-state-management
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
Detailed patterns for functional error management in Flutter.
|
|
4
|
+
|
|
5
|
+
## References
|
|
6
|
+
|
|
7
|
+
- [**Error Mapping**](error-mapping.md) - Mapping Dio/Network exceptions to Failures.
|
|
8
|
+
- [**Consumption Patterns**](consumption.md) - Using `.fold()` in Clean Architecture.
|
|
9
|
+
|
|
10
|
+
## **Quick Syntax**
|
|
11
|
+
|
|
12
|
+
```dart
|
|
13
|
+
// Result handling in BLoC
|
|
14
|
+
final failureOrData = await repository.getData();
|
|
15
|
+
emit(failureOrData.fold(
|
|
16
|
+
(failure) => State.error(failure),
|
|
17
|
+
(data) => State.success(data),
|
|
18
|
+
));
|
|
19
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Functional Failure Patterns
|
|
2
|
+
|
|
3
|
+
## **Global Failures (@freezed)**
|
|
4
|
+
|
|
5
|
+
```dart
|
|
6
|
+
@freezed
|
|
7
|
+
class ApiFailure with _$ApiFailure {
|
|
8
|
+
const factory ApiFailure.serverError() = _ServerError;
|
|
9
|
+
const factory ApiFailure.networkError() = _NetworkError;
|
|
10
|
+
const factory ApiFailure.unauthenticated() = _Unauthenticated;
|
|
11
|
+
const factory ApiFailure.badRequest(String message) = _BadRequest;
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## **Infrastructure Mapper**
|
|
16
|
+
|
|
17
|
+
```dart
|
|
18
|
+
extension DioErrorX on DioException {
|
|
19
|
+
ApiFailure toFailure() {
|
|
20
|
+
switch (type) {
|
|
21
|
+
case DioExceptionType.connectionTimeout:
|
|
22
|
+
return const ApiFailure.networkError();
|
|
23
|
+
case DioExceptionType.badResponse:
|
|
24
|
+
if (response?.statusCode == 401) return const ApiFailure.unauthenticated();
|
|
25
|
+
return const ApiFailure.serverError();
|
|
26
|
+
default:
|
|
27
|
+
return const ApiFailure.serverError();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|