feature_gen_cli 1.5.0
feature_gen_cli: ^1.5.0 copied to clipboard
A command-line tool for generating feature modules.
Changelog #
1.5.0 #
Bug Fixes #
- stderr routing — Sub-process error output (from
dart pub add,build_runner, etc.) is now correctly written tostderrinstead ofstdout, so CI pipelines and IDEs can distinguish errors from normal output. - Invalid schema no longer silently ignored —
Parser.buildContextnow throws aStateErrorwhen schema validation fails instead of returning a broken emptyContextthat would propagate through the entire pipeline. toCamelCasecrash on consecutive underscores — Keys like"my__field"previously caused aRangeError. Empty word segments are now skipped safely, matching the existing guard intoPascalCase.- Dead code removed —
Schema.responseParserwas declared but never called; it has been removed. The equivalent logic already existed inline inSchema.fromJson.
Robustness #
- Friendly JSON parse errors —
Parser.parsenow catchesFormatExceptionfromjsonDecodeand reports a clear message (Invalid JSON in schema file "...") instead of dumping a raw stack trace. - Template file errors —
Generator.renderTemplatewraps file reads in aFileSystemExceptioncatch and throws a descriptiveStateError(Template not found at "...") when a template is missing, making corrupt installs easy to diagnose. YamlHelpergraceful fallback —getProjectNameandgetDependenciesnow issue a warning and continue instead of callingexit(1)in their catch blocks (which left unreachable return statements).CommandHelperis now injectable for consistent output and testability.Configvalidation moved to parser —Configno longer throwsArgumentErrorin its constructor during JSON deserialization. Validation (exactly one layer must be set) is now handled byParser.validateSchema, where it can use the user-friendlyCommandHelper.error()path.
Architecture #
PresentationLayerenum — The three nullablebool?fields (bloc,riverpod,getx) onConfighave been replaced with a singlePresentationLayer? layerenum. Allconfig.bloc == truechecks in the generator and command runner now useconfig.layer == PresentationLayer.bloc. TheConfig.toMap()output is unchanged so Mustache templates are unaffected.generateBoilerplaterefactored — Presentation-layer code is extracted into three focused private helpers (_generateBlocFiles,_generateRiverpodFiles,_generateGetXFiles) and dispatched via an exhaustiveswitchon the enum. Adding a new state-management layer now requires only one new helper.hasUseCaseis a computed getter —ContextMethod.hasUseCaseis nowbool get hasUseCase => hasParams || hasBody || hasQueryinstead of a redundant constructor parameter, eliminating the possibility of it going out of sync.
Tests #
- CI workflow — Added
.github/workflows/test.ymlthat runsdart format,dart analyze, anddart teston every push and pull request so broken code can no longer be published directly. - New unit tests added:
Parser.parse— missing file and invalid JSON both record a friendly error and throw.Parser.buildContext— throwsStateErrorwhen schema validation fails.Generator.renderTemplate— throws a descriptiveStateErrorwhen the template file is missing.CommandRunner.checkAndAddDeps— partial-dep case: only the missing packages are passed todart pub add.FeatureGen.generate— error path: surfaces"Unexpected error"when the parser throws.StringExtension.toCamelCase— double-underscore regression test.Config.fromJson/toMap— new tests covering all three layers and the null-layer sentinel.ContextMethod.hasUseCase— getter correctness andtoMapinclusion.
DX #
--helpinvocation corrected — Help text now showsfeature_gen_cli <name> <schema.json>(the correct post-pub global activateform) instead of the olddart tool/feature_gen_cli.dartpath.--versiontypo fixed — Removed the stray colon that appeared as--version:in the help output.- Stricter lints enabled —
analysis_options.yamlnow includesprefer_final_locals,unawaited_futures,prefer_const_constructors, andavoid_print.
1.4.3 #
Features #
- GetX Support — Added
"getx": trueas a third state-management option in theconfigsection alongsideblocandriverpod. - GetX Controller — Generates a Freezed-state-driven
GetxControllerwith typed success states, loading, and error handling per method. - GetX Binding — Generates a
Bindingsclass that lazily registers the controller viaget_it(sl). - GetX State — Generates a shared Freezed
Stateclass (identical structure to BLoC/Riverpod states) insidepresentation/getx/. - GetX Screen — Generates a starter
Screenwidget usingObxto react to state changes inpresentation/screen/. - Multi-Response + GetX — All multi-response features (per-method typed success factories, void methods) are fully supported under GetX.
Refactor #
- Schema Validation — Updated parser and
Configtype to accept exactly one of"bloc","riverpod", or"getx"beingtrue; validation error message updated accordingly. - Directory Scaffolding — Generator now creates the
presentation/getx/directory when GetX is selected.
1.4.2 #
Features #
- JSON snake_case Convention Support — Generated class properties automatically convert JSON
snake_caserepresentations into Dart-idiomaticcamelCaseacross models, entities, and usecase parameters. - Accurate Model Serialization — Models automatically annotate properties modified into
camelCasewith@JsonKey(name: 'original_key')to guarantee API compatibility. - Accurate Payload Serialization — UseCase parameter classes (
PathParams,BodyParams,QueryParams) correctly invoke original APIsnake_casekeys from theirtoJson()overrides when emitting payloads.
1.4.1 #
Fix #
- Riverpod Typed States — Riverpod notifiers now use explicitly generated Freezed
Stateclasses instead of genericAsyncValue<Object?>. This brings the same per-method typed success factories and explicit loading/error states to Riverpod that are available for BLoC.
Refactor #
- Template Consolidation — BLoC and Riverpod state generation now share a unified
presentation/state.mustachetemplate, eliminating duplicate template logic.
1.4.0 #
Features #
-
Multi-Response Support — The
responsesection now accepts multiple named entity types in addition to the existing single-response format. Any response map whose top-level values are all objects is automatically detected as multi-response mode:"response": { "user": { "id": 123, "name": "string", "email": "string" }, "token": { "accessToken": "string", "refreshToken": "string" } } -
Per-Method Response Binding — Each API method can now declare which response entity it returns via the
"response"key. Array-wrapped values (["user"]) mark the return type asList<UserEntity>:"getUser": { "response": "user" }, "postSomeData": { "body": { ... }, "response": "token" }, "listUsers": { "response": ["user"] }, "deleteUser": { "params": { "id": "int" } } -
Void-Return Methods — Methods without a
responsekey in multi-response mode generateFuture<void>signatures across all layers (repository, datasource, usecase, bloc, riverpod). -
Per-Entity File Generation — In multi-response mode the generator creates one entity file and one model file per named response (e.g.
user_entity.dart+token_entity.dart) instead of a single combined file. -
Per-Method Typed Bloc States — The BLoC
Stateclass gains one typed success factory per method instead of a single generic success state, e.g.:const factory UserState.getUserSuccess(UserEntity data) = ...; const factory UserState.postSomeDataSuccess(TokenEntity data) = ...; const factory UserState.deleteUserSuccess() = ...;
Backward Compatibility #
- Single-response schemas (including array-wrapped
[{...}]) are fully unchanged — all existing generated code is identical to previous versions.
Tests #
- Multi-Response Detection Tests — New tests covering
Schema.fromJsondetection logic,ApiMethodresponse field parsing (string and array-wrapped), and backward-compat of single-response schemas. - Multi-Response Parser Tests — New tests verifying
buildContextcorrectly buildsEntityContextlist, resolvesresponseEntityNameper method, and marks void methods ashasResponse=false.
1.3.5 #
Tests #
- Comprehensive Unit Tests — Added grouped unit tests covering parser, generator, CLI overwrite flag, command runner behavior, and string/type helpers.
Docs #
- Dartdoc Updates — Documented new injectable seams and CLI arg builder for testing.
- README Note — Clarified the test suite runs as pure unit tests without external commands.
1.3.4 #
Features #
- Safe Generation — The generator now only creates missing files by default, preserving user edits.
- Overwrite Flag — Added
--overwrite(-o) to force regeneration of existing files. - Param Base Classes — Generated path/body/query params now extend shared base classes and implement
toJson().
1.3.2 #
Docs #
- README Overhaul — Expanded project documentation with requirements, quick start, schema reference, naming conventions, CLI side effects, and troubleshooting guidance.
- Dartdoc Enhancements — Refined file-level doc comments across CLI, generator, parser, helpers, types, and example entrypoint for clearer behavior and assumptions.
1.3.1 #
Docs #
- Pub Badge URL Fix — Updated the pub.dev badge image URL in
README.mdto point tofeature_gen_cli.svginstead of the old package name.
1.3.0 #
Improvements #
- Constructor Initializer Lists — BLoC and Riverpod templates now use explicit initializer lists (
_useCase = useCase) instead ofthis._useCasefor constructor parameters, improving readability of generated code. - Screen Template — Added
presentation/screen/generation for feature scaffolding. - Injector Template — Added
lib/core/di/injector.dartgeneration for dependency injection setup.
1.2.3+1 #
Docs #
- Pub Badges — Added
pub package,license, andpub pointsbadges toREADME.md. - Pubspec Topics — Added topic tags (
flutter,cli,code-generation,clean-architecture,architecture) for pub.dev discoverability.
1.2.3 #
Features #
- List Response Support — Response arrays (
[{...}]) are automatically detected and propagated asList<Entity>across all generated layers (entity, model, repository, datasource, usecase, bloc state, and riverpod notifier).
Improvements #
- Scoped Formatting —
dart formatnow targets only the generated feature directory instead of the entire project.
1.2.2 #
Docs #
- Example Files — Added
example/example.dartandexample/user_schema.jsonto demonstrate CLI usage and provide a sample schema for feature generation.
1.2.1 #
1.2.0 #
Features #
- Riverpod Support — Support for generating Riverpod
Notifierclasses as an alternative to BLoC. - Configurable Presentation Layer — New
configsection in the JSON schema allows choosing betweenblocandriverpod. - Selective Dependency Management — Only installs the dependencies required for the selected state management (e.g., skips
flutter_blocif usingriverpod). - Strict Schema Validation — Enforces at least one state management option in the
configsection.
1.1.0 #
Features #
- Nested Object Support — Support for nested JSON objects and lists of objects in both API request models (
params,body,query) and response entities/models. - Recursive Model Generation — Automatically generates nested Freezed models and entities for complex schema structures.
- Enhanced Type Mapping — Improved template logic for handling lists, maps, and custom types during
toEntitymapping. - Root Entity Markers — Added comments to generated entities to clearly identify root objects.
1.0.0 #
Features #
- Feature scaffolding — Generate clean-architecture feature modules from a JSON schema.
- Schema-driven generation — Define API methods (
params,body,query) and response fields in a single JSON file. - Auto dependency management — Automatically checks and installs required packages (
flutter_bloc,freezed,get_it,injectable, etc.). - Build runner integration — Runs
build_runnerafter generation for Freezed models and JSON serialization. - Code formatting — Applies
dart formatto the entire project after generation. - Use-case generation — Generates use-case classes for methods that define params, body, or query fields, along with a shared
BaseUseCaseabstract class. - BLoC generation — Generates BLoC, Event, and State files for each feature.
- Dynamic package name — Reads the project name from
pubspec.yamlfor correct import paths in generated files. - CLI flags —
--helpand--versionsupport.
Generated Files #
data/models/<feature>_model.dartdata/repositories/<feature>_repository_impl.dartdata/datasources/<feature>_remote_datasource.dartdomain/entities/<feature>_entity.dartdomain/repositories/<feature>_repository.dartdomain/usecases/<method>_usecase.dartpresentation/bloc/<feature>_bloc.dartpresentation/bloc/<feature>_event.dartpresentation/bloc/<feature>_state.dart