This commit is contained in:
Ashita Prasad
2024-10-22 07:06:06 +05:30
parent 3c51af39bc
commit a3536b021b
187 changed files with 538 additions and 504 deletions

View File

@ -2,3 +2,9 @@ include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
analyzer:
errors:
invalid_annotation_target: ignore
exclude:
- "**/*.freezed.dart"
- "**/*.g.dart"

View File

@ -1,7 +1,13 @@
library apidash_core;
/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
}
export 'consts.dart';
export 'extensions/extensions.dart';
export 'models/models.dart';
export 'utils/utils.dart';
export 'services/services.dart';
// Export 3rd party packages
export 'package:collection/collection.dart';
export 'package:freezed_annotation/freezed_annotation.dart';
export 'package:http/http.dart';
export 'package:http_parser/http_parser.dart';

View File

@ -0,0 +1,70 @@
import 'dart:convert';
enum HTTPVerb { get, head, post, put, patch, delete }
enum FormDataType { text, file }
const kSupportedUriSchemes = ["https", "http"];
const kDefaultUriScheme = "https";
const kMethodsWithBody = [
HTTPVerb.post,
HTTPVerb.put,
HTTPVerb.patch,
HTTPVerb.delete,
];
const kDefaultHttpMethod = HTTPVerb.get;
const kDefaultContentType = ContentType.json;
const kTypeApplication = 'application';
// application
const kSubTypeJson = 'json';
const kSubTypeOctetStream = 'octet-stream';
const kSubTypePdf = 'pdf';
const kSubTypeSql = 'sql';
const kSubTypeXml = 'xml';
const kSubTypeYaml = 'yaml';
const kSubTypeXYaml = 'x-yaml';
const kSubTypeYml = 'x-yml';
const kSubTypeXWwwFormUrlencoded = 'x-www-form-urlencoded';
const kTypeText = 'text';
// text
const kSubTypeCss = 'css';
const kSubTypeCsv = 'csv';
const kSubTypeHtml = 'html';
const kSubTypeJavascript = 'javascript';
const kSubTypeMarkdown = 'markdown';
const kSubTypePlain = 'plain';
const kSubTypeTextXml = 'xml';
const kSubTypeTextYaml = 'yaml';
const kSubTypeTextYml = 'yml';
const kTypeImage = 'image';
//image
const kSubTypeSvg = 'svg+xml';
const kTypeAudio = 'audio';
const kTypeVideo = 'video';
const kTypeMultipart = "multipart";
const kSubTypeFormData = "form-data";
const kSubTypeDefaultViewOptions = 'all';
enum ContentType {
json("$kTypeApplication/$kSubTypeJson"),
text("$kTypeText/$kSubTypePlain"),
formdata("$kTypeMultipart/$kSubTypeFormData");
const ContentType(this.header);
final String header;
}
const JsonEncoder kJsonEncoder = JsonEncoder.withIndent(' ');
const JsonDecoder kJsonDecoder = JsonDecoder();
const LineSplitter kSplitter = LineSplitter();
const kCodeCharsPerLineLimit = 200;
const kHeaderContentType = "Content-Type";

View File

@ -0,0 +1 @@
export 'string_extensions.dart';

View File

@ -0,0 +1,21 @@
extension StringExtension on String {
String capitalize() {
if (isEmpty) {
return this;
}
if (length == 1) {
return toUpperCase();
}
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
}
String clip(int limit) {
if (limit < 0) {
return '...';
}
if (length <= limit) {
return this;
}
return "${substring(0, limit)}...";
}
}

View File

@ -0,0 +1,23 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../consts.dart';
part 'form_data_model.freezed.dart';
part 'form_data_model.g.dart';
@freezed
class FormDataModel with _$FormDataModel {
const factory FormDataModel({
required String name,
required String value,
required FormDataType type,
}) = _FormDataModel;
factory FormDataModel.fromJson(Map<String, Object?> json) =>
_$FormDataModelFromJson(json);
}
const kFormDataEmptyModel = FormDataModel(
name: "",
value: "",
type: FormDataType.text,
);

View File

@ -0,0 +1,187 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'form_data_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
FormDataModel _$FormDataModelFromJson(Map<String, dynamic> json) {
return _FormDataModel.fromJson(json);
}
/// @nodoc
mixin _$FormDataModel {
String get name => throw _privateConstructorUsedError;
String get value => throw _privateConstructorUsedError;
FormDataType get type => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$FormDataModelCopyWith<FormDataModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $FormDataModelCopyWith<$Res> {
factory $FormDataModelCopyWith(
FormDataModel value, $Res Function(FormDataModel) then) =
_$FormDataModelCopyWithImpl<$Res, FormDataModel>;
@useResult
$Res call({String name, String value, FormDataType type});
}
/// @nodoc
class _$FormDataModelCopyWithImpl<$Res, $Val extends FormDataModel>
implements $FormDataModelCopyWith<$Res> {
_$FormDataModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? value = null,
Object? type = null,
}) {
return _then(_value.copyWith(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
as FormDataType,
) as $Val);
}
}
/// @nodoc
abstract class _$$FormDataModelImplCopyWith<$Res>
implements $FormDataModelCopyWith<$Res> {
factory _$$FormDataModelImplCopyWith(
_$FormDataModelImpl value, $Res Function(_$FormDataModelImpl) then) =
__$$FormDataModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String name, String value, FormDataType type});
}
/// @nodoc
class __$$FormDataModelImplCopyWithImpl<$Res>
extends _$FormDataModelCopyWithImpl<$Res, _$FormDataModelImpl>
implements _$$FormDataModelImplCopyWith<$Res> {
__$$FormDataModelImplCopyWithImpl(
_$FormDataModelImpl _value, $Res Function(_$FormDataModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? value = null,
Object? type = null,
}) {
return _then(_$FormDataModelImpl(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
as FormDataType,
));
}
}
/// @nodoc
@JsonSerializable()
class _$FormDataModelImpl implements _FormDataModel {
const _$FormDataModelImpl(
{required this.name, required this.value, required this.type});
factory _$FormDataModelImpl.fromJson(Map<String, dynamic> json) =>
_$$FormDataModelImplFromJson(json);
@override
final String name;
@override
final String value;
@override
final FormDataType type;
@override
String toString() {
return 'FormDataModel(name: $name, value: $value, type: $type)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$FormDataModelImpl &&
(identical(other.name, name) || other.name == name) &&
(identical(other.value, value) || other.value == value) &&
(identical(other.type, type) || other.type == type));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(runtimeType, name, value, type);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$FormDataModelImplCopyWith<_$FormDataModelImpl> get copyWith =>
__$$FormDataModelImplCopyWithImpl<_$FormDataModelImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$FormDataModelImplToJson(
this,
);
}
}
abstract class _FormDataModel implements FormDataModel {
const factory _FormDataModel(
{required final String name,
required final String value,
required final FormDataType type}) = _$FormDataModelImpl;
factory _FormDataModel.fromJson(Map<String, dynamic> json) =
_$FormDataModelImpl.fromJson;
@override
String get name;
@override
String get value;
@override
FormDataType get type;
@override
@JsonKey(ignore: true)
_$$FormDataModelImplCopyWith<_$FormDataModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'form_data_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$FormDataModelImpl _$$FormDataModelImplFromJson(Map<String, dynamic> json) =>
_$FormDataModelImpl(
name: json['name'] as String,
value: json['value'] as String,
type: $enumDecode(_$FormDataTypeEnumMap, json['type']),
);
Map<String, dynamic> _$$FormDataModelImplToJson(_$FormDataModelImpl instance) =>
<String, dynamic>{
'name': instance.name,
'value': instance.value,
'type': _$FormDataTypeEnumMap[instance.type]!,
};
const _$FormDataTypeEnumMap = {
FormDataType.text: 'text',
FormDataType.file: 'file',
};

View File

@ -0,0 +1,88 @@
import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:collection/collection.dart' show mergeMaps;
import 'package:http/http.dart';
import 'package:http_parser/http_parser.dart';
import '../utils/utils.dart';
import '../consts.dart';
part 'http_response_model.freezed.dart';
part 'http_response_model.g.dart';
class Uint8ListConverter implements JsonConverter<Uint8List?, List<int>?> {
const Uint8ListConverter();
@override
Uint8List? fromJson(List<int>? json) {
return json == null ? null : Uint8List.fromList(json);
}
@override
List<int>? toJson(Uint8List? object) {
return object?.toList();
}
}
class DurationConverter implements JsonConverter<Duration?, int?> {
const DurationConverter();
@override
Duration? fromJson(int? json) {
return json == null ? null : Duration(microseconds: json);
}
@override
int? toJson(Duration? object) {
return object?.inMicroseconds;
}
}
@freezed
class HttpResponseModel with _$HttpResponseModel {
const HttpResponseModel._();
@JsonSerializable(
explicitToJson: true,
anyMap: true,
)
const factory HttpResponseModel({
int? statusCode,
Map<String, String>? headers,
Map<String, String>? requestHeaders,
String? body,
String? formattedBody,
@Uint8ListConverter() Uint8List? bodyBytes,
@DurationConverter() Duration? time,
}) = _HttpResponseModel;
factory HttpResponseModel.fromJson(Map<String, Object?> json) =>
_$HttpResponseModelFromJson(json);
String? get contentType => getContentTypeFromHeaders(headers);
MediaType? get mediaType => getMediaTypeFromHeaders(headers);
HttpResponseModel fromResponse({
required Response response,
Duration? time,
}) {
final responseHeaders = mergeMaps(
{HttpHeaders.contentLengthHeader: response.contentLength.toString()},
response.headers);
MediaType? mediaType = getMediaTypeFromHeaders(responseHeaders);
final body = (mediaType?.subtype == kSubTypeJson)
? utf8.decode(response.bodyBytes)
: response.body;
return HttpResponseModel(
statusCode: response.statusCode,
headers: responseHeaders,
requestHeaders: response.request?.headers,
body: body,
formattedBody: formatBody(body, mediaType),
bodyBytes: response.bodyBytes,
time: time,
);
}
}

View File

@ -0,0 +1,314 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'http_response_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
HttpResponseModel _$HttpResponseModelFromJson(Map<String, dynamic> json) {
return _HttpResponseModel.fromJson(json);
}
/// @nodoc
mixin _$HttpResponseModel {
int? get statusCode => throw _privateConstructorUsedError;
Map<String, String>? get headers => throw _privateConstructorUsedError;
Map<String, String>? get requestHeaders => throw _privateConstructorUsedError;
String? get body => throw _privateConstructorUsedError;
String? get formattedBody => throw _privateConstructorUsedError;
@Uint8ListConverter()
Uint8List? get bodyBytes => throw _privateConstructorUsedError;
@DurationConverter()
Duration? get time => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$HttpResponseModelCopyWith<HttpResponseModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $HttpResponseModelCopyWith<$Res> {
factory $HttpResponseModelCopyWith(
HttpResponseModel value, $Res Function(HttpResponseModel) then) =
_$HttpResponseModelCopyWithImpl<$Res, HttpResponseModel>;
@useResult
$Res call(
{int? statusCode,
Map<String, String>? headers,
Map<String, String>? requestHeaders,
String? body,
String? formattedBody,
@Uint8ListConverter() Uint8List? bodyBytes,
@DurationConverter() Duration? time});
}
/// @nodoc
class _$HttpResponseModelCopyWithImpl<$Res, $Val extends HttpResponseModel>
implements $HttpResponseModelCopyWith<$Res> {
_$HttpResponseModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? statusCode = freezed,
Object? headers = freezed,
Object? requestHeaders = freezed,
Object? body = freezed,
Object? formattedBody = freezed,
Object? bodyBytes = freezed,
Object? time = freezed,
}) {
return _then(_value.copyWith(
statusCode: freezed == statusCode
? _value.statusCode
: statusCode // ignore: cast_nullable_to_non_nullable
as int?,
headers: freezed == headers
? _value.headers
: headers // ignore: cast_nullable_to_non_nullable
as Map<String, String>?,
requestHeaders: freezed == requestHeaders
? _value.requestHeaders
: requestHeaders // ignore: cast_nullable_to_non_nullable
as Map<String, String>?,
body: freezed == body
? _value.body
: body // ignore: cast_nullable_to_non_nullable
as String?,
formattedBody: freezed == formattedBody
? _value.formattedBody
: formattedBody // ignore: cast_nullable_to_non_nullable
as String?,
bodyBytes: freezed == bodyBytes
? _value.bodyBytes
: bodyBytes // ignore: cast_nullable_to_non_nullable
as Uint8List?,
time: freezed == time
? _value.time
: time // ignore: cast_nullable_to_non_nullable
as Duration?,
) as $Val);
}
}
/// @nodoc
abstract class _$$HttpResponseModelImplCopyWith<$Res>
implements $HttpResponseModelCopyWith<$Res> {
factory _$$HttpResponseModelImplCopyWith(_$HttpResponseModelImpl value,
$Res Function(_$HttpResponseModelImpl) then) =
__$$HttpResponseModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{int? statusCode,
Map<String, String>? headers,
Map<String, String>? requestHeaders,
String? body,
String? formattedBody,
@Uint8ListConverter() Uint8List? bodyBytes,
@DurationConverter() Duration? time});
}
/// @nodoc
class __$$HttpResponseModelImplCopyWithImpl<$Res>
extends _$HttpResponseModelCopyWithImpl<$Res, _$HttpResponseModelImpl>
implements _$$HttpResponseModelImplCopyWith<$Res> {
__$$HttpResponseModelImplCopyWithImpl(_$HttpResponseModelImpl _value,
$Res Function(_$HttpResponseModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? statusCode = freezed,
Object? headers = freezed,
Object? requestHeaders = freezed,
Object? body = freezed,
Object? formattedBody = freezed,
Object? bodyBytes = freezed,
Object? time = freezed,
}) {
return _then(_$HttpResponseModelImpl(
statusCode: freezed == statusCode
? _value.statusCode
: statusCode // ignore: cast_nullable_to_non_nullable
as int?,
headers: freezed == headers
? _value._headers
: headers // ignore: cast_nullable_to_non_nullable
as Map<String, String>?,
requestHeaders: freezed == requestHeaders
? _value._requestHeaders
: requestHeaders // ignore: cast_nullable_to_non_nullable
as Map<String, String>?,
body: freezed == body
? _value.body
: body // ignore: cast_nullable_to_non_nullable
as String?,
formattedBody: freezed == formattedBody
? _value.formattedBody
: formattedBody // ignore: cast_nullable_to_non_nullable
as String?,
bodyBytes: freezed == bodyBytes
? _value.bodyBytes
: bodyBytes // ignore: cast_nullable_to_non_nullable
as Uint8List?,
time: freezed == time
? _value.time
: time // ignore: cast_nullable_to_non_nullable
as Duration?,
));
}
}
/// @nodoc
@JsonSerializable(explicitToJson: true, anyMap: true)
class _$HttpResponseModelImpl extends _HttpResponseModel {
const _$HttpResponseModelImpl(
{this.statusCode,
final Map<String, String>? headers,
final Map<String, String>? requestHeaders,
this.body,
this.formattedBody,
@Uint8ListConverter() this.bodyBytes,
@DurationConverter() this.time})
: _headers = headers,
_requestHeaders = requestHeaders,
super._();
factory _$HttpResponseModelImpl.fromJson(Map<String, dynamic> json) =>
_$$HttpResponseModelImplFromJson(json);
@override
final int? statusCode;
final Map<String, String>? _headers;
@override
Map<String, String>? get headers {
final value = _headers;
if (value == null) return null;
if (_headers is EqualUnmodifiableMapView) return _headers;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
final Map<String, String>? _requestHeaders;
@override
Map<String, String>? get requestHeaders {
final value = _requestHeaders;
if (value == null) return null;
if (_requestHeaders is EqualUnmodifiableMapView) return _requestHeaders;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(value);
}
@override
final String? body;
@override
final String? formattedBody;
@override
@Uint8ListConverter()
final Uint8List? bodyBytes;
@override
@DurationConverter()
final Duration? time;
@override
String toString() {
return 'HttpResponseModel(statusCode: $statusCode, headers: $headers, requestHeaders: $requestHeaders, body: $body, formattedBody: $formattedBody, bodyBytes: $bodyBytes, time: $time)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$HttpResponseModelImpl &&
(identical(other.statusCode, statusCode) ||
other.statusCode == statusCode) &&
const DeepCollectionEquality().equals(other._headers, _headers) &&
const DeepCollectionEquality()
.equals(other._requestHeaders, _requestHeaders) &&
(identical(other.body, body) || other.body == body) &&
(identical(other.formattedBody, formattedBody) ||
other.formattedBody == formattedBody) &&
const DeepCollectionEquality().equals(other.bodyBytes, bodyBytes) &&
(identical(other.time, time) || other.time == time));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType,
statusCode,
const DeepCollectionEquality().hash(_headers),
const DeepCollectionEquality().hash(_requestHeaders),
body,
formattedBody,
const DeepCollectionEquality().hash(bodyBytes),
time);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$HttpResponseModelImplCopyWith<_$HttpResponseModelImpl> get copyWith =>
__$$HttpResponseModelImplCopyWithImpl<_$HttpResponseModelImpl>(
this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$HttpResponseModelImplToJson(
this,
);
}
}
abstract class _HttpResponseModel extends HttpResponseModel {
const factory _HttpResponseModel(
{final int? statusCode,
final Map<String, String>? headers,
final Map<String, String>? requestHeaders,
final String? body,
final String? formattedBody,
@Uint8ListConverter() final Uint8List? bodyBytes,
@DurationConverter() final Duration? time}) = _$HttpResponseModelImpl;
const _HttpResponseModel._() : super._();
factory _HttpResponseModel.fromJson(Map<String, dynamic> json) =
_$HttpResponseModelImpl.fromJson;
@override
int? get statusCode;
@override
Map<String, String>? get headers;
@override
Map<String, String>? get requestHeaders;
@override
String? get body;
@override
String? get formattedBody;
@override
@Uint8ListConverter()
Uint8List? get bodyBytes;
@override
@DurationConverter()
Duration? get time;
@override
@JsonKey(ignore: true)
_$$HttpResponseModelImplCopyWith<_$HttpResponseModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'http_response_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$HttpResponseModelImpl _$$HttpResponseModelImplFromJson(Map json) =>
_$HttpResponseModelImpl(
statusCode: (json['statusCode'] as num?)?.toInt(),
headers: (json['headers'] as Map?)?.map(
(k, e) => MapEntry(k as String, e as String),
),
requestHeaders: (json['requestHeaders'] as Map?)?.map(
(k, e) => MapEntry(k as String, e as String),
),
body: json['body'] as String?,
formattedBody: json['formattedBody'] as String?,
bodyBytes:
const Uint8ListConverter().fromJson(json['bodyBytes'] as List<int>?),
time: const DurationConverter().fromJson((json['time'] as num?)?.toInt()),
);
Map<String, dynamic> _$$HttpResponseModelImplToJson(
_$HttpResponseModelImpl instance) =>
<String, dynamic>{
'statusCode': instance.statusCode,
'headers': instance.headers,
'requestHeaders': instance.requestHeaders,
'body': instance.body,
'formattedBody': instance.formattedBody,
'bodyBytes': const Uint8ListConverter().toJson(instance.bodyBytes),
'time': const DurationConverter().toJson(instance.time),
};

View File

@ -1,2 +1,4 @@
export 'form_data_model.dart';
export 'http_request_model.dart';
export 'http_response_model.dart';
export 'name_value_model.dart';

View File

@ -0,0 +1,97 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import '../consts.dart';
import '../models/models.dart';
import '../utils/utils.dart';
typedef HttpResponse = http.Response;
Future<(HttpResponse?, Duration?, String?)> request(
HttpRequestModel requestModel, {
String defaultUriScheme = kDefaultUriScheme,
}) async {
(Uri?, String?) uriRec = getValidRequestUri(
requestModel.url,
requestModel.enabledParams,
defaultUriScheme: defaultUriScheme,
);
if (uriRec.$1 != null) {
Uri requestUrl = uriRec.$1!;
Map<String, String> headers = requestModel.enabledHeadersMap;
HttpResponse response;
String? body;
try {
Stopwatch stopwatch = Stopwatch()..start();
var isMultiPartRequest =
requestModel.bodyContentType == ContentType.formdata;
if (kMethodsWithBody.contains(requestModel.method)) {
var requestBody = requestModel.body;
if (requestBody != null && !isMultiPartRequest) {
var contentLength = utf8.encode(requestBody).length;
if (contentLength > 0) {
body = requestBody;
headers[HttpHeaders.contentLengthHeader] = contentLength.toString();
if (!requestModel.hasContentTypeHeader) {
headers[HttpHeaders.contentTypeHeader] =
requestModel.bodyContentType.header;
}
}
}
if (isMultiPartRequest) {
var multiPartRequest = http.MultipartRequest(
requestModel.method.name.toUpperCase(),
requestUrl,
);
multiPartRequest.headers.addAll(headers);
for (var formData in requestModel.formDataList) {
if (formData.type == FormDataType.text) {
multiPartRequest.fields.addAll({formData.name: formData.value});
} else {
multiPartRequest.files.add(
await http.MultipartFile.fromPath(
formData.name,
formData.value,
),
);
}
}
http.StreamedResponse multiPartResponse =
await multiPartRequest.send();
stopwatch.stop();
http.Response convertedMultiPartResponse =
await convertStreamedResponse(multiPartResponse);
return (convertedMultiPartResponse, stopwatch.elapsed, null);
}
}
switch (requestModel.method) {
case HTTPVerb.get:
response = await http.get(requestUrl, headers: headers);
break;
case HTTPVerb.head:
response = await http.head(requestUrl, headers: headers);
break;
case HTTPVerb.post:
response = await http.post(requestUrl, headers: headers, body: body);
break;
case HTTPVerb.put:
response = await http.put(requestUrl, headers: headers, body: body);
break;
case HTTPVerb.patch:
response = await http.patch(requestUrl, headers: headers, body: body);
break;
case HTTPVerb.delete:
response =
await http.delete(requestUrl, headers: headers, body: body);
break;
}
stopwatch.stop();
return (response, stopwatch.elapsed, null);
} catch (e) {
return (null, null, e.toString());
}
} else {
return (null, null, uriRec.$2);
}
}

View File

@ -0,0 +1 @@
export 'http_service.dart';

View File

@ -0,0 +1,83 @@
import 'package:collection/collection.dart';
import '../consts.dart';
import '../models/models.dart';
Map<String, String>? rowsToMap(List<NameValueModel>? kvRows,
{bool isHeader = false}) {
if (kvRows == null) {
return null;
}
Map<String, String> finalMap = {};
for (var row in kvRows) {
if (row.name.trim() != "") {
String key = row.name;
if (isHeader) {
key = key.toLowerCase();
}
finalMap[key] = row.value.toString();
}
}
return finalMap;
}
List<NameValueModel>? mapToRows(Map<String, String>? kvMap) {
if (kvMap == null) {
return null;
}
List<NameValueModel> finalRows = [];
for (var k in kvMap.keys) {
finalRows.add(NameValueModel(name: k, value: kvMap[k]));
}
return finalRows;
}
List<Map<String, String>>? rowsToFormDataMapList(
List<FormDataModel>? kvRows,
) {
if (kvRows == null) {
return null;
}
List<Map<String, String>> finalMap = kvRows
.map((FormDataModel formData) =>
(formData.name.trim().isEmpty && formData.value.trim().isEmpty)
? null
: {
"name": formData.name,
"value": formData.value,
"type": formData.type.name,
})
.whereNotNull()
.toList();
return finalMap;
}
List<FormDataModel>? mapListToFormDataModelRows(List<Map>? kvMap) {
if (kvMap == null) {
return null;
}
List<FormDataModel> finalRows = kvMap.map(
(formData) {
return FormDataModel(
name: formData["name"],
value: formData["value"],
type: getFormDataType(formData["type"]),
);
},
).toList();
return finalRows;
}
FormDataType getFormDataType(String? type) {
return FormDataType.values.firstWhere((element) => element.name == type,
orElse: () => FormDataType.text);
}
List<NameValueModel>? getEnabledRows(
List<NameValueModel>? rows, List<bool>? isRowEnabledList) {
if (rows == null || isRowEnabledList == null) {
return rows;
}
List<NameValueModel> finalRows =
rows.where((element) => isRowEnabledList[rows.indexOf(element)]).toList();
return finalRows == [] ? null : finalRows;
}

View File

@ -0,0 +1,75 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:xml/xml.dart';
import '../consts.dart';
String? getContentTypeFromHeaders(Map? headers) {
return headers?[HttpHeaders.contentTypeHeader];
}
MediaType? getMediaTypeFromHeaders(Map? headers) {
var contentType = getContentTypeFromHeaders(headers);
MediaType? mediaType = getMediaTypeFromContentType(contentType);
return mediaType;
}
MediaType? getMediaTypeFromContentType(String? contentType) {
if (contentType != null) {
try {
MediaType mediaType = MediaType.parse(contentType);
return mediaType;
} catch (e) {
return null;
}
}
return null;
}
String? formatBody(String? body, MediaType? mediaType) {
if (mediaType != null && body != null) {
var subtype = mediaType.subtype;
try {
if (subtype.contains(kSubTypeJson)) {
final tmp = jsonDecode(body);
String result = kJsonEncoder.convert(tmp);
return result;
}
if (subtype.contains(kSubTypeXml)) {
final document = XmlDocument.parse(body);
String result = document.toXmlString(pretty: true, indent: ' ');
return result;
}
if (subtype == kSubTypeHtml) {
var len = body.length;
var lines = kSplitter.convert(body);
var numOfLines = lines.length;
if (numOfLines != 0 && len / numOfLines <= kCodeCharsPerLineLimit) {
return body;
}
}
} catch (e) {
return null;
}
}
return null;
}
Future<http.Response> convertStreamedResponse(
http.StreamedResponse streamedResponse,
) async {
Uint8List bodyBytes = await streamedResponse.stream.toBytes();
http.Response response = http.Response.bytes(
bodyBytes,
streamedResponse.statusCode,
headers: streamedResponse.headers,
persistentConnection: streamedResponse.persistentConnection,
reasonPhrase: streamedResponse.reasonPhrase,
request: streamedResponse.request,
);
return response;
}

View File

@ -0,0 +1,60 @@
import 'package:collection/collection.dart' show mergeMaps;
import '../consts.dart';
import '../models/name_value_model.dart';
import 'http_request_utils.dart';
(String?, bool) getUriScheme(Uri uri) {
if (uri.hasScheme) {
if (kSupportedUriSchemes.contains(uri.scheme)) {
return (uri.scheme, true);
}
return (uri.scheme, false);
}
return (null, false);
}
String stripUriParams(Uri uri) {
return "${uri.scheme}://${uri.authority}${uri.path}";
}
String stripUrlParams(String url) {
var idx = url.indexOf("?");
return idx > 0 ? url.substring(0, idx) : url;
}
(Uri?, String?) getValidRequestUri(
String? url, List<NameValueModel>? requestParams,
{String defaultUriScheme = kDefaultUriScheme}) {
url = url?.trim();
if (url == null || url == "") {
return (null, "URL is missing!");
}
Uri? uri = Uri.tryParse(url);
if (uri == null) {
return (null, "Check URL (malformed)");
}
(String?, bool) urlScheme = getUriScheme(uri);
if (urlScheme.$1 != null) {
if (!urlScheme.$2) {
return (null, "Unsupported URL Scheme (${urlScheme.$1})");
}
} else {
url = "$defaultUriScheme://$url";
}
uri = Uri.parse(url);
if (uri.hasFragment) {
uri = uri.removeFragment();
}
Map<String, String>? queryParams = rowsToMap(requestParams);
if (queryParams != null && queryParams.isNotEmpty) {
if (uri.hasQuery) {
Map<String, String> urlQueryParams = uri.queryParameters;
queryParams = mergeMaps(urlQueryParams, queryParams);
}
uri = uri.replace(queryParameters: queryParams);
}
return (uri, null);
}

View File

@ -0,0 +1,3 @@
export 'http_request_utils.dart';
export 'http_response_utils.dart';
export 'uri_utils.dart';

View File

@ -2,6 +2,7 @@ name: apidash_core
description: "API Dash Core"
version: 0.0.1
homepage:
publish_to: none
environment:
sdk: ^3.5.3
@ -10,7 +11,11 @@ environment:
dependencies:
flutter:
sdk: flutter
collection: ^1.18.0
freezed_annotation: ^2.4.1
http: ^1.2.1
http_parser: ^4.0.2
xml: ^6.3.0
dev_dependencies:
flutter_test: