feat: update
This commit is contained in:
parent
53f89940ed
commit
d6a31d5a24
|
|
@ -27,4 +27,3 @@ 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';
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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/utils/string_utils.dart';
|
import 'package:swagger_generator_flutter/utils/string_helper.dart';
|
||||||
|
|
||||||
/// 代码生成器基类
|
/// 代码生成器基类
|
||||||
/// 定义通用的接口和功能
|
/// 定义通用的接口和功能
|
||||||
|
|
@ -16,7 +16,7 @@ abstract class BaseGenerator {
|
||||||
/// [description] 文件描述
|
/// [description] 文件描述
|
||||||
/// [fileName] 文件名(可选)
|
/// [fileName] 文件名(可选)
|
||||||
String generateFileHeader(String description, {String? fileName}) {
|
String generateFileHeader(String description, {String? fileName}) {
|
||||||
final header = StringUtils.generateFileHeader(
|
final header = StringHelper.generateFileHeader(
|
||||||
description,
|
description,
|
||||||
SwaggerConfig.swaggerJsonUrls.isNotEmpty
|
SwaggerConfig.swaggerJsonUrls.isNotEmpty
|
||||||
? SwaggerConfig.swaggerJsonUrls.first
|
? SwaggerConfig.swaggerJsonUrls.first
|
||||||
|
|
@ -105,7 +105,7 @@ abstract class ModelGenerator extends BaseGenerator {
|
||||||
throw CodeGenerationException('模型不是枚举类型', generatorType: generatorType);
|
throw CodeGenerationException('模型不是枚举类型', generatorType: generatorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
final className = StringUtils.generateClassName(model.name);
|
final className = StringHelper.generateClassName(model.name);
|
||||||
final enumType = model.enumType?.value ?? 'string';
|
final enumType = model.enumType?.value ?? 'string';
|
||||||
final valueType =
|
final valueType =
|
||||||
enumType == 'integer' || enumType == 'number' ? 'int' : 'String';
|
enumType == 'integer' || enumType == 'number' ? 'int' : 'String';
|
||||||
|
|
@ -116,7 +116,7 @@ abstract class ModelGenerator extends BaseGenerator {
|
||||||
|
|
||||||
// 生成枚举类
|
// 生成枚举类
|
||||||
if (model.description.isNotEmpty) {
|
if (model.description.isNotEmpty) {
|
||||||
buffer.writeln(StringUtils.generateComment(model.description));
|
buffer.writeln(StringHelper.generateComment(model.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.writeln('enum $className {');
|
buffer.writeln('enum $className {');
|
||||||
|
|
@ -124,7 +124,7 @@ abstract class ModelGenerator extends BaseGenerator {
|
||||||
// 生成枚举值
|
// 生成枚举值
|
||||||
for (var i = 0; i < model.enumValues.length; i++) {
|
for (var i = 0; i < model.enumValues.length; i++) {
|
||||||
final value = model.enumValues[i];
|
final value = model.enumValues[i];
|
||||||
final enumName = StringUtils.generateEnumValueName(value, i);
|
final enumName = StringHelper.generateEnumValueName(value, i);
|
||||||
final enumLine = enumType == 'integer' || enumType == 'number'
|
final enumLine = enumType == 'integer' || enumType == 'number'
|
||||||
? ' $enumName($value),'
|
? ' $enumName($value),'
|
||||||
: " $enumName('$value'),";
|
: " $enumName('$value'),";
|
||||||
|
|
@ -226,7 +226,7 @@ abstract class ModelGenerator extends BaseGenerator {
|
||||||
return 'Map<String, dynamic>';
|
return 'Map<String, dynamic>';
|
||||||
case PropertyType.reference:
|
case PropertyType.reference:
|
||||||
return property.reference != null
|
return property.reference != null
|
||||||
? StringUtils.generateClassName(property.reference!)
|
? StringHelper.generateClassName(property.reference!)
|
||||||
: 'dynamic';
|
: 'dynamic';
|
||||||
case PropertyType.file:
|
case PropertyType.file:
|
||||||
return 'dynamic';
|
return 'dynamic';
|
||||||
|
|
@ -248,7 +248,7 @@ abstract class ModelGenerator extends BaseGenerator {
|
||||||
items.name != 'integer' &&
|
items.name != 'integer' &&
|
||||||
items.name != 'number' &&
|
items.name != 'number' &&
|
||||||
items.name != 'boolean') {
|
items.name != 'boolean') {
|
||||||
return StringUtils.generateClassName(items.name);
|
return StringHelper.generateClassName(items.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是基本类型,转换为对应的Dart类型
|
// 如果是基本类型,转换为对应的Dart类型
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ String _generateModelCodeWithoutImports(
|
||||||
}
|
}
|
||||||
|
|
||||||
String _generateEnumCodeWithoutImports(ApiModel model) {
|
String _generateEnumCodeWithoutImports(ApiModel model) {
|
||||||
final className = StringUtils.generateClassName(model.name);
|
final className = StringHelper.generateClassName(model.name);
|
||||||
final enumType = model.enumType?.value ?? 'string';
|
final enumType = model.enumType?.value ?? 'string';
|
||||||
final valueType =
|
final valueType =
|
||||||
enumType == 'integer' || enumType == 'number' ? 'int' : 'String';
|
enumType == 'integer' || enumType == 'number' ? 'int' : 'String';
|
||||||
final buffer = StringBuffer();
|
final buffer = StringBuffer();
|
||||||
|
|
||||||
if (model.description.isNotEmpty) {
|
if (model.description.isNotEmpty) {
|
||||||
buffer.writeln(StringUtils.generateComment(model.description));
|
buffer.writeln(StringHelper.generateComment(model.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
|
|
@ -27,7 +27,7 @@ String _generateEnumCodeWithoutImports(ApiModel model) {
|
||||||
|
|
||||||
for (var i = 0; i < model.enumValues.length; i++) {
|
for (var i = 0; i < model.enumValues.length; i++) {
|
||||||
final value = model.enumValues[i];
|
final value = model.enumValues[i];
|
||||||
final enumName = StringUtils.generateEnumValueName(value, i);
|
final enumName = StringHelper.generateEnumValueName(value, i);
|
||||||
final enumLine = enumType == 'integer' || enumType == 'number'
|
final enumLine = enumType == 'integer' || enumType == 'number'
|
||||||
? ' $enumName($value),'
|
? ' $enumName($value),'
|
||||||
: " $enumName('$value'),";
|
: " $enumName('$value'),";
|
||||||
|
|
@ -73,10 +73,10 @@ String _generateAnnotatedModelCodeWithoutImports(
|
||||||
ModelCodeGenerator generator,
|
ModelCodeGenerator generator,
|
||||||
ApiModel model,
|
ApiModel model,
|
||||||
) {
|
) {
|
||||||
final className = StringUtils.generateClassName(model.name);
|
final className = StringHelper.generateClassName(model.name);
|
||||||
final buffer = StringBuffer();
|
final buffer = StringBuffer();
|
||||||
|
|
||||||
final partFileName = StringUtils.generateFileName(model.name);
|
final partFileName = StringHelper.generateFileName(model.name);
|
||||||
final freezedPart = partFileName.replaceAll('.dart', '.freezed.dart');
|
final freezedPart = partFileName.replaceAll('.dart', '.freezed.dart');
|
||||||
final generatedPart = partFileName.replaceAll('.dart', '.g.dart');
|
final generatedPart = partFileName.replaceAll('.dart', '.g.dart');
|
||||||
buffer
|
buffer
|
||||||
|
|
@ -85,7 +85,7 @@ String _generateAnnotatedModelCodeWithoutImports(
|
||||||
..writeln();
|
..writeln();
|
||||||
|
|
||||||
if (model.description.isNotEmpty) {
|
if (model.description.isNotEmpty) {
|
||||||
buffer.writeln(StringUtils.generateComment(model.description));
|
buffer.writeln(StringHelper.generateComment(model.description));
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
|
|
@ -100,11 +100,11 @@ String _generateAnnotatedModelCodeWithoutImports(
|
||||||
property.format != 'date';
|
property.format != 'date';
|
||||||
final hasDefaultValue = property.defaultValue != null || isNormalString;
|
final hasDefaultValue = property.defaultValue != null || isNormalString;
|
||||||
final nullable = hasDefaultValue ? '' : (property.nullable ? '?' : '');
|
final nullable = hasDefaultValue ? '' : (property.nullable ? '?' : '');
|
||||||
final dartPropName = StringUtils.toDartPropertyName(propName);
|
final dartPropName = StringHelper.toDartPropertyName(propName);
|
||||||
|
|
||||||
if (property.description.isNotEmpty) {
|
if (property.description.isNotEmpty) {
|
||||||
buffer.writeln(
|
buffer.writeln(
|
||||||
' ${StringUtils.generateComment(property.description)}',
|
' ${StringHelper.generateComment(property.description)}',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ String _generateSubDirectoryIndexFile(
|
||||||
..sort((a, b) => a.name.compareTo(b.name));
|
..sort((a, b) => a.name.compareTo(b.name));
|
||||||
|
|
||||||
for (final model in sortedModels) {
|
for (final model in sortedModels) {
|
||||||
final fileName = StringUtils.generateFileName(model.name);
|
final fileName = StringHelper.generateFileName(model.name);
|
||||||
buffer.writeln("export '$fileName';");
|
buffer.writeln("export '$fileName';");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ Map<String, String> buildSeparateModelFiles(ModelCodeGenerator generator) {
|
||||||
final subDir = _getModelSubDirectory(model);
|
final subDir = _getModelSubDirectory(model);
|
||||||
modelsByDirectory.putIfAbsent(subDir, () => []).add(model);
|
modelsByDirectory.putIfAbsent(subDir, () => []).add(model);
|
||||||
|
|
||||||
final fileName = StringUtils.generateFileName(model.name);
|
final fileName = StringHelper.generateFileName(model.name);
|
||||||
final filePath = '$subDir/$fileName';
|
final filePath = '$subDir/$fileName';
|
||||||
final content = buildSingleModelFile(generator, model, fileName: fileName);
|
final content = buildSingleModelFile(generator, model, fileName: fileName);
|
||||||
files[filePath] = content;
|
files[filePath] = content;
|
||||||
|
|
@ -38,7 +38,7 @@ String buildSingleModelFile(
|
||||||
..writeln(
|
..writeln(
|
||||||
generator.generateFileHeader(
|
generator.generateFileHeader(
|
||||||
'${model.name} 模型定义',
|
'${model.name} 模型定义',
|
||||||
fileName: fileName ?? StringUtils.generateFileName(model.name),
|
fileName: fileName ?? StringHelper.generateFileName(model.name),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
..writeln();
|
..writeln();
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ String _getPaginationItemType(ApiModel items) {
|
||||||
items.name != 'integer' &&
|
items.name != 'integer' &&
|
||||||
items.name != 'number' &&
|
items.name != 'number' &&
|
||||||
items.name != 'boolean') {
|
items.name != 'boolean') {
|
||||||
return StringUtils.generateClassName(items.name);
|
return StringHelper.generateClassName(items.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (items.name) {
|
switch (items.name) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
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/pipeline/generate/impl/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_helper.dart';
|
||||||
|
|
||||||
part 'model/model_content_builders.dart';
|
part 'model/model_content_builders.dart';
|
||||||
part 'model/model_file_writers.dart';
|
part 'model/model_file_writers.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
/// 生成参数实体类的类名
|
/// 生成参数实体类的类名
|
||||||
String _generateParameterEntityClassName(ApiPath path) {
|
String _generateParameterEntityClassName(ApiPath path) {
|
||||||
final methodName = _g._generateSimpleMethodName(path);
|
final methodName = _g._generateSimpleMethodName(path);
|
||||||
return '${StringUtils.toPascalCase(methodName)}Parameters';
|
return '${StringHelper.toPascalCase(methodName)}Parameters';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 生成参数实体类
|
/// 生成参数实体类
|
||||||
|
|
@ -19,7 +19,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
..writeln(
|
..writeln(
|
||||||
_g.generateFileHeader(
|
_g.generateFileHeader(
|
||||||
'参数实体类 - $className',
|
'参数实体类 - $className',
|
||||||
fileName: '${StringUtils.toSnakeCase(className)}.dart',
|
fileName: '${StringHelper.toSnakeCase(className)}.dart',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
..writeln(
|
..writeln(
|
||||||
|
|
@ -28,12 +28,12 @@ mixin RetrofitApiParameterEntities {
|
||||||
..writeln()
|
..writeln()
|
||||||
..writeln("import 'package:json_annotation/json_annotation.dart';")
|
..writeln("import 'package:json_annotation/json_annotation.dart';")
|
||||||
..writeln()
|
..writeln()
|
||||||
..writeln("part '${StringUtils.toSnakeCase(className)}.g.dart';")
|
..writeln("part '${StringHelper.toSnakeCase(className)}.g.dart';")
|
||||||
..writeln()
|
..writeln()
|
||||||
..writeln('@JsonSerializable(checked: true, includeIfNull: false)')
|
..writeln('@JsonSerializable(checked: true, includeIfNull: false)')
|
||||||
..writeln('class $className {');
|
..writeln('class $className {');
|
||||||
for (final param in queryParams) {
|
for (final param in queryParams) {
|
||||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
final dartName = StringHelper.toDartPropertyName(param.name);
|
||||||
final dartType = _g._getDartType(param.type);
|
final dartType = _g._getDartType(param.type);
|
||||||
final nullable = param.required ? '' : '?';
|
final nullable = param.required ? '' : '?';
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
|
|
||||||
buffer.writeln(' const $className({');
|
buffer.writeln(' const $className({');
|
||||||
for (final param in queryParams) {
|
for (final param in queryParams) {
|
||||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
final dartName = StringHelper.toDartPropertyName(param.name);
|
||||||
final required = param.required ? 'required ' : '';
|
final required = param.required ? 'required ' : '';
|
||||||
buffer.writeln(' ${required}this.$dartName,');
|
buffer.writeln(' ${required}this.$dartName,');
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
..writeln(' Map<String, dynamic> toQueryMap() {')
|
..writeln(' Map<String, dynamic> toQueryMap() {')
|
||||||
..writeln(' final map = <String, dynamic>{};');
|
..writeln(' final map = <String, dynamic>{};');
|
||||||
for (final param in queryParams) {
|
for (final param in queryParams) {
|
||||||
final dartName = StringUtils.toDartPropertyName(param.name);
|
final dartName = StringHelper.toDartPropertyName(param.name);
|
||||||
buffer.writeln(
|
buffer.writeln(
|
||||||
" if ($dartName != null) map['${param.name}'] = $dartName;",
|
" if ($dartName != null) map['${param.name}'] = $dartName;",
|
||||||
);
|
);
|
||||||
|
|
@ -96,7 +96,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
for (final entry in _generatedParameterEntities.entries) {
|
for (final entry in _generatedParameterEntities.entries) {
|
||||||
final className = entry.key;
|
final className = entry.key;
|
||||||
final content = entry.value;
|
final content = entry.value;
|
||||||
final fileName = StringUtils.generateFileName(className);
|
final fileName = StringHelper.generateFileName(className);
|
||||||
files[fileName] = content;
|
files[fileName] = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ mixin RetrofitApiParameters {
|
||||||
for (final param in pathParams) {
|
for (final param in pathParams) {
|
||||||
parameters.add(
|
parameters.add(
|
||||||
ApiMethodParameter(
|
ApiMethodParameter(
|
||||||
name: StringUtils.toDartPropertyName(param.name),
|
name: StringHelper.toDartPropertyName(param.name),
|
||||||
type: _getDartType(param.type),
|
type: _getDartType(param.type),
|
||||||
annotation: _g.useRetrofit ? "@Path('${param.name}')" : '',
|
annotation: _g.useRetrofit ? "@Path('${param.name}')" : '',
|
||||||
required: param.required,
|
required: param.required,
|
||||||
|
|
@ -46,7 +46,7 @@ mixin RetrofitApiParameters {
|
||||||
final nullable = param.required ? '' : '?';
|
final nullable = param.required ? '' : '?';
|
||||||
parameters.add(
|
parameters.add(
|
||||||
ApiMethodParameter(
|
ApiMethodParameter(
|
||||||
name: StringUtils.toDartPropertyName(param.name),
|
name: StringHelper.toDartPropertyName(param.name),
|
||||||
type: '${_getDartType(param.type)}$nullable',
|
type: '${_getDartType(param.type)}$nullable',
|
||||||
annotation: _g.useRetrofit ? "@Query('${param.name}')" : '',
|
annotation: _g.useRetrofit ? "@Query('${param.name}')" : '',
|
||||||
required: param.required,
|
required: param.required,
|
||||||
|
|
@ -64,7 +64,7 @@ mixin RetrofitApiParameters {
|
||||||
final bodyType = _inferRequestBodyType(path);
|
final bodyType = _inferRequestBodyType(path);
|
||||||
parameters.add(
|
parameters.add(
|
||||||
ApiMethodParameter(
|
ApiMethodParameter(
|
||||||
name: StringUtils.toDartPropertyName(
|
name: StringHelper.toDartPropertyName(
|
||||||
param.name.isNotEmpty ? param.name : 'request',
|
param.name.isNotEmpty ? param.name : 'request',
|
||||||
),
|
),
|
||||||
type: bodyType,
|
type: bodyType,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ mixin RetrofitApiSchemaComposition {
|
||||||
if (schemaData[r'$ref'] != null) {
|
if (schemaData[r'$ref'] != null) {
|
||||||
final ref = schemaData[r'$ref'] as String;
|
final ref = schemaData[r'$ref'] as String;
|
||||||
final refName = ref.split('/').last;
|
final refName = ref.split('/').last;
|
||||||
return StringUtils.generateClassName(refName);
|
return StringHelper.generateClassName(refName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schemaData['type'] != null) {
|
if (schemaData['type'] != null) {
|
||||||
|
|
@ -67,7 +67,7 @@ mixin RetrofitApiSchemaComposition {
|
||||||
if (schemaData is Map<String, dynamic> && schemaData[r'$ref'] != null) {
|
if (schemaData is Map<String, dynamic> && schemaData[r'$ref'] != null) {
|
||||||
final ref = schemaData[r'$ref'] as String;
|
final ref = schemaData[r'$ref'] as String;
|
||||||
final refName = ref.split('/').last;
|
final refName = ref.split('/').last;
|
||||||
refTypes.add(StringUtils.generateClassName(refName));
|
refTypes.add(StringHelper.generateClassName(refName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ mixin RetrofitApiSchemaComposition {
|
||||||
for (final value in mapping.values) {
|
for (final value in mapping.values) {
|
||||||
if (value is String) {
|
if (value is String) {
|
||||||
final refName = value.split('/').last;
|
final refName = value.split('/').last;
|
||||||
mappedTypes.add(StringUtils.generateClassName(refName));
|
mappedTypes.add(StringHelper.generateClassName(refName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ mixin RetrofitApiSchema {
|
||||||
if (schema[r'$ref'] != null) {
|
if (schema[r'$ref'] != null) {
|
||||||
final ref = schema[r'$ref'] as String;
|
final ref = schema[r'$ref'] as String;
|
||||||
final refName = ref.split('/').last;
|
final refName = ref.split('/').last;
|
||||||
return StringUtils.generateClassName(refName);
|
return StringHelper.generateClassName(refName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema['type'] != null) {
|
if (schema['type'] != null) {
|
||||||
|
|
@ -110,7 +110,7 @@ mixin RetrofitApiSchema {
|
||||||
/// 生成简单方法名
|
/// 生成简单方法名
|
||||||
String _generateSimpleMethodName(ApiPath path) {
|
String _generateSimpleMethodName(ApiPath path) {
|
||||||
if (path.operationId.isNotEmpty) {
|
if (path.operationId.isNotEmpty) {
|
||||||
return StringUtils.toCamelCase(path.operationId);
|
return StringHelper.toCamelCase(path.operationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
final pathParts = path.path
|
final pathParts = path.path
|
||||||
|
|
@ -124,7 +124,7 @@ mixin RetrofitApiSchema {
|
||||||
|
|
||||||
final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), '');
|
final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), '');
|
||||||
final method = path.method.value.toLowerCase();
|
final method = path.method.value.toLowerCase();
|
||||||
final pascalPart = StringUtils.toPascalCase(lastPart);
|
final pascalPart = StringHelper.toPascalCase(lastPart);
|
||||||
final methodName = '$method$pascalPart';
|
final methodName = '$method$pascalPart';
|
||||||
|
|
||||||
return methodName;
|
return methodName;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ mixin RetrofitApiTemplateData {
|
||||||
List<String> _getMainImports() {
|
List<String> _getMainImports() {
|
||||||
final tagGroups = _g._groupPathsByTags();
|
final tagGroups = _g._groupPathsByTags();
|
||||||
final tagImports = tagGroups.keys.map((tag) {
|
final tagImports = tagGroups.keys.map((tag) {
|
||||||
final fileName = StringUtils.generateFileName(tag);
|
final fileName = StringHelper.generateFileName(tag);
|
||||||
return "import '$fileName.dart';";
|
return "import '$fileName.dart';";
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
|
@ -22,8 +22,8 @@ mixin RetrofitApiTemplateData {
|
||||||
'apis': tagGroups.entries.map((entry) {
|
'apis': tagGroups.entries.map((entry) {
|
||||||
final tagName = entry.key;
|
final tagName = entry.key;
|
||||||
return {
|
return {
|
||||||
'name': StringUtils.toCamelCase(tagName),
|
'name': StringHelper.toCamelCase(tagName),
|
||||||
'className': '${StringUtils.toPascalCase(tagName)}Api',
|
'className': '${StringHelper.toPascalCase(tagName)}Api',
|
||||||
};
|
};
|
||||||
}).toList(),
|
}).toList(),
|
||||||
};
|
};
|
||||||
|
|
@ -34,7 +34,7 @@ mixin RetrofitApiTemplateData {
|
||||||
_g.document.servers.isNotEmpty ? _g.document.servers.first.url : '';
|
_g.document.servers.isNotEmpty ? _g.document.servers.first.url : '';
|
||||||
var fileName = '';
|
var fileName = '';
|
||||||
if (_g.className.isNotEmpty) {
|
if (_g.className.isNotEmpty) {
|
||||||
fileName = StringUtils.generateFileName(_g.className);
|
fileName = StringHelper.generateFileName(_g.className);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ 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/pipeline/generate/impl/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_helper.dart';
|
||||||
|
|
||||||
part 'retrofit_api/api_grouping.dart';
|
part 'retrofit_api/api_grouping.dart';
|
||||||
part 'retrofit_api/api_method_parameter.dart';
|
part 'retrofit_api/api_method_parameter.dart';
|
||||||
|
|
@ -108,8 +108,8 @@ class RetrofitApiGenerator extends BaseGenerator
|
||||||
final tagName = entry.key;
|
final tagName = entry.key;
|
||||||
final paths = entry.value;
|
final paths = entry.value;
|
||||||
// Use ${tagName}Api to match old behavior (user -> user_api.dart)
|
// Use ${tagName}Api to match old behavior (user -> user_api.dart)
|
||||||
final fileName = StringUtils.generateFileName('${tagName}Api');
|
final fileName = StringHelper.generateFileName('${tagName}Api');
|
||||||
final apiClassName = '${StringUtils.toPascalCase(tagName)}Api';
|
final apiClassName = '${StringHelper.toPascalCase(tagName)}Api';
|
||||||
|
|
||||||
final data = _buildApiClassData(paths);
|
final data = _buildApiClassData(paths);
|
||||||
data['className'] = apiClassName;
|
data['className'] = apiClassName;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ 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';
|
||||||
import 'package:swagger_generator_flutter/utils/reference_resolver.dart';
|
import 'package:swagger_generator_flutter/utils/reference_resolver.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils.dart';
|
import 'package:swagger_generator_flutter/utils/string_helper.dart';
|
||||||
|
|
||||||
/// Swagger数据解析器
|
/// Swagger数据解析器
|
||||||
/// 负责解析Swagger JSON文档并提取相关信息
|
/// 负责解析Swagger JSON文档并提取相关信息
|
||||||
|
|
@ -390,7 +390,7 @@ class SwaggerDataParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认为自定义类型
|
// 默认为自定义类型
|
||||||
return StringUtils.generateClassName(swaggerType);
|
return StringHelper.generateClassName(swaggerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:swagger_generator_flutter/commands/base_command.dart';
|
import 'package:swagger_generator_flutter/commands/base_command.dart';
|
||||||
import 'package:swagger_generator_flutter/commands/generate_command.dart';
|
import 'package:swagger_generator_flutter/commands/generate_command.dart';
|
||||||
import 'package:swagger_generator_flutter/core/config.dart';
|
import 'package:swagger_generator_flutter/core/config.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils.dart';
|
import 'package:swagger_generator_flutter/utils/string_helper.dart';
|
||||||
|
import 'package:swagger_generator_flutter/utils/string_utils/index.dart';
|
||||||
|
|
||||||
/// Swagger CLI 应用程序
|
/// Swagger CLI 应用程序
|
||||||
/// 使用命令模式架构的新版本CLI工具
|
/// 使用命令模式架构的新版本CLI工具
|
||||||
|
|
@ -78,7 +79,9 @@ class SwaggerCLI {
|
||||||
if (exitCode == 0) {
|
if (exitCode == 0) {
|
||||||
_logger
|
_logger
|
||||||
..info('')
|
..info('')
|
||||||
..info('⏱️ 执行时间: ${StringUtils.formatDuration(stopwatch.elapsed)}');
|
..info(
|
||||||
|
'⏱️ 执行时间: ${StringHelper.formatDuration(stopwatch.elapsed)}',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,3 @@ export 'core/error_reporter.dart';
|
||||||
// 核心模型
|
// 核心模型
|
||||||
export 'core/models.dart';
|
export 'core/models.dart';
|
||||||
export 'core/performance_parser.dart';
|
export 'core/performance_parser.dart';
|
||||||
// 工具类
|
|
||||||
export 'utils/string_utils.dart';
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/// API naming utilities for endpoint and controller name generation
|
||||||
|
library;
|
||||||
|
|
||||||
|
import 'package:swagger_generator_flutter/core/models.dart';
|
||||||
|
import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart';
|
||||||
|
|
||||||
|
/// API naming utilities
|
||||||
|
class ApiNamingUtils {
|
||||||
|
/// Generate endpoint name from path and operationId
|
||||||
|
static String generateEndpointName(String path, String? operationId) {
|
||||||
|
// If operationId exists, use it with priority
|
||||||
|
if (operationId != null && operationId.isNotEmpty) {
|
||||||
|
return NamingConverter.toCamelCase(operationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove version prefix from path
|
||||||
|
var cleanPath = path.replaceFirst('/api/v1', '');
|
||||||
|
|
||||||
|
// Remove leading slash
|
||||||
|
if (cleanPath.startsWith('/')) {
|
||||||
|
cleanPath = cleanPath.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert path to camelCase
|
||||||
|
final parts = cleanPath.split('/');
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
final controller = parts[0];
|
||||||
|
final action = parts[1];
|
||||||
|
return NamingConverter.toCamelCase('${controller}_$action');
|
||||||
|
}
|
||||||
|
|
||||||
|
return NamingConverter.toCamelCase(cleanPath.replaceAll('/', '_'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract controller name from API path
|
||||||
|
static String extractControllerName(ApiPath path) {
|
||||||
|
// Extract controller name from tags
|
||||||
|
if (path.tags.isNotEmpty) {
|
||||||
|
return path.tags.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract controller name from path
|
||||||
|
final pathParts = path.path.split('/');
|
||||||
|
if (pathParts.length > 1) {
|
||||||
|
return NamingConverter.toPascalCase(pathParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'General';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/index.dart';
|
||||||
|
|
||||||
/// 缓存管理器
|
/// 缓存管理器
|
||||||
/// 提供简单的内存缓存功能
|
/// 提供简单的内存缓存功能
|
||||||
|
|
@ -115,7 +115,7 @@ class CacheStats {
|
||||||
'memoryItems: $memoryItems, '
|
'memoryItems: $memoryItems, '
|
||||||
'diskItems: $diskItems, '
|
'diskItems: $diskItems, '
|
||||||
'hitRate: ${(hitRate * 100).toStringAsFixed(1)}%, '
|
'hitRate: ${(hitRate * 100).toStringAsFixed(1)}%, '
|
||||||
'totalSize: ${StringUtils.formatBytes(totalSize)}'
|
'totalSize: ${FormattingUtils.formatBytes(totalSize)}'
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,24 @@
|
||||||
/// - NamingConverter: 命名转换(camelCase, PascalCase, snake_case 等)
|
/// - NamingConverter: 命名转换(camelCase, PascalCase, snake_case 等)
|
||||||
/// - TextCleaner: 文本清理和格式化
|
/// - TextCleaner: 文本清理和格式化
|
||||||
/// - TemplateService: 模板服务(注释生成、文件头生成等)
|
/// - TemplateService: 模板服务(注释生成、文件头生成等)
|
||||||
|
/// - FormattingUtils: 格式化工具(缩进、字节大小、持续时间等)
|
||||||
///
|
///
|
||||||
/// # 典型用法示例
|
/// # 典型用法示例
|
||||||
/// ```dart
|
/// ```dart
|
||||||
/// // snake_case 转 camelCase
|
/// // snake_case 转 camelCase
|
||||||
/// StringUtils.toDartPropertyName('user_id'); // userId
|
/// StringHelper.toDartPropertyName('user_id'); // userId
|
||||||
/// // 含特殊字符
|
/// // 含特殊字符
|
||||||
/// StringUtils.toDartPropertyName('user-id'); // userId
|
/// StringHelper.toDartPropertyName('user-id'); // userId
|
||||||
/// // 数字开头
|
/// // 数字开头
|
||||||
/// StringUtils.toDartPropertyName('1st_field'); // n1stField
|
/// StringHelper.toDartPropertyName('1st_field'); // n1stField
|
||||||
/// // 生成注释
|
/// // 生成注释
|
||||||
/// StringUtils.generateComment('API description'); // /// API description
|
/// StringHelper.generateComment('API description'); // /// API description
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
library;
|
library;
|
||||||
|
|
||||||
import 'package:swagger_generator_flutter/core/models.dart';
|
import 'package:swagger_generator_flutter/core/models.dart';
|
||||||
|
import 'package:swagger_generator_flutter/utils/string_utils/formatting_utils.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils/template_service.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/template_service.dart';
|
||||||
import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart';
|
import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart';
|
||||||
|
|
@ -28,7 +30,7 @@ import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart';
|
||||||
/// 字符串工具类 - 统一导出接口
|
/// 字符串工具类 - 统一导出接口
|
||||||
///
|
///
|
||||||
/// 将各子模块的功能聚合到统一的 API 中,保持向后兼容性
|
/// 将各子模块的功能聚合到统一的 API 中,保持向后兼容性
|
||||||
class StringUtils {
|
class StringHelper {
|
||||||
// ==================== 命名转换 (NamingConverter) ====================
|
// ==================== 命名转换 (NamingConverter) ====================
|
||||||
/// 转换为 camelCase
|
/// 转换为 camelCase
|
||||||
static String toCamelCase(String input) => NamingConverter.toCamelCase(input);
|
static String toCamelCase(String input) => NamingConverter.toCamelCase(input);
|
||||||
|
|
@ -77,10 +79,8 @@ class StringUtils {
|
||||||
static String escapeString(String input) => TextCleaner.escapeString(input);
|
static String escapeString(String input) => TextCleaner.escapeString(input);
|
||||||
|
|
||||||
/// 缩进文本
|
/// 缩进文本
|
||||||
static String indent(String text, int spaces) {
|
static String indent(String text, int spaces) =>
|
||||||
final indentation = ' ' * spaces;
|
FormattingUtils.indent(text, spaces);
|
||||||
return text.split('\n').map((line) => '$indentation$line').join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 截断文本到指定长度
|
/// 截断文本到指定长度
|
||||||
static String truncate(String text, int maxLength, {String suffix = '...'}) =>
|
static String truncate(String text, int maxLength, {String suffix = '...'}) =>
|
||||||
|
|
@ -111,9 +111,21 @@ class StringUtils {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 业务逻辑辅助方法 ====================
|
// ==================== 格式化工具 (FormattingUtils) ====================
|
||||||
|
|
||||||
|
/// 格式化字节大小
|
||||||
|
static String formatBytes(int bytes) => FormattingUtils.formatBytes(bytes);
|
||||||
|
|
||||||
|
/// 格式化持续时间
|
||||||
|
static String formatDuration(Duration duration) =>
|
||||||
|
FormattingUtils.formatDuration(duration);
|
||||||
|
|
||||||
|
// ==================== 已废弃的方法(向后兼容) ====================
|
||||||
|
// 这些方法已移至 ApiNamingUtils,保留此处以兼容旧代码
|
||||||
|
|
||||||
/// 生成端点名称
|
/// 生成端点名称
|
||||||
|
/// @deprecated 使用 ApiNamingUtils.generateEndpointName 代替
|
||||||
|
@Deprecated('Use ApiNamingUtils.generateEndpointName instead')
|
||||||
static String generateEndpointName(String path, String? operationId) {
|
static String generateEndpointName(String path, String? operationId) {
|
||||||
// 如果有 operationId,优先使用
|
// 如果有 operationId,优先使用
|
||||||
if (operationId != null && operationId.isNotEmpty) {
|
if (operationId != null && operationId.isNotEmpty) {
|
||||||
|
|
@ -140,6 +152,8 @@ class StringUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 提取控制器名称
|
/// 提取控制器名称
|
||||||
|
/// @deprecated 使用 ApiNamingUtils.extractControllerName 代替
|
||||||
|
@Deprecated('Use ApiNamingUtils.extractControllerName instead')
|
||||||
static String extractControllerName(ApiPath path) {
|
static String extractControllerName(ApiPath path) {
|
||||||
// 从 tags 中提取控制器名称
|
// 从 tags 中提取控制器名称
|
||||||
if (path.tags.isNotEmpty) {
|
if (path.tags.isNotEmpty) {
|
||||||
|
|
@ -154,31 +168,4 @@ class StringUtils {
|
||||||
|
|
||||||
return 'General';
|
return 'General';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 清理路径,保留版本前缀
|
|
||||||
static String cleanPath(String path) {
|
|
||||||
// 保留版本前缀,只清理其他不必要的字符
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 格式化工具 ====================
|
|
||||||
|
|
||||||
/// 格式化字节大小
|
|
||||||
static String formatBytes(int bytes) {
|
|
||||||
if (bytes < 1024) return '${bytes}B';
|
|
||||||
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB';
|
|
||||||
if (bytes < 1024 * 1024 * 1024) {
|
|
||||||
return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB';
|
|
||||||
}
|
|
||||||
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 格式化持续时间
|
|
||||||
static String formatDuration(Duration duration) {
|
|
||||||
if (duration.inMilliseconds >= 1000) {
|
|
||||||
return '${(duration.inMilliseconds / 1000).toStringAsFixed(2)}秒';
|
|
||||||
} else {
|
|
||||||
return '${duration.inMilliseconds}毫秒';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/// Formatting utilities for various data types
|
||||||
|
library;
|
||||||
|
|
||||||
|
/// Formatting utilities for bytes, durations, and text indentation
|
||||||
|
class FormattingUtils {
|
||||||
|
/// Indent text by specified number of spaces
|
||||||
|
static String indent(String text, int spaces) {
|
||||||
|
final indentation = ' ' * spaces;
|
||||||
|
return text.split('\n').map((line) => '$indentation$line').join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format byte size to human-readable string
|
||||||
|
static String formatBytes(int bytes) {
|
||||||
|
if (bytes < 1024) return '${bytes}B';
|
||||||
|
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB';
|
||||||
|
if (bytes < 1024 * 1024 * 1024) {
|
||||||
|
return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB';
|
||||||
|
}
|
||||||
|
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format duration to human-readable string
|
||||||
|
static String formatDuration(Duration duration) {
|
||||||
|
if (duration.inMilliseconds >= 1000) {
|
||||||
|
return '${(duration.inMilliseconds / 1000).toStringAsFixed(2)}秒';
|
||||||
|
} else {
|
||||||
|
return '${duration.inMilliseconds}毫秒';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/// String utilities - unified export
|
||||||
|
///
|
||||||
|
/// This file provides a single export point for all string utilities
|
||||||
|
library;
|
||||||
|
|
||||||
|
export 'formatting_utils.dart';
|
||||||
|
export 'naming_converter.dart';
|
||||||
|
export 'template_service.dart';
|
||||||
|
export 'text_cleaner.dart';
|
||||||
Loading…
Reference in New Issue