THATMobile/api_automatic/lib/swagger_dart_code_generator.dart

223 lines
7.7 KiB
Dart

import 'package:build/build.dart';
import 'package:code_builder/code_builder.dart';
import 'package:swagger_dart_code_generator/src/extensions/file_name_extensions.dart';
import 'package:swagger_dart_code_generator/src/models/generator_options.dart';
import 'package:swagger_dart_code_generator/src/swagger_code_generator.dart';
import 'package:swagger_dart_code_generator/src/swagger_models/responses/swagger_schema.dart';
import 'package:universal_io/io.dart';
import 'package:dart_style/dart_style.dart';
///Returns instance of SwaggerDartCodeGenerator
SwaggerDartCodeGenerator swaggerCodeBuilder(BuilderOptions options) => SwaggerDartCodeGenerator(options);
const _inputFileExtensions = ['.swagger', '.json'];
const String _outputFileExtension = '.dart';
const String _outputEnumsFileExtension = '_enums.dart';
const String _outputModelsFileExtension = '_models.dart';
const String _indexFileName = 'client_index.dart';
// const String _mappingFileName = 'client_mapping.dart';
Map<String, List<String>> _generateExtensions(GeneratorOptions options) {
final filesList = Directory(options.inputFolder)
.listSync()
.where((FileSystemEntity file) => _inputFileExtensions.any((ending) => file.path.endsWith(ending)));
final result = <String, List<String>>{};
filesList.forEach((FileSystemEntity element) {
final name = getFileNameBase(element.path);
result[element.path] = <String>[
'${options.outputFolder}$name$_outputFileExtension',
'${options.outputFolder}$name$_outputEnumsFileExtension',
'${options.outputFolder}$name$_outputModelsFileExtension',
];
});
///Register additional outputs in first input
result[filesList.first.path]!.add('${options.outputFolder}$_indexFileName');
// result[filesList.first.path]!.add('${options.outputFolder}$_mappingFileName');
return result;
}
///Root library entry
class SwaggerDartCodeGenerator implements Builder {
SwaggerDartCodeGenerator(BuilderOptions builderOptions) {
options = GeneratorOptions.fromJson(builderOptions.config);
}
@override
Map<String, List<String>> get buildExtensions => _buildExtensionsCopy ??= _generateExtensions(options);
Map<String, List<String>>? _buildExtensionsCopy;
late GeneratorOptions options;
final DartFormatter _formatter = DartFormatter();
@override
Future<void> build(BuildStep buildStep) async {
final fileNameWithExtension = buildStep.inputId.pathSegments.last.replaceAll('-', '_');
final fileNameWithoutExtension = getFileNameBase(fileNameWithExtension);
final contents = await buildStep.readAsString(buildStep.inputId);
final codeGenerator = SwaggerCodeGenerator();
final responses =
codeGenerator.generateResponses(contents, getFileNameWithoutExtension(fileNameWithExtension), options);
final requestBodies =
codeGenerator.generateRequestBodies(contents, getFileNameWithoutExtension(fileNameWithExtension), options);
final enums = codeGenerator.generateEnums(contents, getFileNameWithoutExtension(fileNameWithExtension));
final converter =
codeGenerator.generateConverter(contents, getFileNameWithoutExtension(fileNameWithExtension), options);
var requestClass = <String, dynamic>{};
final requests = codeGenerator.generateRequests(contents, getClassNameFromFileName(fileNameWithExtension),
getFileNameWithoutExtension(fileNameWithExtension), options, requestClass);
// print('---------');
// print(requestClass);
final models = codeGenerator.generateModels(
contents, getFileNameWithoutExtension(fileNameWithExtension), options, requestClass);
final imports = codeGenerator.generateImportsContent(contents, fileNameWithoutExtension, models.isNotEmpty,
options.buildOnlyModels, enums.isNotEmpty, options.separateModels, options);
// final customDecoder = codeGenerator.generateCustomJsonConverter(
// contents, getFileNameWithoutExtension(fileNameWithExtension), options);
// final dateToJson = codeGenerator.generateDateToJson(contents);
final copyAssetId =
AssetId(buildStep.inputId.package, '${options.outputFolder}$fileNameWithoutExtension$_outputFileExtension');
if (!options.separateModels || !options.buildOnlyModels) {
await buildStep.writeAsString(
copyAssetId,
_generateFileContent(
imports, requests, converter, options.separateModels ? '' : models,
options.separateModels ? '' : responses, options.separateModels ? '' : requestBodies, '', '',
// customDecoder,
// dateToJson,
));
}
if (enums.isNotEmpty) {
///Write enums
final formatterEnums = _tryFormatCode(enums);
final enumsAssetId = AssetId(
buildStep.inputId.package, '${options.outputFolder}$fileNameWithoutExtension$_outputEnumsFileExtension');
await buildStep.writeAsString(enumsAssetId, formatterEnums);
}
if (options.separateModels) {
///Write models to separate file
final formattedModels = _tryFormatCode(_generateSeparateModelsFileContent(
models,
responses,
requestBodies,
fileNameWithoutExtension,
enums.isNotEmpty,
));
final enumsAssetId = AssetId(
buildStep.inputId.package, '${options.outputFolder}$fileNameWithoutExtension$_outputModelsFileExtension');
await buildStep.writeAsString(enumsAssetId, formattedModels);
}
///Write additional files on first input
// if (buildExtensions.keys.first == buildStep.inputId.path) {
// await _generateAdditionalFiles(contents, buildStep.inputId, buildStep, models.isNotEmpty);
// }
}
String _generateFileContent(String imports, String requests, String converter, String models, String responses,
String requestBodies, String customDecoder, String dateToJson) {
final result = """
$imports
${options.buildOnlyModels ? '' : requests}
${options.withConverter && !options.buildOnlyModels ? converter : ''}
$models
$responses
$requestBodies
${options.buildOnlyModels ? '' : customDecoder}
$dateToJson
""";
return _tryFormatCode(result);
}
String _tryFormatCode(String code) {
try {
final formattedResult = _formatter.format(code);
return formattedResult;
} catch (e) {
print('''[WARNING] Code formatting failed.
Please raise an issue on https://github.com/epam-cross-platform-lab/swagger-dart-code-generator/issues/
Reason: $e''');
return code;
}
}
// Future<void> _generateAdditionalFiles(
// String swaggerCode, AssetId inputId, BuildStep buildStep, bool hasModels) async {
// final codeGenerator = SwaggerCodeGenerator();
// final indexAssetId = AssetId(inputId.package, '${options.outputFolder}$_indexFileName');
// final imports = codeGenerator.generateIndexes(swaggerCode, buildExtensions);
// if (!options.buildOnlyModels) {
// await buildStep.writeAsString(indexAssetId, _formatter.format(imports));
// }
// if (options.withConverter && !options.buildOnlyModels) {
// final mappingAssetId = AssetId(inputId.package, '${options.outputFolder}$_mappingFileName');
// final mapping = codeGenerator.generateConverterMappings(swaggerCode, buildExtensions, hasModels);
// await buildStep.writeAsString(mappingAssetId, _formatter.format(mapping));
// }
// }
String _generateSeparateModelsFileContent(
String models,
String responses,
String requestBodies,
String fileNameWithoutExtension,
bool hasEnums,
) {
final enumsImport = hasEnums ? "import '${fileNameWithoutExtension}_enums.dart' as enums;" : '';
return '''
import 'package:json_annotation/json_annotation.dart';
import 'package:collection/collection.dart';
$enumsImport
part '${fileNameWithoutExtension}_models.g.dart';
$models
$responses
$requestBodies
''';
}
}