Updated framework

This commit is contained in:
thomashii 2021-05-16 01:58:51 +08:00
parent 515c813900
commit 3df9010af0
19 changed files with 67 additions and 58 deletions

View file

@ -1,3 +1,6 @@
# 4.0.2
* Updated README
# 4.0.1
* Updated README

View file

@ -1,5 +1,5 @@
# angel3_framework
[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_framework)
[![version](https://img.shields.io/badge/pub-v4.0.2-brightgreen)](https://pub.dartlang.org/packages/angel3_framework)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)

View file

@ -1,4 +1,5 @@
# include: package:pedantic/analysis_options.yaml
include: package:pedantic/analysis_options.yaml
analyzer:
errors:
always_declare_return_types: ignore

View file

@ -13,12 +13,15 @@ class AnonymousService<Id, Data> extends Service<Id, Data> {
FutureOr<Data> Function(Id, Data, [Map<String, dynamic>?])? _modify, _update;
AnonymousService(
{FutureOr<List<Data>> index([Map<String, dynamic>? params])?,
FutureOr<Data> read(Id id, [Map<String, dynamic>? params])?,
FutureOr<Data> create(Data data, [Map<String, dynamic>? params])?,
FutureOr<Data> modify(Id id, Data data, [Map<String, dynamic>? params])?,
FutureOr<Data> update(Id id, Data data, [Map<String, dynamic>? params])?,
FutureOr<Data> remove(Id id, [Map<String, dynamic>? params])?,
{FutureOr<List<Data>> Function([Map<String, dynamic>? params])? index,
FutureOr<Data> Function(Id id, [Map<String, dynamic>? params])? read,
FutureOr<Data> Function(Data data, [Map<String, dynamic>? params])?
create,
FutureOr<Data> Function(Id id, Data data, [Map<String, dynamic>? params])?
modify,
FutureOr<Data> Function(Id id, Data data, [Map<String, dynamic>? params])?
update,
FutureOr<Data> Function(Id id, [Map<String, dynamic>? params])? remove,
FutureOr<Data> Function(RequestContext, ResponseContext)? readData})
: super(readData: readData) {
_index = index;

View file

@ -50,7 +50,7 @@ class Controller {
Future<String> applyRoutes(
Router<RequestHandler> router, Reflector reflector) async {
// Load global expose decl
var classMirror = reflector.reflectClass(this.runtimeType)!;
var classMirror = reflector.reflectClass(runtimeType)!;
Expose? exposeDecl = findExpose(reflector);
if (exposeDecl == null) {
@ -60,7 +60,7 @@ class Controller {
var routable = Routable();
var m = router.mount(exposeDecl.path!, routable);
_mountPoint = m;
var typeMirror = reflector.reflectType(this.runtimeType);
var typeMirror = reflector.reflectType(runtimeType);
// Pre-reflect methods
var instanceMirror = reflector.reflectInstance(this);

View file

@ -45,7 +45,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
HookedService(this.inner) {
// Clone app instance
if (inner.app != null) this.app = inner.app;
if (inner.app != null) app = inner.app;
}
@override
@ -131,6 +131,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
applyListeners(inner.remove, afterRemoved, true);
}
@override
List<RequestHandler> get bootstrappers =>
List<RequestHandler>.from(super.bootstrappers)
..add((RequestContext req, ResponseContext res) {
@ -140,6 +141,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
return true;
});
@override
void addRoutes([Service? s]) {
super.addRoutes(s ?? inner);
}
@ -509,13 +511,13 @@ class HookedServiceEvent<Id, Data, T extends Service<Id, Data>> {
Service? getService(Pattern path) => service.app!.findService(path);
bool _canceled = false;
String _eventName;
final String _eventName;
Id? _id;
bool _isAfter;
final bool _isAfter;
Data? data;
Map<String, dynamic>? _params;
RequestContext? _request;
ResponseContext? _response;
final RequestContext? _request;
final ResponseContext? _response;
var result;
String get eventName => _eventName;

View file

@ -4,7 +4,7 @@ import 'package:string_scanner/string_scanner.dart';
/// Parses a string into a [RegExp] that is matched against hostnames.
class HostnameSyntaxParser {
final SpanScanner _scanner;
var _safe = RegExp(r"[0-9a-zA-Z-_:]+");
final _safe = RegExp(r"[0-9a-zA-Z-_:]+");
HostnameSyntaxParser(String hostname)
: _scanner = SpanScanner(hostname, sourceUrl: hostname);

View file

@ -71,8 +71,7 @@ class MapService extends Service<String?, Map<String, dynamic>> {
[Map<String, dynamic>? params]) {
return Future.value(items.firstWhere(_matchesId(id),
orElse: (() => throw AngelHttpException.notFound(
message: 'No record found for ID $id'))
as Map<String, dynamic> Function()?));
message: 'No record found for ID $id'))));
}
@override
@ -112,9 +111,8 @@ class MapService extends Service<String?, Map<String, dynamic>> {
var result = Map<String, dynamic>.from(item)..addAll(data);
if (autoIdAndDateFields == true) {
result
..[autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'] =
DateTime.now().toIso8601String();
result[autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'] =
DateTime.now().toIso8601String();
}
return Future.value(items[idx] = result);
});

View file

@ -145,7 +145,9 @@ abstract class RequestContext<RawRequest> {
List? get bodyAsList {
if (!hasParsedBody) {
throw StateError('The request body has not been parsed yet.');
} else if (_bodyList == null) {
// TODO: Relook at this
//} else if (_bodyList == null) {
} else if (_bodyList.isEmpty) {
throw StateError('The request body, $_bodyObject, is not a List.');
}
@ -258,9 +260,8 @@ abstract class RequestContext<RawRequest> {
_hasParsedBody = true;
var contentBody = body;
if (contentBody == null) {
contentBody = Stream.empty();
}
//TODO: Relook at this
contentBody ??= Stream.empty();
if (contentType.type == 'application' && contentType.subtype == 'json') {
_uploadedFiles = [];

View file

@ -160,6 +160,7 @@ abstract class ResponseContext<RawResponse>
}
/// Prevents more data from being written to the response, and locks it entire from further editing.
@override
Future<void> close() {
if (buffer is LockableBytesBuilder) {
(buffer as LockableBytesBuilder).lock();
@ -326,9 +327,7 @@ abstract class ResponseContext<RawResponse>
: MediaType.parse(mimeType);
if (correspondingRequest!.method != 'HEAD') {
return this
.addStream(file.openRead().cast<List<int>>())
.then((_) => this.close());
return addStream(file.openRead().cast<List<int>>()).then((_) => close());
}
}
@ -356,6 +355,7 @@ abstract class ResponseContext<RawResponse>
}
/// Writes data to the response.
@override
void write(value, {Encoding? encoding}) {
encoding ??= utf8;

View file

@ -66,7 +66,8 @@ class Routable extends Router<RequestHandler> {
/// A set of [Service] objects that have been mapped into routes.
Map<Pattern, Service> get services => _services;
StreamController<Service> _onService = StreamController<Service>.broadcast();
final StreamController<Service> _onService =
StreamController<Service>.broadcast();
/// Fired whenever a service is added to this instance.
///
@ -108,9 +109,7 @@ class Routable extends Router<RequestHandler> {
}
final handlerSequence = <RequestHandler>[];
if (middleware != null) {
handlerSequence.addAll(middleware);
}
handlerSequence.addAll(middleware);
handlerSequence.addAll(handlers);
return super.addRoute(method, path.toString(), handler,

View file

@ -71,6 +71,7 @@ class Service<Id, Data> extends Routable {
Angel? app;
/// Closes this service, including any database connections or stream controllers.
@override
void close() {}
/// An optional [readData] function can be passed to handle non-map/non-json bodies.
@ -230,7 +231,7 @@ class Service<Id, Data> extends Routable {
Middleware? indexMiddleware =
getAnnotation<Middleware>(service.index, app!.container!.reflector);
get('/', (req, res) {
return this.index(mergeMap([
return index(mergeMap([
{'query': req.queryParameters},
restProvider,
req.serviceParams
@ -246,15 +247,13 @@ class Service<Id, Data> extends Routable {
getAnnotation<Middleware>(service.create, app!.container!.reflector);
post('/', (req, ResponseContext res) {
return req.parseBody().then((_) async {
return await this
.create(
(await readData!(req, res))!,
mergeMap([
{'query': req.queryParameters},
restProvider,
req.serviceParams
]))
.then((r) {
return await create(
(await readData!(req, res))!,
mergeMap([
{'query': req.queryParameters},
restProvider,
req.serviceParams
])).then((r) {
res.statusCode = 201;
return r;
});
@ -270,7 +269,7 @@ class Service<Id, Data> extends Routable {
getAnnotation<Middleware>(service.read, app!.container!.reflector);
get('/:id', (req, res) {
return this.read(
return read(
parseId<Id>(req.params['id']),
mergeMap([
{'query': req.queryParameters},
@ -289,7 +288,7 @@ class Service<Id, Data> extends Routable {
patch('/:id', (req, res) {
return req.parseBody().then((_) async {
return await this.modify(
return await modify(
parseId<Id>(req.params['id']),
(await readData!(req, res))!,
mergeMap([
@ -309,7 +308,7 @@ class Service<Id, Data> extends Routable {
getAnnotation<Middleware>(service.update, app!.container!.reflector);
post('/:id', (req, res) {
return req.parseBody().then((_) async {
return await this.update(
return await update(
parseId<Id>(req.params['id']),
(await readData!(req, res))!,
mergeMap([
@ -327,7 +326,7 @@ class Service<Id, Data> extends Routable {
put('/:id', (req, res) {
return req.parseBody().then((_) async {
return await this.update(
return await update(
parseId<Id>(req.params['id']),
(await readData!(req, res))!,
mergeMap([
@ -346,7 +345,7 @@ class Service<Id, Data> extends Routable {
Middleware? removeMiddleware =
getAnnotation<Middleware>(service.remove, app!.container!.reflector);
delete('/', (req, res) {
return this.remove(
return remove(
'' as Id,
mergeMap([
{'query': req.queryParameters},
@ -361,7 +360,7 @@ class Service<Id, Data> extends Routable {
: removeMiddleware.handlers.toList()));
delete('/:id', (req, res) {
return this.remove(
return remove(
parseId<Id>(req.params['id']),
mergeMap([
{'query': req.queryParameters},

View file

@ -38,6 +38,7 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
}
/// The underlying [HttpRequest] instance underneath this context.
@override
HttpRequest? get rawRequest => _io;
@override

View file

@ -168,7 +168,7 @@ class _FakeServerSocket extends Stream<Socket> implements ServerSocket {
@override
Future<ServerSocket> close() async {
(_ctrl.close());
await (_ctrl.close());
return this;
}
@ -217,10 +217,13 @@ class _AngelHttp2ServerSocket extends Stream<SecureSocket>
);
}
@override
InternetAddress get address => socket.address;
@override
int get port => socket.port;
@override
Future<SecureServerSocket> close() {
_sub?.cancel();
_fake.close();

View file

@ -126,9 +126,7 @@ class Http2RequestContext extends RequestContext<ServerTransportStream?> {
// Apply session
var dartSessId = cookies.firstWhereOrNull((c) => c.name == 'DARTSESSID');
if (dartSessId == null) {
dartSessId = Cookie('DARTSESSID', uuid.v4());
}
dartSessId ??= Cookie('DARTSESSID', uuid.v4());
req._session = sessions.putIfAbsent(
dartSessId.value,

View file

@ -9,6 +9,7 @@ class Http2ResponseContext extends ResponseContext<ServerTransportStream> {
final Angel? app;
final ServerTransportStream stream;
@override
ServerTransportStream get rawResponse => stream;
LockableBytesBuilder? _buffer;

View file

@ -16,7 +16,7 @@ abstract class SafeCtrl<T> {
Future close();
void whenInitialized(void callback());
void whenInitialized(void Function() callback);
}
class _SingleSafeCtrl<T> implements SafeCtrl<T> {
@ -60,7 +60,7 @@ class _SingleSafeCtrl<T> implements SafeCtrl<T> {
}
@override
void whenInitialized(void callback()) {
void whenInitialized(void Function() callback) {
if (!_initialized) {
if (!_hasListener) {
_initializer = callback;
@ -110,7 +110,7 @@ class _BroadcastSafeCtrl<T> implements SafeCtrl<T> {
}
@override
void whenInitialized(void callback()) {
void whenInitialized(void Function() callback) {
if (!_initialized) {
if (_listeners <= 0) {
_initializer = callback;

View file

@ -20,7 +20,7 @@ T? getAnnotation<T>(obj, Reflector? reflector) {
var methodMirror = reflector.reflectFunction(obj)!;
return matchingAnnotation<T>(methodMirror.annotations);
} else {
var classMirror = reflector.reflectClass(obj.runtimeType as Type)!;
var classMirror = reflector.reflectClass(obj.runtimeType)!;
return matchingAnnotation<T>(classMirror.annotations);
}
}

View file

@ -1,5 +1,5 @@
name: angel3_framework
version: 4.0.1
version: 4.0.2
description: A high-powered HTTP server with dependency injection, routing and much more.
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/framework
environment:
@ -33,4 +33,4 @@ dev_dependencies:
http: ^0.13.1
io: ^1.0.0
test: ^1.17.4
pedantic: ^1.11.0