fix(refactor): correct import paths after pipeline migration

- Updated all internal import statements to point to the new 'pipeline' directory structure.
- Resolved all 'uri_does_not_exist' and 'undefined_class' errors caused by the refactoring.
- The project now passes 'dart analyze' with no errors.
This commit is contained in:
Max 2025-11-23 10:04:02 +08:00
parent 481db5bf8f
commit 53f89940ed
54 changed files with 147 additions and 169 deletions

View File

@ -118,8 +118,8 @@ dart run build_runner build --delete-conflicting-outputs
### 🧩 编程式用法 ### 🧩 编程式用法
```dart ```dart
import 'dart:io'; import 'dart:io';
import 'package:swagger_generator_flutter/parsers/swagger_data_parser.dart'; import 'package:swagger_generator_flutter/pipeline/parse/swagger_data_parser.dart';
import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/retrofit_api_generator.dart';
Future<void> main() async { Future<void> main() async {
// 解析本地或远程的 Swagger 文档(支持 file:// 与 http(s):// // 解析本地或远程的 Swagger 文档(支持 file:// 与 http(s)://
@ -321,10 +321,8 @@ swagger_generator_flutter/
lib/ # 核心代码 lib/ # 核心代码
commands/ # CLI 命令GenerateCommand 等) commands/ # CLI 命令GenerateCommand 等)
core/ # 配置、模型、异常 core/ # 配置、模型、异常
generators/ # 模型/API/文档生成器 pipeline/ # 核心处理流程 (Parse -> Validate -> Generate -> Render -> Output)
parsers/ # SwaggerDataParser
utils/ # FileUtils、StringUtils 等 utils/ # FileUtils、StringUtils 等
validators/ # Schema/Enhanced 校验器
tests/ # 基础测试示例 tests/ # 基础测试示例
generator_config.template.yaml generator_config.template.yaml
``` ```

View File

@ -117,16 +117,12 @@ flowchart TD
- **SwaggerCLI / GenerateCommand**: 注册命令、展示帮助、执行生成,支持多 Swagger 合并、版本化输出、Tag 过滤和忽略列表 - **SwaggerCLI / GenerateCommand**: 注册命令、展示帮助、执行生成,支持多 Swagger 合并、版本化输出、Tag 过滤和忽略列表
- **ConfigLoader / SwaggerConfig**: 解析 `generator_config.yaml`,提供 swagger_urls 顺序合并、输出目录、版本提取正则、ApiClient 命名、BaseResult 导入等配置 - **ConfigLoader / SwaggerConfig**: 解析 `generator_config.yaml`,提供 swagger_urls 顺序合并、输出目录、版本提取正则、ApiClient 命名、BaseResult 导入等配置
#### 2. 解析器 (Parsers) #### 2. Pipeline (核心流程)
- **SwaggerDataParser**: 支持 http(s) 与 file:// 源的 OpenAPI 解析,内置缓存与性能监测,解析 controllers/tags/schema 依赖 - **Parse**: `SwaggerDataParser` 支持 http(s) 与 file:// 源的 OpenAPI 解析,内置缓存与性能监测。
- **Validate**: `SchemaValidator``EnhancedValidator` 用于在生成前验证文档一致性。
#### 3. 验证器 (Validators) - **Generate**: `ModelCodeGenerator``RetrofitApiGenerator` 负责生成数据模型和 API 代码。
- **SchemaValidator / EnhancedValidator**: 基础与增强校验器,用于在生成前验证文档一致性 - **Render**: `TemplateRenderer` (内部使用) 负责模板渲染。
- **Output**: `GenerationOutputService` 负责将生成的文件写入磁盘。
#### 4. 生成器 (Generators)
- **ModelCodeGenerator**: 生成基于 Freezed 的不可变数据模型,自动获得 `copyWith`、`toString`、`==/hashCode` 等功能,并与 `json_serializable` 无缝集成。
- **RetrofitApiGenerator**: 支持按 tag 拆分、多版本目录与统一 ApiClient自动生成查询参数实体并处理版本化类名
- **DocumentationGenerator**: 输出 Markdown API 文档与统计摘要
#### 5. 工具类 (Utils) #### 5. 工具类 (Utils)
- **CacheManager / PerformanceMonitor**: 缓存解析结果并记录耗时 - **CacheManager / PerformanceMonitor**: 缓存解析结果并记录耗时

View File

@ -1,6 +1,6 @@
import 'package:swagger_generator_flutter/commands/services/service_typedefs.dart'; import 'package:swagger_generator_flutter/commands/services/service_typedefs.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/parsers/swagger_data_parser.dart'; import 'package:swagger_generator_flutter/pipeline/parse/impl/swagger_data_parser.dart';
class DocumentMergeService { class DocumentMergeService {
DocumentMergeService({SwaggerDataParser? parser}) DocumentMergeService({SwaggerDataParser? parser})

View File

@ -96,6 +96,12 @@ class ApiPath {
/// ///
final List<ApiSecurityRequirement> security; final List<ApiSecurityRequirement> security;
bool get isMultipart =>
parameters.any((p) => p.type == PropertyType.file) ||
(requestBody?.content.keys
.any((k) => k.contains('multipart/form-data')) ??
false);
} }
/// API参数信息 /// API参数信息

View File

@ -357,6 +357,7 @@ class ApiModel {
this.not, this.not,
this.discriminator, this.discriminator,
this.usageType = ModelUsageType.unknown, this.usageType = ModelUsageType.unknown,
this.type,
}); });
/// JSON创建ApiModel /// JSON创建ApiModel
@ -415,6 +416,7 @@ class ApiModel {
: null; : null;
return ApiModel( return ApiModel(
type: json['type'] as String?,
name: name, name: name,
description: json['description'] as String? ?? '', description: json['description'] as String? ?? '',
required: required, required: required,
@ -461,6 +463,7 @@ class ApiModel {
/// ///
/// API /// /// API ///
final ModelUsageType usageType; final ModelUsageType usageType;
final String? type;
/// 使 /// 使
bool get isComposition => bool get isComposition =>
@ -498,6 +501,7 @@ class ApiModel {
not: not, not: not,
discriminator: discriminator, discriminator: discriminator,
usageType: newUsageType, usageType: newUsageType,
type: type,
); );
} }
} }

View File

@ -1,4 +0,0 @@
/// Backward-compat shim for BaseGenerator
library;
export 'package:swagger_generator_flutter/pipeline/generate/impl/base_generator.dart';

View File

@ -1,4 +0,0 @@
/// Backward-compat shim for ModelCodeGenerator
library;
export 'package:swagger_generator_flutter/pipeline/generate/impl/model_code_generator.dart';

View File

@ -1,4 +0,0 @@
/// Backward-compat shim for RetrofitApiGenerator
library;
export 'package:swagger_generator_flutter/pipeline/generate/impl/retrofit_api_generator.dart';

View File

@ -11,23 +11,20 @@
/// - **Render**: `TemplateRenderer` for Mustache-based template rendering. /// - **Render**: `TemplateRenderer` for Mustache-based template rendering.
/// - **Output**: `GenerationOutputService` to write generated files to disk. /// - **Output**: `GenerationOutputService` to write generated files to disk.
library swagger_generator_flutter; library;
// --- Core Public API --- // --- Core Public API ---
export 'core/config_repository.dart'; export 'core/config_repository.dart';
export 'core/error_reporter.dart'; export 'core/error_reporter.dart';
export 'core/models.dart'; export 'core/models.dart';
// --- Pipeline API ---
// --- Pipeline API (New Structure) --- export 'pipeline/generate/apis.dart';
export 'pipeline/parse/swagger_data_parser.dart'; export 'pipeline/generate/models.dart';
export 'pipeline/validate/enhanced_validator.dart';
export 'pipeline/generate/model_code_generator.dart';
export 'pipeline/generate/retrofit_api_generator.dart';
export 'pipeline/render/template_renderer.dart';
export 'pipeline/output/generation_output_service.dart'; export 'pipeline/output/generation_output_service.dart';
export 'pipeline/parse/swagger_data_parser.dart';
export 'pipeline/render/template_renderer.dart';
export 'pipeline/validate/enhanced_validator.dart';
// --- Utilities --- // --- Utilities ---
export 'utils/logger.dart'; export 'utils/logger.dart';
export 'utils/path_resolver.dart'; export 'utils/path_resolver.dart';
export 'utils/string_utils.dart'; export 'utils/string_utils.dart';

View File

@ -1,5 +0,0 @@
/// Backward-compat shim for SwaggerDataParser
library;
export 'package:swagger_generator_flutter/pipeline/parse/impl/swagger_data_parser.dart';

View File

@ -1,4 +0,0 @@
/// Backward-compat shim for parser fetcher
library;
export 'package:swagger_generator_flutter/pipeline/parse/impl/swagger_fetcher.dart';

View File

@ -2,4 +2,4 @@
/// Re-export Retrofit API generator for pipeline-oriented imports. /// Re-export Retrofit API generator for pipeline-oriented imports.
library; library;
export 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; export 'impl/retrofit_api_generator.dart';

View File

@ -363,4 +363,3 @@ class GeneratorOptions {
final String endpointsFileName; final String endpointsFileName;
final String docsFileName; final String docsFileName;
} }

View File

@ -237,4 +237,3 @@ String _needsJsonKeyAnnotation(
return annotations.join(', '); return annotations.join(', ');
} }

View File

@ -118,4 +118,3 @@ String _getModelSubDirectory(ApiModel model) {
return 'result'; return 'result';
} }
} }

View File

@ -57,4 +57,3 @@ bool _isPaginationResponseModel(ApiModel model) {
return isTotalNumeric && isItemsArray; return isTotalNumeric && isItemsArray;
} }

View File

@ -1,11 +1,11 @@
import 'package:swagger_generator_flutter/core/config.dart'; import 'package:swagger_generator_flutter/core/config.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/generators/base_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/base_generator.dart';
import 'package:swagger_generator_flutter/utils/string_utils.dart'; import 'package:swagger_generator_flutter/utils/string_utils.dart';
part 'model/model_pagination_helpers.dart';
part 'model/model_file_writers.dart';
part 'model/model_content_builders.dart'; part 'model/model_content_builders.dart';
part 'model/model_file_writers.dart';
part 'model/model_pagination_helpers.dart';
/// ///
/// Dart模型类代码 /// Dart模型类代码
@ -57,4 +57,3 @@ class ModelCodeGenerator extends ModelGenerator {
return _buildIndexFile(this, modelFileNames); return _buildIndexFile(this, modelFileNames);
} }
} }

View File

@ -16,7 +16,7 @@ mixin RetrofitApiGrouping {
} }
/// API paths /// API paths
/// : Map<, Map<Tag, List<ApiPath>>> /// : `Map<, Map<Tag, List<ApiPath>>>`
Map<String, Map<String, List<ApiPath>>> groupApisByVersion( Map<String, Map<String, List<ApiPath>>> groupApisByVersion(
List<ApiPath> paths, List<ApiPath> paths,
) { ) {
@ -51,4 +51,3 @@ mixin RetrofitApiGrouping {
return groups; return groups;
} }
} }

View File

@ -18,4 +18,3 @@ class ApiMethodParameter {
final String description; final String description;
final dynamic defaultValue; final dynamic defaultValue;
} }

View File

@ -120,4 +120,3 @@ mixin RetrofitApiParameterEntities {
} }
} }
} }

View File

@ -288,4 +288,3 @@ mixin RetrofitApiReturnTypes {
return false; return false;
} }
} }

View File

@ -4,7 +4,7 @@ mixin RetrofitApiSchemaComposition {
RetrofitApiGenerator get _g => this as RetrofitApiGenerator; RetrofitApiGenerator get _g => this as RetrofitApiGenerator;
/// Schema /// Schema
String? _extractTypeFromCompositionSchema(Map<String, dynamic> schema) { String? extractTypeFromCompositionSchema(Map<String, dynamic> schema) {
if (schema['discriminator'] != null) { if (schema['discriminator'] != null) {
final discriminatorType = _handleDiscriminatorSchema(schema); final discriminatorType = _handleDiscriminatorSchema(schema);
if (discriminatorType != null) { if (discriminatorType != null) {
@ -52,7 +52,7 @@ mixin RetrofitApiSchemaComposition {
} }
return 'List<dynamic>'; return 'List<dynamic>';
} else { } else {
return _mapJsonTypeToFlutterType(type); return mapJsonTypeToFlutterType(type);
} }
} }
} }
@ -124,7 +124,7 @@ mixin RetrofitApiSchemaComposition {
} }
/// JSON Schema Flutter /// JSON Schema Flutter
String _mapJsonTypeToFlutterType(String jsonType) { String mapJsonTypeToFlutterType(String jsonType) {
switch (jsonType) { switch (jsonType) {
case 'string': case 'string':
return 'String'; return 'String';
@ -143,4 +143,3 @@ mixin RetrofitApiSchemaComposition {
} }
} }
} }

View File

@ -64,14 +64,14 @@ mixin RetrofitApiSchema {
return 'List<dynamic>'; return 'List<dynamic>';
} }
} else { } else {
return _mapJsonTypeToFlutterType(type); return _g.mapJsonTypeToFlutterType(type);
} }
} }
if (schema['allOf'] != null || if (schema['allOf'] != null ||
schema['oneOf'] != null || schema['oneOf'] != null ||
schema['anyOf'] != null) { schema['anyOf'] != null) {
return _extractTypeFromCompositionSchema(schema); return _g.extractTypeFromCompositionSchema(schema);
} }
return 'dynamic'; return 'dynamic';
@ -123,7 +123,9 @@ mixin RetrofitApiSchema {
} }
final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), ''); final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), '');
final methodName = '${path.method.value.toLowerCase()}${StringUtils.toPascalCase(lastPart)}'; final method = path.method.value.toLowerCase();
final pascalPart = StringUtils.toPascalCase(lastPart);
final methodName = '$method$pascalPart';
return methodName; return methodName;
} }
@ -145,4 +147,3 @@ mixin RetrofitApiSchema {
return isTotalNumeric && isItemsArray; return isTotalNumeric && isItemsArray;
} }
} }

View File

@ -5,8 +5,10 @@ mixin RetrofitApiTemplateData {
List<String> _getMainImports() { List<String> _getMainImports() {
final tagGroups = _g._groupPathsByTags(); final tagGroups = _g._groupPathsByTags();
final tagImports = final tagImports = tagGroups.keys.map((tag) {
tagGroups.keys.map((tag) => "import '${StringUtils.generateFileName(tag)}.dart';").toList(); final fileName = StringUtils.generateFileName(tag);
return "import '$fileName.dart';";
}).toList();
final config = ConfigRepository.loadSync(); final config = ConfigRepository.loadSync();
final customImports = config.packageImports; final customImports = config.packageImports;
@ -30,8 +32,10 @@ mixin RetrofitApiTemplateData {
Map<String, dynamic> _buildApiClassData(List<ApiPath> paths) { Map<String, dynamic> _buildApiClassData(List<ApiPath> paths) {
final baseUrl = final baseUrl =
_g.document.servers.isNotEmpty ? _g.document.servers.first.url : ''; _g.document.servers.isNotEmpty ? _g.document.servers.first.url : '';
final fileName = var fileName = '';
_g.className.isNotEmpty ? StringUtils.generateFileName(_g.className) : ''; if (_g.className.isNotEmpty) {
fileName = StringUtils.generateFileName(_g.className);
}
return { return {
'description': _g.document.description, 'description': _g.document.description,
@ -45,11 +49,11 @@ mixin RetrofitApiTemplateData {
List<String> _getImportsForPaths(List<ApiPath> paths) { List<String> _getImportsForPaths(List<ApiPath> paths) {
final imports = <String>{}; final imports = <String>{};
imports.add("import 'package:dio/dio.dart';");
imports.add("import 'package:retrofit/retrofit.dart';");
final config = ConfigRepository.loadSync(); final config = ConfigRepository.loadSync();
imports.addAll(config.packageImports.map((i) => "import '$i';")); imports
..add("import 'package:dio/dio.dart';")
..add("import 'package:retrofit/retrofit.dart';")
..addAll(config.packageImports.map((i) => "import '$i';"));
return imports.toList(); return imports.toList();
} }
@ -107,8 +111,9 @@ mixin RetrofitApiTemplateData {
final schemes = document.components.securitySchemes.values.toList(); final schemes = document.components.securitySchemes.values.toList();
return { return {
'hasSecuritySchemes': schemes.isNotEmpty, 'hasSecuritySchemes': schemes.isNotEmpty,
'securitySchemes': schemes.map((s) => {'name': s.name, 'type': s.type, 'scheme': s.scheme}).toList(), 'securitySchemes': schemes
.map((s) => {'name': s.name, 'type': s.type, 'scheme': s.scheme})
.toList(),
}; };
} }
} }

View File

@ -1,7 +1,7 @@
import 'package:swagger_generator_flutter/core/config_repository.dart'; import 'package:swagger_generator_flutter/core/config_repository.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/core/template_renderer.dart'; import 'package:swagger_generator_flutter/core/template_renderer.dart';
import 'package:swagger_generator_flutter/generators/base_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/base_generator.dart';
import 'package:swagger_generator_flutter/utils/string_utils.dart'; import 'package:swagger_generator_flutter/utils/string_utils.dart';
part 'retrofit_api/api_grouping.dart'; part 'retrofit_api/api_grouping.dart';
@ -18,12 +18,12 @@ part 'retrofit_api/api_template_data.dart';
class RetrofitApiGenerator extends BaseGenerator class RetrofitApiGenerator extends BaseGenerator
with with
RetrofitApiGrouping, RetrofitApiGrouping,
RetrofitApiTemplateData,
RetrofitApiSchemaComposition, RetrofitApiSchemaComposition,
RetrofitApiSchema, RetrofitApiSchema,
RetrofitApiReturnTypes, RetrofitApiReturnTypes,
RetrofitApiParameters, RetrofitApiParameters,
RetrofitApiParameterEntities { RetrofitApiParameterEntities,
RetrofitApiTemplateData {
RetrofitApiGenerator({ RetrofitApiGenerator({
this.className = 'ApiClient', this.className = 'ApiClient',
this.useRetrofit = true, this.useRetrofit = true,
@ -43,6 +43,9 @@ class RetrofitApiGenerator extends BaseGenerator
late SwaggerDocument document; late SwaggerDocument document;
final templateRenderer = TemplateRenderer(); final templateRenderer = TemplateRenderer();
@override
RetrofitApiGenerator get _g => this;
@override @override
String get generatorType => 'RetrofitApiGenerator'; String get generatorType => 'RetrofitApiGenerator';
@ -120,4 +123,3 @@ class RetrofitApiGenerator extends BaseGenerator
return apiFiles; return apiFiles;
} }
} }

View File

@ -2,4 +2,4 @@
/// Re-export model code generator for pipeline-oriented imports. /// Re-export model code generator for pipeline-oriented imports.
library; library;
export 'package:swagger_generator_flutter/generators/model_code_generator.dart'; export 'impl/model_code_generator.dart';

View File

@ -3,4 +3,3 @@
library; library;
export 'package:swagger_generator_flutter/commands/services/generation_output_service.dart'; export 'package:swagger_generator_flutter/commands/services/generation_output_service.dart';

View File

@ -1,13 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:swagger_generator_flutter/commands/generate_command.dart' show GenerateOptions; import 'package:swagger_generator_flutter/commands/generate_command.dart'
show GenerateOptions;
import 'package:swagger_generator_flutter/commands/services/service_typedefs.dart'; import 'package:swagger_generator_flutter/commands/services/service_typedefs.dart';
import 'package:swagger_generator_flutter/core/config.dart'; import 'package:swagger_generator_flutter/core/config.dart';
import 'package:swagger_generator_flutter/core/config_repository.dart'; import 'package:swagger_generator_flutter/core/config_repository.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/generators/model_code_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/model_code_generator.dart';
import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/retrofit_api_generator.dart';
import 'package:swagger_generator_flutter/utils/file_utils.dart'; import 'package:swagger_generator_flutter/utils/file_utils.dart';
import 'package:swagger_generator_flutter/utils/logger.dart'; import 'package:swagger_generator_flutter/utils/logger.dart';
@ -408,7 +409,8 @@ class GenerationOutputService {
buffer.writeln("export '$basePageResultImport';"); buffer.writeln("export '$basePageResultImport';");
} }
if ((baseResultImport.isNotEmpty || basePageResultImport.isNotEmpty) && fileNames.isNotEmpty) { if ((baseResultImport.isNotEmpty || basePageResultImport.isNotEmpty) &&
fileNames.isNotEmpty) {
buffer.writeln(); buffer.writeln();
} }
@ -437,7 +439,9 @@ class GenerationOutputService {
..writeln() ..writeln()
..writeln('## 控制器列表'); ..writeln('## 控制器列表');
document.controllers.forEach((name, controller) { document.controllers.forEach((name, controller) {
summary.writeln('- **$name**: ${controller.description} (${controller.paths.length} 个路径)'); summary.writeln(
'- **$name**: ${controller.description} (${controller.paths.length} 个路径)',
);
}); });
await FileUtils.writeFile('$outputDir/SUMMARY.md', summary.toString()); await FileUtils.writeFile('$outputDir/SUMMARY.md', summary.toString());
@ -530,7 +534,11 @@ class GenerationOutputService {
final className = fileName final className = fileName
.replaceAll('.dart', '') .replaceAll('.dart', '')
.split('_') .split('_')
.map((word) => word.isEmpty ? '' : (word[0].toUpperCase() + word.substring(1))) .map(
(word) => word.isEmpty
? ''
: (word[0].toUpperCase() + word.substring(1)),
)
.join(); .join();
apiClasses[version]!.add(className); apiClasses[version]!.add(className);
} }
@ -558,7 +566,9 @@ class GenerationOutputService {
for (final className in versionEntry.value) { for (final className in versionEntry.value) {
final suffix = version == 'v1' ? '' : versionUpper; final suffix = version == 'v1' ? '' : versionUpper;
buffer.writeln(' late final $className$suffix _${_toLowerCamelCase(className)}$suffix;'); buffer.writeln(
' late final $className$suffix _${_toLowerCamelCase(className)}$suffix;',
);
} }
} }
@ -590,13 +600,16 @@ class GenerationOutputService {
for (final versionEntry in apiClasses.entries) { for (final versionEntry in apiClasses.entries) {
final version = versionEntry.key; final version = versionEntry.key;
final versionUpper = version == 'v1' ? '' : version.toUpperCase(); final versionUpper = version == 'v1' ? '' : version.toUpperCase();
final versionLabel = version == 'v1' ? 'V1默认版本' : '${version.toUpperCase()} 版本'; final versionLabel =
version == 'v1' ? 'V1默认版本' : '${version.toUpperCase()} 版本';
buffer.writeln(' /// $versionLabel API'); buffer.writeln(' /// $versionLabel API');
for (final className in versionEntry.value) { for (final className in versionEntry.value) {
final fieldName = _toLowerCamelCase(className); final fieldName = _toLowerCamelCase(className);
final suffix = version == 'v1' ? '' : versionUpper; final suffix = version == 'v1' ? '' : versionUpper;
buffer.writeln(' $className$suffix get $fieldName$suffix => _$fieldName$suffix;'); buffer.writeln(
' $className$suffix get $fieldName$suffix => _$fieldName$suffix;',
);
} }
buffer.writeln(); buffer.writeln();
} }
@ -640,4 +653,3 @@ class GenerationOutputService {
await FileUtils.writeFile(indexPath, buffer.toString()); await FileUtils.writeFile(indexPath, buffer.toString());
} }
} }

View File

@ -3,7 +3,7 @@ import 'dart:convert';
import 'package:swagger_generator_flutter/core/config.dart'; import 'package:swagger_generator_flutter/core/config.dart';
import 'package:swagger_generator_flutter/core/exceptions.dart'; import 'package:swagger_generator_flutter/core/exceptions.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/parsers/swagger_fetcher.dart'; import 'package:swagger_generator_flutter/pipeline/parse/impl/swagger_fetcher.dart';
import 'package:swagger_generator_flutter/utils/cache_manager.dart'; import 'package:swagger_generator_flutter/utils/cache_manager.dart';
import 'package:swagger_generator_flutter/utils/logger.dart'; import 'package:swagger_generator_flutter/utils/logger.dart';
import 'package:swagger_generator_flutter/utils/performance_monitor.dart'; import 'package:swagger_generator_flutter/utils/performance_monitor.dart';

View File

@ -81,4 +81,3 @@ class SwaggerFetcher {
} }
} }
} }

View File

@ -2,4 +2,4 @@
/// Re-export swagger data parser for pipeline-oriented imports. /// Re-export swagger data parser for pipeline-oriented imports.
library; library;
export 'package:swagger_generator_flutter/parsers/swagger_data_parser.dart'; export './swagger_data_parser.dart';

View File

@ -2,5 +2,4 @@
/// Re-export swagger fetcher for pipeline-oriented imports. /// Re-export swagger fetcher for pipeline-oriented imports.
library; library;
export 'package:swagger_generator_flutter/parsers/swagger_fetcher.dart'; export 'impl/swagger_fetcher.dart';

View File

@ -82,4 +82,3 @@ class TemplateLoader {
_cache.clear(); _cache.clear();
} }
} }

View File

@ -90,4 +90,3 @@ class TemplateRenderer {
}; };
} }
} }

View File

@ -3,4 +3,3 @@
library; library;
export 'package:swagger_generator_flutter/core/template_renderer.dart'; export 'package:swagger_generator_flutter/core/template_renderer.dart';

View File

@ -1,5 +1,5 @@
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
/// ///
abstract class ValidationRule { abstract class ValidationRule {

View File

@ -1,6 +1,3 @@
/// Pipeline: validate /// Pipeline: validate
/// Re-export enhanced validator (decorator over schema validator). /// Re-export enhanced validator (decorator over schema validator).
library; library;
export 'package:swagger_generator_flutter/validators/enhanced_validator.dart';

View File

@ -4,7 +4,7 @@ library;
import 'package:swagger_generator_flutter/core/error_reporter.dart'; import 'package:swagger_generator_flutter/core/error_reporter.dart';
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/schema_validator.dart'; import 'package:swagger_generator_flutter/pipeline/validate/schema_validator.dart';
/// OpenAPI /// OpenAPI
class EnhancedValidator { class EnhancedValidator {
@ -54,8 +54,9 @@ class EnhancedValidator {
severity: ErrorSeverity.warning, severity: ErrorSeverity.warning,
category: ErrorCategory.bestPractice, category: ErrorCategory.bestPractice,
jsonPath: warning.path, jsonPath: warning.path,
suggestions: suggestions: warning.suggestion != null
warning.suggestion != null ? [FixSuggestion(description: warning.suggestion!)] : [], ? [FixSuggestion(description: warning.suggestion!)]
: [],
); );
} }
@ -82,7 +83,8 @@ class EnhancedValidator {
/// ///
void _checkBestPractices(SwaggerDocument document) { void _checkBestPractices(SwaggerDocument document) {
// 使 // 使
final hasTaggedOperations = document.paths.values.any((path) => path.tags.isNotEmpty); final hasTaggedOperations =
document.paths.values.any((path) => path.tags.isNotEmpty);
if (!hasTaggedOperations) { if (!hasTaggedOperations) {
_errorReporter.reportError( _errorReporter.reportError(
id: 'NO_OPERATION_TAGS', id: 'NO_OPERATION_TAGS',
@ -108,14 +110,16 @@ class EnhancedValidator {
_errorReporter.reportError( _errorReporter.reportError(
id: 'MISSING_OPERATION_ID', id: 'MISSING_OPERATION_ID',
title: 'Missing Operation ID', title: 'Missing Operation ID',
description: 'Operation should have an operationId for better code generation.', description:
'Operation should have an operationId for better code generation.',
severity: ErrorSeverity.warning, severity: ErrorSeverity.warning,
category: ErrorCategory.bestPractice, category: ErrorCategory.bestPractice,
jsonPath: 'paths["$pathPattern"][${method.value}].operationId', jsonPath: 'paths["$pathPattern"][${method.value}].operationId',
suggestions: [ suggestions: [
FixSuggestion( FixSuggestion(
description: 'Add a unique operationId', description: 'Add a unique operationId',
codeExample: '"operationId": "${_generateOperationId(pathPattern, method)}"', codeExample:
'"operationId": "${_generateOperationId(pathPattern, method)}"',
), ),
], ],
); );
@ -125,7 +129,10 @@ class EnhancedValidator {
/// ID /// ID
String _generateOperationId(String path, HttpMethod method) { String _generateOperationId(String path, HttpMethod method) {
final pathParts = path.split('/').where((part) => part.isNotEmpty && !part.startsWith('{')).toList(); final pathParts = path
.split('/')
.where((part) => part.isNotEmpty && !part.startsWith('{'))
.toList();
final methodPrefix = method.value.toLowerCase(); final methodPrefix = method.value.toLowerCase();
if (pathParts.length >= 3) { if (pathParts.length >= 3) {
@ -141,8 +148,11 @@ class EnhancedValidator {
String _toPascalCase(String input) { String _toPascalCase(String input) {
return input return input
.split('_') .split('_')
.map((word) => word.isEmpty ? '' : word[0].toUpperCase() + word.substring(1).toLowerCase()) .map(
(word) => word.isEmpty
? ''
: word[0].toUpperCase() + word.substring(1).toLowerCase(),
)
.join(); .join();
} }
} }

View File

@ -3,19 +3,19 @@
library; library;
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
import 'package:swagger_generator_flutter/validators/rules/component_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/component_rules.dart';
import 'package:swagger_generator_flutter/validators/rules/info_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/info_rules.dart';
import 'package:swagger_generator_flutter/validators/rules/path_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/path_rules.dart';
import 'package:swagger_generator_flutter/validators/rules/security_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/security_rules.dart';
import 'package:swagger_generator_flutter/validators/rules/server_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/server_rules.dart';
import 'package:swagger_generator_flutter/validators/rules/structure_rules.dart'; import 'package:swagger_generator_flutter/pipeline/validate/rules/structure_rules.dart';
export 'package:swagger_generator_flutter/validators/core/validation_context.dart'; export 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
export 'package:swagger_generator_flutter/validators/core/validation_result.dart'; export 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
export 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; export 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// Schema /// Schema
class SchemaValidator { class SchemaValidator {
@ -52,4 +52,3 @@ class SchemaValidator {
return results.merge(); return results.merge();
} }
} }

View File

@ -1,7 +1,7 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// ///
class ComponentValidationRule extends ValidationRule { class ComponentValidationRule extends ValidationRule {

View File

@ -1,6 +1,6 @@
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// API /// API
class InfoValidationRule extends ValidationRule { class InfoValidationRule extends ValidationRule {

View File

@ -1,7 +1,7 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// ///
class PathValidationRule extends ValidationRule { class PathValidationRule extends ValidationRule {

View File

@ -1,7 +1,7 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// ///
class SecurityValidationRule extends ValidationRule { class SecurityValidationRule extends ValidationRule {

View File

@ -1,6 +1,6 @@
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// ///
class ServerValidationRule extends ValidationRule { class ServerValidationRule extends ValidationRule {

View File

@ -1,7 +1,7 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_context.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
import 'package:swagger_generator_flutter/validators/core/validation_rule.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
/// ///
class StructureValidationRule extends ValidationRule { class StructureValidationRule extends ValidationRule {

View File

@ -7,10 +7,5 @@ export 'core/error_reporter.dart';
// //
export 'core/models.dart'; export 'core/models.dart';
export 'core/performance_parser.dart'; export 'core/performance_parser.dart';
//
export 'generators/retrofit_api_generator.dart';
// //
export 'utils/string_utils.dart'; export 'utils/string_utils.dart';
//
export 'validators/enhanced_validator.dart';
export 'validators/schema_validator.dart';

View File

@ -1,5 +1,5 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/validators/core/validation_result.dart'; import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
/// ///
/// ///
@ -400,7 +400,9 @@ class TypeValidator {
/// ///
static ValidationResult _validateParameter( static ValidationResult _validateParameter(
ApiParameter parameter, String parentPath,) { ApiParameter parameter,
String parentPath,
) {
final errors = <ValidationError>[]; final errors = <ValidationError>[];
final warnings = <ValidationWarning>[]; final warnings = <ValidationWarning>[];
final currentPath = '$parentPath.parameters[${parameter.name}]'; final currentPath = '$parentPath.parameters[${parameter.name}]';

View File

@ -1,4 +0,0 @@
/// Backward-compat shim for EnhancedValidator
library;
export 'package:swagger_generator_flutter/pipeline/validate/impl/enhanced_validator.dart';

View File

@ -1,5 +0,0 @@
/// Backward-compat shim for schema validator
library;
export 'package:swagger_generator_flutter/pipeline/validate/impl/schema_validator.dart';

View File

@ -1,5 +1,5 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/retrofit_api_generator.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
void main() { void main() {

View File

@ -3,8 +3,8 @@ import 'dart:io';
import 'package:swagger_generator_flutter/core/error_reporter.dart'; import 'package:swagger_generator_flutter/core/error_reporter.dart';
import 'package:swagger_generator_flutter/core/performance_parser.dart'; import 'package:swagger_generator_flutter/core/performance_parser.dart';
import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/retrofit_api_generator.dart';
import 'package:swagger_generator_flutter/validators/enhanced_validator.dart'; import 'package:swagger_generator_flutter/pipeline/validate/impl/enhanced_validator.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
void main() { void main() {

View File

@ -1,6 +1,6 @@
import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/models.dart';
import 'package:swagger_generator_flutter/generators/model_code_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/apis.dart';
import 'package:swagger_generator_flutter/generators/retrofit_api_generator.dart'; import 'package:swagger_generator_flutter/pipeline/generate/models.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
void main() { void main() {