Browse Source

refactor(dynamite): split code

Signed-off-by: Nikolas Rimikis <leptopoda@users.noreply.github.com>
pull/694/head
Nikolas Rimikis 1 year ago
parent
commit
64b8e9e026
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 313
      packages/dynamite/dynamite/lib/src/builder/resolve_object.dart
  2. 523
      packages/dynamite/dynamite/lib/src/builder/resolve_type.dart
  3. 23
      packages/dynamite/dynamite/lib/src/builder/serializer.dart
  4. 14
      packages/dynamite/dynamite/lib/src/builder/state.dart
  5. 107
      packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart
  6. 43
      packages/dynamite/dynamite/lib/src/helpers/dynamite.dart
  7. 15
      packages/dynamite/dynamite/lib/src/helpers/typeresult.dart
  8. 2
      packages/dynamite/dynamite/lib/src/models/open_api.dart
  9. 3
      packages/dynamite/dynamite/lib/src/models/parameter.dart
  10. 1092
      packages/dynamite/dynamite/lib/src/openapi_builder.dart

313
packages/dynamite/dynamite/lib/src/builder/resolve_object.dart

@ -0,0 +1,313 @@
import 'package:code_builder/code_builder.dart';
import 'package:dynamite/src/builder/resolve_type.dart';
import 'package:dynamite/src/builder/state.dart';
import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/helpers/dynamite.dart';
import 'package:dynamite/src/helpers/typeresult.dart';
import 'package:dynamite/src/models/open_api.dart';
import 'package:dynamite/src/models/schema.dart';
import 'package:dynamite/src/type_result/type_result.dart';
TypeResult resolveObject(
final OpenAPI spec,
final String variablePrefix,
final State state,
final String identifier,
final Schema schema, {
final bool nullable = false,
final bool isHeader = false,
}) {
final result = TypeResultObject(
'${state.classPrefix}$identifier',
nullable: nullable,
);
if (state.resolvedTypes.add(result)) {
state.output.add(
Class(
(final b) {
b
..name = '${state.classPrefix}$identifier'
..docs.addAll(schema.formattedDescription)
..abstract = true
..implements.add(
refer(
'Built<${state.classPrefix}$identifier, ${state.classPrefix}${identifier}Builder>',
),
)
..constructors.addAll([
Constructor(
(final b) => b
..factory = true
..lambda = true
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'b'
..type = refer('void Function(${state.classPrefix}${identifier}Builder)?'),
),
)
..redirect = refer('_\$${state.classPrefix}$identifier'),
),
Constructor(
(final b) => b
..name = '_'
..constant = true,
),
Constructor(
(final b) => b
..factory = true
..name = 'fromJson'
..lambda = true
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'json'
..type = refer('Map<String, dynamic>'),
),
)
..body = const Code('_jsonSerializers.deserializeWith(serializer, json)!'),
),
])
..methods.addAll([
Method(
(final b) => b
..name = 'toJson'
..returns = refer('Map<String, dynamic>')
..lambda = true
..body = const Code('_jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
),
for (final property in schema.properties!.entries) ...[
Method(
(final b) {
final propertyName = property.key;
final propertySchema = property.value;
final result = resolveType(
spec,
variablePrefix,
state,
'${identifier}_${toDartName(propertyName, uppercaseFirstCharacter: true)}',
propertySchema,
nullable: isDartParameterNullable(
schema.required?.contains(propertyName),
propertySchema,
),
);
b
..name = toDartName(propertyName)
..returns = refer(result.nullableName)
..type = MethodType.getter
..docs.addAll(propertySchema.formattedDescription);
if (toDartName(propertyName) != propertyName) {
b.annotations.add(
refer('BuiltValueField').call([], {
'wireName': literalString(propertyName),
}),
);
}
},
),
],
Method((final b) {
b
..name = 'serializer'
..returns = refer('Serializer<${state.classPrefix}$identifier>')
..lambda = true
..static = true
..body = Code(
isHeader
? '_\$${state.classPrefix}${identifier}Serializer()'
: "_\$${toCamelCase('${state.classPrefix}$identifier')}Serializer",
)
..type = MethodType.getter;
if (isHeader) {
b.annotations.add(refer('BuiltValueSerializer').call([], {'custom': refer('true')}));
}
}),
]);
final defaults = <String>[];
for (final property in schema.properties!.entries) {
final propertySchema = property.value;
if (propertySchema.default_ != null) {
final value = propertySchema.default_!.toString();
final result = resolveType(
spec,
variablePrefix,
state,
propertySchema.type!,
propertySchema,
);
defaults.add('..${toDartName(property.key)} = ${valueToEscapedValue(result, value)}');
}
}
if (defaults.isNotEmpty) {
b.methods.add(
Method(
(final b) => b
..name = '_defaults'
..returns = refer('void')
..static = true
..lambda = true
..annotations.add(
refer('BuiltValueHook').call(
[],
{
'initializeBuilder': refer('true'),
},
),
)
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'b'
..type = refer('${state.classPrefix}${identifier}Builder'),
),
)
..body = Code(
<String?>[
'b',
...defaults,
].join(),
),
),
);
}
},
),
);
if (isHeader) {
state.output.add(
Class(
(final b) => b
..name = '_\$${state.classPrefix}${identifier}Serializer'
..implements.add(refer('StructuredSerializer<${state.classPrefix}$identifier>'))
..fields.addAll([
Field(
(final b) => b
..name = 'types'
..modifier = FieldModifier.final$
..type = refer('Iterable<Type>')
..annotations.add(refer('override'))
..assignment = Code('const [${state.classPrefix}$identifier, _\$${state.classPrefix}$identifier]'),
),
Field(
(final b) => b
..name = 'wireName'
..modifier = FieldModifier.final$
..type = refer('String')
..annotations.add(refer('override'))
..assignment = Code("r'${state.classPrefix}$identifier'"),
),
])
..methods.addAll([
Method((final b) {
b
..name = 'serialize'
..returns = refer('Iterable<Object?>')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'object'
..type = refer('${state.classPrefix}$identifier'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
),
)
..body = const Code('throw UnimplementedError();');
}),
Method((final b) {
b
..name = 'deserialize'
..returns = refer('${state.classPrefix}$identifier')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'serialized'
..type = refer('Iterable<Object?>'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
),
);
List<Code> deserializeProperty(final MapEntry<String, Schema> property) {
final propertyName = property.key;
final propertySchema = property.value;
final result = resolveType(
spec,
variablePrefix,
state,
'${identifier}_${toDartName(propertyName, uppercaseFirstCharacter: true)}',
propertySchema,
nullable: isDartParameterNullable(schema.required?.contains(propertyName), propertySchema),
);
return [
Code("case '$propertyName':"),
if (result.className != 'String') ...[
if (result is TypeResultBase || result is TypeResultEnum) ...[
Code(
'result.${toDartName(propertyName)} = ${result.deserialize(result.decode('value!'))};',
),
] else ...[
Code(
'result.${toDartName(propertyName)}.replace(${result.deserialize(result.decode('value!'))});',
),
],
] else ...[
Code(
'result.${toDartName(propertyName)} = value!;',
),
],
];
}
b.body = Block.of([
Code('final result = new ${state.classPrefix}${identifier}Builder();'),
const Code(''),
const Code('final iterator = serialized.iterator;'),
const Code('while (iterator.moveNext()) {'),
const Code('final key = iterator.current! as String;'),
const Code('iterator.moveNext();'),
const Code('final value = iterator.current! as String;'),
const Code('switch (key) {'),
for (final property in schema.properties!.entries) ...deserializeProperty(property),
const Code('}'),
const Code('}'),
const Code(''),
const Code('return result.build();'),
]);
}),
]),
),
);
}
}
return result;
}

523
packages/dynamite/dynamite/lib/src/builder/resolve_type.dart

@ -0,0 +1,523 @@
import 'package:code_builder/code_builder.dart';
import 'package:dynamite/src/builder/resolve_object.dart';
import 'package:dynamite/src/builder/state.dart';
import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/helpers/typeresult.dart';
import 'package:dynamite/src/models/open_api.dart';
import 'package:dynamite/src/models/schema.dart';
import 'package:dynamite/src/type_result/type_result.dart';
TypeResult resolveType(
final OpenAPI spec,
final String variablePrefix,
final State state,
final String identifier,
final Schema schema, {
final bool ignoreEnum = false,
final bool nullable = false,
}) {
TypeResult? result;
if (schema.ref == null && schema.ofs == null && schema.type == null) {
return TypeResultBase(
'JsonObject',
nullable: nullable,
);
}
if (schema.ref != null) {
final name = schema.ref!.split('/').last;
result = resolveType(
spec,
variablePrefix,
state,
name,
spec.components!.schemas![name]!,
nullable: nullable,
);
} else if (schema.ofs != null) {
result = TypeResultObject(
'${state.classPrefix}$identifier',
nullable: nullable,
);
if (state.resolvedTypes.add(result)) {
final results = schema.ofs!
.map(
(final s) => resolveType(
spec,
variablePrefix,
state,
'$identifier${schema.ofs!.indexOf(s)}',
s,
nullable: !(schema.allOf?.contains(s) ?? false),
),
)
.toList();
final fields = <String, String>{};
for (final result in results) {
final dartName = toDartName(result.name.replaceFirst(state.classPrefix, ''));
fields[result.name] = toFieldName(dartName, result.name.replaceFirst(state.classPrefix, ''));
}
state.output.addAll([
Class(
(final b) {
b
..name = '${state.classPrefix}$identifier'
..abstract = true
..implements.add(
refer(
'Built<${state.classPrefix}$identifier, ${state.classPrefix}${identifier}Builder>',
),
)
..constructors.addAll([
Constructor(
(final b) => b
..name = '_'
..constant = true,
),
Constructor(
(final b) => b
..factory = true
..lambda = true
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'b'
..type = refer('void Function(${state.classPrefix}${identifier}Builder)?'),
),
)
..redirect = refer('_\$${state.classPrefix}$identifier'),
),
])
..methods.addAll([
Method(
(final b) {
b
..name = 'data'
..returns = refer('JsonObject')
..type = MethodType.getter;
},
),
for (final result in results) ...[
Method(
(final b) {
final s = schema.ofs![results.indexOf(result)];
b
..name = fields[result.name]
..returns = refer(result.nullableName)
..type = MethodType.getter
..docs.addAll(s.formattedDescription);
},
),
],
Method(
(final b) => b
..static = true
..name = 'fromJson'
..lambda = true
..returns = refer('${state.classPrefix}$identifier')
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'json'
..type = refer('Object'),
),
)
..body = const Code('_jsonSerializers.deserializeWith(serializer, json)!'),
),
Method(
(final b) => b
..name = 'toJson'
..returns = refer('Map<String, dynamic>')
..lambda = true
..body = const Code('_jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
),
Method(
(final b) => b
..name = 'serializer'
..returns = refer('Serializer<${state.classPrefix}$identifier>')
..lambda = true
..static = true
..annotations.add(refer('BuiltValueSerializer').call([], {'custom': refer('true')}))
..body = Code('_\$${state.classPrefix}${identifier}Serializer()')
..type = MethodType.getter,
),
]);
},
),
Class(
(final b) => b
..name = '_\$${state.classPrefix}${identifier}Serializer'
..implements.add(refer('PrimitiveSerializer<${state.classPrefix}$identifier>'))
..fields.addAll([
Field(
(final b) => b
..name = 'types'
..modifier = FieldModifier.final$
..type = refer('Iterable<Type>')
..annotations.add(refer('override'))
..assignment = Code('const [${state.classPrefix}$identifier, _\$${state.classPrefix}$identifier]'),
),
Field(
(final b) => b
..name = 'wireName'
..modifier = FieldModifier.final$
..type = refer('String')
..annotations.add(refer('override'))
..assignment = Code("r'${state.classPrefix}$identifier'"),
),
])
..methods.addAll([
Method((final b) {
b
..name = 'serialize'
..returns = refer('Object')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'object'
..type = refer('${state.classPrefix}$identifier'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
),
)
..body = const Code('return object.data.value;');
}),
Method((final b) {
b
..name = 'deserialize'
..returns = refer('${state.classPrefix}$identifier')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'data'
..type = refer('Object'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
),
)
..body = Code(
<String>[
'final result = new ${state.classPrefix}${identifier}Builder()',
'..data = JsonObject(data);',
if (schema.allOf != null) ...[
for (final result in results) ...[
if (result is TypeResultBase || result is TypeResultEnum) ...[
'result.${fields[result.name]!} = ${result.deserialize('data')};',
] else ...[
'result.${fields[result.name]!}.replace(${result.deserialize('data')});',
],
],
] else ...[
if (schema.discriminator != null) ...[
'if (data is! Iterable) {',
r"throw StateError('Expected an Iterable but got ${data.runtimeType}');",
'}',
'',
'String? discriminator;',
'',
'final iterator = data.iterator;',
'while (iterator.moveNext()) {',
'final key = iterator.current! as String;',
'iterator.moveNext();',
'final Object? value = iterator.current;',
"if (key == '${schema.discriminator!.propertyName}') {",
'discriminator = value! as String;',
'break;',
'}',
'}',
],
for (final result in results) ...[
if (schema.discriminator != null) ...[
"if (discriminator == '${result.name.replaceFirst(state.classPrefix, '')}'",
if (schema.discriminator!.mapping != null && schema.discriminator!.mapping!.isNotEmpty) ...[
for (final key in schema.discriminator!.mapping!.entries
.where(
(final entry) =>
entry.value.endsWith('/${result.name.replaceFirst(state.classPrefix, '')}'),
)
.map((final entry) => entry.key)) ...[
" || discriminator == '$key'",
],
') {',
],
],
'try {',
if (result is TypeResultBase || result is TypeResultEnum) ...[
'result._${fields[result.name]!} = ${result.deserialize('data')};',
] else ...[
'result._${fields[result.name]!} = ${result.deserialize('data')}.toBuilder();',
],
'} catch (_) {',
if (schema.discriminator != null) ...[
'rethrow;',
],
'}',
if (schema.discriminator != null) ...[
'}',
],
],
if (schema.oneOf != null) ...[
"assert([${fields.values.map((final e) => 'result._$e').join(',')}].where((final x) => x != null).length >= 1, 'Need oneOf for \${result._data}');",
],
if (schema.anyOf != null) ...[
"assert([${fields.values.map((final e) => 'result._$e').join(',')}].where((final x) => x != null).length >= 1, 'Need anyOf for \${result._data}');",
],
],
'return result.build();',
].join(),
);
}),
]),
),
]);
}
} else if (schema.isContentString) {
final subResult = resolveType(
spec,
variablePrefix,
state,
identifier,
schema.contentSchema!,
);
result = TypeResultObject(
'ContentString',
generics: [subResult],
nullable: nullable,
);
} else {
switch (schema.type) {
case 'boolean':
result = TypeResultBase(
'bool',
nullable: nullable,
);
case 'integer':
result = TypeResultBase(
'int',
nullable: nullable,
);
case 'number':
result = TypeResultBase(
'num',
nullable: nullable,
);
case 'string':
switch (schema.format) {
case 'binary':
result = TypeResultBase(
'Uint8List',
nullable: nullable,
);
}
result = TypeResultBase(
'String',
nullable: nullable,
);
case 'array':
if (schema.items != null) {
final subResult = resolveType(
spec,
variablePrefix,
state,
identifier,
schema.items!,
);
result = TypeResultList(
'BuiltList',
subResult,
nullable: nullable,
);
} else {
result = TypeResultList(
'BuiltList',
TypeResultBase('JsonObject'),
nullable: nullable,
);
}
case 'object':
if (schema.properties == null) {
if (schema.additionalProperties == null) {
result = TypeResultBase(
'JsonObject',
nullable: nullable,
);
} else if (schema.additionalProperties is EmptySchema) {
result = TypeResultMap(
'BuiltMap',
TypeResultBase('JsonObject'),
nullable: nullable,
);
} else {
final subResult = resolveType(
spec,
variablePrefix,
state,
identifier,
schema.additionalProperties!,
);
result = TypeResultMap(
'BuiltMap',
subResult,
nullable: nullable,
);
}
} else if (schema.properties!.isEmpty) {
result = TypeResultMap(
'BuiltMap',
TypeResultBase('JsonObject'),
nullable: nullable,
);
} else {
result = resolveObject(
spec,
variablePrefix,
state,
identifier,
schema,
nullable: nullable,
);
}
}
}
if (result != null) {
if (!ignoreEnum && schema.enum_ != null) {
if (state.resolvedTypes.add(TypeResultEnum('${state.classPrefix}$identifier', result))) {
state.output.add(
Class(
(final b) => b
..name = '${state.classPrefix}$identifier'
..extend = refer('EnumClass')
..constructors.add(
Constructor(
(final b) => b
..name = '_'
..constant = true
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'name'
..toSuper = true,
),
),
),
)
..fields.addAll(
schema.enum_!.map(
(final value) => Field(
(final b) {
final result = resolveType(
spec,
variablePrefix,
state,
'$identifier${toDartName(value.toString(), uppercaseFirstCharacter: true)}',
schema,
ignoreEnum: true,
);
b
..name = toDartName(value.toString())
..static = true
..modifier = FieldModifier.constant
..type = refer('${state.classPrefix}$identifier')
..assignment = Code(
'_\$${toCamelCase('${state.classPrefix}$identifier')}${toDartName(value.toString(), uppercaseFirstCharacter: true)}',
);
if (toDartName(value.toString()) != value.toString()) {
if (result.name != 'String' && result.name != 'int') {
throw Exception(
'Sorry enum values are a bit broken. '
'See https://github.com/google/json_serializable.dart/issues/616. '
'Please remove the enum values on ${state.classPrefix}$identifier.',
);
}
b.annotations.add(
refer('BuiltValueEnumConst').call([], {
'wireName': refer(valueToEscapedValue(result, value.toString())),
}),
);
}
},
),
),
)
..methods.addAll([
Method(
(final b) => b
..name = 'values'
..returns = refer('BuiltSet<${state.classPrefix}$identifier>')
..lambda = true
..static = true
..body = Code('_\$${toCamelCase('${state.classPrefix}$identifier')}Values')
..type = MethodType.getter,
),
Method(
(final b) => b
..name = 'valueOf'
..returns = refer('${state.classPrefix}$identifier')
..lambda = true
..static = true
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'name'
..type = refer(result!.name),
),
)
..body = Code('_\$valueOf${state.classPrefix}$identifier(name)'),
),
Method(
(final b) => b
..name = 'serializer'
..returns = refer('Serializer<${state.classPrefix}$identifier>')
..lambda = true
..static = true
..body = Code("_\$${toCamelCase('${state.classPrefix}$identifier')}Serializer")
..type = MethodType.getter,
),
]),
),
);
}
result = TypeResultEnum(
'${state.classPrefix}$identifier',
result,
nullable: nullable,
);
}
state.resolvedTypes.add(result);
return result;
}
throw Exception('Can not convert OpenAPI type "${schema.toJson()}" to a Dart type');
}

23
packages/dynamite/dynamite/lib/src/builder/serializer.dart

@ -0,0 +1,23 @@
import 'package:dynamite/src/builder/state.dart';
List<String> buildSerializer(final State state) {
if (state.resolvedTypes.isNotEmpty) {
return [
'// coverage:ignore-start',
'final Serializers _serializers = (Serializers().toBuilder()',
...state.resolvedTypes.map((final type) => type.serializers).expand((final element) => element).toSet(),
').build();',
'',
'Serializers get ${state.variablePrefix}Serializers => _serializers;',
'',
'final Serializers _jsonSerializers = (_serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();',
'',
'T deserialize${state.classPrefix}<T>(final Object data) => _serializers.deserialize(data, specifiedType: FullType(T))! as T;',
'',
'Object? serialize${state.classPrefix}<T>(final T data) => _serializers.serialize(data, specifiedType: FullType(T));',
'// coverage:ignore-end',
];
}
return [];
}

14
packages/dynamite/dynamite/lib/src/builder/state.dart

@ -0,0 +1,14 @@
import 'package:code_builder/code_builder.dart';
import 'package:dynamite/src/type_result/type_result.dart';
class State {
State({
required this.classPrefix,
required this.variablePrefix,
});
final String classPrefix;
final String variablePrefix;
final output = <Spec>[];
final resolvedTypes = <TypeResult>{};
}

107
packages/dynamite/dynamite/lib/src/helpers/dart_helpers.dart

@ -0,0 +1,107 @@
String toDartName(
final String name, {
final bool uppercaseFirstCharacter = false,
}) {
var result = '';
var upperCase = uppercaseFirstCharacter;
var firstCharacter = !uppercaseFirstCharacter;
for (final char in name.split('')) {
if (_isNonAlphaNumericString(char)) {
upperCase = true;
} else {
result += firstCharacter ? char.toLowerCase() : (upperCase ? char.toUpperCase() : char);
upperCase = false;
firstCharacter = false;
}
}
if (_dartKeywords.contains(result) || RegExp(r'^[0-9]+$', multiLine: true).hasMatch(result)) {
return '\$$result';
}
return result;
}
final _dartKeywords = [
'assert',
'break',
'case',
'catch',
'class',
'const',
'continue',
'default',
'do',
'else',
'enum',
'extends',
'false',
'final',
'finally',
'for',
'if',
'in',
'is',
'new',
'null',
'rethrow',
'return',
'super',
'switch',
'this',
'throw',
'true',
'try',
'var',
'void',
'while',
'with',
'async',
'hide',
'on',
'show',
'sync',
'abstract',
'as',
'covariant',
'deferred',
'dynamic',
'export',
'extension',
'external',
'factory',
'function',
'get',
'implements',
'import',
'interface',
'library',
'mixin',
'operator',
'part',
'set',
'static',
'typedef',
];
bool _isNonAlphaNumericString(final String input) => !RegExp(r'^[a-zA-Z0-9]$').hasMatch(input);
String toFieldName(final String dartName, final String type) => dartName == type ? '\$$dartName' : dartName;
String toCamelCase(final String name) {
var result = '';
var upperCase = false;
var firstCharacter = true;
for (final char in name.split('')) {
if (char == '_') {
upperCase = true;
} else if (char == r'$') {
result += r'$';
} else {
result += firstCharacter ? char.toLowerCase() : (upperCase ? char.toUpperCase() : char);
upperCase = false;
firstCharacter = false;
}
}
return result;
}

43
packages/dynamite/dynamite/lib/src/helpers/dynamite.dart

@ -0,0 +1,43 @@
// ignore_for_file: avoid_positional_boolean_parameters
import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/models/parameter.dart';
import 'package:dynamite/src/models/schema.dart';
String filterMethodName(final String operationId, final String tag) {
final expandedTag = tag.split('/').toList();
final parts = operationId.split('-');
final output = <String>[];
for (var i = 0; i < parts.length; i++) {
if (expandedTag.length <= i || expandedTag[i] != parts[i]) {
output.add(parts[i]);
}
}
return output.join('-');
}
String clientName(final String tag) => '${toDartName(tag, uppercaseFirstCharacter: true)}Client';
bool isDartParameterNullable(
final bool? required,
final Schema? schema,
) =>
(!(required ?? false) && schema?.default_ == null) || (schema?.nullable ?? false);
bool isRequired(
final bool? required,
final dynamic default_,
) =>
(required ?? false) && default_ == null;
int sortRequiredParameters(final Parameter a, final Parameter b) {
if (a.isDartRequired != b.isDartRequired) {
if (a.isDartRequired && !b.isDartRequired) {
return -1;
} else {
return 1;
}
}
return 0;
}

15
packages/dynamite/dynamite/lib/src/helpers/typeresult.dart

@ -0,0 +1,15 @@
import 'package:dynamite/src/helpers/dart_helpers.dart';
import 'package:dynamite/src/type_result/type_result.dart';
String valueToEscapedValue(final TypeResult result, final dynamic value) {
if (result is TypeResultBase && result.name == 'String') {
return "'$value'";
}
if (result is TypeResultList) {
return 'const $value';
}
if (result is TypeResultEnum) {
return '${result.name}.${toDartName(value.toString())}';
}
return value.toString();
}

2
packages/dynamite/dynamite/lib/src/models/open_api.dart

@ -41,6 +41,8 @@ class OpenAPI {
final Paths? paths; final Paths? paths;
bool get hasAnySecurity => components?.securitySchemes?.isNotEmpty ?? false;
Iterable<String> formattedTagsFor(final String? tag) sync* { Iterable<String> formattedTagsFor(final String? tag) sync* {
final matchedTags = tags?.where((final t) => t.name == tag); final matchedTags = tags?.where((final t) => t.name == tag);

3
packages/dynamite/dynamite/lib/src/models/parameter.dart

@ -1,3 +1,4 @@
import 'package:dynamite/src/helpers/dynamite.dart';
import 'package:dynamite/src/models/schema.dart'; import 'package:dynamite/src/models/schema.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
@ -28,4 +29,6 @@ class Parameter {
final bool? required; final bool? required;
final Schema? schema; final Schema? schema;
bool get isDartRequired => isRequired(required, schema?.default_);
} }

1092
packages/dynamite/dynamite/lib/src/openapi_builder.dart

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save