Skip to content

Commit

Permalink
Merge pull request #1171 from nextcloud/feat/dynamite/uri-templates
Browse files Browse the repository at this point in the history
  • Loading branch information
provokateurin authored Nov 22, 2023
2 parents 36200dc + cf8fa31 commit f3ef7c3
Show file tree
Hide file tree
Showing 32 changed files with 2,428 additions and 1,069 deletions.
8 changes: 8 additions & 0 deletions packages/app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.2"
uri:
dependency: transitive
description:
name: uri
sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
url_launcher:
dependency: transitive
description:
Expand Down
27 changes: 12 additions & 15 deletions packages/dynamite/dynamite/lib/src/builder/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ Iterable<Method> buildTags(
.join(',');

code.writeln('''
final _pathParameters = <String, dynamic>{};
final _queryParameters = <String, dynamic>{};
final _headers = <String, String>{${acceptHeader.isNotEmpty ? "'Accept': '$acceptHeader'," : ''}};
Uint8List? _body;
Expand Down Expand Up @@ -323,17 +324,12 @@ Iterable<Method> buildTags(
toDartName(identifierBuilder.toString(), uppercaseFirstCharacter: true),
);

var path = pathEntry.key;
for (final pathParameter in parameters.where((final p) => p.$in == openapi.ParameterType.path)) {
path = path.replaceAll('{${pathParameter.name}}', '\$_${toDartName(pathParameter.name)}');
}

code.writeln(
'''
final _path = '$path';
final _uri = Uri(path: _path, queryParameters: _queryParameters.isNotEmpty ? _queryParameters : null);
''',
);
code.writeln('''
var _uri = Uri.parse(UriTemplate('${pathEntry.key}').expand(_pathParameters));
if (_queryParameters.isNotEmpty) {
_uri = _uri.replace(queryParameters: _queryParameters);
}
''');

if (dataType != null) {
returnDataType = dataType.name;
Expand Down Expand Up @@ -429,12 +425,13 @@ Iterable<String> buildParameterSerialization(
onlyChildren: parameter.$in == openapi.ParameterType.query,
);

final assignment = switch (parameter.$in) {
openapi.ParameterType.path => 'final _${toDartName(parameter.name)} = Uri.encodeQueryComponent($value);',
openapi.ParameterType.query => "_queryParameters['${parameter.name}'] = $value;",
openapi.ParameterType.header => "_headers['${parameter.name}'] = $value;",
final mapName = switch (parameter.$in) {
openapi.ParameterType.path => '_pathParameters',
openapi.ParameterType.query => '_queryParameters',
openapi.ParameterType.header => '_headers',
_ => throw UnsupportedError('Can not work with parameter "${parameter.name}" in "${parameter.$in}"'),
};
final assignment = "$mapName['${parameter.name}'] = $value;";

if (!parameter.required && (result.nullable || hasDefault)) {
yield 'if( ';
Expand Down
1 change: 1 addition & 0 deletions packages/dynamite/dynamite/lib/src/builder/imports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Iterable<Spec> generateImports(final AssetId outputId, final State state) sync*
Directive.import('package:dynamite_runtime/utils.dart'),
Directive.import('package:meta/meta.dart'),
Directive.import('package:universal_io/io.dart'),
Directive.import('package:uri/uri.dart'),
const Code(''),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
import 'package:uri/uri.dart';

part 'headers.openapi.g.dart';

Expand Down Expand Up @@ -58,12 +59,15 @@ class Client extends DynamiteClient {
/// * [$get] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<void, GetHeaders> $getRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{};
Uint8List? body;

const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<void, GetHeaders>(
response: executeRequest(
Expand Down Expand Up @@ -105,12 +109,15 @@ class Client extends DynamiteClient {
/// * [withContentOperationId] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<void, WithContentOperationIdHeaders> withContentOperationIdRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{};
Uint8List? body;

const path = '/with_content/operation_id';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/with_content/operation_id').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<void, WithContentOperationIdHeaders>(
response: executeRequest(
Expand Down Expand Up @@ -152,14 +159,17 @@ class Client extends DynamiteClient {
/// * [getWithContent] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<Uint8List, GetWithContentHeaders> getWithContentRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/octet-stream',
};
Uint8List? body;

const path = '/with_content';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/with_content').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<Uint8List, GetWithContentHeaders>(
response: executeRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:dynamite_runtime/http_client.dart';
import 'package:dynamite_runtime/models.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
import 'package:uri/uri.dart';

class Client extends DynamiteClient {
Client(
Expand Down Expand Up @@ -75,6 +76,7 @@ class Client extends DynamiteClient {
final ContentString<BuiltMap<String, JsonObject>>? contentString,
final ContentString<BuiltMap<String, JsonObject>>? contentParameter,
}) {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
Expand All @@ -97,8 +99,65 @@ class Client extends DynamiteClient {
]),
);
}
const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<JsonObject, void>(
response: executeRequest(
'get',
uri,
headers,
body,
const {200},
),
bodyType: const FullType(JsonObject),
headersType: null,
serializers: _jsonSerializers,
);
}

/// Returns a [Future] containing a [DynamiteResponse] with the status code, deserialized body and headers.
/// Throws a [DynamiteApiException] if the API call does not return an expected status code.
///
/// Status codes:
/// * 200
///
/// See:
/// * [getPathParameterRaw] for an experimental operation that returns a [DynamiteRawResponse] that can be serialized.
Future<DynamiteResponse<JsonObject, void>> getPathParameter({required final String pathParameter}) async {
final rawResponse = getPathParameterRaw(
pathParameter: pathParameter,
);

return rawResponse.future;
}

/// This method and the response it returns is experimental. The API might change without a major version bump.
///
/// Returns a [Future] containing a [DynamiteRawResponse] with the raw [HttpClientResponse] and serialization helpers.
/// Throws a [DynamiteApiException] if the API call does not return an expected status code.
///
/// Status codes:
/// * 200
///
/// See:
/// * [getPathParameter] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<JsonObject, void> getPathParameterRaw({required final String pathParameter}) {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
};
Uint8List? body;

pathParameters['path-parameter'] = pathParameter;
var uri = Uri.parse(UriTemplate('/{path-parameter}').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<JsonObject, void>(
response: executeRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@
}
}
}
},
"/{path-parameter}": {
"parameters": [
{
"name": "path-parameter",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"get": {
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {}
}
}
}
}
}
}
},
"tags": []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
import 'package:uri/uri.dart';

class Client extends DynamiteClient {
Client(
Expand Down Expand Up @@ -58,6 +59,7 @@ class Client extends DynamiteClient {
/// * [$get] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<void, void> $getRaw({final Uint8List? uint8List}) {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{};
Uint8List? body;
Expand All @@ -66,8 +68,10 @@ class Client extends DynamiteClient {
if (uint8List != null) {
body = uint8List;
}
const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<void, void>(
response: executeRequest(
Expand Down Expand Up @@ -111,6 +115,7 @@ class Client extends DynamiteClient {
/// * [post] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<void, void> postRaw({final String? string}) {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{};
Uint8List? body;
Expand All @@ -119,8 +124,10 @@ class Client extends DynamiteClient {
if (string != null) {
body = utf8.encode(string);
}
const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<void, void>(
response: executeRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:dynamite_runtime/built_value.dart';
import 'package:dynamite_runtime/http_client.dart';
import 'package:meta/meta.dart';
import 'package:universal_io/io.dart';
import 'package:uri/uri.dart';

class Client extends DynamiteClient {
Client(
Expand Down Expand Up @@ -55,14 +56,17 @@ class Client extends DynamiteClient {
/// * [$get] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<String, void> $getRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
};
Uint8List? body;

const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<String, void>(
response: executeRequest(
Expand Down Expand Up @@ -106,14 +110,17 @@ class Client extends DynamiteClient {
/// * [put] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<String, void> putRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
};
Uint8List? body;

const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<String, void>(
response: executeRequest(
Expand Down Expand Up @@ -159,14 +166,17 @@ class Client extends DynamiteClient {
/// * [post] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<String, void> postRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
};
Uint8List? body;

const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<String, void>(
response: executeRequest(
Expand Down Expand Up @@ -210,14 +220,17 @@ class Client extends DynamiteClient {
/// * [patch] for an operation that returns a [DynamiteResponse] with a stable API.
@experimental
DynamiteRawResponse<String, void> patchRaw() {
final pathParameters = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final headers = <String, String>{
'Accept': 'application/json',
};
Uint8List? body;

const path = '/';
final uri = Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null);
var uri = Uri.parse(UriTemplate('/').expand(pathParameters));
if (queryParameters.isNotEmpty) {
uri = uri.replace(queryParameters: queryParameters);
}

return DynamiteRawResponse<String, void>(
response: executeRequest(
Expand Down
1 change: 1 addition & 0 deletions packages/dynamite/dynamite_end_to_end_test/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies:
path: packages/dynamite/dynamite_runtime
meta: ^1.0.0
universal_io: ^2.0.0
uri: ^1.0.0

dev_dependencies:
build_runner: ^2.4.6
Expand Down
Loading

0 comments on commit f3ef7c3

Please sign in to comment.