addAPICall function

Future<void> addAPICall(
  1. String apiType,
  2. String endPoint,
  3. String apiName,
  4. String featureName,
  5. String responseModelName,
  6. String shimmerChoice,
  7. String requestModelName
)

Implementation

Future<void> addAPICall(
  String apiType,
  String endPoint,
  String apiName,
  String featureName,
  String responseModelName,
  String shimmerChoice,
  String requestModelName,
) async {
  String featureNameString = featureName.toLowerCase();
  String pascalCaseApiName = toPascalCase(apiName);
  String name = getPubspecInfo('name') ?? '';
  String mockEndPoint = "$apiName.json";
  String featureNamePascalCase = toPascalCase(featureNameString);

  /// update api_constants.dart file to add end point
  await apiConstantFileUpdate(apiType, apiName, endPoint);

  /// update api_constants.dart file to add end point
  await mockApiConstantFileUpdate(apiName, mockEndPoint);

  /// update data_source.dart to add imports statement and function signature
  String dataSourceDestinationPath =
      'lib/features/$featureNameString/data/data_source/${featureNameString}_data_source.dart';
  if (doesFileExist(dataSourceDestinationPath)) {
    final importDataSourceStatements = [
      "import 'package:$name/core/api/model/api_response.dart';"
    ];

    List<String> dataSourceAppendLinesDataSource = [];
    if (requestModelName.isNotEmpty) {
      importDataSourceStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${apiName}_request_model.dart';");
      dataSourceAppendLinesDataSource.add(
          "  Future<ApiResponse> ${apiType.toLowerCase()}$pascalCaseApiName (${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)});");
    } else {
      dataSourceAppendLinesDataSource = [
        "  Future<ApiResponse> ${apiType.toLowerCase()}$pascalCaseApiName();"
      ];
    }
    await fileUpdate(dataSourceDestinationPath, importDataSourceStatements,
        dataSourceAppendLinesDataSource);
  }

  /// update data_source_impl.dart to add imports statement and function method
  String destinationPathDataSourceImpl =
      'lib/features/$featureNameString/data/data_source/${featureNameString}_data_source_impl.dart';
  if (doesFileExist(destinationPathDataSourceImpl)) {
    final importDataSourceImplStatements = [
      "import 'package:$name/core/api/model/api_response.dart';",
      "import 'package:$name/core/const/api_constants.dart';"
    ];
    List<String> dataSourceAppendLinesDataSourceImpl = [];

    if (requestModelName.isNotEmpty) {
      importDataSourceImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${apiName}_request_model.dart';");
      dataSourceAppendLinesDataSourceImpl = [
        "  @override",
        "  Future<ApiResponse> ${apiType.toLowerCase()}$pascalCaseApiName(${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)}) =>",
        "      remoteDataSource.executeGet(path: ${apiType.toUpperCase()}_${apiName.toUpperCase()}, \n     queryParameters: ${capitalizeFirstCharacter(requestModelName)}.toJson(),);"
      ];
    } else {
      dataSourceAppendLinesDataSourceImpl = [
        "  @override",
        "  Future<ApiResponse> ${apiType.toLowerCase()}$pascalCaseApiName() =>",
        "      remoteDataSource.executeGet(path: ${apiType.toUpperCase()}_${apiName.toUpperCase()});"
      ];
    }
    await fileUpdate(destinationPathDataSourceImpl,
        importDataSourceImplStatements, dataSourceAppendLinesDataSourceImpl);
  }

  /// update repo.dart to add imports statement and function signature
  String destinationPathRepo =
      'lib/features/$featureNameString/domain/repositories/${featureNameString}_repo.dart';
  if (doesFileExist(destinationPathRepo)) {
    final importRepoImplStatements = [
      "import 'package:$name/core/api/model/failure.dart';",
      "import 'package:$name/core/api/model/success.dart';",
      "import 'package:dartz/dartz.dart';"
    ];
    List<String> repoAppendLines = [];

    if (requestModelName.isNotEmpty) {
      importRepoImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${apiName}_request_model.dart';");
      repoAppendLines = [
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName(${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)});"
      ];
    } else {
      repoAppendLines = [
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName();"
      ];
    }
    await fileUpdate(
        destinationPathRepo, importRepoImplStatements, repoAppendLines);
  }

  /// update repoImpl.dart to add imports statement and function signature
  String destinationPathRepoImpl =
      'lib/features/$featureNameString/data/repository/${featureNameString}_repo_impl.dart';
  if (doesFileExist(destinationPathRepoImpl)) {
    List<String> importRepoImplStatements = [
      "import 'package:dartz/dartz.dart';",
      "import 'package:$name/core/api/model/api_response.dart';",
      "import 'package:$name/core/api/model/failure.dart';",
      "import 'package:$name/core/api/model/success.dart';",
    ];

    if (responseModelName.isNotEmpty) {
      importRepoImplStatements.add(
          "import 'package:$name/features/${featureNameString}/data/model/${responseModelName}.dart';");
    }

    List<String> repoImplAppendLines = [];

    if (requestModelName.isNotEmpty) {
      importRepoImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${apiName}_request_model.dart';");
      repoImplAppendLines = [
        "  @override",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName(${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)}) =>",
        "      baseApiMethod(() => ${apiType.toLowerCase()}${pascalCaseApiName}ApiCall(${capitalizeFirstCharacter(requestModelName)}));",
        "",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}${pascalCaseApiName}ApiCall(${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)}) async {",
        "    ApiResponse response = await dataSource.${apiType.toLowerCase()}$pascalCaseApiName(${capitalizeFirstCharacter(requestModelName)});",
        "",
        "    if (!response.status!) {",
        "      return Left(",
        "        ServerFailure(",
        "          errorMessage: response.message!,",
        "          statusCode: response.statusCode ?? 0,",
        "        ),",
        "      );",
        "    } else {"
      ];
    } else {
      repoImplAppendLines = [
        "  @override",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName() =>",
        "      baseApiMethod(() => ${apiType.toLowerCase()}${pascalCaseApiName}ApiCall());",
        "",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}${pascalCaseApiName}ApiCall() async {",
        "    ApiResponse response = await dataSource.${apiType.toLowerCase()}$pascalCaseApiName();",
        "",
        "    if (!response.status!) {",
        "      return Left(",
        "        ServerFailure(",
        "          errorMessage: response.message!,",
        "          statusCode: response.statusCode ?? 0,",
        "        ),",
        "      );",
        "    } else {"
      ];
    }
    if (responseModelName.isNotEmpty) {
      repoImplAppendLines.add("       if (response.data == null) {");
      repoImplAppendLines.add(
          "           return Right(Success(data: null, message: response.message));");
      repoImplAppendLines.add("       } else {");
      repoImplAppendLines
          .add("           ${camelCase(responseModelName)} responseData =");
      repoImplAppendLines.add(
          "                  ${camelCase(responseModelName)}.fromJson(response.data);");
      repoImplAppendLines.add(
          "           return Right(Success(data: responseData, message: response.message));");
      repoImplAppendLines.add("       }");
      repoImplAppendLines.add("    }");
      repoImplAppendLines.add("  }");
    } else {
      repoImplAppendLines.add(
          "       return Right(Success(data: null, message: response.message));");
      repoImplAppendLines.add("    }");
      repoImplAppendLines.add("  }");
    }

    await fileUpdate(
        destinationPathRepoImpl, importRepoImplStatements, repoImplAppendLines);
  }

  /// update mockRepoImpl.dart to add imports statement and function signature
  String destinationPathMockRepoImpl =
      'lib/features/$featureNameString/data/repository/mock_${featureNameString}_repo_impl.dart';
  if (doesFileExist(destinationPathMockRepoImpl)) {
    List<String> importMockRepoImplStatements = [
      "import 'package:dartz/dartz.dart';",
      "import 'package:$name/core/api/model/api_response.dart';",
      "import 'package:$name/core/api/model/failure.dart';",
      "import 'package:$name/core/api/model/success.dart';",
      "import 'package:$name/core/const/mock_api_constants.dart';",
    ];

    if (responseModelName.isNotEmpty) {
      importMockRepoImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${responseModelName}.dart';");
    }

    List<String> mockRepoImplAppendLines = [];

    if (requestModelName.isNotEmpty) {
      importMockRepoImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${apiName}_request_model.dart';");
      mockRepoImplAppendLines = [
        "  @override",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName(${camelCase(requestModelName)} ${capitalizeFirstCharacter(requestModelName)}) async {",
        "    ApiResponse apiResponse = await loadFromAssetData(${apiName.toUpperCase()}_API);",
      ];
    } else {
      mockRepoImplAppendLines = [
        "  @override",
        "  Future<Either<Failure, Success>> ${apiType.toLowerCase()}$pascalCaseApiName() async {",
        "    ApiResponse apiResponse = await loadFromAssetData(${apiName.toUpperCase()}_API);",
      ];
    }
    if (responseModelName.isNotEmpty) {
      mockRepoImplAppendLines
          .add("     ${camelCase(responseModelName)} response =");
      mockRepoImplAppendLines.add(
          "         ${camelCase(responseModelName)}.fromJson(apiResponse.data);");
      mockRepoImplAppendLines.add("    return Right(Success(data: response));");
      mockRepoImplAppendLines.add("  }");
    } else {
      mockRepoImplAppendLines.add(
          "       return Right(Success(data: null, message: apiResponse.message));");
      mockRepoImplAppendLines.add("  }");
    }

    await fileUpdate(destinationPathMockRepoImpl, importMockRepoImplStatements,
        mockRepoImplAppendLines);
  }

  createUsaCase(featureNameString, apiName, requestModelName);

  /// update event.dart to add imports statement and function signature
  String destinationPathEvent =
      'lib/features/$featureNameString/presentation/bloc/${featureNameString}_event.dart';
  List<String> eventImportStatements = [];
  if (requestModelName.isNotEmpty) {
    eventImportStatements.add(
        "import 'package:$name/features/$featureNameString/data/model/$requestModelName.dart';");
  }
  if (doesFileExist(destinationPathEvent)) {
    List<String> eventAppendLines = [];
    if (requestModelName.isNotEmpty) {
      eventAppendLines.add("");
      eventAppendLines.add(
          "class  ${pascalCaseApiName}Event extends  ${featureNamePascalCase}Event {");
      eventAppendLines.add("  final ${camelCase(requestModelName)} request;");
      eventAppendLines
          .add("  ${pascalCaseApiName}Event({required this.request});");
      eventAppendLines.add("}");
    } else {
      eventAppendLines.add("");
      eventAppendLines.add(
          "class ${pascalCaseApiName}Event extends ${featureNamePascalCase}Event {}");
    }

    await fileUpdate(
        destinationPathEvent, eventImportStatements, eventAppendLines, true);
  }

  /// update state.dart to add imports statement and function method
  String destinationPathState =
      'lib/features/$featureNameString/presentation/bloc/${featureNameString}_state.dart';
  if (doesFileExist(destinationPathState)) {
    List<String> importStateStatements = [];
    if (responseModelName.isNotEmpty) {
      importStateStatements = [
        "import 'package:$name/features/$featureNameString/data/model/${responseModelName}.dart';"
      ];
    }

    List<String> stateSourceAppendLines = [];

    if (responseModelName.isNotEmpty) {
      stateSourceAppendLines = [
        "",
        "class ${pascalCaseApiName}State extends ${featureNamePascalCase}State {",
        "  final ${camelCase(responseModelName)} response;",
        "  final String message;",
        "",
        "  ${pascalCaseApiName}State({",
        "    required this.response,",
        "    required this.message",
        "  });",
        "}",
        "",
        "class ${pascalCaseApiName}ErrorState extends ${featureNamePascalCase}State {",
        "  final String message;",
        "",
        "  ${pascalCaseApiName}ErrorState({",
        "    required this.message,",
        "  });",
        "}",
      ];
    } else {
      stateSourceAppendLines = [
        "",
        "class ${pascalCaseApiName}State extends ${featureNamePascalCase}State {",
        "  final String message;",
        "",
        "  ${pascalCaseApiName}State({",
        "    required this.message",
        "  });",
        "}",
        "",
        "class ${pascalCaseApiName}ErrorState extends ${featureNamePascalCase}State {",
        "  final String message;",
        "",
        "  ${pascalCaseApiName}ErrorState({",
        "    required this.message,",
        "  });",
        "}",
      ];
    }

    if (shimmerChoice == 'y'.toLowerCase()) {
      stateSourceAppendLines.add("");
      stateSourceAppendLines.add(
          "class ${pascalCaseApiName}DataLoadingState extends ${featureNamePascalCase}State {}");
      stateSourceAppendLines.add("");
    }
    await fileUpdate(destinationPathState, importStateStatements,
        stateSourceAppendLines, true);
  }

  /// update bloc.dart to add imports statement and function signature
  String useCaseName = "${apiName}UseCase";
  String useCaseFileName = "${apiName}_usecase";
  String destinationPathBloc =
      'lib/features/$featureNameString/presentation/bloc/${featureNameString}_bloc.dart';
  if (doesFileExist(destinationPathBloc)) {
    List<String> importBlocImplStatements = [
      "",
      "import 'package:$name/core/api/model/no_request.dart';",
      "import 'package:dartz/dartz.dart';",
      "import 'package:$name/core/api/model/failure.dart';",
      "import 'package:$name/core/api/model/success.dart';",
      "import 'package:$name/core/base/bloc/api_base_bloc/api_base_bloc_event.dart';",
      "import 'package:flutter_bloc/flutter_bloc.dart';",
      "import 'package:$name/features/$featureNameString/domain/usecases/$useCaseFileName.dart';"
    ];

    if (responseModelName.isNotEmpty) {
      importBlocImplStatements.add(
          "import 'package:$name/features/$featureNameString/data/model/${responseModelName}.dart';");
    }

    List<String> blockAppendLines = [];

    String usCaseEvent = "$useCaseName(NoRequest())";
    if (requestModelName.isNotEmpty) {
      usCaseEvent = "$useCaseName(event.request)";
    }

    if (shimmerChoice == 'y'.toLowerCase()) {
      blockAppendLines = [
        "",
        "Future<void> ${apiName}Event(${pascalCaseApiName}Event event, Emitter emit) async {",
        "  emit(${pascalCaseApiName}DataLoadingState());",
        "  Either<Failure, Success> result = await $usCaseEvent;",
        "  await result.fold(",
        "    (failure) async {",
        "      emit(${pascalCaseApiName}ErrorState(message: failure.errorMessage));",
        "    },",
        "    (data) async {",
      ];
    } else {
      blockAppendLines = [
        "",
        "Future<void> ${apiName}Event(${pascalCaseApiName}Event event, Emitter emit) async {",
        "  apiBaseBlocObject.add(LoadApiEvent());",
        "  Either<Failure, Success> result = await $usCaseEvent;",
        "  await result.fold(",
        "    (failure) async {",
        "      apiBaseBlocObject.add(ErrorApiEvent(failure: failure));",
        "      emit(${pascalCaseApiName}ErrorState(message: failure.errorMessage));",
        "    },",
        "    (data) async {",
        "      apiBaseBlocObject.add(LoadedApiEvent());"
      ];
    }
    if (responseModelName.isNotEmpty) {
      String responseModel = camelCase(responseModelName);
      String responseName =
          responseModel[0].toLowerCase() + responseModel.substring(1);
      blockAppendLines.add(
          "      ${camelCase(responseModelName)} $responseName = data.data;");
      blockAppendLines.add(
          "      emit(${pascalCaseApiName}State(response: $responseName, message: data.message ?? ''));");
    } else {
      blockAppendLines.add(
          "      emit(${pascalCaseApiName}State(message: data.message ?? ''));");
    }

    blockAppendLines.add("    },");
    blockAppendLines.add("  );");
    blockAppendLines.add("}");

    await fileUpdate(
        destinationPathBloc, importBlocImplStatements, blockAppendLines);

    List<String> linesToAddAfterSuperApiBaseBloc = [
      "    on<${pascalCaseApiName}Event>(${apiName}Event);",
    ];

    await appendLine(destinationPathBloc, linesToAddAfterSuperApiBaseBloc,
        "super(apiBaseBloc");

    List<String> linesToAddBeforeSuperApiBaseBloc = [
      "    required this.$useCaseName,",
    ];

    await appendLine(destinationPathBloc, linesToAddBeforeSuperApiBaseBloc,
        "super(apiBaseBloc",
        isAfter: false);

    List<String> linesToAddUseCaseDeclaration = [
      "    final ${camelCase(useCaseName)} $useCaseName;",
    ];

    await appendLine(
        destinationPathBloc, linesToAddUseCaseDeclaration, "extends BaseBloc");
  }
}