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");
}
}