Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(nextcloud)!: Move all query parameters to body to fix many serialization problems #2129

Merged
merged 3 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cspell/nextcloud.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ displayname
etag
federatedfilesharing
fediverse
groupid
heavyrain
heavyrainshowers
iscustomavatar
Expand All @@ -40,6 +41,7 @@ productname
rainshowers
replyable
requesttoken
reshares
resharing
rgdnvw
roomid
Expand All @@ -54,6 +56,7 @@ stime
stunservers
stylesheet
subadmin
subfiles
subline
systemtags
totalitems
Expand Down
24 changes: 12 additions & 12 deletions packages/dynamite/dynamite/example/lib/petstore.openapi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ class $Client extends _i1.DynamiteClient {
int? limit,
}) {
final _parameters = <String, Object?>{};
final $tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = $tags;
final __tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = __tags;

final $limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = $limit;
final __limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = __limit;

final _path = _i4.UriTemplate('/pets{?tags*,limit*}').expand(_parameters);
final _uri = Uri.parse('$baseURL$_path');
Expand Down Expand Up @@ -156,13 +156,13 @@ class $Client extends _i1.DynamiteClient {
/// * [addPet] for a method executing this request and parsing the response.
/// * [$addPet_Serializer] for a converter to parse the `Response` from an executed this request.
@_i2.experimental
_i3.Request $addPet_Request({required NewPet newPet}) {
_i3.Request $addPet_Request({required NewPet $body}) {
const _path = '/pets';
final _uri = Uri.parse('$baseURL$_path');
final _request = _i3.Request('post', _uri);
_request.headers['Accept'] = 'application/json';
_request.headers['Content-Type'] = 'application/json';
_request.body = json.encode(_$jsonSerializers.serialize(newPet, specifiedType: const FullType(NewPet)));
_request.body = json.encode(_$jsonSerializers.serialize($body, specifiedType: const FullType(NewPet)));
return _request;
}

Expand All @@ -178,9 +178,9 @@ class $Client extends _i1.DynamiteClient {
/// See:
/// * [$addPet_Request] for the request send by this method.
/// * [$addPet_Serializer] for a converter to parse the `Response` from an executed request.
Future<_i1.DynamiteResponse<Pet, void>> addPet({required NewPet newPet}) async {
Future<_i1.DynamiteResponse<Pet, void>> addPet({required NewPet $body}) async {
final _request = $addPet_Request(
newPet: newPet,
$body: $body,
);
final _streamedResponse = await httpClient.send(_request);
final _response = await _i3.Response.fromStream(_streamedResponse);
Expand Down Expand Up @@ -217,8 +217,8 @@ class $Client extends _i1.DynamiteClient {
@_i2.experimental
_i3.Request $findPetById_Request({required int id}) {
final _parameters = <String, Object?>{};
final $id = _$jsonSerializers.serialize(id, specifiedType: const FullType(int));
_parameters['id'] = $id;
final __id = _$jsonSerializers.serialize(id, specifiedType: const FullType(int));
_parameters['id'] = __id;

final _path = _i4.UriTemplate('/pets/{id}').expand(_parameters);
final _uri = Uri.parse('$baseURL$_path');
Expand Down Expand Up @@ -281,8 +281,8 @@ class $Client extends _i1.DynamiteClient {
@_i2.experimental
_i3.Request $deletePet_Request({required int id}) {
final _parameters = <String, Object?>{};
final $id = _$jsonSerializers.serialize(id, specifiedType: const FullType(int));
_parameters['id'] = $id;
final __id = _$jsonSerializers.serialize(id, specifiedType: const FullType(int));
_parameters['id'] = __id;

final _path = _i4.UriTemplate('/pets/{id}').expand(_parameters);
final _uri = Uri.parse('$baseURL$_path');
Expand Down
22 changes: 16 additions & 6 deletions packages/dynamite/dynamite/lib/src/builder/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ Iterable<Method> buildTags(
);
}

({String mimeType, TypeResult result})? bodyParameter;
({String mimeType, TypeResult result, bool dartParameterNullable, String? $default})? bodyParameter;
final requestBody = operation.requestBody;
if (requestBody != null) {
for (final content in requestBody.content.entries) {
Expand Down Expand Up @@ -261,13 +261,17 @@ Iterable<Method> buildTags(
}),
);

bodyParameter = (mimeType: mimeType, result: result);
bodyParameter = (
mimeType: mimeType,
result: result,
dartParameterNullable: dartParameterNullable,
$default: mediaType.schema?.$default,
);

final parameterName = toDartName(result.name);
operationParameters.add(
Parameter(
(b) => b
..name = parameterName
..name = r'$body'
..type = refer(result.nullableName)
..named = true
..required = dartParameterRequired,
Expand Down Expand Up @@ -381,7 +385,13 @@ ${allocate(returnType)}(
}

if (bodyParameter != null) {
resolveMimeTypeEncode(bodyParameter.mimeType, bodyParameter.result, code);
resolveMimeTypeEncode(
bodyParameter.mimeType,
bodyParameter.result,
bodyParameter.dartParameterNullable,
bodyParameter.$default,
code,
);
}

code.writeln('return _request;');
Expand Down Expand Up @@ -555,7 +565,7 @@ String buildParameterSerialization(
String Function(Reference) allocate,
) {
final dartName = toDartName(parameter.name);
final serializedName = '\$$dartName';
final serializedName = '__$dartName';
Leptopoda marked this conversation as resolved.
Show resolved Hide resolved
final buffer = StringBuffer();

final $default = parameter.schema?.$default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void _generateProperties(
propertyName,
identifier: identifier,
)
..nullable = isDartParameterNullable(
..nullable = isDartGetterNullable(
schema.required.contains(propertyName),
propertySchema,
);
Expand Down
28 changes: 17 additions & 11 deletions packages/dynamite/dynamite/lib/src/builder/resolve_mime_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,32 @@ TypeResult? resolveMimeTypeDecode(
void resolveMimeTypeEncode(
String mimeType,
TypeResult result,
// ignore: avoid_positional_boolean_parameters
bool dartParameterNullable,
String? $default,
StringSink output,
) {
output.writeln("_request.headers['Content-Type'] = '$mimeType';");
final parameterName = toDartName(result.name);

if (result.nullable) {
output.writeln('if ($parameterName != null) {');
}

switch (mimeType) {
case 'application/json':
case 'application/x-www-form-urlencoded':
output.writeln('_request.body = ${result.encode(parameterName, mimeType: mimeType)};');
if (dartParameterNullable) {
output.writeln(
'_request.body = \$body != null ? ${result.encode(result.serialize(r'$body'), mimeType: mimeType)} : ${$default != null ? result.encode($default, mimeType: mimeType) : result.encode(result.serialize('${result.name}()'), mimeType: mimeType)};',
);
} else {
output.writeln('_request.body = ${result.encode(result.serialize(r'$body'), mimeType: mimeType)};');
}
case 'application/octet-stream':
output.writeln('_request.bodyBytes = ${result.encode(parameterName, mimeType: mimeType)};');
if (dartParameterNullable) {
output.writeln(
'_request.bodyBytes = \$body != null ? ${result.encode(r'$body', mimeType: mimeType)} : ${$default != null ? result.encode($default, mimeType: mimeType) : 'Uint8List(0)'};',
);
} else {
output.writeln('_request.bodyBytes = ${result.encode(r'$body', mimeType: mimeType)};');
}
case _:
throw Exception('Can not parse any mime type of the Operation.');
}

if (result.nullable) {
output.writeln('}');
}
}
6 changes: 6 additions & 0 deletions packages/dynamite/dynamite/lib/src/helpers/dynamite.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ String clientName(String tag) => '\$${toDartName(tag, className: true)}Client';
bool isDartParameterNullable(
bool required,
json_schema.JsonSchema? schema,
) =>
!required || (schema?.nullable ?? false);

bool isDartGetterNullable(
bool required,
json_schema.JsonSchema? schema,
) =>
(!required && schema?.$default == null) || (schema?.nullable ?? false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,11 @@ sealed class TypeResult {
String object, {
required String mimeType,
}) {
final serialized = serialize(object);

switch (mimeType) {
case 'application/json':
return 'json.encode($serialized)';
return 'json.encode($object)';
case 'application/x-www-form-urlencoded':
return 'Uri(queryParameters: $serialized! as Map<String, dynamic>).query';
return 'Uri(queryParameters: $object! as Map<String, dynamic>).query';
case 'application/octet-stream':
if (className != 'Uint8List') {
throw Exception('octet-stream can only be applied to binary data. Expected Uint8List but got $className');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ class $Client extends _i1.DynamiteClient {
int? limit,
}) {
final _parameters = <String, Object?>{};
final $tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = $tags;
final __tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = __tags;

final $limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = $limit;
final __limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = __limit;

final _path = _i4.UriTemplate('/{?tags*,limit*}').expand(_parameters);
final _uri = Uri.parse('$baseURL$_path');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ class $Client extends _i1.DynamiteClient {
int? limit,
}) {
final _parameters = <String, Object?>{};
final $tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = $tags;
final __tags = _$jsonSerializers.serialize(tags, specifiedType: const FullType(BuiltList, [FullType(String)]));
_parameters['tags'] = __tags;

final $limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = $limit;
final __limit = _$jsonSerializers.serialize(limit, specifiedType: const FullType(int));
_parameters['limit'] = __limit;

final _path = _i4.UriTemplate('/{?tags*,limit*}').expand(_parameters);
final _uri = Uri.parse('$baseURL$_path');
Expand Down
Loading