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

Draft: feat: Modify codegen for low-bandwidth mode #27

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ build/

# Directory created by dartdoc
doc/api/

matrix-doc
matrix.json
67 changes: 34 additions & 33 deletions bin/dart_openapi_codegen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ class ObjectSchema extends DefinitionSchema {
' });\n\n' +
' $dartType.fromJson(Map<String, dynamic> json) :\n' +
allProperties.entries
.map((e) =>
' ${variableName(e.key)} = ${e.value.schema.dartFromJson("json['${e.key}']")}')
.map((e) => dartType == 'BasicEvent' && e.key == 'content'
? 'content = (json[\'content\'] as Map<String, dynamc>).copy()'
: ' ${variableName(e.key)} = ${e.value.schema.dartFromJson("json['${e.key}']")}')
.followedBy([
if (inheritedAdditionalProperties != null)
' additionalProperties = Map.fromEntries(json.entries.where((e) => ![${allProperties.keys.map((k) => "'$k'").join(', ')}].contains(e.key)).map((e) => MapEntry(e.key, ${inheritedAdditionalProperties!.dartFromJson('e.value')})))'
Expand Down Expand Up @@ -603,23 +604,6 @@ class Operation {
' ${e.value.schema.dartToQueryEntry(e.key, variableName(e.key))},\n')
.join('') +
' }';

String get dartSetBody {
final bodyParams =
parameters.entries.where((e) => e.value.type == ParameterType.body);
if (bodyParams.isEmpty) return '';
final bodyParam = bodyParams.single;
final bodySchema = bodyParam.value.schema;
if (bodySchema == SingletonSchema.map['string/byte']) {
return ' request.bodyBytes = ${variableName(bodyParam.key)};\n';
}
final jsonBody =
(unpackedBody && bodySchema is ObjectSchema && bodySchema.inlinable)
? bodySchema.dartToJsonMap
: bodySchema.dartToJson(variableName(bodyParam.key));
return " request.headers['content-type'] = 'application/json';\n"
' request.bodyBytes = utf8.encode(jsonEncode($jsonBody));\n';
}
}

List<Operation> operationsFromApi(Map<String, dynamic> api) {
Expand Down Expand Up @@ -747,7 +731,7 @@ void numberConflicts(List<Operation> operations) {
}

String generateModel(List<Operation> operations) {
return "import 'internal.dart';\n\nclass _NameSource { final String source; const _NameSource(this.source); }\n\n" +
return "import 'internal.dart';\nimport '../utils/map_copy_extension.dart';\n\nclass _NameSource { final String source; const _NameSource(this.source); }\n\n" +
operations
.expand((op) => op.definitionSchemas)
.toSet()
Expand All @@ -759,8 +743,9 @@ String generateApi(List<Operation> operations) {
var ops =
"import 'model.dart';\nimport 'fixed_model.dart';\nimport 'internal.dart';\n\n";
ops +=
"import 'package:http/http.dart';\nimport 'dart:convert';\nimport 'dart:typed_data';\n\nclass Api {\n Client httpClient;\n Uri? baseUri;\n String? bearerToken;\n Api({Client? httpClient, this.baseUri, this.bearerToken})\n : httpClient = httpClient ?? Client();\n"
" Never unexpectedResponse(BaseResponse response, Uint8List body) { throw Exception('http error response'); }\n";
"import 'package:http/http.dart';\nimport 'dart:convert';\nimport 'dart:typed_data';\n\nabstract class Api {\n Uri? baseUri;\n Api({this.baseUri});\n"
' Future<Map<String, dynamic>> doRequest({required Request request, Map<String, dynamic>? json, required bool authenticated});\n'
' Future<StreamedResponse> doRawRequest({required Request request, Map<String, dynamic>? json, required bool authenticated});\n';
for (final op in operations) {
ops += '\n';
ops +=
Expand All @@ -783,27 +768,43 @@ String generateApi(List<Operation> operations) {
ops += ');\n';
ops +=
" final request = Request('${op.method.toUpperCase()}', baseUri!.resolveUri(requestUri));\n";
if (op.accessToken) {
ops +=
" request.headers['authorization'] = 'Bearer \${bearerToken!}';\n";
}
for (final e in op.headerParameters.entries) {
ops +=
" ${e.value.schema.dartCondition(variableName(e.key))}request.headers['${e.key.toLowerCase()}'] = ${e.value.schema.dartToQuery(variableName(e.key))};\n";
}
ops += op.dartSetBody;
ops += ' final response = await httpClient.send(request);\n';
ops += ' final responseBody = await response.stream.toBytes();\n';
// add the body to the `request` only if it is *not* json
final bodyParams =
op.parameters.entries.where((e) => e.value.type == ParameterType.body);
if (bodyParams.isNotEmpty) {
final bodyParam = bodyParams.single;
if (bodyParam.value.schema == SingletonSchema.map['string/byte']) {
ops += ' request.bodyBytes = ${variableName(bodyParam.key)};\n';
}
}
ops +=
' if (response.statusCode != 200) unexpectedResponse(response, responseBody);\n';
' final response = await ${op.response == SingletonSchema.map['file'] ? 'doRawRequest' : 'doRequest'}(\n';
ops += ' request: request,\n';
if (bodyParams.isNotEmpty) {
final bodyParam = bodyParams.single;
final bodySchema = bodyParam.value.schema;
if (bodySchema != SingletonSchema.map['string/byte']) {
final jsonBody = (op.unpackedBody &&
bodySchema is ObjectSchema &&
bodySchema.inlinable)
? bodySchema.dartToJsonMap
: bodySchema.dartToJson(variableName(bodyParam.key));
ops += ' json: $jsonBody,\n';
}
}
ops += ' authenticated: ${op.accessToken},\n';
ops += ' );\n';
if (op.response == SingletonSchema.map['file']) {
ops += ' final responseBody = await response.stream.toBytes();\n';
ops +=
" return FileResponse(contentType: response.headers['content-type'], data: responseBody);";
} else {
ops += ' final responseString = utf8.decode(responseBody);\n';
ops += ' final json = jsonDecode(responseString);\n';
ops +=
' return ${op.dartResponse?.dartFromJson('json${op.dartResponseExtract}') ?? 'null'};\n';
' return ${op.dartResponse?.dartFromJson('response${op.dartResponseExtract}') ?? 'null'};\n';
}
ops += ' }\n';
}
Expand Down
12 changes: 12 additions & 0 deletions scripts/pusher-data-additional-properties.patch
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@ index 9feccb4f..99753841 100644
properties:
url:
type: string
diff --git a/data/api/client-server/versions.yaml b/data/api/client-server/versions.yaml
index e359de3c..fc68a903 100644
--- a/data/api/client-server/versions.yaml
+++ b/data/api/client-server/versions.yaml
@@ -59,6 +59,7 @@ paths:
}
schema:
type: object
+ additionalProperties: true
properties:
versions:
type: array