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> _generateExtensions(GeneratorOptions options) { final filesList = Directory(options.inputFolder) .listSync() .where((FileSystemEntity file) => _inputFileExtensions.any((ending) => file.path.endsWith(ending))); final result = >{}; filesList.forEach((FileSystemEntity element) { final name = getFileNameBase(element.path); result[element.path] = [ '${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> get buildExtensions => _buildExtensionsCopy ??= _generateExtensions(options); Map>? _buildExtensionsCopy; late GeneratorOptions options; final DartFormatter _formatter = DartFormatter(); @override Future 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 = {}; 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 _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 '''; } }