feat: added http and dio code gen

This commit is contained in:
Vidya Sagar
2024-01-03 23:10:51 +05:30
parent e98ee3d2b1
commit 9fa72af06b
3 changed files with 99 additions and 15 deletions

View File

@ -1,5 +1,8 @@
import 'dart:convert';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import 'package:apidash/models/request_model.dart' show RequestModel; import 'package:apidash/models/request_model.dart' show RequestModel;
import 'package:apidash/utils/convert_utils.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
@ -22,6 +25,7 @@ class DartDioCodeGen {
headers: requestModel.headersMap, headers: requestModel.headersMap,
body: requestModel.requestBody, body: requestModel.requestBody,
contentType: requestModel.requestBodyContentType, contentType: requestModel.requestBodyContentType,
formData: rowsToFormDataMap(requestModel.formDataList) ?? [],
); );
return next; return next;
} catch (e) { } catch (e) {
@ -36,6 +40,7 @@ class DartDioCodeGen {
required Map<String, String> headers, required Map<String, String> headers,
required String? body, required String? body,
required ContentType contentType, required ContentType contentType,
required List<Map<String, dynamic>> formData,
}) { }) {
final sbf = StringBuffer(); final sbf = StringBuffer();
final emitter = DartEmitter(); final emitter = DartEmitter();
@ -54,9 +59,22 @@ class DartDioCodeGen {
literalMap(headers.map((key, value) => MapEntry(key, value))), literalMap(headers.map((key, value) => MapEntry(key, value))),
); );
} }
final multiPartList = Code('''
final List<Map<String,String>> formDataList = ${json.encode(formData)};
for (var formField in formDataList) {
if (formField['type'] == 'file') {
formData.files.add(MapEntry(
formField['name'],
await MultipartFile.fromFile(formField['value'], filename: formField['value']),
));
} else {
formData.fields.add(MapEntry(formField['name'], formField['value']));
}
}
''');
Expression? dataExp; Expression? dataExp;
if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) { if ((kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false) ||
contentType == ContentType.formdata)) {
final strContent = CodeExpression(Code('r\'\'\'$body\'\'\'')); final strContent = CodeExpression(Code('r\'\'\'$body\'\'\''));
switch (contentType) { switch (contentType) {
// dio dosen't need pass `content-type` header when body is json or plain text // dio dosen't need pass `content-type` header when body is json or plain text
@ -69,7 +87,7 @@ class DartDioCodeGen {
dataExp = declareFinal('data').assign(strContent); dataExp = declareFinal('data').assign(strContent);
// when add new type of [ContentType], need update [dataExp]. // when add new type of [ContentType], need update [dataExp].
case ContentType.formdata: case ContentType.formdata:
// TODO: Need to Handle this case. dataExp = declareFinal('data').assign(refer('FormData()'));
} }
} }
final responseExp = declareFinal('response').assign(InvokeExpression.newOf( final responseExp = declareFinal('response').assign(InvokeExpression.newOf(
@ -95,6 +113,8 @@ class DartDioCodeGen {
if (queryParamExp != null) queryParamExp, if (queryParamExp != null) queryParamExp,
if (headerExp != null) headerExp, if (headerExp != null) headerExp,
if (dataExp != null) dataExp, if (dataExp != null) dataExp,
if ((contentType == ContentType.formdata && formData.isNotEmpty))
multiPartList,
responseExp, responseExp,
refer('print').call([refer('response').property('statusCode')]), refer('print').call([refer('response').property('statusCode')]),
refer('print').call([refer('response').property('data')]), refer('print').call([refer('response').property('data')]),
@ -124,6 +144,8 @@ class DartDioCodeGen {
sbf.writeln(mainFunction.accept(emitter)); sbf.writeln(mainFunction.accept(emitter));
return DartFormatter(pageWidth: 160).format(sbf.toString()); return DartFormatter(
pageWidth: contentType == ContentType.formdata ? 70 : 160)
.format(sbf.toString());
} }
} }

View File

@ -1,7 +1,9 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:apidash/consts.dart'; import 'package:apidash/consts.dart';
import 'package:apidash/models/models.dart' show RequestModel; import 'package:apidash/models/models.dart' show RequestModel;
import 'package:apidash/utils/convert_utils.dart';
import 'package:code_builder/code_builder.dart'; import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart'; import 'package:dart_style/dart_style.dart';
@ -24,6 +26,7 @@ class DartHttpCodeGen {
headers: requestModel.headersMap, headers: requestModel.headersMap,
body: requestModel.requestBody, body: requestModel.requestBody,
contentType: requestModel.requestBodyContentType, contentType: requestModel.requestBodyContentType,
formData: rowsToFormDataMap(requestModel.formDataList) ?? [],
); );
return next; return next;
} catch (e) { } catch (e) {
@ -38,6 +41,7 @@ class DartHttpCodeGen {
required Map<String, String> headers, required Map<String, String> headers,
required String? body, required String? body,
required ContentType contentType, required ContentType contentType,
required List<Map<String, dynamic>> formData,
}) { }) {
final uri = Uri.parse(url); final uri = Uri.parse(url);
@ -99,7 +103,9 @@ class DartHttpCodeGen {
); );
} }
final responseExp = declareFinal('response').assign(InvokeExpression.newOf( final responseExp = declareFinal('response').assign(InvokeExpression.newOf(
refer('http.${method.name}'), refer(
'http.${method.name}',
),
[refer('uri')], [refer('uri')],
{ {
if (headerExp != null) 'headers': refer('headers'), if (headerExp != null) 'headers': refer('headers'),
@ -107,7 +113,36 @@ class DartHttpCodeGen {
}, },
[], [],
).awaited); ).awaited);
final multiPartRequest =
declareFinal('request').assign(InvokeExpression.newOf(
refer(
'http.MultipartRequest',
),
[refer(jsonEncode(method.name.toUpperCase())), refer('uri')],
));
final multiPartFiles = declareFinal('formDataList').assign(refer(
jsonEncode(formData),
));
final addHeaders = refer('request.headers.addAll').call([refer('headers')]);
const multiPartList = Code('''
for (Map<String, String> formData in formDataList){
if (formData['type'] == 'text') {
request.fields.addAll({formData['name']: formData['value']});
} else {
request.files.add(
await http.MultipartFile.fromPath(
formData['name'],
formData['value'],
),
);
}
}
''');
var multiPartRequestSend =
declareFinal('response').assign(refer('request.send()').awaited);
var multiPartResponseBody = declareFinal('responseBody')
.assign(refer('response.stream.bytesToString()').awaited);
final mainFunction = Method((m) { final mainFunction = Method((m) {
final statusRef = refer('statusCode'); final statusRef = refer('statusCode');
m m
@ -132,25 +167,49 @@ class DartHttpCodeGen {
b.statements.add(headerExp.statement); b.statements.add(headerExp.statement);
} }
b.statements.add(const Code('\n')); b.statements.add(const Code('\n'));
b.statements.add(responseExp.statement); if (contentType == ContentType.formdata) {
b.statements.add(const Code('\n')); if (formData.isNotEmpty) {
b.statements.add(declareVar('statusCode', type: refer('int')) b.statements.add(multiPartFiles.statement);
.assign(refer('response').property('statusCode')) }
.statement); b.statements.add(multiPartRequest.statement);
if (formData.isNotEmpty) {
b.statements.add(multiPartList);
}
if (headerExp != null) {
b.statements.add(addHeaders.statement);
}
b.statements.add(multiPartRequestSend.statement);
b.statements.add(multiPartResponseBody.statement);
b.statements.add(declareVar('statusCode', type: refer('int'))
.assign(refer('response').property('statusCode'))
.statement);
b.statements.add(const Code('\n'));
} else {
b.statements.add(responseExp.statement);
b.statements.add(const Code('\n'));
b.statements.add(declareVar('statusCode', type: refer('int'))
.assign(refer('response').property('statusCode'))
.statement);
}
b.statements.add(declareIfElse( b.statements.add(declareIfElse(
condition: statusRef condition: statusRef
.greaterOrEqualTo(literalNum(200)) .greaterOrEqualTo(literalNum(200))
.and(statusRef.lessThan(literalNum(300))), .and(statusRef.lessThan(literalNum(300))),
body: [ body: [
refer('print').call([literalString(r'Status Code: $statusCode')]), refer('print').call([literalString(r'Status Code: $statusCode')]),
refer('print') refer('print').call([
.call([literalString(r'Response Body: ${response.body}')]), literalString(
'Response Body: ${contentType == ContentType.formdata ? ':\$responseBody' : '\${response.body}'}')
]),
], ],
elseBody: [ elseBody: [
refer('print') refer('print')
.call([literalString(r'Error Status Code: $statusCode')]), .call([literalString(r'Error Status Code: $statusCode')]),
refer('print').call( refer('print').call([
[literalString(r'Error Response Body: ${response.body}')]), literalString(
'Error Response Body: ${contentType == ContentType.formdata ? ':\$responseBody' : '\${response.body}'}')
]),
], ],
)); ));
}); });
@ -158,6 +217,8 @@ class DartHttpCodeGen {
sbf.writeln(mainFunction.accept(emitter)); sbf.writeln(mainFunction.accept(emitter));
return DartFormatter(pageWidth: 160).format(sbf.toString()); return DartFormatter(
pageWidth: contentType == ContentType.formdata ? 70 : 160)
.format(sbf.toString());
} }
} }

View File

@ -39,6 +39,7 @@ Future<(http.Response?, Duration?, String?)> request(
requestModel.method.name.toUpperCase(), requestModel.method.name.toUpperCase(),
requestUrl, requestUrl,
); );
multiPartRequest.headers.addAll(headers);
for (FormDataModel formData in (requestModel.formDataList ?? [])) { for (FormDataModel formData in (requestModel.formDataList ?? [])) {
if (formData.type == FormDataType.text) { if (formData.type == FormDataType.text) {
multiPartRequest.fields.addAll({formData.name: formData.value}); multiPartRequest.fields.addAll({formData.name: formData.value});