diff --git a/lib/eval/bridge/http.dart b/lib/eval/bridge/http.dart new file mode 100644 index 0000000..12d8b14 --- /dev/null +++ b/lib/eval/bridge/http.dart @@ -0,0 +1,681 @@ +import 'dart:convert'; +import 'package:dart_eval/dart_eval.dart'; +import 'package:dart_eval/dart_eval_bridge.dart'; +import 'package:dart_eval/stdlib/core.dart'; +import 'package:http/http.dart'; + +/// dart_eval wrapper for [Client] +class $Client implements $Instance { + $Client.wrap(this.$value); + + @override + final Client $value; + + late final $Instance _superclass = $Object($value); + + /// Compile-time bridged type reference for [$Client] + static const $type = BridgeTypeRef( + BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Client')); + + /// Compile-time bridged class declaration for [$Client] + static const $declaration = BridgeClassDef(BridgeClassType($type), + constructors: { + '': BridgeConstructorDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation($type), params: [], namedParams: [])) + }, + methods: { + 'get': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.future, [$Response.$type])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + ])), + 'post': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.future, [$Response.$type])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + BridgeParameter( + 'body', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), + nullable: true), + true), + BridgeParameter( + 'encoding', + BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), + nullable: true), + true), + ])), + 'put': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.future, [$Response.$type])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + BridgeParameter( + 'body', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), + nullable: true), + true), + BridgeParameter( + 'encoding', + BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), + nullable: true), + true), + ])), + 'delete': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.future, [$Response.$type])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + BridgeParameter( + 'body', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), + nullable: true), + true), + BridgeParameter( + 'encoding', + BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), + nullable: true), + true), + ])), + 'patch': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.future, [$Response.$type])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + BridgeParameter( + 'body', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.object), + nullable: true), + true), + BridgeParameter( + 'encoding', + BridgeTypeAnnotation(BridgeTypeRef(ConvertTypes.encoding), + nullable: true), + true), + ])), + 'read': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef( + CoreTypes.future, [BridgeTypeRef(CoreTypes.string)])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + ])), + 'readBytes': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.future, [ + BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)]) + ])), + params: [ + BridgeParameter('url', + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.uri)), false), + ], + namedParams: [ + BridgeParameter( + 'headers', + BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + nullable: true), + true), + ])), + 'send': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef( + CoreTypes.future, [BridgeTypeRef(CoreTypes.list)])), + params: [ + BridgeParameter( + 'request', BridgeTypeAnnotation($BaseRequest.$type), false), + ])), + 'close': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.voidType)), + )), + }, + wrap: true); + + static $Client $new(Runtime runtime, $Value? target, List<$Value?> args) { + return $Client.wrap(Client()); + } + + @override + $Value? $getProperty(Runtime runtime, String identifier) { + switch (identifier) { + case 'get': + return __get; + case 'post': + return __post; + case 'put': + return __put; + case 'delete': + return __delete; + case 'patch': + return __patch; + case 'read': + return __read; + case 'readBytes': + return __readBytes; + case 'close': + return __close; + default: + return _superclass.$getProperty(runtime, identifier); + } + } + + static const $Function __get = $Function(_get); + + static $Value? _get(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + + final request = (target!.$value as Client).get(url, headers: headers); + return $Future.wrap(request.then((value) => $Response.wrap(value))); + } + + static const $Function __post = $Function(_post); + + static $Value? _post(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + final body = args[2]?.$value as Object?; + final encoding = args[3]?.$value as Encoding?; + + final request = (target!.$value as Client) + .post(url, headers: headers, body: body, encoding: encoding); + return $Future.wrap(request.then((value) => $Response.wrap(value))); + } + + static const $Function __put = $Function(_put); + + static $Value? _put(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + final body = args[2]?.$value as Object?; + final encoding = args[3]?.$value as Encoding?; + + final request = (target!.$value as Client) + .put(url, headers: headers, body: body, encoding: encoding); + return $Future.wrap(request.then((value) => $Response.wrap(value))); + } + + static const $Function __delete = $Function(_delete); + + static $Value? _delete(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + final body = args[2]?.$value as Object?; + final encoding = args[3]?.$value as Encoding?; + + final request = (target!.$value as Client) + .delete(url, headers: headers, body: body, encoding: encoding); + return $Future.wrap(request.then((value) => $Response.wrap(value))); + } + + static const $Function __patch = $Function(_patch); + + static $Value? _patch(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + final body = args[2]?.$value as Object?; + final encoding = args[3]?.$value as Encoding?; + + final request = (target!.$value as Client) + .patch(url, headers: headers, body: body, encoding: encoding); + return $Future.wrap(request.then((value) => $Response.wrap(value))); + } + + static const $Function __read = $Function(_read); + + static $Value? _read(Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + + final request = (target!.$value as Client).read(url, headers: headers); + return $Future.wrap(request.then((value) => $String(value))); + } + + static const $Function __readBytes = $Function(_readBytes); + + static $Value? _readBytes( + Runtime runtime, $Value? target, List<$Value?> args) { + final url = args[0]!.$value as Uri; + final headers = (args[1]?.$value as Map<$Value, $Value>?)?.map( + (key, value) => + MapEntry((key.$reified).toString(), (value.$reified).toString())); + + final request = (target!.$value as Client).readBytes(url, headers: headers); + return $Future.wrap(request.then((value) => $List.wrap(value))); + } + + static const $Function __close = $Function(_close); + + static $Value? _close(Runtime runtime, $Value? target, List<$Value?> args) { + (target!.$value as Client).close(); + return null; + } + + @override + get $reified => $value; + + @override + int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!); + + @override + void $setProperty(Runtime runtime, String identifier, $Value value) {} +} + +/// dart_eval wrapper for [ClientRequest] +class $BaseRequest implements $Instance { + $BaseRequest.wrap(this.$value) : _superclass = $Object($value); + + @override + final BaseRequest $value; + + /// Compile-time bridged type reference for [$BaseRequest] + static const $type = BridgeTypeRef( + BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'BaseRequest')); + + /// Compile-time bridged class declaration for [$BaseRequest] + static const $declaration = + BridgeClassDef(BridgeClassType($type, isAbstract: true), + constructors: {}, + getters: { + 'contentLength': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), + nullable: true), + )), + 'finalized': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'followRedirects': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'headers': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + ), + )), + 'maxRedirects': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), + )), + 'method': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.string), + ), + )), + 'persistentConnection': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.string), + ), + )), + 'url': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.uri), + ), + )), + }, + wrap: true); + + final $Instance _superclass; + + @override + $Value? $getProperty(Runtime runtime, String identifier) { + switch (identifier) { + case 'contentLength': + final res = $value.contentLength; + return res == null ? const $null() : $int(res); + case 'finalized': + return $bool($value.persistentConnection); + case 'followRedirects': + return $bool($value.persistentConnection); + case 'headers': + return $Map.wrap($value.headers); + case 'maxRedirects': + return $int($value.maxRedirects); + case 'method': + return $String($value.method); + case 'persistentConnection': + return $bool($value.persistentConnection); + case 'url': + return $Uri.wrap($value.url); + default: + return _superclass.$getProperty(runtime, identifier); + } + } + + @override + get $reified => $value; + + @override + int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!); + + @override + void $setProperty(Runtime runtime, String identifier, $Value value) { + _superclass.$setProperty(runtime, identifier, value); + } +} + +/// dart_eval wrapper for [Response] +class $Response implements $Instance { + $Response.wrap(this.$value) : _superclass = $Object($value); + + @override + final Response $value; + + /// Compile-time bridged type reference for [$Response] + static const $type = BridgeTypeRef( + BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'Response')); + + /// Compile-time bridged class declaration for [$Response] + static const $declaration = BridgeClassDef( + BridgeClassType($type), + constructors: { + '': BridgeConstructorDef( + BridgeFunctionDef(returns: BridgeTypeAnnotation($type))) + }, + getters: { + 'body': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string)), + )), + 'bodyBytes': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.list, [BridgeTypeRef(CoreTypes.int)])), + )), + 'contentLength': BridgeMethodDef(BridgeFunctionDef( + returns: + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true), + )), + 'headers': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + ), + )), + 'isRedirect': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'persistentConnection': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'reasonPhrase': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), + nullable: true), + )), + 'statusCode': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), + )), + 'request': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation($BaseRequest.$type, nullable: true), + )), + }, + wrap: true, + ); + + final $Instance _superclass; + + @override + $Value? $getProperty(Runtime runtime, String identifier) { + switch (identifier) { + case 'body': + return $String($value.body); + case 'bodyBytes': + return $List.wrap(($value.bodyBytes).map((e) => $int(e)).toList()); + case 'contentLength': + final res = $value.contentLength; + return res == null ? const $null() : $int(res); + case 'headers': + return $Map.wrap($value.headers); + case 'isRedirect': + return $bool($value.isRedirect); + case 'persistentConnection': + return $bool($value.persistentConnection); + case 'reasonPhrase': + final res = $value.reasonPhrase; + return res == null ? const $null() : $String(res); + case 'statusCode': + return $int($value.statusCode); + case 'request': + final res = $value.request; + return res == null ? const $null() : $BaseRequest.wrap(res); + default: + return _superclass.$getProperty(runtime, identifier); + } + } + + @override + get $reified => $value; + + @override + int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!); + + @override + void $setProperty(Runtime runtime, String identifier, $Value value) { + _superclass.$setProperty(runtime, identifier, value); + } +} + +/// dart_eval wrapper for [StreamedResponse] +class $StreamedResponse implements $Instance { + $StreamedResponse.wrap(this.$value) : _superclass = $Object($value); + + @override + final StreamedResponse $value; + + /// Compile-time bridged type reference for [$StreamedResponse] + static const $type = BridgeTypeRef( + BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'StreamedResponse')); + + /// Compile-time bridged class declaration for [$StreamedResponse] + static const $declaration = BridgeClassDef( + BridgeClassType($type), + constructors: { + '': BridgeConstructorDef( + BridgeFunctionDef(returns: BridgeTypeAnnotation($type))) + }, + getters: { + 'stream': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation($ByteStream.$type), + )), + 'contentLength': BridgeMethodDef(BridgeFunctionDef( + returns: + BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int), nullable: true), + )), + 'headers': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation( + BridgeTypeRef(CoreTypes.map, [ + BridgeTypeRef(CoreTypes.string), + BridgeTypeRef(CoreTypes.string) + ]), + ), + )), + 'isRedirect': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'persistentConnection': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.bool)), + )), + 'reasonPhrase': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.string), + nullable: true), + )), + 'statusCode': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.int)), + )), + 'request': BridgeMethodDef(BridgeFunctionDef( + returns: BridgeTypeAnnotation($BaseRequest.$type, nullable: true), + )), + }, + wrap: true, + ); + + final $Instance _superclass; + + @override + $Value? $getProperty(Runtime runtime, String identifier) { + switch (identifier) { + case 'stream': + return $ByteStream.wrap($value.stream); + case 'contentLength': + final res = $value.contentLength; + return res == null ? const $null() : $int(res); + case 'headers': + return $Map.wrap($value.headers); + case 'isRedirect': + return $bool($value.isRedirect); + case 'persistentConnection': + return $bool($value.persistentConnection); + case 'reasonPhrase': + final res = $value.reasonPhrase; + return res == null ? const $null() : $String(res); + case 'statusCode': + return $int($value.statusCode); + case 'request': + final res = $value.request; + return res == null ? const $null() : $BaseRequest.wrap(res); + default: + return _superclass.$getProperty(runtime, identifier); + } + } + + @override + get $reified => $value; + + @override + int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!); + + @override + void $setProperty(Runtime runtime, String identifier, $Value value) { + _superclass.$setProperty(runtime, identifier, value); + } +} + +/// dart_eval wrapper for [ByteStream] +class $ByteStream implements $Instance { + $ByteStream.wrap(this.$value) : _superclass = $Object($value); + + @override + final ByteStream $value; + + /// Compile-time bridged type reference for [$ByteStream] + static const $type = BridgeTypeRef( + BridgeTypeSpec('package:mangayomi/bridge_lib.dart', 'ByteStream')); + + /// Compile-time bridged class declaration for [$ByteStream] + static const $declaration = BridgeClassDef( + BridgeClassType($type), + constructors: { + '': BridgeConstructorDef( + BridgeFunctionDef(returns: BridgeTypeAnnotation($type))) + }, + getters: {}, + wrap: true, + ); + + final $Instance _superclass; + + @override + $Value? $getProperty(Runtime runtime, String identifier) { + switch (identifier) { + default: + return _superclass.$getProperty(runtime, identifier); + } + } + + @override + get $reified => $value; + + @override + int $getRuntimeType(Runtime runtime) => runtime.lookupType($type.spec!); + + @override + void $setProperty(Runtime runtime, String identifier, $Value value) { + _superclass.$setProperty(runtime, identifier, value); + } +} diff --git a/lib/eval/plugin.dart b/lib/eval/plugin.dart index 8670799..d979b20 100644 --- a/lib/eval/plugin.dart +++ b/lib/eval/plugin.dart @@ -2,6 +2,7 @@ import 'package:dart_eval/dart_eval.dart'; import 'package:dart_eval/dart_eval_bridge.dart'; import 'package:mangayomi/eval/bridge/document.dart'; import 'package:mangayomi/eval/bridge/element.dart'; +import 'package:mangayomi/eval/bridge/http.dart'; import 'package:mangayomi/eval/bridge/m_chapter.dart'; import 'package:mangayomi/eval/bridge/filter.dart'; import 'package:mangayomi/eval/bridge/m_pages.dart'; @@ -51,6 +52,12 @@ class MEvalPlugin extends EvalPlugin { registry.defineBridgeClass($Element.$declaration); registry.defineBridgeClass($MDocument.$declaration); registry.defineBridgeClass($Document.$declaration); + //HTTP CLIENT + registry.defineBridgeClass($Client.$declaration); + registry.defineBridgeClass($Response.$declaration); + registry.defineBridgeClass($BaseRequest.$declaration); + registry.defineBridgeClass($StreamedResponse.$declaration); + registry.defineBridgeClass($ByteStream.$declaration); } @override @@ -111,5 +118,8 @@ class MEvalPlugin extends EvalPlugin { 'package:mangayomi/bridge_lib.dart', 'MElement.', $MElement.$new); runtime.registerBridgeFunc( 'package:mangayomi/bridge_lib.dart', 'MDocument.', $MDocument.$new); + //HTTP CLIENT + runtime.registerBridgeFunc( + 'package:mangayomi/bridge_lib.dart', 'Client.', $Client.$new); } }