generateComponent method

Future<void> generateComponent(
  1. String type,
  2. String name, {
  3. String? feature,
})

Generates a component of the specified type and name, optionally targetting a feature.

Implementation

Future<void> generateComponent(String type, String name,
    {String? feature}) async {
  // 1. Read project.yaml to get architecture config
  String architecture = 'Clean Architecture';
  String stateManagement = 'Bloc';
  final projectYaml = File('project.yaml');
  if (await projectYaml.exists()) {
    await _configService.load('project.yaml');
    final projectMap =
        _configService.getValue<Map<String, dynamic>>('project');
    if (projectMap != null) {
      final arch = projectMap['architecture'] as String?;
      if (arch != null) {
        architecture = arch;
      }
      final sm = projectMap['state_management'] as String?;
      if (sm != null) {
        stateManagement = sm;
      }
    }
  } else {
    _logger.info(
        'No project.yaml found. Defaulting to Clean Architecture and Bloc.');
  }

  // 2. Prepare variables
  final snakeName = _toSnakeCase(name);
  final pascalName = _toPascalCase(name);

  final variables = {
    'name_snake': snakeName,
    'name_pascal': pascalName,
  };

  // 3. Determine base path based on feature and architecture
  String basePath = 'lib';
  if (feature != null && feature.isNotEmpty) {
    final featureSnake = _toSnakeCase(feature);
    if (architecture == 'Clean Architecture') {
      basePath = p.join('lib', 'features', featureSnake);
    } else {
      // Fallback for MVC/MVVM or other unknown
      basePath = 'lib';
    }
  } else {
    // if no feature provided, where to put it?
    if (type != 'feature') {
      if (architecture == 'Clean Architecture') {
        basePath = p.join('lib', 'core'); // or shared
      } else {
        basePath = 'lib';
      }
    }
  }

  // 4. Generate based on type
  switch (type) {
    case 'feature':
      await _generateFeature(
          basePath, snakeName, architecture, stateManagement);
      break;
    case 'bloc':
      await _generateBloc(
          basePath, snakeName, pascalName, variables, architecture);
      break;
    case 'repository':
      await _generateRepository(
          basePath, snakeName, pascalName, variables, architecture);
      break;
    case 'model':
      await _generateModel(
          basePath, snakeName, pascalName, variables, architecture);
      break;
    case 'screen':
    case 'page':
      await _generateScreen(
          basePath, snakeName, pascalName, variables, architecture);
      break;
    case 'entity':
      await _generateEntity(
          basePath, snakeName, pascalName, variables, architecture);
      break;
    case 'assets':
      await _generateAssets(p.join('lib', 'core'), architecture);
      break;
    case 'theme':
      await _generateTheme(p.join('lib', 'core'), architecture);
      break;
    case 'network':
      await _generateNetwork(p.join('lib', 'core'), architecture);
      break;
    case 'error':
    case 'errors':
      await _generateError(p.join('lib', 'core'), architecture);
      break;
    case 'extension':
    case 'extensions':
      await _generateExtensions(p.join('lib', 'core'), architecture);
      break;
    case 'route':
    case 'routes':
      await _generateRoutes(p.join('lib', 'core'), architecture);
      break;
    default:
      _logger.error('Unsupported component type: $type');
      throw Exception('Unsupported component type: $type');
  }
}