Finish after YoDesk

This commit is contained in:
thosakwe 2016-11-27 22:28:41 -05:00
parent 29ecf461dd
commit 319e195faa
8 changed files with 125 additions and 38 deletions

View file

@ -2,6 +2,7 @@
library angel_client; library angel_client;
import 'dart:async'; import 'dart:async';
import 'auth_types.dart' as auth_types;
/// A function that configures an [Angel] client in some way. /// A function that configures an [Angel] client in some way.
typedef Future AngelConfigurer(Angel app); typedef Future AngelConfigurer(Angel app);
@ -12,6 +13,8 @@ abstract class Angel {
Angel(String this.basePath); Angel(String this.basePath);
Future<AngelAuthResult> authenticate({String type: auth_types.LOCAL, credentials, String authEndpoint: '/auth'});
/// 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);
@ -20,10 +23,16 @@ abstract class Angel {
Service service(Pattern path, {Type type}); Service service(Pattern path, {Type type});
} }
/// Represents the result of authentication with an Angel server.
abstract class AngelAuthResult {
Map<String, dynamic> get data;
String get token;
}
/// Queries a service on an Angel server, with the same API. /// Queries a service on an Angel server, with the same API.
abstract class Service { abstract class Service {
/// The Angel instance powering this service. /// The Angel instance powering this service.
Angel app; Angel get app;
/// Retrieves all resources. /// Retrieves all resources.
Future<List> index([Map params]); Future<List> index([Map params]);

2
lib/auth_types.dart Normal file
View file

@ -0,0 +1,2 @@
const String GOOGLE = 'google';
const String LOCAL = 'local';

View file

@ -1,92 +1,169 @@
/// Browser library for the Angel framework. /// Browser library for the Angel framework.
library angel_client.browser; library angel_client.browser;
import 'dart:async'; import 'dart:async' show Completer, Future;
import 'dart:convert' show JSON; import 'dart:convert' show JSON;
import 'dart:html'; import 'dart:html' show HttpRequest;
import 'angel_client.dart'; import 'angel_client.dart';
import 'auth_types.dart' as auth_types;
export 'angel_client.dart'; export 'angel_client.dart';
_buildQuery(Map params) { _buildQuery(Map params) {
if (params == null || params == {}) if (params == null || params == {}) return "";
return "";
String result = ""; String result = "";
return result; return result;
} }
_send(HttpRequest request, [data]) {
final completer = new Completer<HttpRequest>();
request
..onLoadEnd.listen((_) {
completer.complete(request.response);
})
..onError.listen((_) {
try {
throw new Exception(
'Request failed with status code ${request.status}.');
} catch (e, st) {
completer.completeError(e, st);
}
});
request.send(data);
return completer.future;
}
/// Queries an Angel server via REST. /// Queries an Angel server via REST.
class Rest extends Angel { class Rest extends Angel {
Rest(String basePath) :super(basePath); String _authToken;
Rest(String basePath) : super(basePath);
@override
Future<AngelAuthResult> authenticate(
{String type: auth_types.LOCAL,
credentials,
String authEndpoint: '/auth'}) async {
final url = '$authEndpoint/$type';
if (type == auth_types.LOCAL) {
final completer = new Completer();
final request = new HttpRequest();
request.open('POST', url);
request.responseType = 'json';
request.setRequestHeader("Accept", "application/json");
request.setRequestHeader("Content-Type", "application/json");
request
..onLoadEnd.listen((_) {
completer
.complete(new _AngelAuthResultImpl.fromMap(request.response));
})
..onError.listen((_) {
try {
throw new Exception(
'Request failed with status code ${request.status}.');
} catch (e, st) {
completer.completeError(e, st);
}
});
request.send(credentials);
return completer.future;
} else {
throw new Exception('angel_client cannot authenticate as "$type" yet.');
}
}
@override @override
RestService service(String path, {Type type}) { RestService service(String path, {Type type}) {
String uri = path.replaceAll(new RegExp(r"(^\/)|(\/+$)"), ""); String uri = path.replaceAll(new RegExp(r"(^\/)|(\/+$)"), "");
return new RestService("$basePath/$uri") return new _RestServiceImpl(this, "$basePath/$uri");
..app = this;
} }
} }
/// Queries an Angel service via REST. abstract class RestService extends Service {
class RestService extends Service { RestService._(String basePath);
String basePath; }
RestService(Pattern path) { class _AngelAuthResultImpl implements AngelAuthResult {
this.basePath = (path is RegExp) ? path.pattern : path; final Map<String, dynamic> data = {};
final String token;
_AngelAuthResultImpl({this.token, Map<String, dynamic> data: const {}}) {
this.data.addAll(data ?? {});
}
factory _AngelAuthResultImpl.fromMap(Map data) =>
new _AngelAuthResultImpl(token: data['token'], data: data['data']);
}
/// Queries an Angel service via REST.
class _RestServiceImpl extends RestService {
final Rest app;
String _basePath;
String get basePath => _basePath;
_RestServiceImpl(this.app, String basePath) : super._(basePath) {
_basePath = basePath;
} }
_makeBody(data) { _makeBody(data) {
return JSON.encode(data); return JSON.encode(data);
} }
HttpRequest buildRequest(String url, Future<HttpRequest> buildRequest(String url,
{String method: "POST", bool write: true}) { {String method: "POST", bool write: true}) async {
HttpRequest request = new HttpRequest(); HttpRequest request = new HttpRequest();
request.open(method, url, async: false); request.open(method, url);
request.responseType = "json"; request.responseType = "json";
request.setRequestHeader("Accept", "application/json"); request.setRequestHeader("Accept", "application/json");
if (write) if (write) request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Content-Type", "application/json"); if (app._authToken != null)
request.setRequestHeader("Authorization", "Bearer ${app._authToken}");
return request; return request;
} }
@override @override
Future<List> index([Map params]) async { Future<List> index([Map params]) async {
return JSON.decode( final request = await buildRequest('$basePath/${_buildQuery(params)}',
await HttpRequest.getString("$basePath/${_buildQuery(params)}")); method: 'GET', write: false);
return await _send(request);
} }
@override @override
Future read(id, [Map params]) async { Future read(id, [Map params]) async {
return JSON.decode( final request = await buildRequest('$basePath/$id${_buildQuery(params)}',
await HttpRequest.getString("$basePath/$id${_buildQuery(params)}")); method: 'GET', write: false);
return await _send(request);
} }
@override @override
Future create(data, [Map params]) async { Future create(data, [Map params]) async {
var request = buildRequest("$basePath/${_buildQuery(params)}"); final request = await buildRequest("$basePath/${_buildQuery(params)}");
request.send(_makeBody(data)); return await _send(request, _makeBody(data));
return request.response;
} }
@override @override
Future modify(id, data, [Map params]) async { Future modify(id, data, [Map params]) async {
var request = buildRequest("$basePath/$id${_buildQuery(params)}", method: "PATCH"); final request = await buildRequest("$basePath/$id${_buildQuery(params)}",
request.send(_makeBody(data)); method: "PATCH");
return request.response; return await _send(request, _makeBody(data));
} }
@override @override
Future update(id, data, [Map params]) async { Future update(id, data, [Map params]) async {
var request = buildRequest("$basePath/$id${_buildQuery(params)}"); final request = await buildRequest("$basePath/$id${_buildQuery(params)}");
request.send(_makeBody(data)); return await _send(request, _makeBody(data));
return request.response;
} }
@override @override
Future remove(id, [Map params]) async { Future remove(id, [Map params]) async {
var request = buildRequest("$basePath/$id${_buildQuery(params)}", method: "DELETE"); final request = await buildRequest("$basePath/$id${_buildQuery(params)}",
request.send(); method: "DELETE");
return request.response; return await _send(request);
} }
} }

View file

@ -1,5 +1,5 @@
name: angel_client name: angel_client
version: 1.0.0-dev+7 version: 1.0.0-dev+8
description: Client library for the Angel framework. description: Client library for the Angel framework.
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_client homepage: https://github.com/angel-dart/angel_client

View file

@ -1,6 +1,6 @@
import 'dart:io'; import 'dart:io';
import "package:angel_framework/angel_framework.dart"; import "package:angel_framework/angel_framework.dart";
import "package:angel_framework/defs.dart"; import "package:angel_framework/src/defs.dart";
main() async { main() async {
Angel app = new Angel(); Angel app = new Angel();

View file

@ -1,5 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:angel_client/cli.dart' as client; import 'package:angel_client/io.dart' as client;
import 'package:angel_framework/angel_framework.dart' as server; import 'package:angel_framework/angel_framework.dart' as server;
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:json_god/json_god.dart' as god; import 'package:json_god/json_god.dart' as god;

View file

@ -1 +0,0 @@
../packages