feature_gen_cli 1.4.2
feature_gen_cli: ^1.4.2 copied to clipboard
A command-line tool for generating feature modules.
Feature Gen #
Feature Gen is a Dart CLI that scaffolds clean-architecture feature modules for Flutter projects from a JSON schema.
Quick Start #
Requirements: Dart SDK >=3.10.4, a Flutter project with a valid pubspec.yaml, and dart on your PATH. Run the CLI from the Flutter project root so pubspec.yaml resolution works.
# 1. Install
dart pub global activate feature_gen_cli
# 2. Run
feature_gen_cli <feature_name> <schema.json>
# Example: feature_gen_cli user example/user_schema.json
# Overwrite existing generated files (optional)
feature_gen_cli <feature_name> <schema.json> --overwrite
Feature names should be lowercase snake_case (the generated folder is lib/features/<feature_name>/).
CLI Options #
feature_gen_cli <feature_name> <schema.json> -o # overwrite existing generated files
feature_gen_cli --version # print package version
feature_gen_cli --help # show help
Schema Reference #
The schema is a single JSON file requiring three sections: config, api.methods, and response.
Single-Response (one entity for the whole feature) #
{
"config": { "bloc": true, "riverpod": false },
"api": {
"methods": {
"getUser": {},
"updateUser": { "body": { "name": "string", "email": "string" } },
"deleteUser": { "params": { "id": "int" } }
}
},
"response": { "id": "int", "name": "string" }
}
Multi-Response (different entities per method) #
When different API methods return different types, define each response type by name and add a "response" key to each method that declares which type it returns.
{
"config": { "bloc": true, "riverpod": false },
"api": {
"methods": {
"getUser": { "response": "user" },
"postSomeData": { "body": { "name": "string", "email": "string" }, "response": "token" },
"updateUser": { "body": { "name": "string" }, "response": "user" },
"deleteUser": { "params": { "id": "int" } }
}
},
"response": {
"user": { "id": 123, "name": "string", "email": "string" },
"token": { "accessToken": "string", "refreshToken": "string", "tokenType": "string" }
}
}
Multi-response rules:
- Detection — if all top-level values in
responseare objects, multi-response mode is activated automatically. No extra flag needed. - Per-method binding — set
"response": "<key>"on any method to link it to a named entity. - List returns — wrap the key in an array to return a list:
"response": ["user"]→Future<List<UserEntity>>. - Void methods — omit
"response"entirely and the method generatesFuture<void>across all layers. - Backward compatible — schemas with primitive values at the top level of
responsecontinue to work as single-response.
Common Options #
config: Both keys (blocandriverpod) are required; exactly one must betrue.api.methods: Define endpoints (camelCase). Optionally includeparams,body, orqueryto generateUseCaseand param classes.response: Define entity fields. Supported primitives:"string","int","double","bool","list","map". Supports nested objects and arrays.
Naming Convention Note: snake_case keys in your configuration JSON are automatically generated into camelCase variables for your data classes, ensuring code idiomacy. Serialization layers accurately map variables back to their exact original JSON keys using Freezed @JsonKey configurations and custom overrides automatically.
Generated Structure #
Running the CLI produces a complete clean-architecture module in lib/features/<feature_name>/:
lib/features/<feature>/
├── data/
│ ├── datasources/ <feature>_remote_datasource.dart
│ ├── models/ <entity>_model.dart (one per entity in multi-response)
│ └── repositories/ <feature>_repository_impl.dart
└── domain/
├── entities/ <entity>_entity.dart (one per entity in multi-response)
├── repositories/ <feature>_repository.dart
└── usecases/ <method>_usecase.dart
└── presentation/
├── bloc/ <feature>_bloc.dart, _event.dart, _state.dart
└── screen/ <feature>_screen.dart
In multi-response mode, the BLoC and Riverpod states get one typed success factory per method:
// generated user_state.dart
const factory UserState.getUserSuccess(UserEntity data) = _GetUserSuccessState;
const factory UserState.postSomeDataSuccess(TokenEntity data) = _PostSomeDataSuccessState;
const factory UserState.deleteUserSuccess() = _DeleteUserSuccessState;
The CLI automatically adds missing dependencies, runs build_runner, and formats the generated code.
Overwrite Behavior #
By default, the CLI only generates missing files and will not overwrite existing files. Use --overwrite (or -o) to force regeneration.
Troubleshooting #
- Schema validation errors: Ensure
config,api.methods, andresponseexist, and that exactly one ofconfig.blocorconfig.riverpodistrue. build_runnerfailed: Re-run it manually:dart run build_runner build -d.
Support ❤️ #
If you find this package helpful, please consider giving it a like on pub.dev and adding a ⭐ star on GitHub! Your support is greatly appreciated.
Contributing #
- Install dependencies:
dart pub get - Run tests:
dart test - Format code:
dart format .
Note: The test suite is pure unit tests and avoids running external commands.
License #
MIT