49!!!
This commit is contained in:
parent
929e7bbac6
commit
4c04e1193c
4 changed files with 99 additions and 76 deletions
|
@ -1,6 +1,6 @@
|
||||||
# angel_framework
|
# angel_framework
|
||||||
|
|
||||||
[![pub 1.0.0-dev.48](https://img.shields.io/badge/pub-1.0.0--dev.48-red.svg)](https://pub.dartlang.org/packages/angel_framework)
|
[![pub 1.0.0-dev.49](https://img.shields.io/badge/pub-1.0.0--dev.49-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)
|
[![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework)
|
||||||
|
|
||||||
Core libraries for the Angel Framework.
|
Core libraries for the Angel Framework.
|
||||||
|
|
|
@ -41,6 +41,16 @@ class HookedService extends Service {
|
||||||
if (inner.app != null) this.app = inner.app;
|
if (inner.app != null) this.app = inner.app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestContext _getRequest(Map params) {
|
||||||
|
if (params == null) return null;
|
||||||
|
return params['__requestctx'];
|
||||||
|
}
|
||||||
|
|
||||||
|
ResponseContext _getResponse(Map params) {
|
||||||
|
if (params == null) return null;
|
||||||
|
return params['__responsectx'];
|
||||||
|
}
|
||||||
|
|
||||||
Map _stripReq(Map params) {
|
Map _stripReq(Map params) {
|
||||||
if (params == null)
|
if (params == null)
|
||||||
return params;
|
return params;
|
||||||
|
@ -192,21 +202,21 @@ class HookedService extends Service {
|
||||||
Future<List> index([Map _params]) async {
|
Future<List> index([Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeIndexed._emit(
|
HookedServiceEvent before = await beforeIndexed._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.INDEXED,
|
_getResponse(_params), inner, HookedServiceEvent.INDEXED,
|
||||||
params: params));
|
params: params));
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await beforeIndexed._emit(
|
HookedServiceEvent after = await beforeIndexed._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.INDEXED,
|
_getResponse(_params), inner, HookedServiceEvent.INDEXED,
|
||||||
params: params, result: before.result));
|
params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List result = await inner.index(params);
|
List result = await inner.index(params);
|
||||||
HookedServiceEvent after = await afterIndexed._emit(
|
HookedServiceEvent after = await afterIndexed._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.INDEXED,
|
_getResponse(_params), inner, HookedServiceEvent.INDEXED,
|
||||||
params: params, result: result));
|
params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
@ -215,22 +225,22 @@ class HookedService extends Service {
|
||||||
Future read(id, [Map _params]) async {
|
Future read(id, [Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeRead._emit(
|
HookedServiceEvent before = await beforeRead._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.READ,
|
_getResponse(_params), inner, HookedServiceEvent.READ,
|
||||||
id: id, params: params));
|
id: id, params: params));
|
||||||
|
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await afterRead._emit(
|
HookedServiceEvent after = await afterRead._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.READ,
|
_getResponse(_params), inner, HookedServiceEvent.READ,
|
||||||
id: id, params: params, result: before.result));
|
id: id, params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await inner.read(id, params);
|
var result = await inner.read(id, params);
|
||||||
HookedServiceEvent after = await afterRead._emit(
|
HookedServiceEvent after = await afterRead._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.READ,
|
_getResponse(_params), inner, HookedServiceEvent.READ,
|
||||||
id: id, params: params, result: result));
|
id: id, params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
@ -239,22 +249,22 @@ class HookedService extends Service {
|
||||||
Future create(data, [Map _params]) async {
|
Future create(data, [Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeCreated._emit(
|
HookedServiceEvent before = await beforeCreated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.CREATED,
|
_getResponse(_params), inner, HookedServiceEvent.CREATED,
|
||||||
data: data, params: params));
|
data: data, params: params));
|
||||||
|
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await afterCreated._emit(
|
HookedServiceEvent after = await afterCreated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.CREATED,
|
_getResponse(_params), inner, HookedServiceEvent.CREATED,
|
||||||
data: data, params: params, result: before.result));
|
data: data, params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await inner.create(data, params);
|
var result = await inner.create(data, params);
|
||||||
HookedServiceEvent after = await afterCreated._emit(
|
HookedServiceEvent after = await afterCreated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.CREATED,
|
_getResponse(_params), inner, HookedServiceEvent.CREATED,
|
||||||
data: data, params: params, result: result));
|
data: data, params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
@ -263,22 +273,22 @@ class HookedService extends Service {
|
||||||
Future modify(id, data, [Map _params]) async {
|
Future modify(id, data, [Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeModified._emit(
|
HookedServiceEvent before = await beforeModified._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.MODIFIED,
|
_getResponse(_params), inner, HookedServiceEvent.MODIFIED,
|
||||||
id: id, data: data, params: params));
|
id: id, data: data, params: params));
|
||||||
|
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await afterModified._emit(
|
HookedServiceEvent after = await afterModified._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.MODIFIED,
|
_getResponse(_params), inner, HookedServiceEvent.MODIFIED,
|
||||||
id: id, data: data, params: params, result: before.result));
|
id: id, data: data, params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await inner.modify(id, data, params);
|
var result = await inner.modify(id, data, params);
|
||||||
HookedServiceEvent after = await afterModified._emit(
|
HookedServiceEvent after = await afterModified._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.MODIFIED,
|
_getResponse(_params), inner, HookedServiceEvent.MODIFIED,
|
||||||
id: id, data: data, params: params, result: result));
|
id: id, data: data, params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
@ -287,22 +297,22 @@ class HookedService extends Service {
|
||||||
Future update(id, data, [Map _params]) async {
|
Future update(id, data, [Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeUpdated._emit(
|
HookedServiceEvent before = await beforeUpdated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.UPDATED,
|
_getResponse(_params), inner, HookedServiceEvent.UPDATED,
|
||||||
id: id, data: data, params: params));
|
id: id, data: data, params: params));
|
||||||
|
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await afterUpdated._emit(
|
HookedServiceEvent after = await afterUpdated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.UPDATED,
|
_getResponse(_params), inner, HookedServiceEvent.UPDATED,
|
||||||
id: id, data: data, params: params, result: before.result));
|
id: id, data: data, params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await inner.update(id, data, params);
|
var result = await inner.update(id, data, params);
|
||||||
HookedServiceEvent after = await afterUpdated._emit(
|
HookedServiceEvent after = await afterUpdated._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.UPDATED,
|
_getResponse(_params), inner, HookedServiceEvent.UPDATED,
|
||||||
id: id, data: data, params: params, result: result));
|
id: id, data: data, params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
@ -311,29 +321,30 @@ class HookedService extends Service {
|
||||||
Future remove(id, [Map _params]) async {
|
Future remove(id, [Map _params]) async {
|
||||||
var params = _stripReq(_params);
|
var params = _stripReq(_params);
|
||||||
HookedServiceEvent before = await beforeRemoved._emit(
|
HookedServiceEvent before = await beforeRemoved._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.REMOVED,
|
_getResponse(_params), inner, HookedServiceEvent.REMOVED,
|
||||||
id: id, params: params));
|
id: id, params: params));
|
||||||
|
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = await afterRemoved._emit(
|
HookedServiceEvent after = await afterRemoved._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.REMOVED,
|
_getResponse(_params), inner, HookedServiceEvent.REMOVED,
|
||||||
id: id, params: params, result: before.result));
|
id: id, params: params, result: before.result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await inner.remove(id, params);
|
var result = await inner.remove(id, params);
|
||||||
HookedServiceEvent after = await afterRemoved._emit(
|
HookedServiceEvent after = await afterRemoved._emit(
|
||||||
new HookedServiceEvent._base(_params['__requestctx'],
|
new HookedServiceEvent._base(_getRequest(_params),
|
||||||
params['__responsectx'], inner, HookedServiceEvent.REMOVED,
|
_getResponse(_params), inner, HookedServiceEvent.REMOVED,
|
||||||
id: id, params: params, result: result));
|
id: id, params: params, result: result));
|
||||||
return after.result;
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fires an `after` event. This will not be propagated to clients,
|
/// Fires an `after` event. This will not be propagated to clients,
|
||||||
/// but will be broadcasted to WebSockets, etc.
|
/// but will be broadcasted to WebSockets, etc.
|
||||||
Future<HookedServiceEvent> fire(String eventName, result, [HookedServiceEventListener callback]) async {
|
Future<HookedServiceEvent> fire(String eventName, result,
|
||||||
|
[HookedServiceEventListener callback]) async {
|
||||||
HookedServiceEventDispatcher dispatcher;
|
HookedServiceEventDispatcher dispatcher;
|
||||||
|
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
|
|
|
@ -124,7 +124,7 @@ class Angel extends AngelBase {
|
||||||
///
|
///
|
||||||
/// Returns false on failure; otherwise, returns the HttpServer.
|
/// Returns false on failure; otherwise, returns the HttpServer.
|
||||||
Future<HttpServer> startServer([InternetAddress address, int port]) async {
|
Future<HttpServer> startServer([InternetAddress address, int port]) async {
|
||||||
final host = address ?? InternetAddress.LOOPBACK_IP_V4;
|
var host = address ?? InternetAddress.LOOPBACK_IP_V4;
|
||||||
this.httpServer = await _serverGenerator(host, port ?? 0);
|
this.httpServer = await _serverGenerator(host, port ?? 0);
|
||||||
preprocessRoutes();
|
preprocessRoutes();
|
||||||
return httpServer..listen(handleRequest);
|
return httpServer..listen(handleRequest);
|
||||||
|
@ -188,38 +188,44 @@ class Angel extends AngelBase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<RequestContext> createRequestContext(HttpRequest request) {
|
||||||
|
_beforeProcessed.add(request);
|
||||||
|
return RequestContext.from(request, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ResponseContext> createResponseContext(HttpResponse response) async =>
|
||||||
|
new ResponseContext(response, this);
|
||||||
|
|
||||||
/// Handles a single request.
|
/// Handles a single request.
|
||||||
Future handleRequest(HttpRequest request) async {
|
Future handleRequest(HttpRequest request) async {
|
||||||
try {
|
try {
|
||||||
_beforeProcessed.add(request);
|
var req = await createRequestContext(request);
|
||||||
|
var res = await createResponseContext(request.response);
|
||||||
final req = await RequestContext.from(request, this);
|
|
||||||
final res = new ResponseContext(request.response, this);
|
|
||||||
String requestedUrl = request.uri.path.replaceAll(_straySlashes, '');
|
String requestedUrl = request.uri.path.replaceAll(_straySlashes, '');
|
||||||
|
|
||||||
if (requestedUrl.isEmpty) requestedUrl = '/';
|
if (requestedUrl.isEmpty) requestedUrl = '/';
|
||||||
|
|
||||||
final resolved =
|
var resolved =
|
||||||
resolveAll(requestedUrl, requestedUrl, method: request.method);
|
resolveAll(requestedUrl, requestedUrl, method: request.method);
|
||||||
|
|
||||||
for (final result in resolved) req.params.addAll(result.allParams);
|
for (var result in resolved) req.params.addAll(result.allParams);
|
||||||
|
|
||||||
if (resolved.isNotEmpty) {
|
if (resolved.isNotEmpty) {
|
||||||
final route = resolved.first.route;
|
var route = resolved.first.route;
|
||||||
req.inject(Match, route.match(requestedUrl));
|
req.inject(Match, route.match(requestedUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
final m = new MiddlewarePipeline(resolved);
|
var m = new MiddlewarePipeline(resolved);
|
||||||
req.inject(MiddlewarePipeline, m);
|
req.inject(MiddlewarePipeline, m);
|
||||||
|
|
||||||
final pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after);
|
var pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after);
|
||||||
|
|
||||||
_printDebug('Handler sequence on $requestedUrl: $pipeline');
|
_printDebug('Handler sequence on $requestedUrl: $pipeline');
|
||||||
|
|
||||||
for (final handler in pipeline) {
|
for (var handler in pipeline) {
|
||||||
try {
|
try {
|
||||||
_printDebug('Executing handler: $handler');
|
_printDebug('Executing handler: $handler');
|
||||||
final result = await executeHandler(handler, req, res);
|
var result = await executeHandler(handler, req, res);
|
||||||
_printDebug('Result: $result');
|
_printDebug('Result: $result');
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -262,27 +268,7 @@ class Angel extends AngelBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_afterProcessed.add(request);
|
await sendRequest(request, req, res);
|
||||||
|
|
||||||
if (!res.willCloseItself) {
|
|
||||||
for (var finalizer in responseFinalizers) {
|
|
||||||
await finalizer(req, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var key in res.headers.keys) {
|
|
||||||
request.response.headers.add(key, res.headers[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
request.response.headers
|
|
||||||
..chunkedTransferEncoding = res.chunked ?? true
|
|
||||||
..set(HttpHeaders.CONTENT_LENGTH, res.buffer.length);
|
|
||||||
|
|
||||||
request.response
|
|
||||||
..statusCode = res.statusCode
|
|
||||||
..cookies.addAll(res.cookies)
|
|
||||||
..add(res.buffer.takeBytes());
|
|
||||||
await request.response.close();
|
|
||||||
}
|
|
||||||
} catch (e, st) {
|
} catch (e, st) {
|
||||||
_fatalErrorStream
|
_fatalErrorStream
|
||||||
.add(new AngelFatalError(request: request, error: e, stack: st));
|
.add(new AngelFatalError(request: request, error: e, stack: st));
|
||||||
|
@ -339,6 +325,32 @@ class Angel extends AngelBase {
|
||||||
// return await closureMirror.apply(args).reflectee;
|
// return await closureMirror.apply(args).reflectee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends a response.
|
||||||
|
Future sendRequest(
|
||||||
|
HttpRequest request, RequestContext req, ResponseContext res) async {
|
||||||
|
_afterProcessed.add(request);
|
||||||
|
|
||||||
|
if (!res.willCloseItself) {
|
||||||
|
for (var finalizer in responseFinalizers) {
|
||||||
|
await finalizer(req, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var key in res.headers.keys) {
|
||||||
|
request.response.headers.add(key, res.headers[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
request.response.headers
|
||||||
|
..chunkedTransferEncoding = res.chunked ?? true
|
||||||
|
..set(HttpHeaders.CONTENT_LENGTH, res.buffer.length);
|
||||||
|
|
||||||
|
request.response
|
||||||
|
..statusCode = res.statusCode
|
||||||
|
..cookies.addAll(res.cookies)
|
||||||
|
..add(res.buffer.takeBytes());
|
||||||
|
await request.response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Applies an [AngelConfigurer] to this instance.
|
/// Applies an [AngelConfigurer] to this instance.
|
||||||
Future configure(AngelConfigurer configurer) async {
|
Future configure(AngelConfigurer configurer) async {
|
||||||
await configurer(this);
|
await configurer(this);
|
||||||
|
@ -366,7 +378,7 @@ class Angel extends AngelBase {
|
||||||
@override
|
@override
|
||||||
use(Pattern path, Routable routable,
|
use(Pattern path, Routable routable,
|
||||||
{bool hooked: true, String namespace: null}) {
|
{bool hooked: true, String namespace: null}) {
|
||||||
final head = path.toString().replaceAll(_straySlashes, '');
|
var head = path.toString().replaceAll(_straySlashes, '');
|
||||||
|
|
||||||
if (routable is Angel) {
|
if (routable is Angel) {
|
||||||
_children.add(routable.._parent = this);
|
_children.add(routable.._parent = this);
|
||||||
|
@ -396,12 +408,12 @@ class Angel extends AngelBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
routable.controllers.forEach((k, v) {
|
routable.controllers.forEach((k, v) {
|
||||||
final tail = k.toString().replaceAll(_straySlashes, '');
|
var tail = k.toString().replaceAll(_straySlashes, '');
|
||||||
controllers['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
controllers['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
||||||
});
|
});
|
||||||
|
|
||||||
routable.services.forEach((k, v) {
|
routable.services.forEach((k, v) {
|
||||||
final tail = k.toString().replaceAll(_straySlashes, '');
|
var tail = k.toString().replaceAll(_straySlashes, '');
|
||||||
services['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
services['$head/$tail'.replaceAll(_straySlashes, '')] = v;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -434,7 +446,7 @@ class Angel extends AngelBase {
|
||||||
/// the server.
|
/// the server.
|
||||||
factory Angel.secure(String certificateChainPath, String serverKeyPath,
|
factory Angel.secure(String certificateChainPath, String serverKeyPath,
|
||||||
{bool debug: false, String password}) {
|
{bool debug: false, String password}) {
|
||||||
final app = new Angel(debug: debug == true);
|
var app = new Angel(debug: debug == true);
|
||||||
|
|
||||||
app._serverGenerator = (InternetAddress address, int port) async {
|
app._serverGenerator = (InternetAddress address, int port) async {
|
||||||
var certificateChain =
|
var certificateChain =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: angel_framework
|
name: angel_framework
|
||||||
version: 1.0.0-dev.48
|
version: 1.0.0-dev.49
|
||||||
description: Core libraries for the Angel framework.
|
description: Core libraries for the Angel framework.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_framework
|
homepage: https://github.com/angel-dart/angel_framework
|
||||||
|
|
Loading…
Reference in a new issue