generateFeature method

Future<void> generateFeature(
  1. String name
)

Generates a complete Clean Architecture feature structure.

name - The name of the feature to generate (e.g., 'user_profile', 'authentication').

This method creates a complete feature following Clean Architecture principles:

  • Data layer: datasources, models, repositories
  • Domain layer: entities, repositories (abstracts), usecases
  • Presentation layer: pages, controllers/blocs, bindings

The generated structure adapts to the configured state management pattern (GetX or BLoC) and includes appropriate dependencies and imports.

Example:

await fileGenerator.generateFeature('user_profile');
// Creates: lib/features/user_profile/...

Implementation

Future<void> generateFeature(String name) async {
  final snakeName = templateGenerator.toSnakeCase(name);
  final isBloc = templateGenerator.config.defaultStateManager == 'bloc';

  // Create directory structure based on state manager
  final dirs = [
    'lib/features/$snakeName/data/datasources',
    'lib/features/$snakeName/data/models',
    'lib/features/$snakeName/data/repositories',
    'lib/features/$snakeName/domain/entities',
    'lib/features/$snakeName/domain/repositories',
    'lib/features/$snakeName/domain/usecases',
    'lib/features/$snakeName/presentation/pages',
    'lib/features/$snakeName/presentation/bindings',
  ];

  // Add state manager specific directories
  if (isBloc) {
    dirs.add('lib/features/$snakeName/presentation/bloc');
  } else {
    dirs.add('lib/features/$snakeName/presentation/controllers');
  }

  for (final dir in dirs) {
    await ensureDirectoryExists(dir);
  }

  // Generate common files
  final files = <String, String>{
    'lib/features/$snakeName/domain/entities/${snakeName}_entity.dart':
        templateGenerator.generateEntity(name),
    'lib/features/$snakeName/data/models/${snakeName}_model.dart':
        templateGenerator.generateModel(name),
    'lib/features/$snakeName/domain/repositories/${snakeName}_repository.dart':
        templateGenerator.generateRepositoryInterface(name),
    'lib/features/$snakeName/data/repositories/${snakeName}_repository_impl.dart':
        templateGenerator.generateRepositoryImplementation(name),
    'lib/features/$snakeName/data/datasources/${snakeName}_remote_data_source.dart':
        templateGenerator.generateDataSource(name),
    'lib/features/$snakeName/domain/usecases/${snakeName}_usecase.dart':
        templateGenerator.generateUseCase(name),
    'lib/features/$snakeName/presentation/pages/${snakeName}_page.dart':
        templateGenerator.generatePage(name),
    'lib/features/$snakeName/presentation/bindings/${snakeName}_binding.dart':
        templateGenerator.generateBinding(name),
  };

  // Add state manager specific files
  if (isBloc) {
    files['lib/features/$snakeName/presentation/bloc/${snakeName}_bloc.dart'] =
        templateGenerator.generateController(name);
    files['lib/features/$snakeName/presentation/bloc/${snakeName}_event.dart'] =
        templateGenerator.generateBlocEvent(name);
    files['lib/features/$snakeName/presentation/bloc/${snakeName}_state.dart'] =
        templateGenerator.generateBlocState(name);
  } else {
    files['lib/features/$snakeName/presentation/controllers/${snakeName}_controller.dart'] =
        templateGenerator.generateController(name);
  }

  for (final entry in files.entries) {
    await writeFile(entry.key, entry.value);
  }

  print('✅ Generated feature "$name" with files:');
  for (final filePath in files.keys) {
    print('  - $filePath');
  }
}