223 lines
7.7 KiB
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
|
|
''';
|
|
}
|
|
}
|