runConvertCommand function

Future<void> runConvertCommand(
  1. List<String> args
)

Implementation

Future<void> runConvertCommand(List<String> args) async {
  if (args.isEmpty) {
    print('āŒ Please provide swagger file');
    print('Example: swagen convert swagger.json');
    return;
  }

  final inputPath = args[0];

  if (!inputPath.startsWith('http://') &&
      !inputPath.startsWith('https://') &&
      !File(inputPath).existsSync()) {
    print('āŒ File "$inputPath" not found. Please check the path.');
    return;
  }

  await installDependencies([
    'http',
    'equatable',
    'dartz',
    'get_it',
    'flutter_secure_storage',
  ]);

  final packageIndex = args.indexOf('--package');
  final packageName =
      packageIndex != -1 ? args[packageIndex + 1] : getPackageName();

  final SwaggerParser parser;

  if (inputPath.startsWith('http://') || inputPath.startsWith('https://')) {
    parser = await SwaggerParser.fromUrl(inputPath);
  } else {
    parser = SwaggerParser.fromFile(inputPath);
  }

  final components = parser.getComponents();
  final schemas = parser.getSchemas();
  final paths = parser.getPaths();
  final baseUrl = parser.getBaseUrl();

  schemas.addAll(parser.extractInlineResponseSchemas());

  final datasourceGenerator = DatasourceGenerator(packageName);
  final repositoryGenerator = RepositoryGenerator(packageName);
  final repositoryImplGenerator = RepositoryImplGenerator(packageName);
  final useCaseGenerator = UseCaseGenerator(packageName);
  final providerGenerator = ProviderGenerator(packageName);

  // Group paths by tag
  final groupedPaths = groupPathsByTag(paths);

  // Generate core files
  Directory('lib/core/error').createSync(recursive: true);
  ExceptionGenerator().generate('lib/core/error/exception.dart');
  FailureGenerator().generate('lib/core/error/failure.dart');
  Directory('lib/core/state').createSync(recursive: true);
  StateGenerator().generate('lib/core/state/request_state.dart');

  // Generate per feature
  for (final entry in groupedPaths.entries) {
    final featureName = entry.key.toLowerCase();
    final featureDir = 'lib/features/$featureName';
    final pathsForFeature = entry.value;
    final usedEntities = <String>{};

    datasourceGenerator.resetImports();

    // Data Layer
    final dataDir = '$featureDir/data';
    final modelsDir = '$dataDir/models';
    final datasourceDir = '$dataDir/datasources';
    final dataRepoDir = '$dataDir/repositories';

    // Domain Layer
    final domainDir = '$featureDir/domain';
    final entitiesDir = '$domainDir/entities';
    final domainRepoDir = '$domainDir/repositories';
    final usecaseDir = '$domainDir/usecases';
    // Presentation Layer
    final presentationDir = '$featureDir/presentation';
    final providerDir = '$presentationDir/providers';

    // Create directories
    Directory(modelsDir).createSync(recursive: true);
    Directory(datasourceDir).createSync(recursive: true);
    Directory(dataRepoDir).createSync(recursive: true);
    Directory(domainRepoDir).createSync(recursive: true);
    Directory(entitiesDir).createSync(recursive: true);
    Directory(usecaseDir).createSync(recursive: true);
    Directory(providerDir).createSync(recursive: true);

    // Generate datasource
    final datasourceCode = datasourceGenerator.generatorDataSource(
      pathsForFeature,
      baseUrl,
      components,
      parser,
      featureName,
    );
    generateDatasource(
      outputPath: datasourceDir,
      code: datasourceCode,
      featureName: featureName,
    );

    schemas.addAll(datasourceGenerator.inlineSchemas);

    for (var usedModel in datasourceGenerator.usedImports) {
      final schemaKey = usedModel.replaceAll('Response', '');
      if (schemas.containsKey(schemaKey)) {
        schemas[usedModel] = schemas[schemaKey]!;
      }
    }

    // Generate repositories
    generateRepositories(
      groupedPaths: {featureName: pathsForFeature},
      packageName: packageName,
      featureName: featureName,
      repoGen: repositoryGenerator,
      implGen: repositoryImplGenerator,
      components: components,
      domainPath: domainRepoDir,
      dataPath: dataRepoDir,
      usedEntities: usedEntities,
    );

    // Generate entities
    final entities = generateEntities(
      usedEntities: usedEntities,
      schemas: schemas,
      outputPath: entitiesDir,
    );

    final modelGenerator = ModelGenerator(generatedEntities: entities);

    // Generate models
    generateModels(
      usedModels: datasourceGenerator.usedImports,
      schemas: schemas,
      generator: modelGenerator,
      outputPath: modelsDir,
      projetName: packageName,
      featureName: featureName,
    );

    // Generate use cases
    generateUseCases(
      featureName: featureName,
      pathsForFeature: pathsForFeature,
      components: components,
      usedEntities: usedEntities,
      packageName: packageName,
      usecaseDir: usecaseDir,
      providerDir: providerDir,
      useCaseGenerator: useCaseGenerator,
      providerGenerator: providerGenerator,
    );
  }

  // Generate injectors
  final injectorFeatures = collectInjectorFeatures(groupedPaths);

  generateInjectors(
    packageName: packageName,
    injectorFeatures: injectorFeatures,
  );

  print('\nšŸš€ Swagger converted successfully into Clean Architecture!');

  await formatGeneratedCode();
}