Browse Source

dynamite: Prefix serializers

pull/439/head
jld3103 1 year ago
parent
commit
72f66bee6d
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 72
      packages/dynamite/dynamite/lib/src/openapi_builder.dart
  2. 4
      packages/dynamite/dynamite/lib/src/type_result/type_result.dart

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

@ -22,7 +22,8 @@ class OpenAPIBuilder implements Builder {
await buildStep.readAsString(inputId), await buildStep.readAsString(inputId),
) as Map<String, dynamic>, ) as Map<String, dynamic>,
); );
final prefix = _toDartName(spec.info.title, uppercaseFirstCharacter: true); final classPrefix = _toDartName(spec.info.title, uppercaseFirstCharacter: true);
final variablePrefix = _toDartName(spec.info.title);
final supportedVersions = ['3.0.3', '3.1.0']; final supportedVersions = ['3.0.3', '3.1.0'];
if (!supportedVersions.contains(spec.version)) { if (!supportedVersions.contains(spec.version)) {
throw Exception('Only OpenAPI ${supportedVersions.join(', ')} are supported'); throw Exception('Only OpenAPI ${supportedVersions.join(', ')} are supported');
@ -55,7 +56,7 @@ class OpenAPIBuilder implements Builder {
final hasAnySecurity = spec.components?.securitySchemes?.isNotEmpty ?? false; final hasAnySecurity = spec.components?.securitySchemes?.isNotEmpty ?? false;
final state = State(prefix); final state = State(classPrefix);
final output = <String>[ final output = <String>[
'// ignore_for_file: camel_case_types', '// ignore_for_file: camel_case_types',
'// ignore_for_file: public_member_api_docs', '// ignore_for_file: public_member_api_docs',
@ -77,7 +78,7 @@ class OpenAPIBuilder implements Builder {
'', '',
Class( Class(
(final b) => b (final b) => b
..name = '${prefix}Response' ..name = '${classPrefix}Response'
..types.addAll([ ..types.addAll([
refer('T'), refer('T'),
refer('U'), refer('U'),
@ -105,14 +106,14 @@ class OpenAPIBuilder implements Builder {
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..lambda = true ..lambda = true
..body = Code( ..body = Code(
"'${prefix}Response(data: \$data, headers: \$headers)'", "'${classPrefix}Response(data: \$data, headers: \$headers)'",
), ),
), ),
), ),
).accept(emitter).toString(), ).accept(emitter).toString(),
Class( Class(
(final b) => b (final b) => b
..name = '${prefix}ApiException' ..name = '${classPrefix}ApiException'
..extend = refer('DynamiteApiException') ..extend = refer('DynamiteApiException')
..constructors.add( ..constructors.add(
Constructor( Constructor(
@ -132,7 +133,7 @@ class OpenAPIBuilder implements Builder {
Method( Method(
(final b) => b (final b) => b
..name = 'fromResponse' ..name = 'fromResponse'
..returns = refer('Future<${prefix}ApiException>') ..returns = refer('Future<${classPrefix}ApiException>')
..static = true ..static = true
..modifier = MethodModifier.async ..modifier = MethodModifier.async
..requiredParameters.add( ..requiredParameters.add(
@ -152,7 +153,7 @@ class OpenAPIBuilder implements Builder {
const Code("body = 'binary';"), const Code("body = 'binary';"),
const Code('}'), const Code('}'),
const Code(''), const Code(''),
Code('return ${prefix}ApiException('), Code('return ${classPrefix}ApiException('),
const Code('response.statusCode,'), const Code('response.statusCode,'),
const Code('response.responseHeaders,'), const Code('response.responseHeaders,'),
const Code('body,'), const Code('body,'),
@ -166,7 +167,7 @@ class OpenAPIBuilder implements Builder {
..annotations.add(refer('override')) ..annotations.add(refer('override'))
..lambda = true ..lambda = true
..body = Code( ..body = Code(
"'${prefix}ApiException(statusCode: \$statusCode, headers: \$headers, body: \$body)'", "'${classPrefix}ApiException(statusCode: \$statusCode, headers: \$headers, body: \$body)'",
), ),
), ),
]), ]),
@ -276,7 +277,7 @@ class OpenAPIBuilder implements Builder {
Field( Field(
(final b) => b (final b) => b
..name = 'rootClient' ..name = 'rootClient'
..type = refer('${prefix}Client') ..type = refer('${classPrefix}Client')
..modifier = FieldModifier.final$, ..modifier = FieldModifier.final$,
), ),
) )
@ -294,7 +295,7 @@ class OpenAPIBuilder implements Builder {
} }
final matchedTags = spec.tags?.where((final t) => t.name == tag).toList(); final matchedTags = spec.tags?.where((final t) => t.name == tag).toList();
b b
..name = '$prefix${isRootClient ? 'Client' : _clientName(tag)}' ..name = '$classPrefix${isRootClient ? 'Client' : _clientName(tag)}'
..docs.addAll( ..docs.addAll(
_descriptionToDocs( _descriptionToDocs(
matchedTags != null && matchedTags.isNotEmpty ? matchedTags.single.description : null, matchedTags != null && matchedTags.isNotEmpty ? matchedTags.single.description : null,
@ -313,8 +314,8 @@ class OpenAPIBuilder implements Builder {
..name = _toDartName(tag == null ? t : t.substring('$tag/'.length)) ..name = _toDartName(tag == null ? t : t.substring('$tag/'.length))
..lambda = true ..lambda = true
..type = MethodType.getter ..type = MethodType.getter
..returns = refer('$prefix${_clientName(t)}') ..returns = refer('$classPrefix${_clientName(t)}')
..body = Code('$prefix${_clientName(t)}(${isRootClient ? 'this' : 'rootClient'})'), ..body = Code('$classPrefix${_clientName(t)}(${isRootClient ? 'this' : 'rootClient'})'),
), ),
], ],
for (final path in paths.keys) ...[ for (final path in paths.keys) ...[
@ -407,6 +408,7 @@ class OpenAPIBuilder implements Builder {
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
_toDartName( _toDartName(
'$operationId-${parameter.name}', '$operationId-${parameter.name}',
@ -519,12 +521,13 @@ class OpenAPIBuilder implements Builder {
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
_toDartName('$operationId-request-$mimeType', uppercaseFirstCharacter: true), _toDartName('$operationId-request-$mimeType', uppercaseFirstCharacter: true),
mediaType.schema!, mediaType.schema!,
nullable: dartParameterNullable, nullable: dartParameterNullable,
); );
final parameterName = _toDartName(result.name.replaceFirst(prefix, '')); final parameterName = _toDartName(result.name.replaceFirst(classPrefix, ''));
switch (mimeType) { switch (mimeType) {
case 'application/json': case 'application/json':
case 'application/x-www-form-urlencoded': case 'application/x-www-form-urlencoded':
@ -584,6 +587,7 @@ class OpenAPIBuilder implements Builder {
'${tag != null ? _toDartName(tag, uppercaseFirstCharacter: true) : null}${_toDartName(operationId, uppercaseFirstCharacter: true)}Headers'; '${tag != null ? _toDartName(tag, uppercaseFirstCharacter: true) : null}${_toDartName(operationId, uppercaseFirstCharacter: true)}Headers';
final result = resolveObject( final result = resolveObject(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
Schema( Schema(
@ -611,6 +615,7 @@ class OpenAPIBuilder implements Builder {
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
_toDartName( _toDartName(
'$operationId-response-$statusCode-$mimeType', '$operationId-response-$statusCode-$mimeType',
@ -645,9 +650,9 @@ class OpenAPIBuilder implements Builder {
} }
if (headersType != null && dataType != null) { if (headersType != null && dataType != null) {
b.returns = refer('Future<${prefix}Response<$dataType, $headersType>>'); b.returns = refer('Future<${classPrefix}Response<$dataType, $headersType>>');
code.write( code.write(
'return ${prefix}Response<$dataType, $headersType>($dataValue, $headersValue,);', 'return ${classPrefix}Response<$dataType, $headersType>($dataValue, $headersValue,);',
); );
} else if (headersType != null) { } else if (headersType != null) {
b.returns = refer('Future<$headersType>'); b.returns = refer('Future<$headersType>');
@ -663,7 +668,7 @@ class OpenAPIBuilder implements Builder {
code.write('}'); code.write('}');
} }
code.write( code.write(
'throw await ${prefix}ApiException.fromResponse(response); // coverage:ignore-line\n', 'throw await ${classPrefix}ApiException.fromResponse(response); // coverage:ignore-line\n',
); );
} else { } else {
b.returns = refer('Future'); b.returns = refer('Future');
@ -690,6 +695,7 @@ class OpenAPIBuilder implements Builder {
} else { } else {
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
schema, schema,
@ -710,18 +716,20 @@ class OpenAPIBuilder implements Builder {
'$name,', '$name,',
], ],
'])', '])',
r'final Serializers serializers = (_$serializers.toBuilder()', r'final Serializers _serializers = (_$_serializers.toBuilder()',
for (final type in state.resolvedTypeCombinations) ...[ for (final type in state.resolvedTypeCombinations) ...[
...type.builderFactories, ...type.builderFactories,
], ],
').build();', ').build();',
'', '',
'final Serializers jsonSerializers = (serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();', 'Serializers get ${variablePrefix}Serializers => _serializers;',
'',
'final Serializers _jsonSerializers = (_serializers.toBuilder()..addPlugin(StandardJsonPlugin())..addPlugin(const ContentStringPlugin())).build();',
'', '',
'// coverage:ignore-start', '// coverage:ignore-start',
'T deserialize$prefix<T>(final Object data) => serializers.deserialize(data, specifiedType: FullType(T))! as T;', 'T deserialize$classPrefix<T>(final Object data) => _serializers.deserialize(data, specifiedType: FullType(T))! as T;',
'', '',
'Object? serialize$prefix<T>(final T data) => serializers.serialize(data, specifiedType: FullType(T));', 'Object? serialize$classPrefix<T>(final T data) => _serializers.serialize(data, specifiedType: FullType(T));',
'// coverage:ignore-end', '// coverage:ignore-end',
]); ]);
} }
@ -929,6 +937,7 @@ class State {
TypeResult resolveObject( TypeResult resolveObject(
final OpenAPI spec, final OpenAPI spec,
final String variablePrefix,
final State state, final State state,
final String identifier, final String identifier,
final Schema schema, { final Schema schema, {
@ -981,7 +990,7 @@ TypeResult resolveObject(
..type = refer('Map<String, dynamic>'), ..type = refer('Map<String, dynamic>'),
), ),
) )
..body = const Code('jsonSerializers.deserializeWith(serializer, json)!'), ..body = const Code('_jsonSerializers.deserializeWith(serializer, json)!'),
), ),
]) ])
..methods.addAll([ ..methods.addAll([
@ -990,7 +999,7 @@ TypeResult resolveObject(
..name = 'toJson' ..name = 'toJson'
..returns = refer('Map<String, dynamic>') ..returns = refer('Map<String, dynamic>')
..lambda = true ..lambda = true
..body = const Code('jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'), ..body = const Code('_jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
), ),
for (final propertyName in schema.properties!.keys) ...[ for (final propertyName in schema.properties!.keys) ...[
Method( Method(
@ -998,6 +1007,7 @@ TypeResult resolveObject(
final propertySchema = schema.properties![propertyName]!; final propertySchema = schema.properties![propertyName]!;
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
'${identifier}_${_toDartName(propertyName, uppercaseFirstCharacter: true)}', '${identifier}_${_toDartName(propertyName, uppercaseFirstCharacter: true)}',
propertySchema, propertySchema,
@ -1049,6 +1059,7 @@ TypeResult resolveObject(
final value = propertySchema.default_!.toString(); final value = propertySchema.default_!.toString();
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
propertySchema.type!, propertySchema.type!,
propertySchema, propertySchema,
@ -1174,6 +1185,7 @@ TypeResult resolveObject(
final propertySchema = schema.properties![propertyName]!; final propertySchema = schema.properties![propertyName]!;
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
'${identifier}_${_toDartName(propertyName, uppercaseFirstCharacter: true)}', '${identifier}_${_toDartName(propertyName, uppercaseFirstCharacter: true)}',
propertySchema, propertySchema,
@ -1188,7 +1200,9 @@ TypeResult resolveObject(
Code("case '$propertyName':"), Code("case '$propertyName':"),
if (result.className != 'String') ...[ if (result.className != 'String') ...[
if (result is TypeResultBase || result is TypeResultEnum) ...[ if (result is TypeResultBase || result is TypeResultEnum) ...[
Code('result.${_toDartName(propertyName)} = ${result.deserialize(result.decode('value!'))};'), Code(
'result.${_toDartName(propertyName)} = ${result.deserialize(result.decode('value!'))};',
),
] else ...[ ] else ...[
Code( Code(
'result.${_toDartName(propertyName)}.replace(${result.deserialize(result.decode('value!'))});', 'result.${_toDartName(propertyName)}.replace(${result.deserialize(result.decode('value!'))});',
@ -1234,6 +1248,7 @@ TypeResult resolveObject(
TypeResult resolveType( TypeResult resolveType(
final OpenAPI spec, final OpenAPI spec,
final String variablePrefix,
final State state, final State state,
final String identifier, final String identifier,
final Schema schema, { final Schema schema, {
@ -1251,6 +1266,7 @@ TypeResult resolveType(
final name = schema.ref!.split('/').last; final name = schema.ref!.split('/').last;
result = resolveType( result = resolveType(
spec, spec,
variablePrefix,
state, state,
name, name,
spec.components!.schemas![name]!, spec.components!.schemas![name]!,
@ -1263,6 +1279,7 @@ TypeResult resolveType(
.map( .map(
(final s) => resolveType( (final s) => resolveType(
spec, spec,
variablePrefix,
state, state,
'$identifier${schema.ofs!.indexOf(s)}', '$identifier${schema.ofs!.indexOf(s)}',
s, s,
@ -1342,14 +1359,14 @@ TypeResult resolveType(
..type = refer('Object'), ..type = refer('Object'),
), ),
) )
..body = const Code('jsonSerializers.deserializeWith(serializer, json)!'), ..body = const Code('_jsonSerializers.deserializeWith(serializer, json)!'),
), ),
Method( Method(
(final b) => b (final b) => b
..name = 'toJson' ..name = 'toJson'
..returns = refer('Map<String, dynamic>') ..returns = refer('Map<String, dynamic>')
..lambda = true ..lambda = true
..body = const Code('jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'), ..body = const Code('_jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
), ),
Method( Method(
(final b) => b (final b) => b
@ -1525,6 +1542,7 @@ TypeResult resolveType(
} else if (schema.isContentString) { } else if (schema.isContentString) {
final subResult = resolveType( final subResult = resolveType(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
schema.contentSchema!, schema.contentSchema!,
@ -1574,6 +1592,7 @@ TypeResult resolveType(
if (schema.items != null) { if (schema.items != null) {
final subResult = resolveType( final subResult = resolveType(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
schema.items!, schema.items!,
@ -1603,6 +1622,7 @@ TypeResult resolveType(
} else { } else {
final subResult = resolveType( final subResult = resolveType(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
schema.additionalProperties!, schema.additionalProperties!,
@ -1632,6 +1652,7 @@ TypeResult resolveType(
result = resolveObject( result = resolveObject(
spec, spec,
variablePrefix,
state, state,
identifier, identifier,
schema, schema,
@ -1670,6 +1691,7 @@ TypeResult resolveType(
(final b) { (final b) {
final result = resolveType( final result = resolveType(
spec, spec,
variablePrefix,
state, state,
'$identifier${_toDartName(value.toString(), uppercaseFirstCharacter: true)}', '$identifier${_toDartName(value.toString(), uppercaseFirstCharacter: true)}',
schema, schema,

4
packages/dynamite/dynamite/lib/src/type_result/type_result.dart

@ -57,13 +57,13 @@ abstract class TypeResult {
/// Serializes the variable named [object]. /// Serializes the variable named [object].
/// ///
/// The serialized result is an [Object]? /// The serialized result is an [Object]?
String serialize(final String object) => 'jsonSerializers.serialize($object, specifiedType: const $fullType)'; String serialize(final String object) => '_jsonSerializers.serialize($object, specifiedType: const $fullType)';
/// Deserializes the variable named [object]. /// Deserializes the variable named [object].
/// ///
/// The serialized result will be of [name]. /// The serialized result will be of [name].
String deserialize(final String object) => String deserialize(final String object) =>
'(jsonSerializers.deserialize($object, specifiedType: const $fullType)! as $name)'; '(_jsonSerializers.deserialize($object, specifiedType: const $fullType)! as $name)';
/// Decodes the variable named [object]. /// Decodes the variable named [object].
String decode(final String object) => 'json.decode($object as String)'; String decode(final String object) => 'json.decode($object as String)';

Loading…
Cancel
Save