createFunction function

dynamic createFunction(
  1. String functionName,
  2. Map<String, List<String>> commands, {
  3. required bool localDataSource,
})

Implementation

createFunction(String functionName, Map<String, List<String>> commands,{required bool localDataSource}) async {



  if (functionName.length < 3) {
    debugPrint('\x1B[31mPlease enter valid function name\x1B[0m');

    return;
  }


 // commands.forEach((key, value) { // check if whether attr is attached but the attributes empty , the same thing for response parameters
 //   if(value.isEmpty){
 //     debugPrint('\x1B[31mPlease enter valid parameters for the $key\x1B[0m');
 //     exit(0);
 //   }
 // });
//

  bool listOf = false;

    String? modelName = commands['modelname']?.first;
    String  endPoint = commands['endpoint']?.first ?? "end_point";
    String  method = commands['method']?.first.toUpperCase() ?? "POST";

  if(modelName!=null){
    if(modelName.isEmpty){
      debugPrint('\x1B[31mPlease enter valid modelName\x1B[0m');
      exit(0);
    }

    modelName = modelName[0].toUpperLowerCase+modelName.substring(1,modelName.length);

  }

  if(commands['response']?.first.toLowerCase() == "listof"){
    listOf = true;
    commands['response']!.removeAt(0);
  }

  final Map<String,String> functionAttributes = getAttributes(commands['attr'] ?? [], 'attr'); // var : type
  final Map<String,String> responseAttributes = getAttributes(commands['response'] ?? [], "response"); // var : type



    final String upperCamelCase = functionName[0].toUpperCase() + functionName.substring(1, functionName.length);
  final String lowerCamelCase = functionName[0].toLowerCase() +
      functionName.substring(1, functionName.length);

  const String modelsPath = "lib/domain/models/models.dart";
  const String requestsPath = "lib/data/requests/requests.dart";
  const String responsesPath = "lib/data/responses/responses.dart";
  const String repositoryPath = "lib/domain/repository/repository.dart";
  const String repositoryImplPath = "lib/data/repository/repository_impl.dart";
  const String mapperPath = "lib/data/mapper/mapper.dart";
  const String remoteDataSourcePath = "lib/data/data_source/remote_data_source.dart";
  const String localDataSourcePath = "lib/data/data_source/local_data_source.dart";
  const String useCasePath = "lib/domain/usecases/";
  const String appApiPath = "lib/data/network/app_api.dart";

  String modelAttributesString = responseAttributes.entries.map((e) => "${e.value} ${e.key};")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '')
      .replaceAll(",", '\n');

  String functionAttributesString = functionAttributes.entries.map((e) => "${e.value} ${e.key};")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '')
      .replaceAll(",", '\n');


  String functionAttributesStringConstructor = functionAttributes.entries.map((e) => "this.${e.key}")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '');


  String appApiAttributesString = functionAttributes.entries.map((e) => "\n@Field('${e.key}') ${e.value} ${e.key}")
      .toString();

  appApiAttributesString= appApiAttributesString.substring(1,appApiAttributesString.length-1) ;

  String modelAttributesStringConstructor = responseAttributes.keys.map((e) => "this.$e")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '');



  String mapperAttributesStringConstructor = responseAttributes.keys.map((e) => "${listOf ? "element" : "data!"}.$e.orEmpty")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '');




  String responseAttributesString = responseAttributes.entries.map((e) => "${e.value}? ${e.key};")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '')
      .replaceAll(",", '\n');



  String dataSourceAttributes = functionAttributes.keys.map((e) => "${lowerCamelCase}Request.$e")
      .toString()
      .replaceAll("(", '')
      .replaceAll(")", '');


  // models
  await addToTheEndOfFile(modelsPath, '''

   class ${modelName ?? upperCamelCase}Model {
   $modelAttributesString
   ${modelName ?? upperCamelCase}Model($modelAttributesStringConstructor);



   }
   ''');

  // requests
  await addToTheEndOfFile(requestsPath, '''


   class ${upperCamelCase}Request {
     $functionAttributesString

   ${upperCamelCase}Request($functionAttributesStringConstructor);
   }
   ''');
  // responses
  await addToTheEndOfFile(responsesPath, '''
  @JsonSerializable()
   class ${modelName ?? upperCamelCase}ResponseData {
   $responseAttributesString

   ${modelName ?? upperCamelCase}ResponseData($modelAttributesStringConstructor);


  factory ${modelName ?? upperCamelCase}ResponseData.fromJson(Map<String,dynamic> json)=>_\$${modelName ?? upperCamelCase}ResponseDataFromJson(json);
  Map<String, dynamic> toJson() => _\$${modelName ?? upperCamelCase}ResponseDataToJson(this);

   }


     @JsonSerializable()
   class ${modelName ?? upperCamelCase}Response extends BaseResponse<${listOf? "List<${modelName ?? upperCamelCase}ResponseData>" : "${modelName ?? upperCamelCase}ResponseData" } > {
   ${modelName ?? upperCamelCase}Response();


  factory ${modelName ?? upperCamelCase}Response.fromJson(Map<String,dynamic> json)=>_\$${modelName ?? upperCamelCase}ResponseFromJson(json);
  Map<String, dynamic> toJson() => _\$${modelName ?? upperCamelCase}ResponseToJson(this);

   }
   ''');

  // repository
  await addToTheEndOfClass(repositoryPath, '''
   Future<Either<Failure,${listOf ? "List<${modelName ?? upperCamelCase}Model>" : "${modelName ?? upperCamelCase}Model"}>> $lowerCamelCase(${upperCamelCase}Request ${lowerCamelCase}Request);
   ''');

  // repository implementation
  await addToTheEndOfClass(repositoryImplPath, '''
  @override

   Future<Either<Failure,${listOf ? "List<${modelName ?? upperCamelCase}Model>" : "${modelName ?? upperCamelCase}Model"}>> $lowerCamelCase(${upperCamelCase}Request ${lowerCamelCase}Request)async{
       if (await _networkInfo.isConnected) {
      try {
        final response = await ${localDataSource? '_localDataSource' : '_remoteDataSource'}.$lowerCamelCase(${lowerCamelCase}Request);

         // todo handle the response
        return Right(response.toDomain());

      } catch (error) {
        return Left(ErrorHandler.handle(error).failure);
      }
    } else {
      return Left(DataSource.NO_INTERNET_CONNECTION.getFailure());
    }
   }
   ''');

  // remote data source implementation
  await addToTheEndOfClass(localDataSource ? localDataSourcePath : remoteDataSourcePath, '''
  @override
   Future<${modelName ?? upperCamelCase}Response> $lowerCamelCase(${upperCamelCase}Request ${lowerCamelCase}Request)async{
         ${!localDataSource ? '''
  return await _appServiceClient.$lowerCamelCase(
   $dataSourceAttributes
    );''' : '''
 // todo implement the function here
   throw UnimplementedError();
         '''}
   }
   ''');

  // remote data source
  await _addToFirstAbstractClass(localDataSource ? localDataSourcePath : remoteDataSourcePath, '''
     Future<${modelName ?? upperCamelCase}Response> $lowerCamelCase(${upperCamelCase}Request ${lowerCamelCase}Request);
  ''');

  // appApi
 if(!localDataSource) {
   await addToTheEndOfClass(appApiPath, '''
    @$method("$endPoint")
  Future<${modelName ?? upperCamelCase}Response> $lowerCamelCase( $appApiAttributesString
  );

  ''');
 }

  // mapper
  await addToTheEndOfFile(mapperPath, '''


  extension ${modelName ?? upperCamelCase}ResponseMapper on ${modelName ?? upperCamelCase}Response {

  ${listOf? 'List<${modelName ?? upperCamelCase}Model>' : '${modelName ?? upperCamelCase}Model'} toDomain() {
        if(data == null) throw Failure(null,message);

    ${listOf ? '''

        List<${modelName ?? upperCamelCase}Model> list = [];
        for (var element in data!) {
          ${modelName ?? upperCamelCase}Model model = ${modelName ?? upperCamelCase}Model($mapperAttributesStringConstructor);
          list.add(model);
        }

        return list;
    ''' :
  '''
  return ${modelName ?? upperCamelCase}Model(
    $mapperAttributesStringConstructor
    );
    '''}
  }
}
   ''');

  // useCase
  createFile(
    FileModel(
      content: '''
import 'package:dartz/dartz.dart';

import '../../core/base/base_usecase.dart';
import '../../data/network/failure.dart';
import '../models/models.dart';
import '../repository/repository.dart';

class ${upperCamelCase}UseCase implements BaseUseCase<${upperCamelCase}UseCaseInput, ${listOf? "List<${modelName ?? upperCamelCase}Model>" : "${modelName ?? upperCamelCase}Model"}> {
  final Repository _repository;

  ${upperCamelCase}UseCase(this._repository);

  @override
  Future<Either<Failure, ${listOf? "List<${modelName ?? upperCamelCase}Model>" : "${modelName ?? upperCamelCase}Model"}>> execute(${upperCamelCase}UseCaseInput input) {
    // TODO: implement execute
    throw UnimplementedError();
  }

}

class ${upperCamelCase}UseCaseInput {
$modelAttributesString

  ${upperCamelCase}UseCaseInput($modelAttributesStringConstructor);
}
        ''',
      name: "${lowerCamelCase.toLowercaseWithUnderscores}_usecase.dart",
    ),
    useCasePath,
  );

  await _runPubget();
}