mirror of
https://github.com/foss42/apidash.git
synced 2025-08-06 13:51:20 +08:00
feat: added http and dio code gen
This commit is contained in:
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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});
|
||||||
|
Reference in New Issue
Block a user