Merge branch 'feature/refactor_framework' into release/5.0.0
This commit is contained in:
commit
8469a05ff0
24 changed files with 138 additions and 98 deletions
|
@ -6,8 +6,8 @@ publish_to: none
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.10.0 <3.0.0"
|
sdk: ">=2.10.0 <3.0.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
angel_auth:
|
angel_auth: ^2.0.0
|
||||||
angel_framework:
|
angel_framework: ^2.0.0
|
||||||
http: ^0.13.0
|
http: ^0.13.0
|
||||||
path: ^1.0.0
|
path: ^1.0.0
|
||||||
twitter:
|
twitter:
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
## 6.0.0
|
## 6.0.0
|
||||||
|
|
||||||
* Updated to min SDK 2.15.x
|
* Updated to min SDK 2.15.x
|
||||||
|
* Updated `container` to non nullable
|
||||||
|
* Updated `angel` to non nullable
|
||||||
|
* Updated `logger` to non nullable
|
||||||
|
* Refactored error handler
|
||||||
|
|
||||||
## 5.0.0
|
## 5.0.0
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,13 @@ class Controller {
|
||||||
Angel? _app;
|
Angel? _app;
|
||||||
|
|
||||||
/// The [Angel] application powering this controller.
|
/// 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.
|
/// If `true` (default), this class will inject itself as a singleton into the [app]'s container when bootstrapped.
|
||||||
final bool injectSingleton;
|
final bool injectSingleton;
|
||||||
|
@ -36,12 +42,12 @@ class Controller {
|
||||||
_app = app;
|
_app = app;
|
||||||
|
|
||||||
if (injectSingleton != false) {
|
if (injectSingleton != false) {
|
||||||
if (!app.container!.has(runtimeType)) {
|
if (!app.container.has(runtimeType)) {
|
||||||
_app!.container!.registerSingleton(this, as: 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;
|
app.controllers[name] = this;
|
||||||
//return null;
|
//return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,9 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
|
||||||
|
|
||||||
HookedService(this.inner) {
|
HookedService(this.inner) {
|
||||||
// Clone app instance
|
// Clone app instance
|
||||||
if (inner.app != null) app = inner.app;
|
if (inner.isAppActive) {
|
||||||
|
app = inner.app;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -62,9 +64,9 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
|
||||||
return params['__responsectx'] as ResponseContext?;
|
return params['__responsectx'] as ResponseContext?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic>? _stripReq(Map<String, dynamic>? params) {
|
Map<String, dynamic> _stripReq(Map<String, dynamic>? params) {
|
||||||
if (params == null) {
|
if (params == null) {
|
||||||
return params;
|
return {};
|
||||||
} else {
|
} else {
|
||||||
return params.keys
|
return params.keys
|
||||||
.where((key) => key != '__requestctx' && key != '__responsectx')
|
.where((key) => key != '__requestctx' && key != '__responsectx')
|
||||||
|
@ -97,7 +99,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
|
||||||
|
|
||||||
/// Adds hooks to this instance.
|
/// Adds hooks to this instance.
|
||||||
void addHooks(Angel app) {
|
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 before = <HookedServiceEventListener<Id, Data, T>>[];
|
||||||
var after = <HookedServiceEventListener<Id, Data, T>>[];
|
var after = <HookedServiceEventListener<Id, Data, T>>[];
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ class HookedService<Id, Data, T extends Service<Id, Data>>
|
||||||
void applyListeners(
|
void applyListeners(
|
||||||
Function fn, HookedServiceEventDispatcher<Id, Data, T> dispatcher,
|
Function fn, HookedServiceEventDispatcher<Id, Data, T> dispatcher,
|
||||||
[bool? isAfter]) {
|
[bool? isAfter]) {
|
||||||
var hooks = getAnnotation<Hooks>(fn, app.container!.reflector);
|
var hooks = getAnnotation<Hooks>(fn, app.container.reflector);
|
||||||
final listeners = <HookedServiceEventListener<Id, Data, T>>[
|
final listeners = <HookedServiceEventListener<Id, Data, T>>[
|
||||||
...isAfter == true ? after : before
|
...isAfter == true ? after : before
|
||||||
];
|
];
|
||||||
|
@ -512,7 +514,7 @@ class HookedServiceEvent<Id, Data, T extends Service<Id, Data>> {
|
||||||
/// Resolves a service from the application.
|
/// Resolves a service from the application.
|
||||||
///
|
///
|
||||||
/// Shorthand for `e.service.app.service(...)`.
|
/// Shorthand for `e.service.app.service(...)`.
|
||||||
Service? getService(Pattern path) => service.app!.findService(path);
|
Service? getService(Pattern path) => service.app.findService(path);
|
||||||
|
|
||||||
bool _canceled = false;
|
bool _canceled = false;
|
||||||
final String _eventName;
|
final String _eventName;
|
||||||
|
@ -532,7 +534,7 @@ class HookedServiceEvent<Id, Data, T extends Service<Id, Data>> {
|
||||||
|
|
||||||
bool get isBefore => !isAfter;
|
bool get isBefore => !isAfter;
|
||||||
|
|
||||||
Map? get params => _params;
|
Map get params => _params ?? {};
|
||||||
|
|
||||||
RequestContext? get request => _request;
|
RequestContext? get request => _request;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ RequestHandler ioc(Function handler, {Iterable<String> optional = const []}) {
|
||||||
RequestHandler? contained;
|
RequestHandler? contained;
|
||||||
|
|
||||||
if (req.app?.container != null) {
|
if (req.app?.container != null) {
|
||||||
var injection = preInject(handler, req.app!.container!.reflector);
|
var injection = preInject(handler, req.app!.container.reflector);
|
||||||
//if (injection != null) {
|
//if (injection != null) {
|
||||||
injection.optional.addAll(optional);
|
injection.optional.addAll(optional);
|
||||||
contained = handleContained(handler, injection);
|
contained = handleContained(handler, injection);
|
||||||
|
@ -70,7 +70,7 @@ Future resolveInjection(requirement, InjectionRequest injection,
|
||||||
}
|
}
|
||||||
} else if (requirement is Type && requirement != dynamic) {
|
} else if (requirement is Type && requirement != dynamic) {
|
||||||
try {
|
try {
|
||||||
var futureType = container!.reflector.reflectFutureOf(requirement);
|
var futureType = container.reflector.reflectFutureOf(requirement);
|
||||||
if (container.has(futureType.reflectedType)) {
|
if (container.has(futureType.reflectedType)) {
|
||||||
return await container.make(futureType.reflectedType);
|
return await container.make(futureType.reflectedType);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ Future resolveInjection(requirement, InjectionRequest injection,
|
||||||
// Ignore.
|
// Ignore.
|
||||||
}
|
}
|
||||||
|
|
||||||
return await container!.make(requirement);
|
return await container.make(requirement);
|
||||||
} else if (throwOnUnresolved) {
|
} else if (throwOnUnresolved) {
|
||||||
throw ArgumentError(
|
throw ArgumentError(
|
||||||
'$requirement cannot be injected into a request handler.');
|
'$requirement cannot be injected into a request handler.');
|
||||||
|
|
|
@ -287,7 +287,7 @@ abstract class ResponseContext<RawResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
final head = controller
|
final head = controller
|
||||||
.findExpose(app!.container!.reflector)!
|
.findExpose(app!.container.reflector)!
|
||||||
.path
|
.path
|
||||||
.toString()
|
.toString()
|
||||||
.replaceAll(_straySlashes, '');
|
.replaceAll(_straySlashes, '');
|
||||||
|
|
|
@ -48,14 +48,15 @@ class Routable extends Router<RequestHandler> {
|
||||||
final Map<Pattern, Service?> _serviceLookups = {};
|
final Map<Pattern, Service?> _serviceLookups = {};
|
||||||
final Map configuration = {};
|
final Map configuration = {};
|
||||||
|
|
||||||
final Container? _container;
|
final Container _container;
|
||||||
|
|
||||||
Routable([Reflector? reflector])
|
Routable([Reflector? reflector])
|
||||||
: _container = reflector == null ? null : Container(reflector),
|
// : _container = reflector == null ? null : Container(reflector),
|
||||||
|
: _container = Container(reflector ?? ThrowingReflector()),
|
||||||
super();
|
super();
|
||||||
|
|
||||||
/// A [Container] used to inject dependencies.
|
/// A [Container] used to inject dependencies.
|
||||||
Container? get container => _container;
|
Container get container => _container;
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
_services.clear();
|
_services.clear();
|
||||||
|
@ -99,10 +100,10 @@ class Routable extends Router<RequestHandler> {
|
||||||
{Iterable<RequestHandler> middleware = const {}}) {
|
{Iterable<RequestHandler> middleware = const {}}) {
|
||||||
final handlers = <RequestHandler>[];
|
final handlers = <RequestHandler>[];
|
||||||
// Merge @Middleware declaration, if any
|
// Merge @Middleware declaration, if any
|
||||||
var reflector = _container?.reflector;
|
var reflector = _container.reflector;
|
||||||
if (reflector != null && reflector is! ThrowingReflector) {
|
if (reflector is! ThrowingReflector) {
|
||||||
var middlewareDeclaration =
|
var middlewareDeclaration =
|
||||||
getAnnotation<Middleware>(handler, _container?.reflector);
|
getAnnotation<Middleware>(handler, _container.reflector);
|
||||||
if (middlewareDeclaration != null) {
|
if (middlewareDeclaration != null) {
|
||||||
handlers.addAll(middlewareDeclaration.handlers);
|
handlers.addAll(middlewareDeclaration.handlers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'dart:async';
|
||||||
import 'dart:collection' show HashMap;
|
import 'dart:collection' show HashMap;
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:angel3_container/angel3_container.dart';
|
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_http_exception/angel3_http_exception.dart';
|
||||||
import 'package:angel3_route/angel3_route.dart';
|
import 'package:angel3_route/angel3_route.dart';
|
||||||
import 'package:belatuk_combinator/belatuk_combinator.dart';
|
import 'package:belatuk_combinator/belatuk_combinator.dart';
|
||||||
|
@ -21,17 +22,44 @@ import 'service.dart';
|
||||||
|
|
||||||
//final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
|
//final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
|
||||||
|
|
||||||
/// A function that configures an [Angel] server in some way.
|
/// A function that configures an [Angel] server.
|
||||||
typedef AngelConfigurer = FutureOr<void> Function(Angel app);
|
typedef AngelConfigurer = FutureOr<void> Function(Angel app);
|
||||||
|
|
||||||
/// A function that asynchronously generates a view from the given path and data.
|
/// A function that asynchronously generates a view from the given path and data.
|
||||||
typedef ViewGenerator = FutureOr<String> Function(String path,
|
typedef ViewGenerator = FutureOr<String> Function(String path,
|
||||||
[Map<String, dynamic>? data]);
|
[Map<String, dynamic>? data]);
|
||||||
|
|
||||||
|
/// A function that handles error
|
||||||
|
typedef AngelErrorHandler = dynamic Function(
|
||||||
|
AngelHttpException e, RequestContext req, ResponseContext res);
|
||||||
|
|
||||||
|
/// The default error handler for [Angel] server
|
||||||
|
Future<bool> _defaultErrorHandler(
|
||||||
|
AngelHttpException e, RequestContext req, ResponseContext res) async {
|
||||||
|
if (!req.accepts('text/html', strict: true) &&
|
||||||
|
(req.accepts('application/json') ||
|
||||||
|
req.accepts('application/javascript'))) {
|
||||||
|
await res.json(e.toJson());
|
||||||
|
return Future.value(false);
|
||||||
|
} else {
|
||||||
|
res.contentType = MediaType('text', 'html', {'charset': 'utf8'});
|
||||||
|
res.statusCode = e.statusCode;
|
||||||
|
res.write('<!DOCTYPE html><html><head><title>${e.message}</title>');
|
||||||
|
res.write('</head><body><h1>${e.message}</h1><ul>');
|
||||||
|
|
||||||
|
for (var error in e.errors) {
|
||||||
|
res.write('<li>$error</li>');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.write('</ul></body></html>');
|
||||||
|
return Future.value(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A powerful real-time/REST/MVC server class.
|
/// A powerful real-time/REST/MVC server class.
|
||||||
class Angel extends Routable {
|
class Angel extends Routable {
|
||||||
static ViewGenerator noViewEngineConfigured =
|
static Future<String> _noViewEngineConfigured(String view, [Map? data]) =>
|
||||||
(String view, [Map? data]) => 'No view engine has been configured yet.';
|
Future.value('No view engine has been configured yet.');
|
||||||
|
|
||||||
final List<Angel> _children = [];
|
final List<Angel> _children = [];
|
||||||
final Map<
|
final Map<
|
||||||
|
@ -114,7 +142,7 @@ class Angel extends Routable {
|
||||||
/// A [Map] of application-specific data that can be accessed by any
|
/// A [Map] of application-specific data that can be accessed by any
|
||||||
/// piece of code that can see this [Angel] instance.
|
/// piece of code that can see this [Angel] instance.
|
||||||
///
|
///
|
||||||
/// Packages like `package:angel_configuration` populate this map
|
/// Packages like `package:angel3_configuration` populate this map
|
||||||
/// for you.
|
/// for you.
|
||||||
@override
|
@override
|
||||||
final Map configuration = {};
|
final Map configuration = {};
|
||||||
|
@ -122,31 +150,10 @@ class Angel extends Routable {
|
||||||
/// A function that renders views.
|
/// A function that renders views.
|
||||||
///
|
///
|
||||||
/// Called by [ResponseContext]@`render`.
|
/// Called by [ResponseContext]@`render`.
|
||||||
ViewGenerator? viewGenerator = noViewEngineConfigured;
|
ViewGenerator? viewGenerator = _noViewEngineConfigured;
|
||||||
|
|
||||||
/// The handler currently configured to run on [AngelHttpException]s.
|
/// The handler currently configured to run on [AngelHttpException]s.
|
||||||
Function(AngelHttpException e, RequestContext req, ResponseContext res)
|
AngelErrorHandler errorHandler = _defaultErrorHandler;
|
||||||
errorHandler =
|
|
||||||
(AngelHttpException e, RequestContext req, ResponseContext res) {
|
|
||||||
if (!req.accepts('text/html', strict: true) &&
|
|
||||||
(req.accepts('application/json') ||
|
|
||||||
req.accepts('application/javascript'))) {
|
|
||||||
res.json(e.toJson());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.contentType = MediaType('text', 'html', {'charset': 'utf8'});
|
|
||||||
res.statusCode = e.statusCode; // ?? 200;
|
|
||||||
res.write('<!DOCTYPE html><html><head><title>${e.message}</title>');
|
|
||||||
res.write('</head><body><h1>${e.message}</h1><ul>');
|
|
||||||
|
|
||||||
for (var error in e.errors) {
|
|
||||||
res.write('<li>$error</li>');
|
|
||||||
}
|
|
||||||
|
|
||||||
res.write('</ul></body></html>');
|
|
||||||
res.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Route<RequestHandler> addRoute(
|
Route<RequestHandler> addRoute(
|
||||||
|
@ -184,12 +191,12 @@ class Angel extends Routable {
|
||||||
/// Loads some base dependencies into the service container.
|
/// Loads some base dependencies into the service container.
|
||||||
void bootstrapContainer() {
|
void bootstrapContainer() {
|
||||||
if (runtimeType != Angel) {
|
if (runtimeType != Angel) {
|
||||||
container?.registerSingleton(this);
|
container.registerSingleton(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
container?.registerSingleton<Angel>(this);
|
container.registerSingleton<Angel>(this);
|
||||||
container?.registerSingleton<Routable>(this);
|
container.registerSingleton<Routable>(this);
|
||||||
container?.registerSingleton<Router>(this);
|
container.registerSingleton<Router>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shuts down the server, and closes any open [StreamController]s.
|
/// Shuts down the server, and closes any open [StreamController]s.
|
||||||
|
@ -202,7 +209,7 @@ class Angel extends Routable {
|
||||||
});
|
});
|
||||||
|
|
||||||
super.close();
|
super.close();
|
||||||
viewGenerator = noViewEngineConfigured;
|
viewGenerator = _noViewEngineConfigured;
|
||||||
_preContained.clear();
|
_preContained.clear();
|
||||||
handlerCache.clear();
|
handlerCache.clear();
|
||||||
encoders.clear();
|
encoders.clear();
|
||||||
|
@ -315,6 +322,7 @@ class Angel extends Routable {
|
||||||
/// the execution will be faster, as the injection requirements were stored beforehand.
|
/// the execution will be faster, as the injection requirements were stored beforehand.
|
||||||
Future runContained(Function handler, RequestContext req, ResponseContext res,
|
Future runContained(Function handler, RequestContext req, ResponseContext res,
|
||||||
[Container? container]) {
|
[Container? container]) {
|
||||||
|
container ??= Container(MirrorsReflector());
|
||||||
return Future.sync(() {
|
return Future.sync(() {
|
||||||
if (_preContained.containsKey(handler)) {
|
if (_preContained.containsKey(handler)) {
|
||||||
return handleContained(handler, _preContained[handler]!, container)(
|
return handleContained(handler, _preContained[handler]!, container)(
|
||||||
|
@ -328,10 +336,11 @@ class Angel extends Routable {
|
||||||
/// Runs with DI, and *always* reflects. Prefer [runContained].
|
/// Runs with DI, and *always* reflects. Prefer [runContained].
|
||||||
Future runReflected(Function handler, RequestContext req, ResponseContext res,
|
Future runReflected(Function handler, RequestContext req, ResponseContext res,
|
||||||
[Container? container]) {
|
[Container? container]) {
|
||||||
container ??= req.container ?? res.app!.container;
|
container ??=
|
||||||
|
req.container ?? res.app?.container ?? Container(ThrowingReflector());
|
||||||
var h = handleContained(
|
var h = handleContained(
|
||||||
handler,
|
handler,
|
||||||
_preContained[handler] = preInject(handler, container!.reflector),
|
_preContained[handler] = preInject(handler, container.reflector),
|
||||||
container);
|
container);
|
||||||
return Future.sync(() => h(req, res));
|
return Future.sync(() => h(req, res));
|
||||||
// return closureMirror.apply(args).reflectee;
|
// return closureMirror.apply(args).reflectee;
|
||||||
|
@ -350,7 +359,7 @@ class Angel extends Routable {
|
||||||
///
|
///
|
||||||
/// If you are on `Dart >=2.0.0`, simply call `mountController<T>()`.
|
/// If you are on `Dart >=2.0.0`, simply call `mountController<T>()`.
|
||||||
Future<T> mountController<T extends Controller>([Type? type]) {
|
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);
|
return configure(controller.configureServer).then((_) => controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +401,7 @@ class Angel extends Routable {
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrapContainer();
|
bootstrapContainer();
|
||||||
viewGenerator ??= noViewEngineConfigured;
|
viewGenerator ??= _noViewEngineConfigured;
|
||||||
serializer ??= json.encode;
|
serializer ??= json.encode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,20 @@ class Service<Id, Data> extends Routable {
|
||||||
List<RequestHandler> get bootstrappers => [];
|
List<RequestHandler> get bootstrappers => [];
|
||||||
|
|
||||||
/// The [Angel] app powering this service.
|
/// The [Angel] app powering this service.
|
||||||
Angel? app;
|
Angel? _app;
|
||||||
|
|
||||||
|
Angel get app {
|
||||||
|
if (_app == null) {
|
||||||
|
throw ArgumentError("Angel is not initialized");
|
||||||
|
}
|
||||||
|
return _app!;
|
||||||
|
}
|
||||||
|
|
||||||
|
set app(Angel angel) {
|
||||||
|
_app = angel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get isAppActive => _app != null;
|
||||||
|
|
||||||
/// Closes this service, including any database connections or stream controllers.
|
/// Closes this service, including any database connections or stream controllers.
|
||||||
@override
|
@override
|
||||||
|
@ -223,12 +236,12 @@ class Service<Id, Data> extends Routable {
|
||||||
var handlers = List<RequestHandler>.from(handlerss);
|
var handlers = List<RequestHandler>.from(handlerss);
|
||||||
|
|
||||||
// Add global middleware if declared on the instance itself
|
// 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);
|
if (before != null) handlers.addAll(before.handlers);
|
||||||
|
|
||||||
var indexMiddleware =
|
var indexMiddleware =
|
||||||
getAnnotation<Middleware>(service.index, app!.container!.reflector);
|
getAnnotation<Middleware>(service.index, app.container.reflector);
|
||||||
get('/', (req, res) {
|
get('/', (req, res) {
|
||||||
return index(mergeMap([
|
return index(mergeMap([
|
||||||
{'query': req.queryParameters},
|
{'query': req.queryParameters},
|
||||||
|
@ -241,7 +254,7 @@ class Service<Id, Data> extends Routable {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var createMiddleware =
|
var createMiddleware =
|
||||||
getAnnotation<Middleware>(service.create, app!.container!.reflector);
|
getAnnotation<Middleware>(service.create, app.container.reflector);
|
||||||
post('/', (req, ResponseContext res) {
|
post('/', (req, ResponseContext res) {
|
||||||
return req.parseBody().then((_) async {
|
return req.parseBody().then((_) async {
|
||||||
return await create(
|
return await create(
|
||||||
|
@ -261,7 +274,7 @@ class Service<Id, Data> extends Routable {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var readMiddleware =
|
var readMiddleware =
|
||||||
getAnnotation<Middleware>(service.read, app!.container!.reflector);
|
getAnnotation<Middleware>(service.read, app.container.reflector);
|
||||||
|
|
||||||
get('/:id', (req, res) {
|
get('/:id', (req, res) {
|
||||||
return read(
|
return read(
|
||||||
|
@ -277,7 +290,7 @@ class Service<Id, Data> extends Routable {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var modifyMiddleware =
|
var modifyMiddleware =
|
||||||
getAnnotation<Middleware>(service.modify, app!.container!.reflector);
|
getAnnotation<Middleware>(service.modify, app.container.reflector);
|
||||||
|
|
||||||
patch('/:id', (req, res) {
|
patch('/:id', (req, res) {
|
||||||
return req.parseBody().then((_) async {
|
return req.parseBody().then((_) async {
|
||||||
|
@ -296,7 +309,7 @@ class Service<Id, Data> extends Routable {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var updateMiddleware =
|
var updateMiddleware =
|
||||||
getAnnotation<Middleware>(service.update, app!.container!.reflector);
|
getAnnotation<Middleware>(service.update, app.container.reflector);
|
||||||
post('/:id', (req, res) {
|
post('/:id', (req, res) {
|
||||||
return req.parseBody().then((_) async {
|
return req.parseBody().then((_) async {
|
||||||
return await update(
|
return await update(
|
||||||
|
@ -330,7 +343,7 @@ class Service<Id, Data> extends Routable {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
var removeMiddleware =
|
var removeMiddleware =
|
||||||
getAnnotation<Middleware>(service.remove, app!.container!.reflector);
|
getAnnotation<Middleware>(service.remove, app.container.reflector);
|
||||||
delete('/', (req, res) {
|
delete('/', (req, res) {
|
||||||
return remove(
|
return remove(
|
||||||
'' as Id,
|
'' as Id,
|
||||||
|
|
|
@ -15,6 +15,8 @@ import 'http_response_context.dart';
|
||||||
|
|
||||||
final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
|
final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
|
||||||
|
|
||||||
|
typedef ServerGeneratorType = Future<HttpServer> Function(dynamic, int);
|
||||||
|
|
||||||
/// Adapts `dart:io`'s [HttpServer] to serve Angel.
|
/// Adapts `dart:io`'s [HttpServer] to serve Angel.
|
||||||
class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
|
class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
|
||||||
HttpRequestContext, HttpResponseContext> {
|
HttpRequestContext, HttpResponseContext> {
|
||||||
|
@ -27,8 +29,7 @@ class AngelHttp extends Driver<HttpRequest, HttpResponse, HttpServer,
|
||||||
scheme: 'http', host: server?.address.address, port: server?.port);
|
scheme: 'http', host: server?.address.address, port: server?.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
AngelHttp._(Angel app,
|
AngelHttp._(Angel app, ServerGeneratorType serverGenerator, bool useZone)
|
||||||
Future<HttpServer> Function(dynamic, int) serverGenerator, bool useZone)
|
|
||||||
: super(app, serverGenerator, useZone: useZone);
|
: super(app, serverGenerator, useZone: useZone);
|
||||||
|
|
||||||
factory AngelHttp(Angel app, {bool useZone = true}) {
|
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].
|
/// An instance mounted on a server started by the [serverGenerator].
|
||||||
factory AngelHttp.custom(
|
factory AngelHttp.custom(Angel app, ServerGeneratorType serverGenerator,
|
||||||
Angel app, Future<HttpServer> Function(dynamic, int) serverGenerator,
|
|
||||||
{bool useZone = true}) {
|
{bool useZone = true}) {
|
||||||
return AngelHttp._(app, serverGenerator, useZone);
|
return AngelHttp._(app, serverGenerator, useZone);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class HttpRequestContext extends RequestContext<HttpRequest?> {
|
||||||
/// Magically transforms an [HttpRequest] into a [RequestContext].
|
/// Magically transforms an [HttpRequest] into a [RequestContext].
|
||||||
static Future<HttpRequestContext> from(
|
static Future<HttpRequestContext> from(
|
||||||
HttpRequest request, Angel app, String path) {
|
HttpRequest request, Angel app, String path) {
|
||||||
var ctx = HttpRequestContext().._container = app.container!.createChild();
|
var ctx = HttpRequestContext().._container = app.container.createChild();
|
||||||
|
|
||||||
var override = request.method;
|
var override = request.method;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
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:angel3_framework/angel3_framework.dart';
|
||||||
import 'package:collection/collection.dart' show IterableExtension;
|
import 'package:collection/collection.dart' show IterableExtension;
|
||||||
import 'package:http2/transport.dart';
|
import 'package:http2/transport.dart';
|
||||||
|
@ -35,7 +35,7 @@ class Http2RequestContext extends RequestContext<ServerTransportStream?> {
|
||||||
Map<String, MockHttpSession> sessions,
|
Map<String, MockHttpSession> sessions,
|
||||||
Uuid uuid) {
|
Uuid uuid) {
|
||||||
var c = Completer<Http2RequestContext>();
|
var c = Completer<Http2RequestContext>();
|
||||||
var req = Http2RequestContext._(app.container!.createChild())
|
var req = Http2RequestContext._(app.container.createChild())
|
||||||
..app = app
|
..app = app
|
||||||
.._socket = socket
|
.._socket = socket
|
||||||
.._stream = stream;
|
.._stream = stream;
|
||||||
|
|
|
@ -3,7 +3,7 @@ library performance.hello;
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
Future<Null> main() {
|
Future<void> main() {
|
||||||
return HttpServer.bind('127.0.0.1', 3000, shared: true).then((server) {
|
return HttpServer.bind('127.0.0.1', 3000, shared: true).then((server) {
|
||||||
print('Listening at http://${server.address.address}:${server.port}');
|
print('Listening at http://${server.address.address}:${server.port}');
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@ description: A high-powered HTTP server extensible framework with dependency inj
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/framework
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/framework
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.12.0 <3.0.0'
|
sdk: '>=2.15.0 <3.0.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
angel3_container: ^3.1.0
|
angel3_container: ^6.0.0
|
||||||
angel3_http_exception: ^3.0.0
|
angel3_http_exception: ^6.0.0
|
||||||
angel3_model: ^3.1.0
|
angel3_model: ^6.0.0
|
||||||
angel3_route: ^5.2.0
|
angel3_route: ^6.0.0
|
||||||
angel3_mock_request: ^2.0.0
|
angel3_mock_request: ^6.0.0
|
||||||
belatuk_merge_map: ^3.0.0
|
belatuk_merge_map: ^3.0.0
|
||||||
belatuk_combinator: ^3.0.0
|
belatuk_combinator: ^3.0.0
|
||||||
belatuk_http_server: ^2.1.0
|
belatuk_http_server: ^2.1.0
|
||||||
|
|
|
@ -85,8 +85,8 @@ void main() {
|
||||||
res.redirectToAction('TodoController@foo', {'foo': 'world'}));
|
res.redirectToAction('TodoController@foo', {'foo': 'world'}));
|
||||||
|
|
||||||
// Register as a singleton, just for the purpose of this test
|
// Register as a singleton, just for the purpose of this test
|
||||||
if (!app.container!.has<TodoController>()) {
|
if (!app.container.has<TodoController>()) {
|
||||||
app.container!.registerSingleton(todoController = TodoController());
|
app.container.registerSingleton(todoController = TodoController());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using mountController<T>();
|
// Using mountController<T>();
|
||||||
|
@ -98,7 +98,7 @@ void main() {
|
||||||
// Until https://github.com/angel-dart/route/issues/28 is closed,
|
// Until https://github.com/angel-dart/route/issues/28 is closed,
|
||||||
// this will need to be done by manually mounting the router.
|
// this will need to be done by manually mounting the router.
|
||||||
var subRouter = Router<RequestHandler>();
|
var subRouter = Router<RequestHandler>();
|
||||||
await todoController.applyRoutes(subRouter, app.container!.reflector);
|
await todoController.applyRoutes(subRouter, app.container.reflector);
|
||||||
app.mount('/ctrl_group', subRouter);
|
app.mount('/ctrl_group', subRouter);
|
||||||
|
|
||||||
print(app.controllers);
|
print(app.controllers);
|
||||||
|
@ -165,7 +165,7 @@ void main() {
|
||||||
test('named actions', () async {
|
test('named actions', () async {
|
||||||
var response = await client.get(Uri.parse('$url/redirect'));
|
var response = await client.get(Uri.parse('$url/redirect'));
|
||||||
print('Response: ${response.body}');
|
print('Response: ${response.body}');
|
||||||
expect(response.body, equals('Hello, \"world!\"'));
|
expect(response.body, equals('Hello, "world!"'));
|
||||||
});
|
});
|
||||||
|
|
||||||
group('optional expose', () {
|
group('optional expose', () {
|
||||||
|
|
|
@ -25,8 +25,8 @@ void main() {
|
||||||
client = http.Client();
|
client = http.Client();
|
||||||
|
|
||||||
// Inject some todos
|
// Inject some todos
|
||||||
app.container!.registerSingleton(Todo(text: TEXT, over: OVER));
|
app.container.registerSingleton(Todo(text: TEXT, over: OVER));
|
||||||
app.container!.registerFactory<Future<Foo>>((container) async {
|
app.container.registerFactory<Future<Foo>>((container) async {
|
||||||
var req = container.make<RequestContext>();
|
var req = container.make<RequestContext>();
|
||||||
var text = await utf8.decoder.bind(req.body!).join();
|
var text = await utf8.decoder.bind(req.body!).join();
|
||||||
return Foo(text);
|
return Foo(text);
|
||||||
|
|
|
@ -135,8 +135,8 @@ void main() {
|
||||||
var type = e.isBefore ? 'before' : 'after';
|
var type = e.isBefore ? 'before' : 'after';
|
||||||
print('Params to $type ${e.eventName}: ${e.params}');
|
print('Params to $type ${e.eventName}: ${e.params}');
|
||||||
expect(e.params, isMap);
|
expect(e.params, isMap);
|
||||||
expect(e.params?.keys, contains('provider'));
|
expect(e.params.keys, contains('provider'));
|
||||||
expect(e.params?['provider'], const IsInstanceOf<Providers>());
|
expect(e.params['provider'], const IsInstanceOf<Providers>());
|
||||||
}
|
}
|
||||||
|
|
||||||
svc
|
svc
|
||||||
|
|
|
@ -8,7 +8,7 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
charcode: ^1.2.0
|
charcode: ^1.2.0
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
angel3_framework: ^4.2.0
|
angel3_framework: ^6.0.0
|
||||||
http: ^0.13.2
|
http: ^0.13.2
|
||||||
test: ^1.17.4
|
test: ^1.17.4
|
||||||
lints: ^1.0.0
|
lints: ^1.0.0
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
## 3.1.2
|
## 3.1.2
|
||||||
|
|
||||||
* Updated repo link
|
* Updated repo link
|
||||||
|
* Fixed null safety warnings
|
||||||
|
|
||||||
## 3.1.1
|
## 3.1.1
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,15 @@ void main(List<String> args) => Runner('example', configureServer).run(args);
|
||||||
|
|
||||||
Future configureServer(Angel app) async {
|
Future configureServer(Angel app) async {
|
||||||
// Use the injected `pub_sub.Client` to send messages.
|
// 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.';
|
var greeting = 'Hello! This is the default greeting.';
|
||||||
|
|
||||||
// We can listen for an event to perform some behavior.
|
// We can listen for an event to perform some behavior.
|
||||||
//
|
//
|
||||||
// Here, we use message passing to synchronize some common state.
|
// 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
|
onGreetingChanged
|
||||||
?.cast<String>()
|
.cast<String>()
|
||||||
.listen((newGreeting) => greeting = newGreeting);
|
.listen((newGreeting) => greeting = newGreeting);
|
||||||
|
|
||||||
// Add some routes...
|
// Add some routes...
|
||||||
|
@ -33,7 +33,7 @@ Future configureServer(Angel app) async {
|
||||||
// This route will push a new value for `greeting`.
|
// This route will push a new value for `greeting`.
|
||||||
app.get('/change_greeting/:newGreeting', (req, res) {
|
app.get('/change_greeting/:newGreeting', (req, res) {
|
||||||
greeting = (req.params['newGreeting'] as String? ?? '');
|
greeting = (req.params['newGreeting'] as String? ?? '');
|
||||||
client?.publish('greeting_changed', greeting);
|
client.publish('greeting_changed', greeting);
|
||||||
return 'Changed greeting -> $greeting';
|
return 'Changed greeting -> $greeting';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -233,8 +233,8 @@ _ ___ | /| / / /_/ / _ /___ _ /___
|
||||||
pub_sub.IsolateClient('client${argsWithId.id}', args.pubSubSendPort);
|
pub_sub.IsolateClient('client${argsWithId.id}', args.pubSubSendPort);
|
||||||
|
|
||||||
var app = Angel(reflector: args.reflector)
|
var app = Angel(reflector: args.reflector)
|
||||||
..container!.registerSingleton<pub_sub.Client>(client)
|
..container.registerSingleton<pub_sub.Client>(client)
|
||||||
..container!.registerSingleton(InstanceInfo(id: argsWithId.id));
|
..container.registerSingleton(InstanceInfo(id: argsWithId.id));
|
||||||
|
|
||||||
app.shutdownHooks.add((_) => client.close());
|
app.shutdownHooks.add((_) => client.close());
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## 3.0.0-dev.3
|
||||||
|
|
||||||
|
* Fixed null safety warnings
|
||||||
|
|
||||||
## 3.0.0-dev.2
|
## 3.0.0-dev.2
|
||||||
|
|
||||||
* Updated to use `package:belatuk_pretty_logging`
|
* Updated to use `package:belatuk_pretty_logging`
|
||||||
|
|
|
@ -106,7 +106,7 @@ class AngelShelf extends Driver<shelf.Request, ShelfResponseContext?,
|
||||||
var path = request.url.path.replaceAll(_straySlashes, '');
|
var path = request.url.path.replaceAll(_straySlashes, '');
|
||||||
if (path.isEmpty) path = '/';
|
if (path.isEmpty) path = '/';
|
||||||
var rq =
|
var rq =
|
||||||
ShelfRequestContext(app, app.container!.createChild(), request, path);
|
ShelfRequestContext(app, app.container.createChild(), request, path);
|
||||||
return Future.value(rq);
|
return Future.value(rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel3_shelf
|
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.
|
description: Shelf interop with Angel3. Use this to wrap existing server code.
|
||||||
homepage: https://angel3-framework.web.app/
|
homepage: https://angel3-framework.web.app/
|
||||||
repository: https://github.com/dukefirehawk/angel/tree/master/packages/shelf
|
repository: https://github.com/dukefirehawk/angel/tree/master/packages/shelf
|
||||||
|
|
Loading…
Reference in a new issue