diff --git a/README.md b/README.md index a6efbe79..6974fe84 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # angel_framework -[![pub 1.0.0-dev.51](https://img.shields.io/badge/pub-1.0.0--dev.51-red.svg)](https://pub.dartlang.org/packages/angel_framework) +[![pub 1.0.0-dev.52](https://img.shields.io/badge/pub-1.0.0--dev.52-red.svg)](https://pub.dartlang.org/packages/angel_framework) [![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework) Core libraries for the Angel Framework. diff --git a/lib/hooks.dart b/lib/hooks.dart index 7ed483c9..6962ee3b 100644 --- a/lib/hooks.dart +++ b/lib/hooks.dart @@ -1,6 +1,7 @@ /// Easy helper hooks. library angel_framework.hooks; +import 'dart:async'; import 'package:json_god/json_god.dart' as god; import 'angel_framework.dart'; @@ -19,3 +20,68 @@ HookedServiceEventListener toType(Type type) { e.data = god.deserializeDatum(e.data, outputType: type); }; } + +/// Removes one or more [key]s from service results. +/// Works on single results, and iterable results. +HookedServiceEventListener remove(key, remover(key, obj)) { + return (HookedServiceEvent e) async { + if (!e.isAfter) throw new StateError("'remove' only works on after hooks."); + + _remover(key, obj) { + if (remover != null) + return remover(key, obj); + else if (obj is List) + return obj..remove(key); + else if (obj is Iterable) + return obj.where((k) => !key); + else if (obj is Map) + return obj..remove(key); + else if (obj is Extensible) + return obj..properties.remove(key); + else + throw new ArgumentError("Cannot remove key 'key' from $obj."); + } + + var keys = key is Iterable ? key : [key]; + + _removeAll(obj) async { + var r = obj; + + for (var key in keys) { + r = await _remover(key, r); + } + + return r; + } + + if (e.result is Iterable) { + var r = await Future.wait(e.result.map(_removeAll)); + e.result = e.result is List ? r.toList() : r; + } else + e.result = await _removeAll(e.result); + }; +} + +/// Disables a service method for access from a provider. +/// +/// [provider] can be either a String, [Providers], an Iterable of String, or a +/// function that takes a [HookedServiceEvent] and returns a bool. +/// Futures are allowed. +HookedServiceEventListener disable([provider]) { + return (HookedServiceEvent e) async { + if (provider is Function) { + var r = await provider(e); + + if (r != true) throw new AngelHttpException.methodNotAllowed(); + } else { + _provide(p) => p is Providers ? p : new Providers(p.toString()); + + var providers = + provider is Iterable ? provider.map(_provide) : [_provide(provider)]; + + if (providers.any((Providers p) => p == e.params['provider'])) { + throw new AngelHttpException.methodNotAllowed(); + } + } + }; +} diff --git a/lib/src/http/hooked_service.dart b/lib/src/http/hooked_service.dart index 73eb5fa9..d5824548 100644 --- a/lib/src/http/hooked_service.dart +++ b/lib/src/http/hooked_service.dart @@ -438,9 +438,9 @@ class HookedServiceEvent { static const String REMOVED = "removed"; /// Use this to end processing of an event. - void cancel(result) { + void cancel([result]) { _canceled = true; - _result = result; + this.result = result ?? this.result; } bool _canceled = false; @@ -449,9 +449,9 @@ class HookedServiceEvent { bool _isAfter; var data; Map _params; - var _result; RequestContext _request; ResponseContext _response; + var result; String get eventName => _eventName; @@ -467,17 +467,14 @@ class HookedServiceEvent { ResponseContext get response => _response; - get result => _result; - /// The inner service whose method was hooked. Service service; HookedServiceEvent._base(this._isAfter, this._request, this._response, Service this.service, String this._eventName, - {id, this.data, Map params, result}) { + {id, this.data, Map params, this.result}) { _id = id; _params = params ?? {}; - _result = result; } } diff --git a/pubspec.yaml b/pubspec.yaml index 8ebee790..6d04f23c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_framework -version: 1.0.0-dev.51 +version: 1.0.0-dev.52 description: Core libraries for the Angel framework. author: Tobe O homepage: https://github.com/angel-dart/angel_framework