Updated framework

This commit is contained in:
thomashii 2021-11-28 12:15:56 +08:00
parent da207f2ddf
commit 8b2d9bf725
22 changed files with 99 additions and 73 deletions

View file

@ -6,8 +6,8 @@ publish_to: none
environment:
sdk: ">=2.10.0 <3.0.0"
dependencies:
angel_auth:
angel_framework:
angel_auth: ^2.0.0
angel_framework: ^2.0.0
http: ^0.13.0
path: ^1.0.0
twitter:

View file

@ -1,5 +1,9 @@
# Change Log
## 4.3.0
* Updated `container` to non nullable
## 4.2.2
* Added `Date` to response header

View file

@ -12,7 +12,13 @@ class Controller {
Angel? _app;
/// The [Angel] application powering this controller.
Angel? get app => _app;
Angel get app {
if (_app == null) {
throw ArgumentError("Angel is not instantiated.");
}
return _app!;
}
/// If `true` (default), this class will inject itself as a singleton into the [app]'s container when bootstrapped.
final bool injectSingleton;
@ -36,14 +42,14 @@ class Controller {
_app = app;
if (injectSingleton != false) {
if (!app.container!.has(runtimeType)) {
_app!.container!.registerSingleton(this, as: runtimeType);
if (!app.container.has(runtimeType)) {
_app!.container.registerSingleton(this, as: runtimeType);
}
}
var name = await applyRoutes(app, app.container!.reflector);
var name = await applyRoutes(app, app.container.reflector);
app.controllers[name] = this;
return null;
//return null;
}
/// Applies the routes from this [Controller] to some [router].

View file

@ -76,7 +76,9 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
/// Closes any open [StreamController]s on this instance. **Internal use only**.
@override
Future close() {
_ctrl.forEach((c) => c.close());
for (var c in _ctrl) {
c.close();
}
beforeIndexed._close();
beforeRead._close();
beforeCreated._close();
@ -95,7 +97,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
/// Adds hooks to this instance.
void addHooks(Angel app) {
var hooks = getAnnotation<Hooks>(inner, app.container!.reflector);
var hooks = getAnnotation<Hooks>(inner, app.container.reflector);
var before = <HookedServiceEventListener<Id, Data, T>>[];
var after = <HookedServiceEventListener<Id, Data, T>>[];
@ -107,7 +109,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
void applyListeners(
Function fn, HookedServiceEventDispatcher<Id, Data, T> dispatcher,
[bool? isAfter]) {
var hooks = getAnnotation<Hooks>(fn, app.container!.reflector);
var hooks = getAnnotation<Hooks>(fn, app.container.reflector);
final listeners = <HookedServiceEventListener<Id, Data, T>>[
...isAfter == true ? after : before
];
@ -144,8 +146,8 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
});
@override
void addRoutes([Service? s]) {
super.addRoutes(s ?? inner);
void addRoutes([Service? service]) {
super.addRoutes(service ?? inner);
}
/// Runs the [listener] before every service method specified.
@ -274,26 +276,26 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
}
@override
Future<List<Data>> index([Map<String, dynamic>? _params]) {
var params = _stripReq(_params);
Future<List<Data>> index([Map<String, dynamic>? params]) {
var localParams = _stripReq(params);
return beforeIndexed
._emit(HookedServiceEvent(false, _getRequest(_params),
_getResponse(_params), inner, HookedServiceEvent.indexed,
params: params))
._emit(HookedServiceEvent(false, _getRequest(params),
_getResponse(params), inner, HookedServiceEvent.indexed,
params: localParams))
.then((before) {
if (before._canceled) {
return afterIndexed
._emit(HookedServiceEvent(true, _getRequest(_params),
_getResponse(_params), inner, HookedServiceEvent.indexed,
params: params, result: before.result))
._emit(HookedServiceEvent(true, _getRequest(params),
_getResponse(params), inner, HookedServiceEvent.indexed,
params: localParams, result: before.result))
.then((after) => after.result as List<Data>);
}
return inner.index(params).then((result) {
return inner.index(localParams).then((result) {
return afterIndexed
._emit(HookedServiceEvent(true, _getRequest(_params),
_getResponse(_params), inner, HookedServiceEvent.indexed,
params: params, result: result))
._emit(HookedServiceEvent(true, _getRequest(params),
_getResponse(params), inner, HookedServiceEvent.indexed,
params: localParams, result: result))
.then((after) => after.result as List<Data>);
});
});
@ -557,7 +559,9 @@ class HookedServiceEventDispatcher<Id, Data, T extends Service<Id, Data>> {
final List<HookedServiceEventListener<Id, Data, T>> listeners = [];
void _close() {
_ctrl.forEach((c) => c.close());
for (var c in _ctrl) {
c.close();
}
listeners.clear();
}

View file

@ -12,7 +12,7 @@ RequestHandler ioc(Function handler, {Iterable<String> optional = const []}) {
RequestHandler? contained;
if (req.app?.container != null) {
var injection = preInject(handler, req.app!.container!.reflector);
var injection = preInject(handler, req.app!.container.reflector);
//if (injection != null) {
injection.optional.addAll(optional);
contained = handleContained(handler, injection);
@ -70,7 +70,7 @@ Future resolveInjection(requirement, InjectionRequest injection,
}
} else if (requirement is Type && requirement != dynamic) {
try {
var futureType = container!.reflector.reflectFutureOf(requirement);
var futureType = container.reflector.reflectFutureOf(requirement);
if (container.has(futureType.reflectedType)) {
return await container.make(futureType.reflectedType);
}
@ -78,7 +78,7 @@ Future resolveInjection(requirement, InjectionRequest injection,
// Ignore.
}
return await container!.make(requirement);
return await container.make(requirement);
} else if (throwOnUnresolved) {
throw ArgumentError(
'$requirement cannot be injected into a request handler.');

View file

@ -288,7 +288,7 @@ abstract class ResponseContext<RawResponse>
}
final head = controller
.findExpose(app!.container!.reflector)!
.findExpose(app!.container.reflector)!
.path
.toString()
.replaceAll(_straySlashes, '');

View file

@ -48,14 +48,15 @@ class Routable extends Router<RequestHandler> {
final Map<Pattern, Service?> _serviceLookups = {};
final Map configuration = {};
final Container? _container;
final Container _container;
Routable([Reflector? reflector])
: _container = reflector == null ? null : Container(reflector),
// : _container = reflector == null ? null : Container(reflector),
: _container = Container(reflector ?? ThrowingReflector()),
super();
/// A [Container] used to inject dependencies.
Container? get container => _container;
Container get container => _container;
void close() {
_services.clear();
@ -99,10 +100,10 @@ class Routable extends Router<RequestHandler> {
{Iterable<RequestHandler> middleware = const {}}) {
final handlers = <RequestHandler>[];
// Merge @Middleware declaration, if any
var reflector = _container?.reflector;
if (reflector != null && reflector is! ThrowingReflector) {
var reflector = _container.reflector;
if (reflector is! ThrowingReflector) {
var middlewareDeclaration =
getAnnotation<Middleware>(handler, _container?.reflector);
getAnnotation<Middleware>(handler, _container.reflector);
if (middlewareDeclaration != null) {
handlers.addAll(middlewareDeclaration.handlers);
}

View file

@ -4,6 +4,7 @@ import 'dart:async';
import 'dart:collection' show HashMap;
import 'dart:convert';
import 'package:angel3_container/angel3_container.dart';
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_http_exception/angel3_http_exception.dart';
import 'package:angel3_route/angel3_route.dart';
import 'package:belatuk_combinator/belatuk_combinator.dart';
@ -184,12 +185,12 @@ class Angel extends Routable {
/// Loads some base dependencies into the service container.
void bootstrapContainer() {
if (runtimeType != Angel) {
container?.registerSingleton(this);
container.registerSingleton(this);
}
container?.registerSingleton<Angel>(this);
container?.registerSingleton<Routable>(this);
container?.registerSingleton<Router>(this);
container.registerSingleton<Angel>(this);
container.registerSingleton<Routable>(this);
container.registerSingleton<Router>(this);
}
/// Shuts down the server, and closes any open [StreamController]s.
@ -315,6 +316,7 @@ class Angel extends Routable {
/// the execution will be faster, as the injection requirements were stored beforehand.
Future runContained(Function handler, RequestContext req, ResponseContext res,
[Container? container]) {
container ??= Container(MirrorsReflector());
return Future.sync(() {
if (_preContained.containsKey(handler)) {
return handleContained(handler, _preContained[handler]!, container)(
@ -328,10 +330,11 @@ class Angel extends Routable {
/// Runs with DI, and *always* reflects. Prefer [runContained].
Future runReflected(Function handler, RequestContext req, ResponseContext res,
[Container? container]) {
container ??= req.container ?? res.app!.container;
container ??=
req.container ?? res.app?.container ?? Container(ThrowingReflector());
var h = handleContained(
handler,
_preContained[handler] = preInject(handler, container!.reflector),
_preContained[handler] = preInject(handler, container.reflector),
container);
return Future.sync(() => h(req, res));
// return closureMirror.apply(args).reflectee;
@ -350,7 +353,7 @@ class Angel extends Routable {
///
/// If you are on `Dart >=2.0.0`, simply call `mountController<T>()`.
Future<T> mountController<T extends Controller>([Type? type]) {
var controller = container!.make<T>(type);
var controller = container.make<T>(type);
return configure(controller.configureServer).then((_) => controller);
}

View file

@ -223,12 +223,12 @@ class Service<Id, Data> extends Routable {
var handlers = List<RequestHandler>.from(handlerss);
// Add global middleware if declared on the instance itself
var before = getAnnotation<Middleware>(service, app!.container!.reflector);
var before = getAnnotation<Middleware>(service, app!.container.reflector);
if (before != null) handlers.addAll(before.handlers);
var indexMiddleware =
getAnnotation<Middleware>(service.index, app!.container!.reflector);
getAnnotation<Middleware>(service.index, app!.container.reflector);
get('/', (req, res) {
return index(mergeMap([
{'query': req.queryParameters},
@ -241,7 +241,7 @@ class Service<Id, Data> extends Routable {
]);
var createMiddleware =
getAnnotation<Middleware>(service.create, app!.container!.reflector);
getAnnotation<Middleware>(service.create, app!.container.reflector);
post('/', (req, ResponseContext res) {
return req.parseBody().then((_) async {
return await create(
@ -261,7 +261,7 @@ class Service<Id, Data> extends Routable {
]);
var readMiddleware =
getAnnotation<Middleware>(service.read, app!.container!.reflector);
getAnnotation<Middleware>(service.read, app!.container.reflector);
get('/:id', (req, res) {
return read(
@ -277,7 +277,7 @@ class Service<Id, Data> extends Routable {
]);
var modifyMiddleware =
getAnnotation<Middleware>(service.modify, app!.container!.reflector);
getAnnotation<Middleware>(service.modify, app!.container.reflector);
patch('/:id', (req, res) {
return req.parseBody().then((_) async {
@ -296,7 +296,7 @@ class Service<Id, Data> extends Routable {
]);
var updateMiddleware =
getAnnotation<Middleware>(service.update, app!.container!.reflector);
getAnnotation<Middleware>(service.update, app!.container.reflector);
post('/:id', (req, res) {
return req.parseBody().then((_) async {
return await update(
@ -330,7 +330,7 @@ class Service<Id, Data> extends Routable {
]);
var removeMiddleware =
getAnnotation<Middleware>(service.remove, app!.container!.reflector);
getAnnotation<Middleware>(service.remove, app!.container.reflector);
delete('/', (req, res) {
return remove(
'' as Id,

View file

@ -15,6 +15,8 @@ import 'http_response_context.dart';
final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
typedef ServerGeneratorType = Future<HttpServer> Function(dynamic, int);
/// Adapts `dart:io`'s [HttpServer] to serve Angel.
class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
HttpRequestContext, HttpResponseContext> {
@ -27,8 +29,7 @@ class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
scheme: 'http', host: server?.address.address, port: server?.port);
}
AngelHttp._(Angel app,
Future<HttpServer> Function(dynamic, int) serverGenerator, bool useZone)
AngelHttp._(Angel app, ServerGeneratorType serverGenerator, bool useZone)
: super(app, serverGenerator, useZone: useZone);
factory AngelHttp(Angel app, {bool useZone = true}) {
@ -36,8 +37,7 @@ class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
}
/// An instance mounted on a server started by the [serverGenerator].
factory AngelHttp.custom(
Angel app, Future<HttpServer> Function(dynamic, int) serverGenerator,
factory AngelHttp.custom(Angel app, ServerGeneratorType serverGenerator,
{bool useZone = true}) {
return AngelHttp._(app, serverGenerator, useZone);
}

View file

@ -77,7 +77,7 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
/// Magically transforms an [HttpRequest] into a [RequestContext].
static Future<HttpRequestContext> from(
HttpRequest request, Angel app, String path) {
var ctx = HttpRequestContext().._container = app.container!.createChild();
var ctx = HttpRequestContext().._container = app.container.createChild();
var override = request.method;

View file

@ -1,7 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:angel3_container/src/container.dart';
import 'package:angel3_container/angel3_container.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:http2/transport.dart';
@ -35,7 +35,7 @@ class Http2RequestContext extends RequestContext<ServerTransportStream?> {
Map<String, MockHttpSession> sessions,
Uuid uuid) {
var c = Completer<Http2RequestContext>();
var req = Http2RequestContext._(app.container!.createChild())
var req = Http2RequestContext._(app.container.createChild())
..app = app
.._socket = socket
.._stream = stream;

View file

@ -1,5 +1,5 @@
name: angel3_framework
version: 4.2.2
version: 4.3.0
description: A high-powered HTTP server extensible framework with dependency injection, routing and much more.
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/master/packages/framework

View file

@ -85,8 +85,8 @@ void main() {
res.redirectToAction('TodoController@foo', {'foo': 'world'}));
// Register as a singleton, just for the purpose of this test
if (!app.container!.has<TodoController>()) {
app.container!.registerSingleton(todoController = TodoController());
if (!app.container.has<TodoController>()) {
app.container.registerSingleton(todoController = TodoController());
}
// Using mountController<T>();
@ -98,7 +98,7 @@ void main() {
// Until https://github.com/angel-dart/route/issues/28 is closed,
// this will need to be done by manually mounting the router.
var subRouter = Router<RequestHandler>();
await todoController.applyRoutes(subRouter, app.container!.reflector);
await todoController.applyRoutes(subRouter, app.container.reflector);
app.mount('/ctrl_group', subRouter);
print(app.controllers);
@ -165,7 +165,7 @@ void main() {
test('named actions', () async {
var response = await client.get(Uri.parse('$url/redirect'));
print('Response: ${response.body}');
expect(response.body, equals('Hello, \"world!\"'));
expect(response.body, equals('Hello, "world!"'));
});
group('optional expose', () {

View file

@ -25,8 +25,8 @@ void main() {
client = http.Client();
// Inject some todos
app.container!.registerSingleton(Todo(text: TEXT, over: OVER));
app.container!.registerFactory<Future<Foo>>((container) async {
app.container.registerSingleton(Todo(text: TEXT, over: OVER));
app.container.registerFactory<Future<Foo>>((container) async {
var req = container.make<RequestContext>();
var text = await utf8.decoder.bind(req.body!).join();
return Foo(text);

View file

@ -1,5 +1,9 @@
# Change Log
## 3.1.2
* Fixed null safety warnings
## 3.1.1
* Fixed license link

View file

@ -8,15 +8,15 @@ void main(List<String> args) => Runner('example', configureServer).run(args);
Future configureServer(Angel app) async {
// Use the injected `pub_sub.Client` to send messages.
var client = app.container?.make<pub_sub.Client>();
var client = app.container.make<pub_sub.Client>();
var greeting = 'Hello! This is the default greeting.';
// We can listen for an event to perform some behavior.
//
// Here, we use message passing to synchronize some common state.
var onGreetingChanged = await client?.subscribe('greeting_changed');
var onGreetingChanged = await client.subscribe('greeting_changed');
onGreetingChanged
?.cast<String>()
.cast<String>()
.listen((newGreeting) => greeting = newGreeting);
// Add some routes...
@ -33,7 +33,7 @@ Future configureServer(Angel app) async {
// This route will push a new value for `greeting`.
app.get('/change_greeting/:newGreeting', (req, res) {
greeting = (req.params['newGreeting'] as String? ?? '');
client?.publish('greeting_changed', greeting);
client.publish('greeting_changed', greeting);
return 'Changed greeting -> $greeting';
});

View file

@ -50,7 +50,7 @@ ____________ ________________________
___ |__ | / /_ ____/__ ____/__ /
__ /| |_ |/ /_ / __ __ __/ __ /
_ ___ | /| / / /_/ / _ /___ _ /___
/_/ |_/_/ |_/ \____/ /_____/ /_____/
/_/ |_/_/ |_/ ____/ /_____/ /_____/
''';
@ -233,8 +233,8 @@ _ ___ | /| / / /_/ / _ /___ _ /___
pub_sub.IsolateClient('client${argsWithId.id}', args.pubSubSendPort);
var app = Angel(reflector: args.reflector)
..container!.registerSingleton<pub_sub.Client>(client)
..container!.registerSingleton(InstanceInfo(id: argsWithId.id));
..container.registerSingleton<pub_sub.Client>(client)
..container.registerSingleton(InstanceInfo(id: argsWithId.id));
app.shutdownHooks.add((_) => client.close());

View file

@ -1,5 +1,5 @@
name: angel3_production
version: 3.1.1
version: 3.1.2
description: Helpers for concurrency, message-passing, rotating loggers, and other production functionality in Angel3.
homepage: https://angel3-framework.web.app
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/production

View file

@ -1,5 +1,9 @@
# Change Log
## 3.0.0-dev.3
* Fixed null safety warnings
## 3.0.0-dev.2
* Updated to use `package:belatuk_pretty_logging`

View file

@ -106,7 +106,7 @@ class AngelShelf extends Driver<shelf.Request, ShelfResponseContext?,
var path = request.url.path.replaceAll(_straySlashes, '');
if (path.isEmpty) path = '/';
var rq =
ShelfRequestContext(app, app.container!.createChild(), request, path);
ShelfRequestContext(app, app.container.createChild(), request, path);
return Future.value(rq);
}

View file

@ -1,5 +1,5 @@
name: angel3_shelf
version: 3.0.0-dev.2
version: 3.0.0-dev.3
description: Shelf interop with Angel3. Use this to wrap existing server code.
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/master/packages/shelf