160 lines
4.3 KiB
Dart
160 lines
4.3 KiB
Dart
import 'package:swagger_generator_flutter/core/models.dart';
|
|
import 'package:swagger_generator_flutter/pipeline/validate/core/validation_context.dart';
|
|
import 'package:swagger_generator_flutter/pipeline/validate/core/validation_result.dart';
|
|
import 'package:swagger_generator_flutter/pipeline/validate/core/validation_rule.dart';
|
|
|
|
/// 组件验证规则
|
|
class ComponentValidationRule extends ValidationRule {
|
|
@override
|
|
String get id => 'component_validation';
|
|
|
|
@override
|
|
String get name => '组件验证';
|
|
|
|
@override
|
|
ValidationResult validate(ValidationContext context) {
|
|
final components = context.document.components;
|
|
final errors = <ValidationError>[];
|
|
final warnings = <ValidationWarning>[];
|
|
|
|
// 验证 schemas
|
|
components.schemas.forEach((name, model) {
|
|
_validateModel(model, 'components.schemas["$name"]', errors, warnings);
|
|
});
|
|
|
|
// 验证安全方案
|
|
components.securitySchemes.forEach((name, scheme) {
|
|
_validateSecurityScheme(
|
|
scheme,
|
|
'components.securitySchemes["$name"]',
|
|
errors,
|
|
warnings,
|
|
);
|
|
});
|
|
|
|
return ValidationResult(
|
|
isValid: errors.isEmpty,
|
|
errors: errors,
|
|
warnings: warnings,
|
|
);
|
|
}
|
|
|
|
void _validateModel(
|
|
ApiModel model,
|
|
String path,
|
|
List<ValidationError> errors,
|
|
List<ValidationWarning> warnings,
|
|
) {
|
|
if (model.name.isEmpty) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.name',
|
|
message: '模型名称不能为空',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
|
|
// 验证属性
|
|
model.properties.forEach((name, property) {
|
|
_validateProperty(
|
|
property,
|
|
'$path.properties["$name"]',
|
|
errors,
|
|
warnings,
|
|
);
|
|
});
|
|
|
|
// 验证必需字段
|
|
for (final requiredField in model.required) {
|
|
if (!model.properties.containsKey(requiredField)) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.required',
|
|
message: '必需字段 "$requiredField" 在属性中未定义',
|
|
type: ValidationErrorType.reference,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
void _validateProperty(
|
|
ApiProperty property,
|
|
String path,
|
|
List<ValidationError> errors,
|
|
List<ValidationWarning> warnings,
|
|
) {
|
|
if (property.name.isEmpty) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.name',
|
|
message: '属性名称不能为空',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
|
|
if (property.type == PropertyType.unknown) {
|
|
warnings.add(
|
|
ValidationWarning(
|
|
path: '$path.type',
|
|
message: '属性类型未知',
|
|
suggestion: '建议明确指定属性类型',
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _validateSecurityScheme(
|
|
ApiSecurityScheme scheme,
|
|
String path,
|
|
List<ValidationError> errors,
|
|
List<ValidationWarning> warnings,
|
|
) {
|
|
switch (scheme.type) {
|
|
case SecuritySchemeType.apiKey:
|
|
if (scheme.name == null || scheme.name!.isEmpty) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.name',
|
|
message: 'API Key 安全方案必须指定参数名称',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
case SecuritySchemeType.http:
|
|
if (scheme.scheme == null || scheme.scheme!.isEmpty) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.scheme',
|
|
message: 'HTTP 安全方案必须指定认证方案',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
case SecuritySchemeType.oauth2:
|
|
if (scheme.flows == null) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.flows',
|
|
message: 'OAuth2 安全方案必须定义流程',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
case SecuritySchemeType.openIdConnect:
|
|
if (scheme.openIdConnectUrl == null ||
|
|
scheme.openIdConnectUrl!.isEmpty) {
|
|
errors.add(
|
|
ValidationError(
|
|
path: '$path.openIdConnectUrl',
|
|
message: 'OpenID Connect 安全方案必须指定 URL',
|
|
type: ValidationErrorType.required,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|